| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- # -*- coding: utf-8 -*-
- """pages.yaml 校验 + pages.json 生成脚本
- 用法: python build_pages.py (在本目录 references/ 下运行或任意目录均可)
- """
- import json
- import re
- import sys
- from pathlib import Path
- try:
- import yaml
- except ImportError:
- print("ERROR: 需要 PyYAML(pip install pyyaml)")
- sys.exit(1)
- HERE = Path(__file__).parent
- YAML_PATH = HERE / "pages.yaml"
- JSON_PATH = HERE / "pages.json"
- CONFIG_PATH = HERE.parent / "config.yaml"
- errors, warns = [], []
- # ---------- 读取 ----------
- data = yaml.safe_load(YAML_PATH.read_text(encoding="utf-8"))
- cfg = yaml.safe_load(CONFIG_PATH.read_text(encoding="utf-8"))
- base_url = (cfg.get("base_url") or "").rstrip("/")
- if not re.match(r"^https?://[^/\s]+(:\d+)?$", base_url):
- errors.append(f"config.yaml base_url 非法: {base_url}")
- # ---------- 遍历校验 ----------
- pages, all_ids, menu_keys = [], [], []
- def check_page(p, cat, group):
- pid = p.get("id")
- if not pid:
- errors.append(f"缺少 id: {p.get('name')}")
- return
- if pid in all_ids:
- errors.append(f"id 重复: {pid}")
- all_ids.append(pid)
- path = p.get("path", "")
- if not path.startswith("/"):
- errors.append(f"[{pid}] path 不以 / 开头: {path}")
- url = base_url + path
- if "//" in url.replace("://", ""):
- errors.append(f"[{pid}] URL 拼接出现双斜杠: {url}")
- if not p.get("name"):
- errors.append(f"[{pid}] 缺少 name")
- if not p.get("desc"):
- errors.append(f"[{pid}] 缺少 desc")
- mk = p.get("menu_key", "")
- if mk:
- if mk in menu_keys:
- warns.append(f"menu_key 重复: {mk} ({pid})")
- menu_keys.append(mk)
- pages.append({
- "id": pid, "name": p["name"], "aliases": p.get("aliases") or [],
- "keywords": p.get("keywords") or [], "menu_key": mk or None,
- "path": path, "desc": p.get("desc", ""),
- "usage": p.get("usage"), "usage_tip": p.get("usage_tip"),
- "visible": p.get("visible", True), "note": p.get("note"),
- "category": cat["name"], "group": group,
- })
- for cat in data.get("categories", []):
- if cat.get("pages"):
- for p in cat["pages"]:
- check_page(p, cat, None)
- for g in cat.get("groups") or []:
- for p in g.get("pages") or []:
- check_page(p, cat, g["name"])
- # ---------- docx 原 URL 覆盖性比对 ----------
- docx_paths = [
- "/monitorChannel/monitor-windrect?id=1931597465741889538&deviceType=windrect",
- "/monitorChannel/monitor-sensorMonitor",
- "/monitorChannel/monitor-fanmain?id=2087348159538384898&deviceType=fanmain",
- "/monitorChannel/monitor-fanlocal?id=1712030595700707330&deviceType=fanlocal",
- "/monitorChannel/monitor-gate?id=1796536612492324866&deviceType=gate",
- "/monitorChannel/monitor-window?id=1427837547259232258&deviceType=window",
- "/micro-vent-3dModal/configurable/default/ventS/home?type=model3D&deviceType=model3D&isNoReverse=1",
- "/micro-vent-2dModal/configurable/default/ventS/home?type=model3D&deviceType=model3D&isNoReverse=1",
- "/micro-vent-3dModal/dashboard/analysis?type=sysMonitor&deviceType=timenetcal",
- "/micro-vent-3dModal/dashboard/analysis?type=sysMonitor&deviceType=pathDecison",
- "/micro-need-air/",
- "/micro-need-air/workAccount/",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=fiber&tabtype=monitor",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=bundletube",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=modelsensor_temperature&deviceid=",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=modelsensor_smoke&deviceid=",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=modelsensor_co&deviceid=",
- "/nitrogen-home", "/grout-home",
- "/monitorChannel/monitor-firedoor?id=2019226919389147138&deviceType=door",
- "/micro-vent-3dModal/configurable/belt/fireS/home",
- "/configurable/default/fireDoorMonitor/home",
- "/monitorChannel/balancePress-home", "/fire/warn/home?p=0",
- "/bundle/bundleTable", "/bundleSpy/bundleSpyTable",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=gaspatrol",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=modelsensor_gas&deviceid=",
- "/gas/gas-pump-monitor/home", "/gas/warn/home?p=0", "/gas/gas-report-inspect",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=dusting&tabtype=monitor",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=atomizing",
- "/dust/dedustefan/home", "/dust/warn/home", "/dust/dustMonitorTable",
- "/monitorChannel/monitor-alarm-home", "/monitorChannel/wokerFace-home",
- "/monitorChannel/tunFace-home",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=location&tabtype=monitor",
- "/micro-vent-3dModal/dashboard/analysis?type=tunMonitor&deviceType=vehicle",
- "/monitorChannel/device-monitor/safetymonitor", "/camera", "/forcFan/home",
- "/fileManager/fileDetail/home", "/monitorChannel/system/user",
- "/monitorChannel/system/project-setting",
- ]
- # 温度/烟雾/CO/瓦斯传感器 docx 旧地址在注册表中有意替换为菜单地址,单独登记
- replaced_intentionally = {
- "modelsensor_temperature", "modelsensor_smoke", "modelsensor_co", "modelsensor_gas",
- }
- reg_paths = {p["path"] for p in pages}
- for dp in docx_paths:
- if dp in reg_paths:
- continue
- if any(k in dp for k in replaced_intentionally):
- warns.append(f"docx地址已按菜单有意替换: {dp}")
- continue
- if "sysfiretest" in dp:
- warns.append(f"docx地址已更新参数(菜单最新值): {dp}")
- continue
- if "electro-chamber" in dp:
- warns.append(f"docx错误地址已弃用(electro-chamber): {dp}")
- continue
- errors.append(f"docx 页面缺失: {dp}")
- # ---------- 统计与输出 ----------
- visible_pages = [p for p in pages if p["visible"]]
- with_usage = [p for p in pages if p.get("usage")]
- out = {
- "version": data.get("version"), "updated": data.get("updated"),
- "base_url": base_url,
- "stats": {
- "total": len(pages), "visible": len(visible_pages),
- "with_usage": len(with_usage),
- "categories": len(data.get("categories", [])),
- },
- "pages": pages,
- }
- JSON_PATH.write_text(json.dumps(out, ensure_ascii=False, indent=2), encoding="utf-8")
- print(f"总条目: {len(pages)} | 可见: {len(visible_pages)} | 含操作指引: {len(with_usage)} | 分类: {len(data.get('categories', []))}")
- print(f"pages.json 已生成: {JSON_PATH}")
- for w in warns:
- print("WARN:", w)
- if errors:
- print("\n== 校验失败 ==")
- for e in errors:
- print("ERROR:", e)
- sys.exit(1)
- print("校验全部通过 ✔")
|