# -*- coding: utf-8 -*- """从 @iconify-json/icon-park-outline 里抽出**本项目实际用到的那几十个图标**, 生成 `frontend-pc/src/icons/icon-data.ts`。 为什么不直接依赖 `@iconify/vue` + 在线 API: 1. 这套系统要能**内网离线部署**,运行时去 iconify 拉图标会白屏; 2. 整包 `icons.json` 有 4MB+,为了 20 个图标打进产物不划算。 所以:构建前跑一次本脚本(图标集升级时重跑),产物是一个纯数据的 TS 文件。 """ from __future__ import annotations import json import os ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SRC = os.path.join(ROOT, "frontend-pc", "node_modules", "@iconify-json", "icon-park-outline", "icons.json") OUT = os.path.join(ROOT, "frontend-pc", "src", "icons", "icon-data.ts") # 键 = 前端用的短名;值 = iconify 集合里的图标名 WANTED = { # ── 菜单与分组 ───────────────────────────── "dashboard": "dashboard-one", "collect": "application-two", "setting": "setting-two", "org-group": "every-user", "platform": "server", "task": "list-two", "audit": "check-one", "export": "download-two", "notify": "remind", "dict": "list-two", "org": "tree-list", "user": "peoples", "role": "permissions", "tenant": "school", "log": "log", # ── 通用动作 ─────────────────────────────── "fold": "menu-fold-one", "unfold": "menu-unfold-one", "account": "user", "logout": "logout", "refresh": "refresh", "plus": "plus", "search": "search", "close": "close", "check": "check", "warning": "caution", "info": "info", "download": "download", "upload": "upload", "edit": "edit", "delete": "delete", "more": "more", "arrow-down": "down", "file": "file-text", "photo": "picture-one", "idcard": "id-card", "school-roll": "book-one", "work-proof": "doc-detail", } def main() -> int: if not os.path.exists(SRC): print(f"找不到图标集:{SRC}\n(先 cd frontend-pc && pnpm install)") return 1 with open(SRC, encoding="utf-8") as f: data = json.load(f) icons = data.get("icons") or {} aliases = data.get("aliases") or {} out: dict[str, dict] = {} missing: list[str] = [] for short, name in WANTED.items(): node = icons.get(name) if node is None and name in aliases: parent = aliases[name].get("parent") node = icons.get(parent) if parent else None if node is None: missing.append(name) continue out[short] = { "body": node["body"], "width": node.get("width", data.get("width", 48)), "height": node.get("height", data.get("height", 48)), } os.makedirs(os.path.dirname(OUT), exist_ok=True) lines = [ "/**", " * 菜单与通用图标的数据(由 scripts/extract-pc-icons.py 生成,**不要手改**)。", " *", f" * 来源:@iconify-json/icon-park-outline({data.get('info', {}).get('name', '?')}),", f" * 只抽了本项目实际用到的 {len(out)} 个,避免把 4MB 的整包打进来。", " */", "", "export interface IconData {", " body: string", " width: number", " height: number", "}", "", "export const ICONS: Record = {", ] for short in WANTED: if short not in out: continue node = out[short] body = node["body"].replace("\\", "\\\\").replace("'", "\\'") lines.append(f" '{short}': {{") lines.append(f" body: '{body}',") lines.append(f" width: {node['width']},") lines.append(f" height: {node['height']}") lines.append(" },") lines.append("}") lines.append("") with open(OUT, "w", encoding="utf-8", newline="\n") as f: f.write("\n".join(lines)) print(f"已生成 {os.path.relpath(OUT, ROOT)}:{len(out)} 个图标") if missing: print("⚠️ 集合里没有这些图标(已跳过,请改名或换一个):") for m in missing: print(f" - {m}") return 0 if __name__ == "__main__": raise SystemExit(main())