ykxmz 1.5.0锛氫慨澶嶆墜琛ㄧ TLS 璇佷功鏍¢獙 + MTU 淇缃戠粶绋冲畾鎬?

琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞
- 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀?
鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException
- 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴?
鏈嶅姟鍣ㄧ
- 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級
- 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯
- 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺?
鏂囨。
- 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
This commit is contained in:
xmz7891
2026-10-06 19:01:05 +08:00
commit b705216e4a
3195 changed files with 203292 additions and 0 deletions
+202
View File
@@ -0,0 +1,202 @@
# -*- coding: utf-8 -*-
"""中转管理端加"批量删除"(重写版)。
上一版的坑:
1. JS 里的换行我写成 \\n,但 relay.py 里是 f-string,
\\n 会被还原成真换行 -> JS 字符串跨行 -> 语法错误。
正确写法是补丁里用 \\\\n,这样 relay.py 源码里是 \\n,
f-string 渲染后 JS 拿到的是 反斜杠+n 两个字符。
2. rows.append 的锚点带太多上下文,容易被空格差异搞挂。
换成最小锚点。
"""
from __future__ import annotations
import ast
import sys
from pathlib import Path
RELAY = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\relay" r"\relay.py")
# ---------------------------------------------------------------- 后端
BACKEND_ANCHOR = ''' if path in ("/v1/admin/delete", "/v1/admin/delete_all"):'''
BACKEND_NEW = ''' if path == "/v1/admin/delete_many":
# 批量删除:勾几台删几台。
# 和"删除全部"的区别:不动没勾的,也不清孤儿绑定。
body = self._json_body()
wanted = body.get("deviceIds") or []
if not isinstance(wanted, list):
self._json(400, {"ok": False, "error": "deviceIds 要是数组"})
return
wanted = [str(item).strip() for item in wanted
if str(item).strip()]
if not wanted:
self._json(400, {"ok": False, "error": "没有勾选任何设备"})
return
results = [RELAY.delete_device(device_id=item)
for item in wanted]
done = [r for r in results if r.get("ok")]
failed = [r for r in results if not r.get("ok")]
log(f"管理操作:批量删除 {len(done)}/{len(wanted)} 台设备")
self._json(200, {
"ok": True,
"requested": len(wanted),
"deleted": len(done),
"failed": len(failed),
"devices": done,
"errors": failed[:10],
})
return
''' + BACKEND_ANCHOR
# ---------------------------------------------------------------- 行里加复选框(最小锚点)
ROW_ANCHOR = ''' rows.append(
"<tr>"
'''
ROW_NEW = ''' rows.append(
"<tr>"
# 批量删除用的复选框。value 放 deviceId。
"<td class=pickcell>"
f'<input type=checkbox class=pick value="{_esc(device["deviceId"])}">'
"</td>"
'''
# ---------------------------------------------------------------- 表头全选
HEADER_ANCHOR = "<table><tr><th>设备</th>"
HEADER_NEW = ("<table><tr><th class=pickcell>"
'<input type=checkbox id=pickAll title="全选"></th>'
"<th>设备</th>")
# ---------------------------------------------------------------- 顶部按钮
BAR_ANCHOR = " <button class=del id=delAll>删除全部设备</button>"
BAR_NEW = (" <button class=del id=delPicked>删除选中</button>\n"
" <button class=del id=delAll>删除全部设备</button>")
# ---------------------------------------------------------------- 样式
CSS_ANCHOR = (" button.del:hover{{background:#5a1c22;border-color:#a33;"
"color:#ffa198}}")
CSS_NEW = CSS_ANCHOR + """
button.del:disabled{{opacity:.45;cursor:not-allowed}}
.pickcell{{width:34px;text-align:center;padding-left:10px;padding-right:0}}
input[type=checkbox]{{width:15px;height:15px;cursor:pointer;accent-color:#2f81f7}}
tr.picked td{{background:#1f2733}}"""
# ---------------------------------------------------------------- 前端 JS
# 注意:这里写 \\\\n,落到 relay.py 里是 \\n,
# 再经 f-string 渲染,JS 拿到的才是 反斜杠+n。
JS_ANCHOR = '''document.querySelectorAll('button.del[data-device]').forEach(b => {{
b.onclick = () => del(b.dataset.device, b.dataset.name, b.dataset.code);
}});'''
JS_NEW = JS_ANCHOR + """
// ---------------- 批量删除 ----------------
const picks = () => Array.from(document.querySelectorAll('input.pick'));
const picked = () => picks().filter(c => c.checked).map(c => c.value);
function refreshPickState() {{
const chosen = picked().length;
const btn = document.getElementById('delPicked');
if (btn) {{
btn.disabled = chosen === 0;
btn.textContent = chosen ? ('删除选中 (' + chosen + ')') : '删除选中';
}}
picks().forEach(c => {{
const tr = c.closest('tr');
if (tr) tr.classList.toggle('picked', c.checked);
}});
const all = document.getElementById('pickAll');
if (all) {{
const total = picks().length;
all.checked = total > 0 && chosen === total;
all.indeterminate = chosen > 0 && chosen < total;
}}
}}
picks().forEach(c => c.addEventListener('change', refreshPickState));
const pickAll = document.getElementById('pickAll');
if (pickAll) pickAll.addEventListener('change', () => {{
picks().forEach(c => {{ c.checked = pickAll.checked; }});
refreshPickState();
}});
refreshPickState();
const delPicked = document.getElementById('delPicked');
if (delPicked) delPicked.onclick = async () => {{
const ids = picked();
if (!ids.length) return;
if (!confirm('删除选中的 ' + ids.length + ' 台设备?\\\\n\\\\n'
+ '会断开它们现在的手表连接,并清掉它们占的配对码。'))
return;
delPicked.disabled = true;
try {{
const r = await fetch('/v1/admin/delete_many', {{
method: 'POST',
headers: {{'Content-Type': 'application/json'}},
body: JSON.stringify({{deviceIds: ids}})
}});
const j = await r.json();
if (j.ok) {{
alert('已删除 ' + j.deleted + ' 台设备'
+ (j.failed ? (',' + j.failed + ' 台失败') : ''));
location.reload();
}} else {{
alert('删除失败:' + (j.error || '未知错误'));
delPicked.disabled = false;
}}
}} catch (e) {{
alert('请求出错:' + e);
delPicked.disabled = false;
}}
}};"""
PAIRS = [
(BACKEND_ANCHOR, BACKEND_NEW),
(ROW_ANCHOR, ROW_NEW),
(HEADER_ANCHOR, HEADER_NEW),
(BAR_ANCHOR, BAR_NEW),
(CSS_ANCHOR, CSS_NEW),
(JS_ANCHOR, JS_NEW),
]
def main() -> int:
text = RELAY.read_text(encoding="utf-8")
if "delete_many" in text:
print(" 已经加过了")
return 0
ok = True
for old, new in PAIRS:
if old not in text:
print(f" [失败] 锚点没找到 -> {old.strip()[:70]!r}")
ok = False
continue
if text.count(old) != 1:
print(f" [警告] 锚点出现 {text.count(old)} 次,只替换第一处")
text = text.replace(old, new, 1)
RELAY.write_text(text, encoding="utf-8", newline="\n")
if ok:
print(" 已加:/v1/admin/delete_many + 复选框 + 全选 + 删除选中")
try:
ast.parse(RELAY.read_text(encoding="utf-8"))
print(" relay.py 语法 OK")
except SyntaxError as exc:
print(f" relay.py 语法错误: 行 {exc.lineno}: {exc.msg}")
ok = False
return 0 if ok else 1
if __name__ == "__main__":
sys.exit(main())