1.7.1:修白屏 + 配对 + 官网管理页分家

手表端
- 修「连上后一片白屏」:initTabs() 从来没被调用过,
  导致 tabDefs 为 null、selectTab 直接 return,
  标签栏里只剩一个孤立的滑动指示器
- 应用名改成 ykxmz

被控端
- 修「设备已关闭新设备配对」:配对码本身就是密钥,
  拿着正确的码就该放行。老逻辑"首台配对后自动关窗"会把
  手表重装的人永久挡在外面
- 应用名改成 ykxmz

服务器端
- / 改成官网(公开,简洁介绍 + 下载)
- /zhingzhuanzhan 中转站管理(要登录),/admin 自动跳转
- 管理账号 xmz7891,可改
- 官网 / 登录页 / 管理页都加上 favicon
This commit is contained in:
xmz7891
2026-10-06 23:08:07 +08:00
parent bc7a022c6e
commit 81e923a0aa
24 changed files with 1829 additions and 23 deletions
+121
View File
@@ -0,0 +1,121 @@
# -*- coding: utf-8 -*-
r"""白屏排查:直接问被控端要 feature_list,看返回什么。
手表连上后是白屏 —— 说明 buildFeatureTab() 里那个
client.call({"cmd": "feature_list"})
没拿到可用数据。这里用 Python 直接走一遍同样的流程,
把原始返回打出来。
"""
from __future__ import annotations
import json
import os
import shutil
import socket
import subprocess
import sys
import time
from pathlib import Path
ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote")
PORT = 8871
DATA = ROOT / "_build" / "_whitetest"
def send(sock, obj) -> dict:
sock.sendall((json.dumps(obj, ensure_ascii=False) + "\n").encode("utf-8"))
buf = b""
deadline = time.time() + 20
while time.time() < deadline:
chunk = sock.recv(65536)
if not chunk:
break
buf += chunk
if b"\n" in buf:
line = buf.split(b"\n", 1)[0]
return json.loads(line.decode("utf-8"))
raise TimeoutError("没收到回复")
def main() -> int:
shutil.rmtree(DATA, ignore_errors=True)
env = dict(os.environ)
env["YKXMZ_DATA"] = str(DATA)
env["PYTHONIOENCODING"] = "utf-8"
print(" 起被控端…")
proc = subprocess.Popen(
[sys.executable, "run_agent.py", "--port", str(PORT),
"--new-code", "--add-device", "10"],
cwd=str(ROOT / "windows"), env=env,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
try:
ready = False
for _ in range(50):
try:
s = socket.create_connection(("127.0.0.1", PORT), timeout=1)
s.close()
ready = True
break
except OSError:
time.sleep(0.4)
print(f" 端口就绪: {ready}")
if not ready:
return 1
time.sleep(1)
# 读配对码
settings = json.loads((DATA / "settings.json").read_text(encoding="utf-8"))
code = settings.get("pairing_code")
print(f" 配对码: {code}")
sock = socket.create_connection(("127.0.0.1", PORT), timeout=10)
sock.settimeout(20)
print()
print(" 1) 配对(命令名是 pair,不是 handshake)")
reply = send(sock, {"cmd": "pair", "code": code,
"deviceId": "watch-probe-1",
"name": "手表"})
print(f" 完整回复: {json.dumps(reply, ensure_ascii=False)[:400]}")
print(f" ok={reply.get('ok')} token={'有' if reply.get('token') else '无'}")
token = reply.get("token")
print()
print(" 2) feature_list")
reply = send(sock, {"cmd": "feature_list", "token": token})
print(f" 顶层键: {list(reply.keys())}")
features = reply.get("features")
print(f" features 类型: {type(features).__name__}")
if isinstance(features, list):
print(f" features 条数: {len(features)}")
groups = {}
for item in features[:200]:
if isinstance(item, dict):
g = item.get("group", "(无 group)")
groups[g] = groups.get(g, 0) + 1
else:
print(f" ⚠ 非字典元素: {item!r}")
print(f" 分组: {groups}")
if features:
print(f" 第一条: {json.dumps(features[0], ensure_ascii=False)[:200]}")
else:
print(f" ⚠ features 不是列表: {str(features)[:200]}")
print()
print(" 3) 原始返回(前 400 字符)")
print(f" {json.dumps(reply, ensure_ascii=False)[:400]}")
sock.close()
finally:
proc.terminate()
try:
proc.wait(timeout=10)
except subprocess.TimeoutExpired:
proc.kill()
return 0
if __name__ == "__main__":
sys.exit(main())