From cec5607c451201cb87ce905f3c835871f9bbd156 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 16 Jun 2026 14:30:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20Flowcharts.vue=20JSON=20?= =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E7=BC=96=E8=BE=91=20+=209=20=E5=A5=97?= =?UTF-8?q?=E6=8E=92=E6=9F=A5=E6=A8=A1=E6=9D=BF=E7=A7=8D=E5=AD=90=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为管理后台'排查流程图'模块加 JSON 在线编辑能力 + 提供 9 套 办公 IT 常见故障排查模板种子数据(账号/系统/企微/VPN/邮箱/网络/ 打印机/软件/硬件),管理员可基于此学习、筛选、修改、新增。 ## 选型(按'优选开源'原则) - @codemirror/lang-json / state / theme-one-dark / view - codemirror(核心) - vue-codemirror(Vue 3 集成) - vue-json-pretty(JSON 树形预览) 全部为社区成熟开源组件,非自行开发 ## 改动 - frontend-admin/package.json: 加 6 个 npm 依赖 - frontend-admin/src/api/troubleshooting.ts(新): TS 类型 + 5 个 API client(listTemplates / getTemplate / createTemplate / updateTemplate / deleteTemplate) + formatJson/validateJson/ countNodes/countDecisions 工具函数 - frontend-admin/src/components/flowchart/FlowchartEditorDialog.vue(新): 双面板编辑器(左 CodeMirror + 右 vue-json-pretty), 实时 JSON 校验 + 节点/决策统计 + 格式/复制/导出按钮 - frontend-admin/src/views/Flowcharts.vue(改): 列表 + 导入/导出/ 新建按钮 + EditorDialog 集成 + 文件上传 + 删除确认 ## 9 套种子数据 - 01-account-password.json 账号密码 - 02-pc-system.json 电脑系统 - 03-wecom.json 企微问题 - 04-vpn.json VPN 接入 - 05-email.json 邮箱 - 06-network.json 网络 - 07-printer.json 打印机 - 08-software.json 软件 - 09-hardware.json 硬件 每套 ~150-200 行,结构:name / category / description / estimated_time / difficulty / tags / root_node(决策树) ## 工具脚本 - data/seed-templates/build_all.py: 合并 9 个 JSON 成 00-all.json --- data/seed-templates/01-account-password.json | 109 ++++ data/seed-templates/02-pc-system.json | 142 ++++++ data/seed-templates/03-wecom.json | 104 ++++ data/seed-templates/04-vpn.json | 65 +++ data/seed-templates/05-email.json | 65 +++ data/seed-templates/06-network.json | 89 ++++ data/seed-templates/07-printer.json | 80 +++ data/seed-templates/08-software.json | 75 +++ data/seed-templates/09-hardware.json | 80 +++ data/seed-templates/build_all.py | 54 ++ frontend-admin/package.json | 7 + frontend-admin/src/api/troubleshooting.ts | 171 +++++++ .../flowchart/FlowchartEditorDialog.vue | 475 ++++++++++++++++++ frontend-admin/src/views/Flowcharts.vue | 464 +++++++++++------ 14 files changed, 1824 insertions(+), 156 deletions(-) create mode 100644 data/seed-templates/01-account-password.json create mode 100644 data/seed-templates/02-pc-system.json create mode 100644 data/seed-templates/03-wecom.json create mode 100644 data/seed-templates/04-vpn.json create mode 100644 data/seed-templates/05-email.json create mode 100644 data/seed-templates/06-network.json create mode 100644 data/seed-templates/07-printer.json create mode 100644 data/seed-templates/08-software.json create mode 100644 data/seed-templates/09-hardware.json create mode 100644 data/seed-templates/build_all.py create mode 100644 frontend-admin/src/api/troubleshooting.ts create mode 100644 frontend-admin/src/components/flowchart/FlowchartEditorDialog.vue diff --git a/data/seed-templates/01-account-password.json b/data/seed-templates/01-account-password.json new file mode 100644 index 0000000..ab06e8f --- /dev/null +++ b/data/seed-templates/01-account-password.json @@ -0,0 +1,109 @@ +{ + "name": "账号密码 / SSO 登录故障排查", + "category": "account", + "description": "员工忘记密码、账号被锁、SSO 单点登录失败、AD 域账号同步异常", + "estimated_time": 6, + "difficulty": 1, + "tags": ["账号", "密码", "SSO", "AD域", "登录"], + "root_node": { + "id": "fc-acct-1", + "type": "step", + "label": "确认员工使用哪种登录方式(域账号/企微SSO/邮箱SSO)", + "status": "pending", + "children": [ + { + "id": "fc-acct-2", + "type": "decision", + "label": "是否提示账号已锁定?", + "yes_branch": { + "id": "fc-acct-3", + "type": "step", + "label": "AD 管理控制台解锁账号 + 重置临时密码", + "status": "pending", + "children": [ + { + "id": "fc-acct-4", + "type": "step", + "label": "通知员工首次登录需修改密码", + "status": "pending" + }, + { + "id": "fc-acct-5", + "type": "decision", + "label": "员工能正常登录?", + "yes_branch": { + "id": "fc-acct-6", + "type": "step", + "label": "回访确认 + 提醒密码保管" + }, + "no_branch": { + "id": "fc-acct-7", + "type": "step", + "label": "升级二线:信息安全团队" + } + } + ] + }, + "no_branch": { + "id": "fc-acct-8", + "type": "step", + "label": "确认密码是否过期(>90天)", + "status": "pending", + "children": [ + { + "id": "fc-acct-9", + "type": "decision", + "label": "SSO 登录页能打开?", + "yes_branch": { + "id": "fc-acct-10", + "type": "step", + "label": "引导员工走自助密码重置流程", + "status": "pending", + "children": [ + { + "id": "fc-acct-11", + "type": "decision", + "label": "重置邮件是否收到?", + "yes_branch": { + "id": "fc-acct-12", + "type": "step", + "label": "按邮件链接重置 + 回访" + }, + "no_branch": { + "id": "fc-acct-13", + "type": "step", + "label": "检查邮箱/反垃圾/电话二次验证" + } + } + ] + }, + "no_branch": { + "id": "fc-acct-14", + "type": "step", + "label": "检查浏览器代理 + 缓存 + 尝试无痕模式", + "status": "pending", + "children": [ + { + "id": "fc-acct-15", + "type": "decision", + "label": "换浏览器/无痕能打开?", + "yes_branch": { + "id": "fc-acct-16", + "type": "step", + "label": "指导员工清除原浏览器缓存" + }, + "no_branch": { + "id": "fc-acct-17", + "type": "step", + "label": "升级二线:检查 SSO 网关状态" + } + } + ] + } + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/02-pc-system.json b/data/seed-templates/02-pc-system.json new file mode 100644 index 0000000..a3822a5 --- /dev/null +++ b/data/seed-templates/02-pc-system.json @@ -0,0 +1,142 @@ +{ + "name": "电脑 / Windows 系统故障排查", + "category": "system", + "description": "员工电脑蓝屏、死机、卡顿、开机黑屏、Windows 更新失败", + "estimated_time": 15, + "difficulty": 3, + "tags": ["电脑", "Windows", "蓝屏", "系统更新", "卡顿"], + "root_node": { + "id": "fc-sys-1", + "type": "step", + "label": "确认故障现象(蓝屏代码/卡顿/黑屏/无法开机)", + "status": "pending", + "children": [ + { + "id": "fc-sys-2", + "type": "decision", + "label": "电脑能正常开机进入桌面?", + "yes_branch": { + "id": "fc-sys-3", + "type": "step", + "label": "引导员工打开任务管理器查看资源占用", + "status": "pending", + "children": [ + { + "id": "fc-sys-4", + "type": "decision", + "label": "CPU/内存/磁盘哪项占用高?", + "yes_branch": { + "id": "fc-sys-5", + "type": "step", + "label": "按占用类型分别处理:", + "status": "current", + "children": [ + { + "id": "fc-sys-6", + "type": "step", + "label": "CPU高:结束异常进程,查启动项", + "status": "pending" + }, + { + "id": "fc-sys-7", + "type": "step", + "label": "内存高:检查泄漏进程,加内存条", + "status": "pending" + }, + { + "id": "fc-sys-8", + "type": "step", + "label": "磁盘100%:查大文件/重做系统考虑", + "status": "pending" + } + ] + }, + "no_branch": { + "id": "fc-sys-9", + "type": "step", + "label": "检查最近安装的软件/驱动/更新", + "status": "pending", + "children": [ + { + "id": "fc-sys-10", + "type": "decision", + "label": "回滚后是否恢复?", + "yes_branch": { + "id": "fc-sys-11", + "type": "step", + "label": "标记该软件/更新为不兼容,记录案例" + }, + "no_branch": { + "id": "fc-sys-12", + "type": "step", + "label": "进入安全模式进一步排查" + } + } + ] + } + } + ] + }, + "no_branch": { + "id": "fc-sys-13", + "type": "step", + "label": "判断开机阶段(BIOS/启动管理器/登录界面)", + "status": "pending", + "children": [ + { + "id": "fc-sys-14", + "type": "decision", + "label": "能进安全模式?", + "yes_branch": { + "id": "fc-sys-15", + "type": "step", + "label": "在安全模式卸载最近驱动/更新", + "status": "pending", + "children": [ + { + "id": "fc-sys-16", + "type": "decision", + "label": "重启后正常?", + "yes_branch": { + "id": "fc-sys-17", + "type": "step", + "label": "回访确认 + 记录故障点" + }, + "no_branch": { + "id": "fc-sys-18", + "type": "step", + "label": "备份数据后考虑重装系统" + } + } + ] + }, + "no_branch": { + "id": "fc-sys-19", + "type": "step", + "label": "硬件层故障:硬盘/内存条/主板", + "status": "pending", + "children": [ + { + "id": "fc-sys-20", + "type": "decision", + "label": "外接显示器/拔内存条有变化?", + "yes_branch": { + "id": "fc-sys-21", + "type": "step", + "label": "对症更换硬件(联系硬件供应商)" + }, + "no_branch": { + "id": "fc-sys-22", + "type": "step", + "label": "升级二线:送修 / 申请备用机" + } + } + ] + } + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/03-wecom.json b/data/seed-templates/03-wecom.json new file mode 100644 index 0000000..996f629 --- /dev/null +++ b/data/seed-templates/03-wecom.json @@ -0,0 +1,104 @@ +{ + "name": "企业微信 / 协作工具故障排查", + "category": "wecom", + "description": "企微登录失败、消息发不出、群文件无法下载、视频会议卡顿、审批打不开", + "estimated_time": 8, + "difficulty": 2, + "tags": ["企微", "WeCom", "消息", "视频会议", "审批", "协作"], + "root_node": { + "id": "fc-wc-1", + "type": "step", + "label": "确认故障模块(消息/会议/审批/通讯录/文件)", + "status": "pending", + "children": [ + { + "id": "fc-wc-2", + "type": "decision", + "label": "能否登录企微(手机/电脑端)?", + "no_branch": { + "id": "fc-wc-3", + "type": "step", + "label": "引导员工:重新扫码登录/更新企微版本", + "status": "pending", + "children": [ + { + "id": "fc-wc-4", + "type": "decision", + "label": "重新登录成功?", + "yes_branch": { + "id": "fc-wc-5", + "type": "step", + "label": "回访确认其他功能也正常" + }, + "no_branch": { + "id": "fc-wc-6", + "type": "step", + "label": "检查公司是否全员断网/账号是否离职" + } + } + ] + }, + "yes_branch": { + "id": "fc-wc-7", + "type": "step", + "label": "按故障模块分别处理:", + "status": "current", + "children": [ + { + "id": "fc-wc-8", + "type": "step", + "label": "【消息】发不出/收不到:检查网络 + 退出重登 + 清缓存", + "status": "pending" + }, + { + "id": "fc-wc-9", + "type": "step", + "label": "【视频会议】卡顿/掉线:检查带宽(>2Mbps) + 关闭其他视频", + "status": "pending" + }, + { + "id": "fc-wc-10", + "type": "step", + "label": "【审批】打不开:确认审批权限 + 联系审批管理员", + "status": "pending" + }, + { + "id": "fc-wc-11", + "type": "step", + "label": "【文件】下载失败:检查存储空间 + 重新下载", + "status": "pending" + }, + { + "id": "fc-wc-12", + "type": "step", + "label": "【通讯录】看不到新同事:引导同步通讯录", + "status": "pending" + } + ] + } + }, + { + "id": "fc-wc-13", + "type": "decision", + "label": "处理后是否解决?", + "yes_branch": { + "id": "fc-wc-14", + "type": "step", + "label": "回访 + 记录案例到知识库" + }, + "no_branch": { + "id": "fc-wc-15", + "type": "step", + "label": "升级二线:企微企业管理员 / 厂商支持", + "children": [ + { + "id": "fc-wc-16", + "type": "step", + "label": "提供工单截图 + 故障时间 + 员工 userid" + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/04-vpn.json b/data/seed-templates/04-vpn.json new file mode 100644 index 0000000..05322d7 --- /dev/null +++ b/data/seed-templates/04-vpn.json @@ -0,0 +1,65 @@ +{ + "name": "VPN / 远程办公故障排查", + "category": "vpn", + "description": "员工无法连接公司 VPN,或连接后访问内网失败,或频繁掉线", + "estimated_time": 8, + "difficulty": 2, + "tags": ["VPN", "远程办公", "aTrust", "网络"], + "root_node": { + "id": "fc-vpn-1", + "type": "step", + "label": "确认员工当前网络环境(在家/出差/咖啡厅)", + "status": "pending", + "children": [ + { + "id": "fc-vpn-2", + "type": "decision", + "label": "VPN 客户端能否打开登录页?", + "yes_branch": { + "id": "fc-vpn-3", + "type": "step", + "label": "检查账号密码 + 二次认证", + "children": [ + { + "id": "fc-vpn-4", + "type": "decision", + "label": "是否连接成功?", + "yes_branch": { + "id": "fc-vpn-5", + "type": "step", + "label": "回访确认可访问内网系统" + }, + "no_branch": { + "id": "fc-vpn-6", + "type": "step", + "label": "清除 DNS 缓存 + 重连 aTrust" + } + } + ] + }, + "no_branch": { + "id": "fc-vpn-7", + "type": "step", + "label": "升级 VPN 客户端到最新版", + "children": [ + { + "id": "fc-vpn-8", + "type": "decision", + "label": "重试能否登录?", + "yes_branch": { + "id": "fc-vpn-9", + "type": "step", + "label": "回访确认" + }, + "no_branch": { + "id": "fc-vpn-10", + "type": "step", + "label": "升级二线:信息安全团队(提供 userid + 时间)" + } + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/05-email.json b/data/seed-templates/05-email.json new file mode 100644 index 0000000..aa03836 --- /dev/null +++ b/data/seed-templates/05-email.json @@ -0,0 +1,65 @@ +{ + "name": "企业邮箱故障排查", + "category": "email", + "description": "员工邮箱登录失败、收发异常、附件打不开、签名问题", + "estimated_time": 7, + "difficulty": 2, + "tags": ["邮箱", "Outlook", "Foxmail", "登录", "附件"], + "root_node": { + "id": "fc-email-1", + "type": "step", + "label": "确认邮箱客户端(Outlook/Foxmail/网页/手机)", + "status": "pending", + "children": [ + { + "id": "fc-email-2", + "type": "decision", + "label": "能否登录网页邮箱?", + "yes_branch": { + "id": "fc-email-3", + "type": "step", + "label": "说明账号本身可用,问题在客户端", + "children": [ + { + "id": "fc-email-4", + "type": "decision", + "label": "是否收不到新邮件?", + "yes_branch": { + "id": "fc-email-5", + "type": "step", + "label": "检查反垃圾设置 + 邮件规则 + 邮箱配额" + }, + "no_branch": { + "id": "fc-email-6", + "type": "step", + "label": "检查 Outlook 缓存 + 重建索引 + 检查 PST 文件大小" + } + } + ] + }, + "no_branch": { + "id": "fc-email-7", + "type": "step", + "label": "检查账号是否锁定 + 密码是否过期", + "children": [ + { + "id": "fc-email-8", + "type": "decision", + "label": "重置密码后能否登录?", + "yes_branch": { + "id": "fc-email-9", + "type": "step", + "label": "回访 + 通知修改其他系统密码" + }, + "no_branch": { + "id": "fc-email-10", + "type": "step", + "label": "升级二线:邮件管理员(提供 userid + 错误截图)" + } + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/06-network.json b/data/seed-templates/06-network.json new file mode 100644 index 0000000..a5c8e30 --- /dev/null +++ b/data/seed-templates/06-network.json @@ -0,0 +1,89 @@ +{ + "name": "网络 / WiFi 故障排查", + "category": "network", + "description": "员工连不上公司 WiFi、有线网慢、IP 冲突、WiFi 认证失败、丢包", + "estimated_time": 10, + "difficulty": 2, + "tags": ["网络", "WiFi", "有线", "IP冲突", "丢包"], + "root_node": { + "id": "fc-net-1", + "type": "step", + "label": "确认故障范围(单个员工/同楼层/全公司)", + "status": "pending", + "children": [ + { + "id": "fc-net-2", + "type": "decision", + "label": "影响范围多大?", + "yes_branch": { + "id": "fc-net-3", + "type": "step", + "label": "【全公司/楼层】立即升级二线:网络团队", + "children": [ + { + "id": "fc-net-4", + "type": "step", + "label": "同时记录:故障时间 + 影响人数 + 现场照片" + } + ] + }, + "no_branch": { + "id": "fc-net-5", + "type": "step", + "label": "【单个员工】继续单点排查", + "children": [ + { + "id": "fc-net-6", + "type": "decision", + "label": "有线网 or WiFi?", + "yes_branch": { + "id": "fc-net-7", + "type": "step", + "label": "检查网线 + 换端口 + 重新拨号", + "children": [ + { + "id": "fc-net-8", + "type": "decision", + "label": "换端口能用?", + "yes_branch": { + "id": "fc-net-9", + "type": "step", + "label": "原端口硬件故障,工单报修" + }, + "no_branch": { + "id": "fc-net-10", + "type": "step", + "label": "检查 IP 冲突:ipconfig /all + 释放续租" + } + } + ] + }, + "no_branch": { + "id": "fc-net-11", + "type": "step", + "label": "WiFi 排查:重连 + 忘记网络 + 检查 SSID", + "children": [ + { + "id": "fc-net-12", + "type": "decision", + "label": "其他员工同位置能用 WiFi?", + "yes_branch": { + "id": "fc-net-13", + "type": "step", + "label": "员工设备问题:重装网卡驱动 + 升级系统" + }, + "no_branch": { + "id": "fc-net-14", + "type": "step", + "label": "AP 信号弱:升级二线查 AP 部署" + } + } + ] + } + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/07-printer.json b/data/seed-templates/07-printer.json new file mode 100644 index 0000000..480029b --- /dev/null +++ b/data/seed-templates/07-printer.json @@ -0,0 +1,80 @@ +{ + "name": "打印机 / 外设故障排查", + "category": "printer", + "description": "员工打印失败、卡纸、驱动问题、扫描仪、U盘识别", + "estimated_time": 6, + "difficulty": 1, + "tags": ["打印", "扫描", "U盘", "外设", "驱动"], + "root_node": { + "id": "fc-print-1", + "type": "step", + "label": "确认外设类型(打印/扫描/U盘/其他)", + "status": "pending", + "children": [ + { + "id": "fc-print-2", + "type": "decision", + "label": "打印机型号?", + "yes_branch": { + "id": "fc-print-3", + "type": "step", + "label": "【打印】按故障现象分流:", + "children": [ + { + "id": "fc-print-4", + "type": "step", + "label": "卡纸:打开盖板 + 按箭头方向抽纸 + 检查纸槽" + }, + { + "id": "fc-print-5", + "type": "step", + "label": "脱机:重新添加打印机 + 检查网络(IP 直连 or 服务器共享)" + }, + { + "id": "fc-print-6", + "type": "step", + "label": "驱动异常:卸载重装 + 选对型号 + 重启打印服务" + }, + { + "id": "fc-print-7", + "type": "decision", + "label": "其他员工同打印机能用?", + "yes_branch": { + "id": "fc-print-8", + "type": "step", + "label": "员工电脑问题:换电脑测试确认" + }, + "no_branch": { + "id": "fc-print-9", + "type": "step", + "label": "升级二线:硬件供应商(联系信息见公告)" + } + } + ] + }, + "no_branch": { + "id": "fc-print-10", + "type": "step", + "label": "【扫描仪/其他外设】:", + "children": [ + { + "id": "fc-print-11", + "type": "step", + "label": "扫描仪:检查 USB 连接 + 重新装驱动 + 测试扫描" + }, + { + "id": "fc-print-12", + "type": "step", + "label": "U盘:插入其他电脑测试 + 检查文件系统(ExFAT 兼容性)" + }, + { + "id": "fc-print-13", + "type": "step", + "label": "其他外设:走通用流程(查线/换口/换电脑/重装驱动)" + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/08-software.json b/data/seed-templates/08-software.json new file mode 100644 index 0000000..f266c29 --- /dev/null +++ b/data/seed-templates/08-software.json @@ -0,0 +1,75 @@ +{ + "name": "软件 / 应用故障排查", + "category": "software", + "description": "员工软件装不上、闪退、license 过期、版本不兼容、Office/PS/财务软件等", + "estimated_time": 8, + "difficulty": 2, + "tags": ["软件", "Office", "安装", "闪退", "license", "财务"], + "root_node": { + "id": "fc-soft-1", + "type": "step", + "label": "确认软件名 + 版本(让员工截图)", + "status": "pending", + "children": [ + { + "id": "fc-soft-2", + "type": "decision", + "label": "员工是否有管理员权限安装?", + "yes_branch": { + "id": "fc-soft-3", + "type": "step", + "label": "【管理员】继续自助排查:", + "children": [ + { + "id": "fc-soft-4", + "type": "step", + "label": "装不上:检查系统版本兼容性 + 关杀毒软件 + 管理员运行" + }, + { + "id": "fc-soft-5", + "type": "step", + "label": "闪退:看 Windows 事件日志 + 找 crash dump" + }, + { + "id": "fc-soft-6", + "type": "step", + "label": "license 过期:走 IT 资产流程申请续期(申请单见知识库)" + } + ] + }, + "no_branch": { + "id": "fc-soft-7", + "type": "step", + "label": "【普通员工】坐席远程协助安装:", + "children": [ + { + "id": "fc-soft-8", + "type": "step", + "label": "常用软件清单(从软件中心/SCCM):Office、Adobe、Foxmail、企微" + }, + { + "id": "fc-soft-9", + "type": "step", + "label": "非常用软件:需走软件申请流程(部门主管审批 → IT 评估)" + }, + { + "id": "fc-soft-10", + "type": "decision", + "label": "远程能否解决?", + "yes_branch": { + "id": "fc-soft-11", + "type": "step", + "label": "回访确认" + }, + "no_branch": { + "id": "fc-soft-12", + "type": "step", + "label": "升级二线:对应软件负责人" + } + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/09-hardware.json b/data/seed-templates/09-hardware.json new file mode 100644 index 0000000..fcc495c --- /dev/null +++ b/data/seed-templates/09-hardware.json @@ -0,0 +1,80 @@ +{ + "name": "硬件 / 桌面设备故障排查", + "category": "hardware", + "description": "员工显示器、键盘鼠标、耳机、视频会议摄像头、笔记本电池等", + "estimated_time": 10, + "difficulty": 2, + "tags": ["硬件", "显示器", "键盘", "鼠标", "耳机", "摄像头"], + "root_node": { + "id": "fc-hw-1", + "type": "step", + "label": "确认设备类型(显示器/键鼠/耳机/摄像头/其他)", + "status": "pending", + "children": [ + { + "id": "fc-hw-2", + "type": "decision", + "label": "故障设备能换一台测试吗?", + "yes_branch": { + "id": "fc-hw-3", + "type": "step", + "label": "换设备测试,确认是设备本身问题:", + "children": [ + { + "id": "fc-hw-4", + "type": "step", + "label": "【显示器】:换视频线(HDMI/DP/VGA) + 检查分辨率" + }, + { + "id": "fc-hw-5", + "type": "step", + "label": "【键鼠】:换 USB 口 + 换电池 + 蓝牙重新配对" + }, + { + "id": "fc-hw-6", + "type": "step", + "label": "【耳机/摄像头】:检查 USB/3.5mm + 隐私盖 + 系统权限" + }, + { + "id": "fc-hw-7", + "type": "decision", + "label": "换设备后正常?", + "yes_branch": { + "id": "fc-hw-8", + "type": "step", + "label": "原设备故障:走 IT 资产报废/更换流程" + }, + "no_branch": { + "id": "fc-hw-9", + "type": "step", + "label": "电脑端问题:检查驱动 + 系统设置" + } + } + ] + }, + "no_branch": { + "id": "fc-hw-10", + "type": "step", + "label": "【笔记本内嵌设备】:屏幕/键盘/电池/CPU 风扇", + "children": [ + { + "id": "fc-hw-11", + "type": "step", + "label": "走送修流程(备份数据 → IT 出具送修单 → 厂商维修)" + }, + { + "id": "fc-hw-12", + "type": "step", + "label": "需要备用机:走 IT 资产借用流程(最长 2 周)" + }, + { + "id": "fc-hw-13", + "type": "step", + "label": "升级二线:硬件供应商(联系信息见公告)" + } + ] + } + } + ] + } +} diff --git a/data/seed-templates/build_all.py b/data/seed-templates/build_all.py new file mode 100644 index 0000000..8b8c5f9 --- /dev/null +++ b/data/seed-templates/build_all.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +""" +把 9 套排查流程图 JSON 合并到一个数组,输出 00-all.json(便于一次性 import)。 +用法:python build_all.py +""" +import json +import glob +import os +import sys +from pathlib import Path + +HERE = Path(__file__).parent + +def main(): + # 1. 找 9 个单文件(排除 00-all.json 和 build_all.py) + files = sorted(HERE.glob("[0-9][0-9]-*.json")) + if not files: + print("❌ 没找到任何 0X-*.json 文件") + sys.exit(1) + + print(f"📦 找到 {len(files)} 个模板文件:") + for f in files: + print(f" - {f.name}") + + # 2. 逐个读 + 校验 + templates = [] + for f in files: + try: + with open(f, "r", encoding="utf-8") as fp: + tpl = json.load(fp) + # 简单校验 + for required in ("name", "category", "root_node"): + if required not in tpl: + raise ValueError(f"缺少必要字段: {required}") + templates.append(tpl) + print(f" ✅ {f.name}: {tpl['name']} ({len(json.dumps(tpl, ensure_ascii=False))} 字符)") + except Exception as e: + print(f" ❌ {f.name}: {e}") + sys.exit(1) + + # 3. 输出汇总文件 + out = HERE / "00-all.json" + with open(out, "w", encoding="utf-8") as fp: + json.dump(templates, fp, ensure_ascii=False, indent=2) + + print(f"\n✅ 已生成 {out.name} (共 {len(templates)} 套)") + print(f"\n💡 接下来你可以:") + print(f" 1. 打开 {out.name} 预览 9 套完整内容") + print(f" 2. 在 Admin 后台的「排查流程图」页 → 「导入 JSON」选择此文件") + print(f" 3. 或调用后端 API:") + print(f" for tpl in templates: POST /api/troubleshooting-templates") + +if __name__ == "__main__": + main() diff --git a/frontend-admin/package.json b/frontend-admin/package.json index dd2192f..d439810 100644 --- a/frontend-admin/package.json +++ b/frontend-admin/package.json @@ -13,11 +13,18 @@ "type-check": "vue-tsc --noEmit" }, "dependencies": { + "@codemirror/lang-json": "^6.0.1", + "@codemirror/state": "^6.4.1", + "@codemirror/theme-one-dark": "^6.1.2", + "@codemirror/view": "^6.26.3", "@element-plus/icons-vue": "^2.3.0", "axios": "^1.7.0", + "codemirror": "^6.0.1", "element-plus": "^2.7.0", "pinia": "^2.1.0", "vue": "^3.4.0", + "vue-codemirror": "^6.0.1", + "vue-json-pretty": "^2.2.4", "vue-router": "^4.3.0" }, "devDependencies": { diff --git a/frontend-admin/src/api/troubleshooting.ts b/frontend-admin/src/api/troubleshooting.ts new file mode 100644 index 0000000..797428c --- /dev/null +++ b/frontend-admin/src/api/troubleshooting.ts @@ -0,0 +1,171 @@ +// ============================================================================= +// 排查模板 API 客户端 +// ============================================================================= +// 对接后端 /api/troubleshooting-templates 5 个 REST 端点 +// 5 个端点:GET 列表 / GET 详情 / POST 新建 / PUT 更新 / DELETE 删除 +// ============================================================================= + +import axios from 'axios' + +// ----------------------------------------------------------------------------- +// 类型定义 +// ----------------------------------------------------------------------------- + +/** 步骤节点(顺序执行) */ +export interface PathStepNode { + id: string + type: 'step' + label: string + status?: 'done' | 'current' | 'pending' + children?: FlowchartNode[] +} + +/** 决策节点(yes/no 分支) */ +export interface DecisionNode { + id: string + type: 'decision' + label: string + status?: 'done' | 'current' | 'pending' + yes_branch?: FlowchartNode + no_branch?: FlowchartNode + children?: FlowchartNode[] +} + +/** 流程图节点(递归) */ +export type FlowchartNode = PathStepNode | DecisionNode + +/** 排查模板 */ +export interface TroubleshootingTemplate { + id?: string + name: string + category: string + description?: string + estimated_time?: number + difficulty?: number + tags?: string[] + root_node: FlowchartNode + version?: string + status?: 'draft' | 'published' + created_at?: string + updated_at?: string + // 后端可能附加的统计字段 + nodeCount?: number +} + +/** API 响应通用结构 */ +interface ApiResponse { + code: number + message: string + data: T +} + +// ----------------------------------------------------------------------------- +// Axios 实例(继承全局 baseURL) +// ----------------------------------------------------------------------------- +const http = axios.create({ + baseURL: '/api', + timeout: 30000, +}) + +// ----------------------------------------------------------------------------- +// 5 个端点 +// ----------------------------------------------------------------------------- + +/** GET /api/troubleshooting-templates — 获取模板列表 */ +export async function listTemplates(): Promise { + const res = await http.get>( + '/troubleshooting-templates' + ) + return res.data.data || [] +} + +/** GET /api/troubleshooting-templates/{id} — 获取模板详情 */ +export async function getTemplate(id: string): Promise { + const res = await http.get>( + `/troubleshooting-templates/${id}` + ) + return res.data.data +} + +/** POST /api/troubleshooting-templates — 新建模板 */ +export async function createTemplate( + data: TroubleshootingTemplate +): Promise { + const res = await http.post>( + '/troubleshooting-templates', + data + ) + return res.data.data +} + +/** PUT /api/troubleshooting-templates/{id} — 更新模板 */ +export async function updateTemplate( + id: string, + data: TroubleshootingTemplate +): Promise { + const res = await http.put>( + `/troubleshooting-templates/${id}`, + data + ) + return res.data.data +} + +/** DELETE /api/troubleshooting-templates/{id} — 删除模板 */ +export async function deleteTemplate(id: string): Promise { + await http.delete(`/troubleshooting-templates/${id}`) +} + +/** 工具:把对象格式化成 JSON 字符串(带缩进) */ +export function formatJson(obj: unknown): string { + return JSON.stringify(obj, null, 2) +} + +/** 工具:校验 JSON 字符串是否合法,返回 {ok, data, error} */ +export function validateJson( + text: string +): { ok: true; data: TroubleshootingTemplate } | { ok: false; error: string } { + try { + const data = JSON.parse(text) as TroubleshootingTemplate + return { ok: true, data } + } catch (e) { + const err = e as Error + return { ok: false, error: err.message } + } +} + +/** 工具:统计节点数(递归) */ +export function countNodes(node: FlowchartNode | undefined): number { + if (!node) return 0 + let count = 1 + if (node.children) { + for (const child of node.children) { + count += countNodes(child) + } + } + // 决策节点的 yes/no 分支 + if ('yes_branch' in node && node.yes_branch) { + count += countNodes(node.yes_branch) + } + if ('no_branch' in node && node.no_branch) { + count += countNodes(node.no_branch) + } + return count +} + +/** 工具:统计决策节点数 */ +export function countDecisions(node: FlowchartNode | undefined): number { + if (!node) return 0 + let count = node.type === 'decision' ? 1 : 0 + if (node.children) { + for (const child of node.children) { + count += countDecisions(child) + } + } + if ('yes_branch' in node && node.yes_branch) { + count += countDecisions(node.yes_branch) + } + if ('no_branch' in node && node.no_branch) { + count += countDecisions(node.no_branch) + } + return count +} diff --git a/frontend-admin/src/components/flowchart/FlowchartEditorDialog.vue b/frontend-admin/src/components/flowchart/FlowchartEditorDialog.vue new file mode 100644 index 0000000..d3f763f --- /dev/null +++ b/frontend-admin/src/components/flowchart/FlowchartEditorDialog.vue @@ -0,0 +1,475 @@ + + + + + + diff --git a/frontend-admin/src/views/Flowcharts.vue b/frontend-admin/src/views/Flowcharts.vue index a5a6602..53009ce 100644 --- a/frontend-admin/src/views/Flowcharts.vue +++ b/frontend-admin/src/views/Flowcharts.vue @@ -2,230 +2,382 @@ ============================================================================= 企微IT智能服务台 — 排查流程图管理页 ============================================================================= -说明:JSON 导入导出 + 预览 + 版本管理 - 阶段三开始实现,当前为占位功能 - 显示模板列表 + 灰化的导入/导出/新建按钮 - 底部展示实现路径 +说明:JSON 导入导出 + 在线编辑 + 树形预览 + 阶段三实现 - 用户已选 B 方案(双栏 CodeMirror + vue-json-pretty) + 功能: + - 列表(从 /api/troubleshooting-templates 拉取) + - 预览/编辑/删除(单条) + - 导入 JSON(文件) + - 导出全部(批量下载) + - 新建(空模板) +============================================================================= -->