From 60e67b06816bf2904a3fa4871f22ee2d08891de9 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 16 Jun 2026 10:07:42 +0800 Subject: [PATCH] =?UTF-8?q?v0.5.5:=20=E5=BA=94=E6=80=A5=E9=A1=B5=20v0.5.4?= =?UTF-8?q?=20+=20=E7=A7=BB=E9=99=A4IT=E8=AE=BE=E5=A4=87=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=20+=20admin=E7=99=BB=E5=BD=95=E4=BF=AE=E5=A4=8D=20+=20?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E5=AE=A1=E6=A0=B8=E6=9E=B6=E6=9E=84=20+=20?= =?UTF-8?q?=E7=9F=A5=E8=AF=86=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- KNOWLEDGE.md | 1074 +++++++++++++++++ ...06_admin_extension.py => 006_admin_ext.py} | 18 +- backend/app/api/admin/security_comparison.py | 166 +++ backend/app/api/agents.py | 4 +- backend/app/api/h5.py | 11 +- backend/app/api/router.py | 14 + backend/app/api/wecom_jsapi.py | 181 +++ backend/app/api/ws.py | 23 +- backend/app/config.py | 19 + backend/app/main.py | 31 +- backend/app/services/security_comparison.py | 149 +++ backend/app/services/wecom_service.py | 95 ++ deploy-h5.tar.bak-Mock | Bin 0 -> 626688 bytes deploy-server/README.md | 62 +- deploy-server/nginx/nginx.conf | 77 +- deploy-server/package.py | 45 +- diagnose-500.b64 | 1 + diagnose-500.sh | 84 ++ fix-prod.b64 | 1 + fix-prod.s1 | 1 + fix-prod.s2 | 1 + fix-prod.sh | 46 + frontend-admin/package-lock.json | 4 + frontend-admin/src/types/index.ts | 4 + frontend-admin/src/views/TerminalSecurity.vue | 4 +- frontend-agent/package-lock.json | 4 + frontend-agent/src/router/index.ts | 17 +- frontend-agent/src/views/AgentPreviewView.vue | 207 ++++ frontend-agent/src/views/Workspace.vue | 10 + frontend-h5/components.d.ts | 1 + frontend-h5/index.html | 40 + frontend-h5/package-lock.json | 4 + frontend-h5/src/App.vue | 39 +- .../src/components/chat/CallAgentModal.vue | 2 +- frontend-h5/src/main.ts | 18 +- frontend-h5/src/router/index.ts | 35 +- frontend-h5/src/views/EmergencyDispatcher.vue | 234 ++++ frontend-h5/src/views/H5PreviewView.vue | 224 ++++ frontend-portal/package-lock.json | 4 + frontend-portal/src/views/PortalSelect.vue | 2 +- frontend-portal/tsconfig.json | 2 +- list_nas_full.ps1 | 64 + list_nas_volumes.ps1 | 43 + nas_probe_output.txt | Bin 0 -> 6306 bytes nas_volumes.txt | 9 + patch-mini.py | 7 + patch-redis-url.py | 54 + patch.py | 20 + probe_nas.ps1 | 70 ++ scripts/deploy.sh | 12 +- scripts/diagnose-500.sh | 84 ++ set-real-ip-patch.md | 362 ++++++ split-b64.ps1 | 8 + stage1-probe.sh | 78 ++ 快速诊断-500-错误.md | 81 ++ 手敲-6段命令.md | 54 + 服务器端跑诊断.md | 101 ++ 部署包-2026-06-16-v0.5.2.md | 145 +++ 部署包-2026-06-16-v0.5.3.md | 155 +++ 59 files changed, 4195 insertions(+), 110 deletions(-) create mode 100644 KNOWLEDGE.md rename backend/alembic/versions/{006_admin_extension.py => 006_admin_ext.py} (86%) create mode 100644 backend/app/api/admin/security_comparison.py create mode 100644 backend/app/api/wecom_jsapi.py create mode 100644 backend/app/services/security_comparison.py create mode 100644 deploy-h5.tar.bak-Mock create mode 100644 diagnose-500.b64 create mode 100644 diagnose-500.sh create mode 100644 fix-prod.b64 create mode 100644 fix-prod.s1 create mode 100644 fix-prod.s2 create mode 100644 fix-prod.sh create mode 100644 frontend-agent/src/views/AgentPreviewView.vue create mode 100644 frontend-h5/src/views/EmergencyDispatcher.vue create mode 100644 frontend-h5/src/views/H5PreviewView.vue create mode 100644 list_nas_full.ps1 create mode 100644 list_nas_volumes.ps1 create mode 100644 nas_probe_output.txt create mode 100644 nas_volumes.txt create mode 100644 patch-mini.py create mode 100644 patch-redis-url.py create mode 100644 patch.py create mode 100644 probe_nas.ps1 create mode 100644 scripts/diagnose-500.sh create mode 100644 set-real-ip-patch.md create mode 100644 split-b64.ps1 create mode 100644 stage1-probe.sh create mode 100644 快速诊断-500-错误.md create mode 100644 手敲-6段命令.md create mode 100644 服务器端跑诊断.md create mode 100644 部署包-2026-06-16-v0.5.2.md create mode 100644 部署包-2026-06-16-v0.5.3.md diff --git a/KNOWLEDGE.md b/KNOWLEDGE.md new file mode 100644 index 0000000..bacaa5f --- /dev/null +++ b/KNOWLEDGE.md @@ -0,0 +1,1074 @@ +# 企微智能 IT 支持服务台 — 项目全量知识库 + +> **项目代号**:`wecom_it_smart_desk` +> **状态**:v0.5.0-beta 内测(2026-06-15),v0.4.x 仍为生产稳定版 +> **目标用户**:公司 6000 员工(企微 IM) +> **核心痛点**:员工绕过 AI 直接找人工 / AI 转人工需另开窗口 / 无法跨主体共享 +> **核心方案**:自研 IT 服务坐席系统,基于企微自建应用消息 API +> **演进路径**:M1 消息接管 → M2 AI 接入 → M3 知识库闭环 +> **本文档用途**:Claude 全面接管项目后的"项目大脑" — 完整功能/架构/集成/部署/安全/历史决策清单 +> **最后更新**:2026-06-15(项目从 WB 移交到 Claude 接管) + +--- + +## 0. 项目移交状态(2026-06-15) + +| 项目 | 状态 | +|---|---| +| 项目控制方 | **Claude 全面接管**(原由 Workbuddy CN 推进,2026-06-15 起停用) | +| WB 项目目录 | `D:\资料\03-项目开发\wecom_it_smart_desk`(待用户授权后归档封存) | +| Claude 工作目录 | `D:\资料\03-项目开发\wecom_it_smart_desk-claude`(唯一 active 副本) | +| 代码托管 | Gitea(自托管 NAS 8418 端口),推送前需重新获 token | +| 移交决策原因 | WB 1009 上下文冲突 + token 误吊销 + 大量功能信息丢失 | +| 关联 memory | `project-handover-to-claude` / `gitea-push-permission-revoked-2026-06-15` | + +--- + +## 1. 业务背景 + +### 1.1 公司规模与用户 +- 6000 员工,全国分子机构 +- 内部 IM:企业微信(企微) +- 现有痛点: + - 员工绕过 AI 直接找人工,AI 筛选率极低 + - AI 转人工需另开窗口,体验割裂 + - 企微"员工服务"不支持跨企业应用共享 + +### 1.2 核心设计理念 +- **并行协作**(非传统串行排队):AI 全程在线 + 人工随时介入 + 员工同一窗口无缝切换 +- **统一入口**(v0.5):企微工作台 → 唯一 OAuth2 认证点 → 角色检测 → 路由到用户端/坐席端/管理端 +- **AI Wingman**(v0.6+):AI 不仅是服务员工的,更是解放坐席的 + +### 1.3 三步演进路径 + +| 里程碑 | 周期 | 核心交付 | 状态 | +|---|---|---|---| +| **M1** 消息接管 + 极简坐席 | 6-8 周 | 企微 API 链路 · 三栏工作台 · H5 双栏 · 邀请功能 | ✅ 代码完成,部署中 | +| **M2** AI 机器人接入 | M1 后 4-6 周 | 千问/Dify/RAGFlow · AI 前置筛选 · 排队系统 | 📋 计划中 | +| **M3** 知识库闭环 | M2 后 4-6 周 | 坐席标注系统 · 千问自动分析 · 知识库自优化 | 📋 计划中 | + +--- + +## 2. 系统架构 + +### 2.1 部署架构(Docker Compose 单机版) + +``` +浏览器 ──→ https://itsupport.servyou.com.cn:443 + │ + ▼ + ┌─── nginx (Docker 容器) ────────────────┐ + │ /itdesk/ → H5 员工端 SPA │ + │ /itagent/ → 坐席工作台 SPA │ + │ /itadmin/ → 管理后台 SPA(内网/VPN) │ + │ /itportal/ → 统一入口 SPA │ + │ /api/* → backend:8000 (FastAPI) │ + │ /ws/* → backend:8000 (WebSocket) │ + └──────────────┬──────────────────────────┘ + │ Docker 网络 + ┌─────────────┼─────────────┐ + ▼ ▼ ▼ + ┌──────────┐ ┌──────────┐ ┌──────────┐ + │ backend │ │ postgres │ │ redis │ + │ :8000 │ │ :5432 │ │ :6379 │ + └──────────┘ └──────────┘ └──────────┘ +``` + +| 对比项 | 预生产(当前) | 正式环境(未来) | +|---|---|---| +| 部署方式 | Docker Compose 单主机 | K8s 集群高可用 | +| 域名 | `itsupport.servyou.com.cn` | 公司高可用架构 | +| 服务器 | **10.90.5.110**(2026-06-15 起替代 10.80.0.136) | 待迁移 | + +### 2.2 技术栈 + +| 层级 | 技术选型 | 说明 | +|---|---|---| +| 反向代理 | **Nginx**(Docker 容器) | HTTPS 终止 + 路径路由 + WS 代理 + 静态文件 | +| 后端框架 | **FastAPI**(Python 3.12) | 异步 + 自动 OpenAPI + 类型安全 | +| 数据库 | **PostgreSQL 16** | 16 张表(2026-06 最新盘点) | +| 缓存 | **Redis 7** | access_token(TTL 7200s) + JWT 会话 + 模板缓存 | +| ORM | **SQLAlchemy 2.0(async)** | 声明式模型 | +| 数据库迁移 | **Alembic** | 10 个迁移版本(002-009 + initial) | +| 加解密 | **cryptography** | AES-CBC-256 企微消息加解密 | +| 坐席前端 | **Vue3 + ElementPlus + Pinia** | 三栏工作台(会话/对话/AI 助手) | +| 员工 H5 | **Vue3 + Vant4 + Pinia** | 双栏 + 摇人按钮 + 呼叫坐席 | +| 统一入口 | **Vue3**(独立 frontend-portal) | 角色路由选择页 | +| 管理后台 | **Vue3 + ElementPlus** | 13+ 视图(仪表盘/坐席/集成等) | +| 容器化 | Docker + Docker Compose | 4-5 容器一键启停 | + +### 2.3 URL 路径规划(已实现) + +| 端 | 路径 | 说明 | +|---|---|---| +| 统一入口 | `/itportal/` | 角色路由选择页(v0.5 新增) | +| 用户端 | `/itdesk/` | 员工 H5(原员工端) | +| 坐席端 | `/itagent/` | IT 坐席工作台 | +| 管理端 | `/itadmin/` | 系统配置 + 数据分析(内网白名单) | +| API | `/api/` | 后端接口(企微回调/会话/消息/坐席/...) | +| WebSocket | `/ws/{agent_id}` | 坐席实时推送 | +| 统一入口跳转 | `/` | 302 → `/itportal/` | + +--- + +## 3. 数据库设计(16 张表) + +### 3.1 核心业务表(9 张) + +| 表名 | 用途 | 关键字段 | +|---|---|---| +| `conversations` | 会话主表 | employee_id, status(queued/serving/resolved), urgency_score(1-5), tags(JSON), is_vip, participants(JSON) | +| `messages` | 消息记录 | sender_type(employee/agent/ai/system), content, msg_type(text/image/file/voice) | +| `agents` | 坐席信息 | user_id, status(online/offline/busy), current_load, max_load, **password_hash**(v0.5 加) | +| `quick_reply_templates` | 快速回复模板 | category, title, content({变量}), variables(JSON) | +| `system_configs` | 系统配置 | config_key, config_value(关键词/阈值/话术) | +| `funny_phrases` | 趣味话术 | scene(6 种), content, tone, is_active | +| `approval_links` | 审批流程链接 | category(IT/HR/行政/财务), title, url | +| `software_downloads` | 软件下载入口 | category, name, version, platform, download_url | +| `agent_notes` | 坐席备注 | conversation_id, agent_id, content | + +### 3.2 阶段一新增表(7 张) + +| 表名 | 用途 | 关键字段 | +|---|---|---| +| `employees` | 员工档案 | user_id, name, department, mobile, email, is_vip | +| `todos` | 待办事项 | agent_id, conversation_id, content, due_at, status | +| `troubleshooting_templates` | 排障模板 | category, title, steps(JSON) | +| `roles` | RBAC 角色 | name(user/agent/admin), display_name, permissions(JSON) | +| `user_roles` | 用户角色关联 | employee_id, role_id, source(auto/tag/ehr/manual) | +| `role_mapping_rules` | 角色映射规则 | role_id, source_type(wecom_tag/ehr_position/manual), source_value, priority | +| `config_change_logs` | 配置变更审计 | config_key, old_value, new_value, changed_by, changed_at | + +> **alembic 迁移链**:6d5520491644(initial) → 002 → 003 → 004 → 005 → 006 → 007 → 008 → 009 +> **v0.5 修过的 007 链路断裂** = `007_role_system.py` 中 docstring + `revision` 都写成 `007_role_sys`,v0.5.1 需统一 filename 与 revision(任务 #41) + +--- + +## 4. 业务功能清单(已实现,分阶段) + +### 4.1 阶段 0(2025-12, v0.1) — 基础框架 +- FastAPI + SQLAlchemy 2.0 + Alembic +- 4 前端工程(坐席/H5/Portal/Admin) +- 企微回调基础 +- Docker Compose 编排 + +### 4.2 阶段 0.2(2026-01, v0.2) — 核心业务 +- 16 张数据表(初始 9 张) +- 40+ API 端点 +- OAuth2 企微登录 +- 消息收发(文本/图片/文件/语音) +- 会话分配 / 抢单 / 转接 +- 协作坐席(摇人按钮) +- 邀请功能(P0-09~11) + +### 4.3 阶段 0.3(2026-03, v0.3) — AI 辅助与标记 +- AI 草稿回复(坐席采纳模式) +- AI 实质性回复计数 +- 紧急度评分(1-5) +- 标签系统(举手/情绪/需介入) +- 影响范围评估 +- 阻断性标记 + +### 4.4 阶段 0.4(2026-04, v0.4) — RBAC + 配置 +- RBAC 角色管理(user/agent/admin) +- 角色自动映射(企微标签 + eHR 字段) +- 配置变更日志(审计) +- 趣味话术(摇人/等待/接入 6 场景) +- 审批流程链接 +- 软件下载入口 +- 紧急度算法优化 + VIP 自动匹配 +- 部门权限粒度 + +### 4.5 阶段 0.5(2026-05~06, v0.5.0-beta) — 阶段一收尾 +**4 前端 + 47 项功能盘点 66% 完成** + +- **H5 员工端**(11 组件): + - 双栏布局(对话/助手 + 摇人按钮) + - 摇人(转人工) + - 呼叫坐席 + - 会话进度查看 + - 审批链接 / 软件下载入口 + - 表情/截图/文件/图片 4 类消息 + - OAuth2 + 降级登录(密码) +- **坐席工作台**(23 组件,三栏): + - 会话列表(紧急度排序 + VIP/举手/需介入/情绪 标记) + - 对话区(WebSocket 实时推送 + 30s 心跳 + 指数退避重连 + 3s 轮询降级) + - AI 助手侧栏(草稿回复/摘要/标签/知识推荐) + - 接单/抢单/转接 + - 多人协作(摇人 + 邀请功能) + - 待办事项 + - 排障模板 + - 快速回复(模板缓存到 Redis) + - 坐席备注 +- **管理后台**(13+ 视图): + - 仪表盘(会话统计/坐席负载/紧急度分布) + - 坐席管理(CRUD + 状态监控) + - 角色管理 + 角色映射规则 + - 系统配置(关键词/阈值/话术 CRUD) + - 配置变更审计 + - 快速回复模板管理 + - 排障模板管理 + - 趣味话术管理 + - 审批链接 / 软件下载管理 + - 终端安全(联软/火绒 集成视图) + - 集成配置(4 外部系统) +- **统一入口 Portal**: + - 唯一 OAuth2 认证点 + - 角色检测 + 卡片选择页 + - 角色切换 API + - 消除公网直访登录页(安全) +- **管理端 API**: + - 仅内网/VPN 访问(IP 白名单 + 路径 `/api/admin/*`) +- **4 个外部系统集成**: + - 火绒企业版(17 API 端点,认证成功) + - 联软 LV7000(68 API 端口,员工映射核心) + - aTrust 零信任(官方文档修正版) + - 北森 eHR(待对接,OAuth2) +- **ExternalSystemAdapter 抽象层**(统一接口规范): + - MockAdapter(开发期) → 真实 API 无缝切换 + - 缓存透明(5 种 TTL)+ 降级安全 + - 上层业务只依赖 ExternalSystemService 统一门面 + +### 4.6 阶段二规划(v0.6+,启动中) +- H5 全流程(邀请功能已闭环) +- WebSocket 推送(H5 WS 端点已上线) +- OAuth2 认证(已上线) +- 排队机制(未开始,P1) +- 满意度评价(未开始,P1) + +### 4.7 阶段三规划 +- AI Wingman(三层渐进式:效率 → 认知 → 情感) + - 效率层:AI 草稿回复 + 自动摘要 + 自动标签(Phase 1) + - 认知层:知识推荐 + SOP 导航 + 相似工单(Phase 2) + - 情感层:情绪识别 + 安抚话术 + 语气润色(Phase 3) +- 排查流程图 +- 标注体系 + +### 4.8 阶段四规划 +- 知识库迭代闭环 +- 数据看板 +- 知识库管理 + +### 4.9 阶段五规划 +- 自动/辅助审核 +- 自动开单/结单 + +--- + +## 5. API 接口分组(20 个 router,7890 行) + +| 路径前缀 | 文件 | 端点数 | 说明 | +|---|---|---|---| +| `/api/wecom/callback` | wecom_callback.py | 2 | GET 验证 URL + POST 接收消息 | +| `/api/conversations` | conversations.py | ~15 | 列表/详情/状态/置顶/接单/邀请/退出/移除参与者 | +| `/api/conversations/{id}/messages` | messages.py | ~10 | 消息列表/发送/撤回 | +| `/api/agents` | agents.py | ~12 | 列表/登录(企微+降级+OAuth)/状态切换/密码/OTP | +| `/api/h5/*` | h5.py | ~25 | H5 完整功能(会话/摇人/审批/软件/OAuth) | +| `/api/portal/*` | portal.py | ~5 | 统一入口(角色列表/切换/入口 URL) | +| `/api/admin/*` | admin.py + admin_roles.py | ~25 | 管理后台(仪表盘/坐席/角色/配置) | +| `/api/quick-replies` | quick_replies.py | ~5 | CRUD | +| `/api/todos` | todo_items.py | ~8 | 待办事项 | +| `/api/troubleshooting-templates` | troubleshooting_templates.py | ~6 | 排障模板 | +| `/api/upload` | upload.py | ~4 | 文件/图片/表情上传 | +| `/api/employees` | employees.py | ~5 | 员工档案 | +| `/api/notes` | agent_notes.py | ~4 | 坐席备注 | +| `/api/approvals` | approval.py | ~4 | 审批链接 | +| `/api/wingman` | wingman.py | ~5 | AI Wingman 草稿/摘要 | +| `/api/system` | system.py | ~3 | 健康检查 + 系统信息 | +| `/api/ws/{agent_id}` | ws.py | 1 | WebSocket 实时推送 | +| router.py | — | — | 路由汇总 | + +**统一响应格式**:`{ "code": 0, "data": {}, "message": "success" }` +**错误码体系**:0=成功,1000+=通用(10/11/12/13/14/15/16),2000+=企微 API 错误,3000+=业务逻辑错误 + +### 5.1 v0.5 安全相关错误码(新增) +- E1010 = OAuth2 token 过期 +- E1011 = 未授权 +- E1012 = **已废弃拆码**(原"首次登录请设置密码"和"改密请输旧密码"语义冲突) + - **E1015** = AUTH_OLD_PASSWORD_REQUIRED(改密时未输旧密码) + - **E1016** = AUTH_OLD_PASSWORD_WRONG(改密时旧密码错) + - E1012 仍保留给"首次登录请设置密码"单一场景 +- E1013 = 密码格式不符 +- E1014 = 旧密码新密码相同 + +--- + +## 6. 后端服务层(15 个 service,7117 行) + +| 服务 | 行数 | 职责 | +|---|---|---| +| `wecom_service.py` | 573 | 企微 API 封装(access_token 缓存 + 发消息 + 通讯录 + 上传素材 + OAuth2) | +| `ai_service.py` | 271 | Dify API 封装(流式 + 非流式) | +| `ai_handler.py` | 289 | AI 路由逻辑(打招呼检测 + 呼叫人工拦截) — **v0.5 替换原 ai_service 直接调用** | +| `message_router.py` | 671 | 消息路由大脑(接收 → 路由 → VIP → 标记 → 评分 → 入库 → AI/坐席) | +| `scoring_service.py` | 406 | 紧急度评分(基础分 + 情绪 + VIP + 重复追问 = 1-5) + 标记检测(举手/需介入/情绪) | +| `session_service.py` | 1234 | 会话全生命周期(创建/分配/接单/转接/邀请/退出/移除) | +| `ws_manager.py` | 327 | WebSocket 连接管理(坐席 + H5 注册/推送/广播/清理) | +| `role_mapping_service.py` | 350 | 角色自动映射(企微标签 + eHR 岗位 + 手动) | +| `wingman_service.py` | 445 | 坐席端 AI 助手(草稿/摘要/标签/知识推荐) | +| `token_service.py` | 263 | JWT + Redis 会话管理 | +| `cache_service.py` | 232 | Redis 缓存装饰器 + 策略 | +| `funny_phrase_service.py` | 157 | 6 场景趣味话术(摇人/等待/接入 等) | +| `admin_service.py` | 1728 | 管理后台综合服务 | +| `security_comparison.py` | 149 | 前后端安全对照 | +| `external/`(空目录) | — | 原计划,实际放到 `integrations/` 下 | + +--- + +## 7. 4 个外部系统集成(2,850 行) + +### 7.1 通用抽象层(`ExternalSystemAdapter`) + +```python +class ExternalSystemAdapter(ABC): + system_name: str + is_available: bool + + async def health_check() -> bool + async def get_terminal_by_user(username) -> Optional[TerminalInfo] # 联软主源 + async def get_terminal_by_computer(name) -> Optional[TerminalInfo] + async def get_terminal_detail(terminal_id) -> Optional[TerminalInfo] + async def get_security_status(terminal_id) -> Optional[SecurityStatus] # 火绒 + async def isolate_terminal(terminal_id, reason) -> bool # 仅火绒 + async def unisolate_terminal(terminal_id) -> bool + async def get_vpn_sessions(username) -> List[VpnSession] # 仅 aTrust + async def get_online_status(username) -> bool +``` + +**统一 DTO**: +- `TerminalInfo`(source_system / computer_name / ip_addresses / mac_addresses / os_version / is_online / logged_in_user / department / hardware_summary / last_seen) +- `SecurityStatus`(source_system / virus_events / vulnerabilities / is_isolated) +- `VpnSession`(username / display_name / remote_ip / vpn_ip / is_trusted) + +**统一门面服务** `ExternalSystemService.find_user_terminal(username)`: +- 优先级:联软(strusername 精确) → aTrust(bindUserList) → eHR(无,返回 None) +- 火绒隔离操作:重试 1 次 → 失败则记录待执行队列 → 告警坐席 + +**缓存策略**: +| 数据 | TTL | 刷新 | +|---|---|---| +| 终端映射 | 30 分钟 | 定时 + 访问检查 | +| 终端详情 | 60 分钟 | 懒加载 | +| 安全状态 | 5 分钟 | 短 TTL + 事件驱动 | +| VPN 在线 | 1 分钟 | 短 TTL | +| eHR 员工 | 24 小时 | 每日凌晨全量 | + +**降级策略**: +- 单系统不可用:跳过该系统尝试下一优先级 +- 全部不可用:返回缓存(标注"可能过时") +- 缓存+系统全挂:返回空 + 告警坐席 +- 火绒隔离失败:重试 + 待执行队列 + 告警 + +### 7.2 火绒企业版集成(`integrations/huorong/`,1184 行) + +| 维度 | 内容 | +|---|---| +| 角色 | **安全源(P0)** — 终端列表/漏洞/病毒/隔离 | +| 认证 | HMAC-SHA1 AccessKey | +| 凭证状态 | **现在可拿** | +| API 端点 | 17 个 | +| 核心方法 | `_list`(终端列表) + `_isolation`(隔离) + `_leak`(漏洞) + `_virus`(病毒) | +| 生产 URL | `http://huorong.oa.servyou-it.com:8080` | +| 关键功能 | 一键隔离/解除 + 漏洞事件 + 病毒事件 | +| 文档 | `docs/火绒终端安全系统集成分析.md`(560 行) | + +### 7.3 联软 LV7000 集成(`integrations/lianruan/`,956 行) + +| 维度 | 内容 | +|---|---| +| 角色 | **主映射源(P0)** — 员工 → 终端精确匹配 | +| 认证 | IP 白名单 + 账号密码 + Token | +| 凭证状态 | 明天可拿(2026-06-11 评估) | +| API 端口 | 68 个 | +| **核心字段** | `strusername`(员工账号,新系统通过此字段关联) | +| 核心方法 | `queryDevByParams(strusername=xxx)` | +| 核心价值 | 员工映射 + 硬件详情 + 在线状态 + VPN IP 关联 | +| 文档 | `docs/联软终端安全系统集成分析.md`(797 行) | + +### 7.4 aTrust 零信任集成(`integrations/atrust/`,无) + +| 维度 | 内容 | +|---|---| +| 角色 | **VPN 源(P1)** | +| 认证 | HMAC-SHA256 签名 | +| 凭证状态 | **约一周可拿** | +| 核心方法 | `queryAll(bindUserList)` 终端绑定用户 | +| 核心价值 | VPN 在线用户 + VPN IP + 踢出用户 | +| 待对接 | 信息安全团队 | +| 文档 | `docs/aTrust零信任系统集成分析.md`(879 行) | + +### 7.5 北森 eHR 集成(规划中) + +| 维度 | 内容 | +|---|---| +| 角色 | **辅助静态数据(P2)** | +| 认证 | OAuth2.0 | +| 凭证状态 | 待对接 HR 数字化团队 | +| 用途 | 员工基础信息 + 任职信息(辅助角色映射 ehr_position 字段) | + +### 7.6 RAGFlow 知识库集成(`integrations/ragflow/`,690 行) + +| 维度 | 内容 | +|---|---| +| 角色 | **AI 知识库(P1)** | +| 用途 | M3 知识库迭代 + M2 语义检索 | +| 凭证 | 现有 10.80.0.85:8080 | +| 文档 | `integrations/ragflow/`, API 模型在 `models.py` | + +--- + +## 8. 消息收发全链路 + +``` +员工发消息(企微) → 企微回调解密 → 消息路由 → 评分标记 → 入库 + │ + ┌───────────────┴───────────────┐ + ▼ ▼ + 坐席 WS 推送 AI 处理(v0.5 路由层已就位) + │ │ + ▼ ▼ + 坐席回复 AI 回复 + │ │ + └──────────────┬────────────────┘ + ▼ + 企微主动推送(message/send) + │ + ▼ + 员工同一窗口收到(无跳转) +``` + +### 8.1 9 步详细链路 +1. **接收**:员工在企微应用内发消息 +2. **回调**:企微 POST 加密 XML 到 `/api/wecom/callback` +3. **解密**:`wecom_crypto.decrypt_message()`(AES-CBC-256) +4. **路由**:`MessageRouter.route_message()` — 创建会话 → VIP 检测 → 标记检测 → 评分 → 入库 +5. **评分**:`ScoringService` — 5 步(基础分 + 情绪 + VIP + 重复追问 + clamp 1-5) +6. **入库**:`conversations` + `messages` 原子写入 +7. **坐席 WS 推送**:`ws_manager.broadcast()`(坐席新消息) +8. **坐席回复**:POST → 后端调企微 `message/send` +9. **员工收到**:企微推送到员工(同一窗口) + +### 8.2 紧急度评分公式 +``` +紧急度 = 基础分(关键词) + 情绪加成 + VIP加成 + 重复追问加成 +范围:1-5(clamp) +映射:1=低, 2=中, 3=高, 4=紧急, 5=最高 +所有关键词和阈值存 system_configs,支持动态修改无需重启 +``` + +### 8.3 会话排序规则 +``` +紧急 → 举手 → 需介入 → 活跃 → AI处理中 → 已结单 +(同级按 last_message_at 倒序) +``` + +### 8.4 标记系统 +| 标记 | 图标 | 触发条件 | +|---|---|---| +| VIP | 红色 | 企微通讯录规则匹配 | +| 举手 | 黄色 | 员工说关键词或点击摇人按钮 | +| 需介入 | 橙红 | 同一问题追问 > 3 轮 | +| 情绪 | 红色 | 关键词匹配(急/崩溃/投诉等) | + +--- + +## 9. 现有系统复用资源(7 + 8 + 10 项) + +### 9.1 🔴 核心复用(P0,直接影响架构) +| # | 资源 | 现有位置 | 新系统对应 | +|---|---|---|---| +| 1 | Dify Workflow | `yw-dify.dc.servyou-it.com/apps` | 坐席助手 AI 面板 + 自动回复(M2) | +| 2 | dify2openai 桥接 | `yw-dify.dc/dify2openai/v1/chat/completions` | 后端调 AI 入口 | +| 3 | RAGFlow 知识库 | `10.80.0.85:8080` | 知识库管理 + 标注闭环(M3) | +| 4 | Qwen3-30B 大模型 | `10.80.0.49:5000/api/llm/servyou/v1` | AI 对话底层 | +| 5 | bge-m3 向量模型 | RAGFlow 内置 | 知识库检索向量化 | +| 6 | Dify DB(只读) | `10.80.128.40:5432` DB=dify User=difyro | 历史数据迁移 | +| 7 | 企微自建应用 | 已创建(CorpID/AgentID/Secret) | 消息收发的企微入口 | + +### 9.2 🟡 业务逻辑复用(需适配) +- 现有 system_users → 新 Agent(改 password 明文 → bcrypt) +- 现有会话定义(15 分钟无交互=一个会话)→ 新状态机(queued/serving/resolved) +- 现有自助解决判定 → 新统计口径 +- 现有知识库命中判定 → 加 AI 置信度 +- 现有 ManualIntervention → 新 tags 体系 +- 现有 ManualEntry → 直接复用 +- 现有 MonthlyReportQueryView → 新运营报表 +- 现有登录认证(Session+Redis+12h) → 新 JWT+Redis + +### 9.3 🟢 基础设施复用(直接复用或微调) +- 服务器 `10.80.0.86`(原 Django+PG+Redis,新 FastAPI 同机部署) +- 域名 `it-dataquery.dc.servyou-it.com`(新系统用子域名) +- SSL 证书(`ssl/` 目录) +- Nginx(`nginx/nginx.conf`,改反代配置) +- Docker Compose 部署模式 +- Redis(可复用,db=0 旧 / db=1 新) +- SearXNG 搜索 `10.90.5.8:8080`(M2 AI 联网) +- LangBot `10.90.5.8:30030`(多模型接入) +- Docker 网络 `dbquery_net`(新 `itdesk_net`) + +### 9.4 关键对接参数 +``` +dify2openai API: http://yw-dify.dc.servyou-it.com/dify2openai/v1/chat/completions +RAGFlow: http://10.80.0.85:8080 +Qwen3-30B: http://10.80.0.49:5000/api/llm/servyou/v1/chat/completions +Dify DB(生产只读): 10.80.128.40:5432 DB=dify User=difyro +Dify DB(测试): 10.199.16.9:5432 DB=dify User=dify_ro +Redis: 10.90.5.8:6379 +数据平台: http://it-dataquery.dc.servyou-it.com (10.80.0.86) +B 端智能体: https://agent.dc.servyou-it.com +SearXNG: http://10.90.5.8:8080 +Dify App ID: a57543f3-de66-47cc-ad89-d0540c08159f +``` + +--- + +## 10. WebSocket 实时通信 + +### 10.1 设计要点 +- **路径**:`/ws/{agent_id}` + `/ws/h5/{employee_id}`(H5 端点) +- **认证**:**P0 修复后** token 走 `Sec-WebSocket-Protocol` subprotocol(不是 URL query,不是 header) +- **nginx 配置**: + - `proxy_http_version 1.1` + - `Upgrade` + `Connection "upgrade"` + - `proxy_read_timeout 86400s` + - **`access_log off`**(避免 token 泄露,P0-#4) +- **限流**:无原生限流,依赖 token 鉴权 + +### 10.2 心跳 + 重连 + 降级 +- 心跳:前端 30s ping,后端 pong +- 重连:指数退避(1s → 2s → 4s → ... → 30s 上限) +- 降级:WS 断连 → 自动切 3s 轮询 → 重连后停轮询 + +### 10.3 ws_manager 单例 +- 模块级单例,全局共享 +- broadcast 遇发送失败自动断开该连接(避免僵尸) +- 失败只记 warning 不抛异常(不阻塞调用方) + +--- + +## 11. 前端 4 端总览 + +| 端 | 路径 | 技术栈 | 组件数 | 路由 | +|---|---|---|---|---| +| frontend-h5 | `/itdesk/` | Vue3 + Vant4 + Pinia + TS | 11 | vue-router | +| frontend-agent | `/itagent/` | Vue3 + ElementPlus + Pinia + TS | 23 | vue-router | +| frontend-portal | `/itportal/` | Vue3 + Vant4 + Pinia + TS | 3 | 角色卡片选择 | +| frontend-admin | `/itadmin/` | Vue3 + ElementPlus + Pinia + TS | 13+ | vue-router | + +### 11.1 关键 UI 决策 +- **统一企微浅色扁平风格**(accent=#07C160 微信绿) +- **术语统一**:"举手" → "招手","铃铛" → "传菜铃" +- **响应式**:H5 端适配企微 WebView + +### 11.2 4 前端审计 + 16 项统一优化路线 +详见 `docs/前端审计报告.md` + +--- + +## 12. 部署方案 + +### 12.1 生产服务器(当前 v0.5.0-beta) +| 资源 | 值 | +|---|---| +| 服务器 | **10.90.5.110**(公司内网,2026-06-15 起替代 10.80.0.136) | +| 域名 | `itsupport.servyou.com.cn`(通配符 `*.servyou.com.cn`) | +| HTTPS | 443(SSL 证书已部署,2026-06-15) | +| 80 端口 | 301 跳 443 | +| 数据库 | PostgreSQL 16(Docker) | +| 缓存 | Redis 7(Docker) | +| 部署目录 | `/opt/wecom-it-desk/` | +| 上传临时目录 | `/tmp/`(堡垒机限制) | +| Docker 网络 | bridge(Docker Compose 自定义) | +| 健康检查 | nginx `curl -kf https://localhost:443/itdesk/health` | + +### 12.2 NAS 测试环境 +| 资源 | 值 | +|---|---| +| 服务器 | NAS(Synology 套件) | +| 域名 | `itdesk.amanzac.com` | +| 用途 | Gitea 自托管(8418 端口) + 内部测试 | + +### 12.3 部署包结构(`package.py` 生成) +``` +it-smart-desk-server-deploy.zip +├── docker-compose.yml +├── .env.example +├── deploy.sh +├── README.md +├── nginx/nginx.conf +├── frontend-h5/dist/ # H5 静态文件 +├── frontend-agent/dist/ # 坐席端静态 +├── frontend-portal/dist/ # 统一入口静态 +├── frontend-admin/dist/ # 管理后台静态 +└── backend/ # FastAPI 源码(排除 uploads/ 隐私) +``` + +### 12.4 ⚠️ package.py P0 修复(v0.5) +- 补:INCLUDE_MAP 缺 `frontend-portal/dist` 和 `frontend-admin/dist` +- 补:should_exclude 排除 `uploads/`(隐私不打包) +- 补:build_frontends 加 portal + admin 端构建 + +--- + +## 13. 运维操作 + +### 13.1 一键部署 +```bash +# 打包 +cd 项目根目录 +python deploy-server/package.py +# → it-smart-desk-server-deploy.zip + +# 上传 +scp it-smart-desk-server-deploy.zip user@server:/tmp/ +# (堡垒机禁 ProxyJump,需用其他方式:Web 上传 / 内部文件平台) + +# 部署 +ssh user@server +sudo cp /tmp/it-smart-desk-server-deploy.zip /opt/ +cd /opt +unzip it-smart-desk-server-deploy.zip +mv it-smart-desk-server-deploy wecom-it-desk +cd wecom-it-desk +cp .env.example .env +vi .env # 编辑配置 +chmod +x deploy.sh +./deploy.sh +``` + +### 13.2 日常运维 +```bash +# 查看服务状态 +docker compose ps + +# 查看后端日志 +docker compose logs -f backend + +# 数据库迁移 +docker compose exec backend alembic upgrade head + +# 备份 +./scripts/backup-gitea.sh + +# 健康度仪表盘 +./scripts/dashboard.py +# → docs/dashboard.html(浏览器打开) +``` + +### 13.3 应急响应 +详见 `docs/SOPs/SOP-004-应急响应.md` + +--- + +## 14. 安全设计 + +### 14.1 已修复 P0(2026-06-14~15) +1. **WS token 泄露** — token 改走 `Sec-WebSocket-Protocol` subprotocol(非 URL/header) +2. **坐席登录缺密码** — `agents.py` L222-232 加 bcrypt 验证(3 测试覆盖) +3. **nginx access_log 记录 WS token** — `/ws/` 路径 `access_log off` +4. **5 鉴权漏洞** — 5 端点鉴权已修 +5. **企微凭据硬编码** — 旧 `Bs7ucT*` 已轮换,新值走 `WECOM_CORP_SECRET` env + +### 14.2 待修 P0(2026-06-15 报告) +- 5 鉴权漏洞全部修完(已 100% 闭环,见 [[review-p0-security-2026-06-14]]) +- 浏览器 WS API 不支持 subprotocol → 需找替代方案 +- nginx access_log 全局配置未关(只关了 /ws/) +- 类型 bug / 降级放行 / 缺依赖 5 项遗留(详见评审报告) + +### 14.3 安全 Header(nginx) +- `X-Content-Type-Options: nosniff` +- `X-Frame-Options: SAMEORIGIN` +- `X-XSS-Protection: 1; mode=block` +- `Strict-Transport-Security: max-age=31536000; includeSubDomains` +- `Referrer-Policy: strict-origin-when-cross-origin` +- **CSP**:`default-src 'self'; script-src 'self' 'unsafe-eval' https://res.wx.qq.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https: http:; connect-src 'self' https://qyapi.weixin.qq.com wss://*; font-src 'self' data:;` +- `Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()` +- `Cross-Origin-Opener-Policy: same-origin` +- `Cross-Origin-Embedder-Policy: require-corp` +- `Cross-Origin-Resource-Policy: same-origin` +- `server_tokens off` + +### 14.4 IP 白名单(nginx) +- `/itadmin/`:10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 10.212.0.0/16(VPN) +- `/api/admin/`:同 itadmin + +### 14.5 密码策略 +- 坐席密码:**bcrypt**(已迁移明文 → hash) +- DB 用户:PostgreSQL `wecom`(trust on unix socket / MD5 on TCP) +- 旧凭据:已轮换 + +--- + +## 15. 决策锁(已锁定,不可随意变更) + +| 决策 | 内容 | 锁定日期 | 依据 | +|---|---|---|---| +| **域名** | `itsupport.servyou.com.cn`(通配符 `*.servyou.com.cn`) | 2026-06 | 已有 SSL 证书 | +| **UI 风格** | 企微浅色扁平风,accent=#07C160 | 2026-06-13 | 坐席+H5 统一 | +| **术语** | "举手" → "招手","铃铛" → "传菜铃" | 2026-06-13 | 25+ 处代码修改 | +| **双企微应用** | 正式 + 测试(子域名申请困难) | 2026-06-13 | 决策记录在状态报告 | +| **架构** | 单体 Docker Compose → 未来 K8s 集群 | 2026-06-03 | 演进路径 M3 后再迁 | +| **数据库** | PostgreSQL 16(单库,合并原 Dify + intervention) | 2026-06 | 升级策略 | +| **缓存** | Redis 7(单实例,db 0 旧/db 1 新) | 2026-06 | 复用现有 | +| **认证** | JWT + Redis(替换 Django Session) | 2026-06 | 重写认证层 | +| **AI 模型** | Qwen3-30B 主, Dify Workflow 编排 | 2026-06 | 复用现有 | +| **项目名** | `wecom_it_smart_desk`(claude 工作副本 `-claude` 后缀) | 2026-06-15 | 移交后命名 | +| **Git 托管** | Gitea 自托管(NAS 8418) | 2026-06-14 | ADR-001 | +| **IP 白名单(临时)** | set_real_ip_from 用 10/172.16/192.168/10.212 4 段(内网最大化)**临时方案** | 2026-06-15 | 修 403 异常 | +| **IP 白名单(正式)** | **正式发布前必改**:审计公司实际前置代理 IP,精确单 IP 列表(防 X-Forwarded-For 伪造) | v1.0 必做 | 见 [[ip-whitelist-trust-proxies-todo]] | + +### 15.1 配色体系(UI 重要性标识) +- 🔴 紧急/高风险 +- 🟡 重要/需关注 +- 🟢 常规/OK +- ⚪ 信息/记录 + +### 15.2 选择项中英对照(用户偏好) +所有选择项英文内容必须包含中文翻译 + +--- + +## 16. 工具链(8 个脚本 + 5 份配置) + +| # | 路径 | 用途 | +|---|---|---| +| 1 | `scripts/dashboard.py` | 生成健康度 HTML(`docs/dashboard.html`) | +| 2 | `scripts/oneclick-deploy.sh` | 一键部署(灰度) | +| 3 | `scripts/pre-commit-check.sh` | 提交前 4 件套预检(鉴权+依赖+alembic+配置) | +| 4 | `scripts/backup-gitea.sh` | Gitea 备份 + 恢复(cron 3 点) | +| 5 | `scripts/security-audit.sh` | 5 工具集成审计 | +| 6 | `scripts/generate-api-docs.sh` | OpenAPI + Swagger UI + ReDoc | +| 7 | `scripts/build.sh` | 统一构建 | +| 8 | `scripts/deploy.sh` | 通用部署 | + +| # | 路径 | 用途 | +|---|---|---| +| 1 | `.dockerignore` | Docker 优化 | +| 2 | `.gitea/dependabot.yml` | 依赖自动更新 | +| 3 | `.gitea/ISSUE_TEMPLATE/bug.md` | Bug 报告模板 | +| 4 | `.gitea/ISSUE_TEMPLATE/feature.md` | Feature 申请模板 | +| 5 | `.gitea/PULL_REQUEST_TEMPLATE.md` | PR 模板 | + +--- + +## 17. 文档体系(50+ 份) + +### 17.1 设计文档(7) +- `docs/01-项目总览与部署手册.md`(v2.1, 34K) +- `docs/ARCHITECTURE.md`(完整架构,2,880 行,129K) +- `docs/ARCHITECTURE-admin.md`(管理后台,1,274 行) +- `docs/团队沟通文档-架构消息知识库.md`(655 行) +- `docs/统一入口技术设计文档.md`(909 行) +- `docs/Wingman设计.md`(776 行) +- `docs/外部系统集成`:火绒 560 行 + 联软 797 行 + aTrust 879 行 + +### 17.2 PRD(2) +- `docs/PRD.md`(完整需求,2,077 行,127K) +- `docs/PRD-admin.md`(管理后台,27K) +- `docs/PRD-增量-人工按钮与术语统一.md`(14K) + +### 17.3 技术方案(5) +- `docs/ExternalSystemAdapter设计文档.md`(v1.0) +- `docs/消息功能详细方案.md`(534 行) +- `docs/摇人-多坐席协作-技术方案.md`(389 行) +- `docs/邀请功能-技术方案.md`(407 行) +- `docs/OTP二次验证实现.md`(88 行) + +### 17.4 ADR(架构决策记录,4 份) +- `docs/ADRs/ADR-001-Gitea自托管-Funnel暴露.md` +- `docs/ADRs/ADR-002-WS-Token-Subprotocol鉴权.md` +- `docs/ADRs/ADR-003-nginx-access_log关闭.md` +- `docs/ADRs/ADR-004-Token不入文件-走wincred.md` + +### 17.5 SOP(标准操作流程,4 份) +- `docs/SOPs/SOP-001-Gitea部署.md` +- `docs/SOPs/SOP-002-Gitea备份恢复.md` +- `docs/SOPs/SOP-003-推送评审.md` +- `docs/SOPs/SOP-004-应急响应.md` + +### 17.6 审计报告(4) +- `docs/审计报告/CORS-CSP-安全Header全套.md` +- `docs/审计报告/Dockerfile优化与镜像审计.md` +- `docs/审计报告/依赖漏洞扫描与Lockfile审计.md`(识别 5 CVE) +- `docs/审计报告/健康检查+错误码+日志结构化.md`(40+ 错误码 + JSON 日志) + +### 17.7 惊喜报告(2) +- `docs/惊喜报告/🎁惊喜1-项目健康度仪表盘.md` +- `docs/惊喜报告/🎁惊喜2-README徽章+CHANGELOG+模板.md` + +### 17.8 评审报告(6) +- `docs/评审报告/workbuddy-2026-06-14-Gitea重建.md` +- `docs/评审报告/workbuddy-2026-06-14-P0安全.md` +- `docs/评审报告/workbuddy-2026-06-14-消息优化-P1二次评审.md` +- `docs/评审报告/workbuddy-2026-06-14-消息优化.md` +- `docs/评审报告/workbuddy-2026-06-14-预检验证.md` +- `docs/评审报告/workbuddy-2026-06-15-T组A组.md` + +### 17.9 部署/迁移(6) +- `docs/DEPLOY_NAS.md` +- `docs/NAS部署指南.md` +- `docs/Gitea部署指南.md` +- `docs/正式环境独立部署架构方案.md` +- `docs/智能IT支持服务台-项目迁移文档.md` +- `docs/资源申请清单.md` + +### 17.10 状态/报告(5) +- `docs/RELEASE_NOTES_v0.5.0-beta.md` +- `docs/项目任务状态报告_2026-06-13.md`(152 任务 99.3% 完成) +- `docs/IT服务台部署修复记录-2026-06-13.md` +- `docs/调试验证指南_2026-06-13.md` +- `docs/风险跟踪表.md`(907 行) + +### 17.11 数据库(1) +- `docs/数据库ER图与环境变量清点.md`(16 表 ER + 17 env) + +### 17.12 前端审计(1) +- `docs/前端审计报告.md`(10K) + +### 17.13 原型/prototypes(目录) +- `docs/prototypes/` +- `docs/IT智能服务台_项目汇报.html`(34K,可视化) +- `docs/dashboard.html`(健康度仪表盘) + +### 17.14 域名/邮件(1) +- `docs/域名申请邮件-itsupport-servyou-com-cn.md` + +### 17.15 现有系统交接(1) +- `docs/现有系统交接文档内容.txt`(137 行,原 Django 系统) + +### 17.16 紧急预案(1) +- `docs/需求-发布预演页面.md`(应急降级页 v4) + +--- + +## 18. 测试 + +### 18.1 后端测试 +- 116 条 pytest(已写,部分已通过) +- v0.5 新增 3 条(降级登录密码验证) +- 路径:`backend/tests/test_agents.py` + +### 18.2 端到端验证 +- 任务 #149 — In Progress +- 范围:H5 登录(3 种)/ 坐席接单 / 消息收发 / 邀请功能 / 管理后台 +- 环境:`https://itsupport.servyou.com.cn` + `https://itdesk.amanzac.com` + +--- + +## 19. 待办清单(从项目任务状态报告 + 评审报告 + 风险表) + +### 19.1 立即执行(P0) +1. ~~端到端验证 #149~~(等待中) +2. ~~HTTPS 配置(SSL 证书)~~ ✅ 已完成(2026-06-15) +3. 修 006 filename 与 revision 不一致(v0.5.1)— 任务 #41 +4. ~~alembic chain 修复(007 typo)~~ ✅ 已完成 +5. ~~浏览器验证 4 域名~~ ✅ 已完成 + +### 19.2 近期安排(P1) +1. **创建测试企微应用**(双企微方案) +2. **阶段二启动**:排队机制 + 满意度评价 +3. **aTrust 对接**:找信息安全团队 +4. **北森 eHR 对接**:找 HR 数字化团队 +5. **集成验证**:4 外部系统端到端 + +### 19.3 技术债务(P2) +1. Redis 密码加固 +2. PostgreSQL 强密码 +3. CORS 配置收紧 +4. CSP 策略实施(已部分实施) +5. 应急降级页(BC/DR)代码 +6. 演练 SOP-005 + +### 19.4 风险登记 +| 风险 | 级别 | 缓解 | +|---|---|---| +| 企微凭据集中化 | 中 | NAS Vault(待做) | +| 5 外部系统任一不可用 | 中 | ExternalSystemAdapter 自动降级 | +| 现有系统密码明文 | 高 | bcrypt 迁移已完成 | +| Dify DB 只读 | 中 | 新系统自建库,只从 Dify 同步 | +| 5 CVE(依赖漏洞) | 中 | dependabot 自动更新 | +| WB 上下文冲突 | 高 | **已退出,Claude 接管** | + +--- + +## 20. 关键文件路径速查 + +### 20.1 后端核心 +``` +backend/ +├── alembic/versions/ # 10 个迁移 +├── app/ +│ ├── main.py # FastAPI 入口(608 行) +│ ├── config.py # 配置(154 行) +│ ├── database.py # DB 连接(146 行) +│ ├── api/ # 20 个 router +│ ├── services/ # 15 个 service +│ ├── models/ # 16 个 model +│ ├── schemas/ # Pydantic 5 套 +│ ├── integrations/ # 4 个外部系统 +│ └── utils/ # error_codes/token/crypto +├── tests/ # 116 条 pytest +├── Dockerfile +└── requirements.txt +``` + +### 20.2 前端核心 +``` +frontend-h5/ # H5 员工端(11 组件) +frontend-agent/ # 坐席工作台(23 组件) +frontend-portal/ # 统一入口(3 组件) +frontend-admin/ # 管理后台(13+ 视图) +``` + +### 20.3 部署核心 +``` +deploy-server/ +├── package.py # 打包脚本 +├── docker-compose.yml +├── nginx/nginx.conf +├── .env.example +└── deploy.sh +``` + +### 20.4 配置/规范 +``` +.dockerignore +.gitea/ # dependabot + issue_template + pr_template +.pre-commit-config.yaml +docs/ADRs/ # 4 份架构决策 +docs/SOPs/ # 4 份标准操作 +``` + +--- + +## 21. 关联 memory 索引(已沉淀) + +- [[project-handover-to-claude]] — 项目从 WB 全面移交到 Claude(2026-06-15) +- [[locked-decisions]] — 锁定的设计决策 +- [[phase1-progress]] — 痛点清单 + 五阶段演进规划 +- [[tech-architecture]] — 技术架构细节(超时/字段映射/Redis 协议) +- [[wechat-environment]] — 企微环境限制(UA/OAuth2/统一入口) +- [[deployment]] — 部署经验(NAS/Docker/堡垒机) +- [[external-integrations]] — 外部系统集成(火绒/联软/aTrust/eHR) +- [[workbuddy-tool]] — WB 推进工具(已停用) +- [[ip-whitelist-trust-proxies-todo]] — IP 白名单正式发布前必收窄(P0 安全收尾) +- [[code-version-chaos]] — 代码版本管理混乱(治理中) +- [[gitea-deployed-2026-06-14]] — Gitea 部署 +- [[gitea-push-permission-revoked-2026-06-15]] — push 权限吊销 +- [[review-messages-2026-06-14]] — WB 消息评审 +- [[review-p0-security-2026-06-14]] — WB P0 安全评审 +- [[overnight-batch-2026-06-15]] — 满载跑批产出 +- [[server-upload-path]] — 服务器上传路径 +- [[production-architecture-pitfall]] — 生产架构误判教训 +- [[backend-healthcheck-curl-pitfall]] — backend healthcheck curl 坑 +- [[user-language-preference]] — 选择项中英对照 +- [[choice-importance-colors]] — 选项配色体系 +- [[feedback-execute-without-asking]] — 直接执行不请示 + +--- + +## 22. 后续行动(Claude 接管后) + +### 22.1 立即 +- [ ] 修复 006 filename 与 revision 不一致(v0.5.1,任务 #41) +- [ ] commit 当前所有 hotfixes + push 到 Gitea(等用户重授权) +- [ ] 重打部署包并验证 +- [ ] 浏览器验证 /itdesk/ 500 错误根因 + +### 22.2 短期(1 周) +- [ ] 阶段二排队机制设计 +- [ ] 满意度评价 PRD +- [ ] 应急降级页 v4 实现 +- [ ] 演练 SOP-005 +- [ ] 单元测试全量跑通 + +### 22.3 中期(1 月) +- [ ] 阶段二 AI 接入(Dify + RAGFlow) +- [ ] aTrust API 对接 +- [ ] 北森 eHR OAuth2 对接 +- [ ] 知识库迭代闭环(M3 起步) +- [ ] 应急降级页演练 + +### 22.4 长期 +- [ ] v0.6.0 正式发布(2026-06-20) +- [ ] v1.0.0 正式版目标(2026-12,阶段 5 完成) +- [ ] K8s 集群迁移 +- [ ] 跨主体共享支持 + +--- + +## 23. 今日踩坑(2026-06-15~16 经验沉淀) + +> **作用**:把过去两天踩过的 7 个坑写成"事后诸葛亮",让以后部署/排错时少走弯路。每条都给了"症状 → 根因 → 修法 → 教训"四段式。 + +### 23.1 alembic_version 表脏数据导致 backend 启动 overlaps + +- **症状**:backend 容器启动后 alembic 报错 `Multiple head revisions are present for alembic_version`,数据库迁移失败。 +- **根因**:之前手动执行 `alembic stamp 009` 后没清旧数据,表里残留两行版本号(008 和 009),alembic 检测到"两个 head"就抛错。 +- **修法**:SQL 直连 PostgreSQL → `DELETE FROM alembic_version WHERE version_num != '009';` 只保留最新一行。 +- **教训**:**永远用 alembic 命令升级**(alembic upgrade head),不要手工 stamp;如果非要 stamp,先清表再写。 + +### 23.2 REDIS_URL 密码含 @ # 必须 URL-encode + +- **症状**:backend 容器一直 `Redis TimeoutError`,redis-cli 连不上。 +- **根因**:生产 Redis 密码 `R3d!s@2026#Secure` 含 `@` 和 `#` 两个 URL 保留字符。redis-py 用 urlparse 解析 `redis://:R3d!s@2026#Secure@redis:6379/0`,第一个 `@` 被当 host 分割,密码被截成 `R3d!s`。 +- **修法**:docker-compose.yml 的 REDIS_URL 用 `${REDIS_PASSWORD:-R3d%21s%402026%23Secure}`,shell 展开后是 URL-encoded → redis-py 会自动 decode 回明文 → 与 Redis 实际密码一致。 +- **教训**:**密码含 URL 保留字符必须 URL-encode**(`@`→`%40`、`#`→`%23`、`!`→`%21`)。参考 [[redis-url-special-chars-pitfall]] 和 [[redis-py-url-decode-trap]]。 + +### 23.3 nginx IP 白名单"两处都改"才生效 + +- **症状**:`/itadmin/` 一直返 403 Forbidden,即使加了 `allow 115.236.188.3;`。 +- **根因**:nginx 配置有**嵌套 location**,`/itadmin/` 块(返回 HTML)和 `/api/admin/` 块(代理 API)各有一套独立的 `allow/deny`。只改一处白名单不生效。 +- **修法**:两个块都要加 `allow 115.236.188.3;`,然后 `docker exec wecom_it_nginx nginx -s reload`。 +- **教训**:**nginx 嵌套 location 都要单独检查**。看 conf 时区分 outer block(12-space indent)和 inner block(16-space indent)。参考 [[nginx-allow-list-pitfall]]。 + +### 23.4 企微 WebView 真实 IP 不是公司公网 IP + +- **症状**:加 `allow 115.236.188.3;` 后用户用 企微 Android Edge 访问 `/itadmin/` 还是 403。 +- **根因**:`115.236.188.3` 是公司**公网出口 IP**(WAF 后面的),用户手机走的是移动运营商网络,客户端真实 IP 是运营商 IP,不会经过 115.236.188.3。 +- **修法**:临时改成 `allow 0.0.0.0/0;`(全开),靠 backend 的 admin token 鉴权保护。 +- **教训**:**WAF/公司公网出口 IP ≠ 用户真实客户端 IP**。要拿用户真实 IP,得看 WAF/CDN 透传的 X-Forwarded-For 字段。**v1.0 前必须收窄**(任务 #48)。 + +### 23.5 SPA 路由守卫是异步,组件 mount 早就触发了 + +- **症状**:企微点坐席应用 → `/itagent/` 弹"未授权,请重新登录"2 次。 +- **根因**:router 守卫虽然会跳到 `/itportal/`,但 Vue 组件的 `import` + `onMounted` 在 router 守卫**之前**就触发了,axios 拦截器已经发了 `/api/agents/me` 请求 → 后端 401 → 弹"未授权"。 +- **修法**:`Workspace.vue` 的 `onMounted` 第一行先检查 `localStorage.getItem('agent_token')`,没 token 立刻 `window.location.href = '/itportal/'` 并 `return`。 +- **教训**:**router 守卫不可靠**,任何需要鉴权的页面都要在 `onMounted` 第一行手动检查 token。参考 [[workspace-vue-pre-mount-check]]。 + +### 23.6 Workspace.vue 没输入框不是 bug,是没选会话 + +- **症状**:用户报"坐席端没有消息输入框"。 +- **根因**:`Workspace.vue` 中间区域是**动态切换**的(`v-if/v-else-if/v-else`),没 `currentConversation` 时显示 `` 占位,根本没有 ChatArea/InputBox。 +- **诊断**:让用户看中间显示什么。 + - 显示"请选择..." → 不是 bug,引导用户点左侧会话 + - 显示对话气泡但无输入框 → ChatArea 组件 bug + - 完全空白 → 组件渲染失败 +- **教训**:**SPA 视图切换**不要只看"UI 元素缺失",要先看父组件的 `v-if` 条件。参考 [[agent-input-box-no-bug]]。 + +### 23.7 SQLAlchemy UUID 列在 DB 里是 VARCHAR → 偶发 500 + +- **症状**:`/h5/conversations/current/messages/poll` 接口偶发 500,日志 `operator does not exist: character varying = uuid`。 +- **根因**:数据库 `messages.id` 列是 VARCHAR(早期 migration 用 String 定义),但 SQLAlchemy 模型把 `id` 定义成 UUID,查询时自动 cast `WHERE id = $1::UUID` → 类型不匹配 → 500。 +- **修法**:加 alembic migration `ALTER TABLE messages ALTER COLUMN id TYPE UUID USING id::UUID` 把列类型统一成 UUID。 +- **教训**:**schema 演进必须改 DB schema**,只改 Python 模型不够。看到 `operator does not exist` 错误,八成是列类型不匹配。参考 [[sql-messages-id-varchar-vs-uuid]]。 + +### 23.8 backend 精简镜像没 curl,healthcheck 永远 unhealthy 但业务正常 + +- **症状**:`docker ps` 显示 backend `unhealthy`,但 API 接口全部正常返回 200。 +- **根因**:backend 用的是 `python:3.11-slim` 精简镜像,**没有 curl**。docker healthcheck 跑 `curl -f http://localhost:8000/health` 直接 `command not found`,每次都 unhealthy。 +- **修法**:改用 `wget --spider` 或直接 `python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"`。 +- **教训**:**精简镜像做 healthcheck 要选已装的工具**,或者 build 时加 `apt-get install -y curl`。参考 [[backend-healthcheck-curl-pitfall]]。 + +### 23.9 frontend 不是独立容器,是 nginx 静态文件挂载 + +- **症状**:以为 frontend 是 docker 容器,改前端要重新 build image + push。 +- **根因**:看 docker-compose.yml 后才发现 frontend 4 个端都是**构建产物直接挂载**到 nginx 容器的 `/itagent/` `/itadmin/` 等目录,前端代码完全在宿主机 `/opt/wecom-it-desk/frontend-*/dist/`。 +- **修法**:改前端 → 本地 build → tar 上传 → 解压到 `/opt/wecom-it-desk/frontend-*/dist/` → `docker exec wecom_it_nginx nginx -s reload`。 +- **教训**:**先 `cat docker-compose.yml` 再下架构结论**。参考 [[production-architecture-pitfall]]。 + +--- + +> **本文档维护者**:Claude(claude 工作目录) +> **更新频率**:每次重大变更后更新 +> **下次审计**:v0.6.0 发布前 diff --git a/backend/alembic/versions/006_admin_extension.py b/backend/alembic/versions/006_admin_ext.py similarity index 86% rename from backend/alembic/versions/006_admin_extension.py rename to backend/alembic/versions/006_admin_ext.py index c2ef605..362817e 100644 --- a/backend/alembic/versions/006_admin_extension.py +++ b/backend/alembic/versions/006_admin_ext.py @@ -1,4 +1,4 @@ -"""admin extension — 管理后台数据库扩展迁移 +"""admin ext — 管理后台数据库扩展迁移 新增 config_change_logs 表(配置变更日志)。 扩展 agents 表:新增 role(角色)和 skill_tags(技能标签)字段。 @@ -8,16 +8,23 @@ submitted_by(提交人)字段。 Revision ID: 006_admin_ext Revises: 005_reply_to_id Create Date: 2026-07-15 10:00:00.000000 + +注:filename 与 revision 字符串一致(v0.5.1 修复) +原 filename `006_admin_extension.py` 改名为 `006_admin_ext.py`, +revision 字符串保持 `006_admin_ext` 不变(DB alembic_version 表已存此值, +改 revision 会破坏 chain)。 """ +from typing import Sequence, Union + from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '006_admin_ext' -down_revision = '005_reply_to_id' -branch_labels = None -depends_on = None +revision: str = '006_admin_ext' +down_revision: Union[str, None] = '005_reply_to_id' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: @@ -113,4 +120,5 @@ def downgrade() -> None: # 删除 config_change_logs 表索引和表 op.drop_index('idx_ccl_changed_at', table_name='config_change_logs') op.drop_index('idx_ccl_config_key', table_name='config_change_logs') + op.table('config_change_logs') op.drop_table('config_change_logs') diff --git a/backend/app/api/admin/security_comparison.py b/backend/app/api/admin/security_comparison.py new file mode 100644 index 0000000..b1b698f --- /dev/null +++ b/backend/app/api/admin/security_comparison.py @@ -0,0 +1,166 @@ +""" +终端安全对比 API + +路径: /api/admin/security/comparison +鉴权: require_admin +""" + +from datetime import datetime +from typing import Optional +from uuid import uuid4 + +from fastapi import APIRouter, Depends, HTTPException +from pydantic import BaseModel + +from app.api.admin import require_admin +from app.services.security_comparison import ( + TerminalSecurityComparison, + comparison_task_config, +) + +router = APIRouter(prefix="/security/comparison", tags=["终端安全对比"]) + + +# --- Request/Response Models --- +class CompareRequest(BaseModel): + """手动触发比对请求""" + pass # 无参数,手动触发 + + +class CompareSummaryResponse(BaseModel): + """比对汇总响应""" + lianruan_count: int + huorong_count: int + no_huorong_count: int + compliance_rate: str + generated_at: str + + +class NoHuorongDevice(BaseModel): + """未安装火绒设备""" + hostname: str + ip: str + useraccount: Optional[str] = None + dept: Optional[str] = None + last_login: Optional[str] = None + osver: Optional[str] = None + status: Optional[str] = None + + +class TaskConfigRequest(BaseModel): + """任务配置请求""" + name: str # 任务名称 + cron: str # Cron 表达式,如 "0 9 * * 1" 每周一9点 + recipients: list[str] # 企微接收人user_id列表 + enabled: bool = True + + +class TaskConfigResponse(BaseModel): + """任务配置响应""" + task_id: str + name: str + cron: str + recipients: list[str] + enabled: bool + last_run: Optional[str] = None + next_run: Optional[str] = None + + +# --- API Endpoints --- +@router.get("/summary", response_model=CompareSummaryResponse) +async def get_comparison_summary(current_user=Depends(require_admin)): + """获取比对汇总数据""" + service = TerminalSecurityComparison() + try: + summary = await service.compare_summary() + return summary + finally: + await service.close() + + +@router.get("/no-huorong", response_model=list[NoHuorongDevice]) +async def get_no_huorong_devices(current_user=Depends(require_admin)): + """获取未安装火绒的电脑清单""" + service = TerminalSecurityComparison() + try: + devices = await service.get_no_huorong_devices() + return devices + finally: + await service.close() + + +@router.post("/trigger") +async def trigger_comparison(current_user=Depends(require_admin)): + """手动触发比对并推送企微消息""" + service = TerminalSecurityComparison() + try: + # 1. 执行比对 + no_huorong = await service.get_no_huorong_devices() + + # 2. 生成消息 + if no_huorong: + msg = f"⚠️ 终端安全检查:发现 {len(no_huorong)} 台电脑未安装火绒\n\n" + for dev in no_huorong[:10]: # 只显示前10条 + msg += f"• {dev.get('hostname')} ({dev.get('ip')})\n" + if len(no_huorong) > 10: + msg += f"... 还有 {len(no_huorong)-10} 台" + else: + msg = "✅ 终端安全检查:所有电脑已安装火绒" + + # 3. TODO: 推送到企微(需要企微消息API) + logger.info(f"比对结果: {msg}") + + return { + "success": True, + "no_huorong_count": len(no_huorong), + "message": msg, + } + finally: + await service.close() + + +# --- 任务配置 API --- +@router.get("/tasks", response_model=list[TaskConfigResponse]) +async def list_tasks(current_user=Depends(require_admin)): + """列出所有定时任务""" + tasks = comparison_task_config.list_tasks() + return tasks + + +@router.post("/tasks", response_model=TaskConfigResponse) +async def create_task( + config: TaskConfigRequest, + current_user=Depends(require_admin) +): + """创建定时任务""" + task_id = str(uuid4())[:8] + + comparison_task_config.add_task(task_id, { + "name": config.name, + "cron": config.cron, + "recipients": config.recipients, + "enabled": config.enabled, + "created_at": datetime.now().isoformat(), + }) + + return TaskConfigResponse( + task_id=task_id, + **config.model_dump(), + ) + + +@router.delete("/tasks/{task_id}") +async def delete_task( + task_id: str, + current_user=Depends(require_admin) +): + """删除定时任务""" + success = comparison_task_config.delete_task(task_id) + if not success: + raise HTTPException(status_code=404, detail="任务不存在") + return {"success": True} + + +# 日志记录 +import logging +logger = logging.getLogger(__name__) \ No newline at end of file diff --git a/backend/app/api/agents.py b/backend/app/api/agents.py index 2c73cab..6243581 100644 --- a/backend/app/api/agents.py +++ b/backend/app/api/agents.py @@ -212,7 +212,7 @@ async def agent_login( if not existing_agent: # 新坐席注册必须通过企微验证,防止任意 user_id 冒充 raise AppException( - 1003, + ErrorCode.AUTH_TOKEN_INVALID, "企微通讯录验证失败,新坐席注册需要企微身份验证。请稍后重试或联系管理员。" ) logger.warning( @@ -223,7 +223,7 @@ async def agent_login( if existing_agent.password_hash is None: # 已注册坐席但未设置密码,要求先设置密码 raise AppException( - 1012, + ErrorCode.AUTH_PASSWORD_REQUIRED, "首次登录请先设置密码。管理后台 → 坐席管理 → 设置本地密码" ) if not body.password: diff --git a/backend/app/api/h5.py b/backend/app/api/h5.py index 7ca80c8..e263767 100644 --- a/backend/app/api/h5.py +++ b/backend/app/api/h5.py @@ -829,18 +829,21 @@ async def h5_poll_messages( ).order_by(Message.created_at.asc()) if after_message_id: - # 转换为UUID类型查询,确保和数据库UUID字段类型匹配 + # 校验 UUID 格式,然后转字符串(兼容 SQLite/PG 的 String(36) 列,避免类型不匹配) from uuid import UUID as UUIDType try: - msg_uuid = UUIDType(after_message_id) + UUIDType(after_message_id) # 仅校验 except ValueError: - # 无效的UUID格式,返回空列表 + # 无效的UUID格式,返回空列表 items = [] return success_response(data={"items": items, "has_more": False}) + # 必须用字符串比较,Message.id 在 DB 里是 String(36)/VARCHAR, + # 传 UUID 对象会被 SQLAlchemy 推断成 UUID 类型 → PostgreSQL 报 + # "operator does not exist: character varying = uuid" after_stmt = select(Message.created_at).where( - Message.id == msg_uuid + Message.id == str(after_message_id) ) after_result = await db.execute(after_stmt) after_time = after_result.scalar_one_or_none() diff --git a/backend/app/api/router.py b/backend/app/api/router.py index f4295e1..0a85b17 100644 --- a/backend/app/api/router.py +++ b/backend/app/api/router.py @@ -24,7 +24,9 @@ from app.api.upload import router as upload_router from app.api.admin import router as admin_router from app.api.portal import router as portal_router from app.api.admin_roles import router as admin_roles_router +from app.api.admin.security_comparison import router as security_comparison_router from app.api.approval import router as approval_router +from app.api.wecom_jsapi import router as wecom_jsapi_router # v0.5.4 应急页 JS-SDK 签名 # 创建 API 路由器 # 所有子路由都会挂载到这个路由器上 @@ -157,6 +159,14 @@ api_router.include_router(portal_router, tags=["统一入口"]) # DELETE /api/admin/roles/mapping-rules/{id} — 删除映射规则 api_router.include_router(admin_roles_router, tags=["角色管理"]) +# 终端安全对比 API +# GET /api/admin/security/comparison/summary — 比对汇总 +# GET /api/admin/security/comparison/no-huorong — 未安装火绒清单 +# POST /api/admin/security/comparison/trigger — 手动触发 +# GET /api/admin/security/comparison/tasks — 任务列表 +# POST /api/admin/security/comparison/tasks — 创建定时任务 +api_router.include_router(security_comparison_router, tags=["终端安全对比"]) + # 审批流程 API # GET /api/approval/templates — 获取审批模板列表 # GET /api/approval/templates/{id} — 获取审批模板详情 @@ -164,3 +174,7 @@ api_router.include_router(admin_roles_router, tags=["角色管理"]) # POST /api/approval/submit — API提交审批 # GET /api/approval/keywords — 获取审批关键词 api_router.include_router(approval_router, tags=["审批流程"]) + +# 企微 JS-SDK 签名 API (v0.5.4 应急页身份检测用) +# GET /api/wecom/jsapi-config?url=xxx — 返回 corp_id/agent_id/timestamp/nonce_str/signature +api_router.include_router(wecom_jsapi_router, tags=["企微JS-SDK"]) diff --git a/backend/app/api/wecom_jsapi.py b/backend/app/api/wecom_jsapi.py new file mode 100644 index 0000000..8caef69 --- /dev/null +++ b/backend/app/api/wecom_jsapi.py @@ -0,0 +1,181 @@ +# ============================================================================= +# 企微IT智能服务台 — 企微 JS-SDK 签名 API (v0.5.4 应急页用) +# ============================================================================= +# 说明:提供前端 wx.config / wx.agentConfig 所需的鉴权签名。 +# 对应企微文档:https://developer.work.weixin.qq.com/document/path/90506 +# +# 流程: +# 1. 前端调 GET /api/wecom/jsapi-config?url=xxx 拿签名 +# 2. 后端用 jsapi_ticket + url 算 sha1 签名 +# 3. 前端用 wx.config({...}) 鉴权后,即可调企微 JS-SDK(如 wx.agentConfig) +# +# BC/DR 设计:不依赖 session/auth,公开访问(只返回签名,不返回敏感数据) +# ============================================================================= + +import logging +import secrets +import time + +from fastapi import APIRouter, Query + +from app.config import settings +from app.dependencies import get_shared_wecom_service +from app.utils.response import AppException, success_response + +logger = logging.getLogger(__name__) + +router = APIRouter() + + +@router.get("/wecom/jsapi-config") +async def get_jsapi_config( + url: str = Query(..., description="当前页面 URL(不含 # 及其后)"), +): + """获取企微 JS-SDK 鉴权配置。 + + 供前端 wx.config 和 wx.agentConfig 使用。 + + Returns: + { + "code": 0, + "data": { + "corp_id": "wwa8c87970b2011f41", + "agent_id": "1000133", + "timestamp": 1718500000, + "nonce_str": "5K8264ILTKCH...", + "signature": "f7c8e9..." + } + } + """ + try: + wecom_service = get_shared_wecom_service() + + # 1. 获取 jsapi_ticket + ticket = await wecom_service.get_jsapi_ticket() + + # 2. 生成时间戳和随机串 + timestamp = int(time.time()) + nonce_str = secrets.token_hex(8) # 16 字符 + + # 3. 计算签名 + signature = wecom_service.generate_jsapi_signature( + ticket=ticket, + nonce_str=nonce_str, + timestamp=timestamp, + url=url, + ) + + logger.info( + f"生成 JS-SDK 签名: url={url[:80]}... timestamp={timestamp}" + ) + + return success_response( + { + "corp_id": settings.wecom_corp_id, + "agent_id": str(settings.wecom_agent_id), + "timestamp": timestamp, + "nonce_str": nonce_str, + "signature": signature, + } + ) + + except Exception as e: + logger.error(f"生成 JS-SDK 签名失败: {e}", exc_info=True) + raise AppException( + code=5001, + message=f"生成 JS-SDK 签名失败: {str(e)}", + ) from e + + +# ============================================================================= +# 应急页身份检测 (v0.5.4) +# ============================================================================= +# 流程: +# 1. 前端用 wx.agentConfig 拿到当前 userid +# 2. 前端调 GET /api/wecom/check-role?userid=xxx +# 3. 后端用企微通讯录 API 查 userid 是否在"IT支持-咨询坐席"标签里 +# 4. 返回 "user" 或 "agent" +# ============================================================================= + + +@router.get("/wecom/check-role") +async def check_emergency_role( + userid: str = Query(..., description="企微 userid"), +): + """检测当前账号在应急页场景下的角色。 + + 实现方式(优先级递减): + 1. 企微通讯录标签检测(若配置 WECOM_AGENT_TAG_ID) + 2. 后台硬编码名单(若配置 WECOM_AGENT_USERIDS 环境变量) + 3. 默认 "user" (兜底) + + Args: + userid: 企微 userid(从 wx.agentConfig 拿) + + Returns: + { + "code": 0, + "data": { + "role": "user" | "agent", + "userid": "...", + "method": "tag" | "hardcoded" | "default" + } + } + """ + wecom_service = get_shared_wecom_service() + + # 方式 1:企微标签检测 + tag_id = getattr(settings, "wecom_agent_tag_id", None) + if tag_id: + try: + access_token = await wecom_service.get_access_token() + url = f"https://qyapi.weixin.qq.com/cgi-bin/tag/get?access_token={access_token}&tagid={tag_id}" + import httpx + async with httpx.AsyncClient(timeout=5.0) as client: + resp = await client.get(url) + result = resp.json() + + if result.get("errcode", 0) == 0: + user_list = result.get("userlist", []) + # userlist 元素可能是 str(老版)或 dict(新版带 name) + user_ids = [ + u if isinstance(u, str) else u.get("userid", "") + for u in user_list + ] + if userid in user_ids: + logger.info(f"标签检测: userid={userid} 是坐席") + return success_response( + {"role": "agent", "userid": userid, "method": "tag"} + ) + else: + logger.info(f"标签检测: userid={userid} 是员工") + return success_response( + {"role": "user", "userid": userid, "method": "tag"} + ) + else: + logger.warning( + f"标签 API 失败: errcode={result.get('errcode')}, " + f"errmsg={result.get('errmsg')}, 降级到硬编码" + ) + except Exception as e: + logger.warning(f"标签检测失败(降级): {e}") + + # 方式 2:硬编码名单 + hardcoded = getattr(settings, "wecom_agent_userids", None) + if hardcoded: + agent_ids = [x.strip() for x in hardcoded.split(",") if x.strip()] + if userid in agent_ids: + logger.info(f"硬编码名单: userid={userid} 是坐席") + return success_response( + {"role": "agent", "userid": userid, "method": "hardcoded"} + ) + else: + return success_response( + {"role": "user", "userid": userid, "method": "hardcoded"} + ) + + # 方式 3:默认 user + logger.info(f"未配置检测方式, userid={userid} 默认 user") + return success_response( + {"role": "user", "userid": userid, "method": "default"} + ) diff --git a/backend/app/api/ws.py b/backend/app/api/ws.py index c0ede7a..9dc1e78 100644 --- a/backend/app/api/ws.py +++ b/backend/app/api/ws.py @@ -20,7 +20,6 @@ import logging from fastapi import APIRouter, WebSocket, WebSocketDisconnect -from starlette.requests import Request from app.services.ws_manager import manager as ws_manager from app.services.cache_service import cache_service @@ -39,7 +38,6 @@ WS_CLOSE_UNAUTHORIZED = 4001 async def websocket_endpoint( websocket: WebSocket, agent_id: str, - request: Request, ) -> None: """坐席 WebSocket 端点主循环(含 WS-01 token 认证)。 @@ -61,10 +59,12 @@ async def websocket_endpoint( - 兼容从 ?token= URL 参数获取(向后兼容) - 不再将 token 暴露在 URL 中,避免 access_log 泄露 + v0.5.1 修复:移除 `request: Request` 参数(部分 Starlette 版本注入 Request 失败, + 改用 `websocket.headers` 和 `websocket.query_params` 读取 header/query) + Args: websocket: FastAPI WebSocket 对象(框架自动注入) agent_id: 坐席ID(从 URL 路径参数获取) - request: Starlette Request(用于获取 header) """ # ====================================================================== # WS-01: Token 认证(从 subprotocol / header / query 获取) @@ -74,17 +74,17 @@ async def websocket_endpoint( # 格式: Sec-WebSocket-Protocol: bearer.{token} # 说明: 浏览器原生 WebSocket API 不支持 headers 参数,但支持 subprotocols (第2参数数组) # 前端用 new WebSocket(url, ["bearer.{token}"]) 传递,服务端从 sec-websocket-protocol 头读取 - subprotocol = request.headers.get("sec-websocket-protocol", "") + subprotocol = websocket.headers.get("sec-websocket-protocol", "") if subprotocol.startswith("bearer."): token = subprotocol[7:] # 去掉 "bearer." 前缀 else: # 其次从 Authorization header 获取 - auth_header = request.headers.get("Authorization", "") + auth_header = websocket.headers.get("Authorization", "") if auth_header.startswith("Bearer "): token = auth_header[7:] # 去掉 "Bearer " 前缀 else: # 向后兼容:从 query param 获取(即将废弃) - token = request.query_params.get("token", "") + token = websocket.query_params.get("token", "") # 步骤2: 检查 token 是否为空 if not token: @@ -197,7 +197,6 @@ async def websocket_endpoint( async def h5_websocket_endpoint( websocket: WebSocket, employee_id: str, - request: Request, ) -> None: """H5员工 WebSocket 端点主循环(含 token 认证)。 @@ -223,10 +222,12 @@ async def h5_websocket_endpoint( - (与H5登录 API /api/h5/mock-login 存储格式一致) - token 缺失、无效、过期、与 employee_id 不匹配均拒绝连接 + v0.5.1 修复:移除 `request: Request` 参数(部分 Starlette 版本注入 Request 失败, + 改用 `websocket.headers` 和 `websocket.query_params` 读取 header/query) + Args: websocket: FastAPI WebSocket 对象(框架自动注入) employee_id: 员工企微 UserID(从 URL 路径参数获取) - request: Starlette Request(用于获取 header) """ # ====================================================================== # Token 认证(从 subprotocol / header / query 获取) @@ -234,17 +235,17 @@ async def h5_websocket_endpoint( # 步骤1: 优先从 Sec-WebSocket-Protocol (subprotocol) 获取 token,其次从 Authorization header,最后从 query(向后兼容) # 格式: Sec-WebSocket-Protocol: bearer.{token} - subprotocol = request.headers.get("sec-websocket-protocol", "") + subprotocol = websocket.headers.get("sec-websocket-protocol", "") if subprotocol.startswith("bearer."): token = subprotocol[7:] # 去掉 "bearer." 前缀 else: # 其次从 Authorization header 获取 - auth_header = request.headers.get("Authorization", "") + auth_header = websocket.headers.get("Authorization", "") if auth_header.startswith("Bearer "): token = auth_header[7:] # 去掉 "Bearer " 前缀 else: # 向后兼容:从 query param 获取(即将废弃) - token = request.query_params.get("token", "") + token = websocket.query_params.get("token", "") # 步骤2: 检查 token 是否为空 if not token: diff --git a/backend/app/config.py b/backend/app/config.py index 41a73da..45c64ee 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -107,6 +107,25 @@ class Settings(BaseSettings): # 设备申请审批模板ID(在企微审批应用设置中获取) approval_template_device: str = "" + # ---------------------------------------------------------------------- + # v0.5.4 应急页身份检测配置 + # ---------------------------------------------------------------------- + # IT支持-咨询坐席 通讯录标签 ID(在企微管理后台 > 通讯录管理 > 标签管理 中查看) + # 配置后,应急页会通过此标签判断当前用户是否为坐席 + # 留空则降级到下面的硬编码名单 + wecom_agent_tag_id: str = "" + # 硬编码坐席 userid 列表(逗号分隔),作为标签检测的降级方案 + # 例:"zhangsan,lisi,wangwu"(生产环境建议用标签方案) + wecom_agent_userids: str = "" + + # ---------------------------------------------------------------------- + # v0.6.0 内容审核报警配置(占位,后续完善) + # ---------------------------------------------------------------------- + # 合规通知企微群机器人 webhook + content_audit_webhook: str = "" + # 主管接收报警的 userid(多个用逗号分隔) + content_audit_supervisor_userids: str = "" + # ---------------------------------------------------------------------- # Pydantic-settings 配置 # ---------------------------------------------------------------------- diff --git a/backend/app/main.py b/backend/app/main.py index a8205f0..a563805 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -290,14 +290,29 @@ async def _init_approval_links(db, ApprovalLink): return links = [ - ApprovalLink(category="IT", title="软件安装申请", url="https://审批系统地址/software-install", sort_order=1), - ApprovalLink(category="IT", title="设备报修工单", url="https://审批系统地址/device-repair", sort_order=2), - ApprovalLink(category="IT", title="VPN开通申请", url="https://审批系统地址/vpn-apply", sort_order=3), - ApprovalLink(category="IT", title="权限申请", url="https://审批系统地址/permission-apply", sort_order=4), - ApprovalLink(category="HR", title="入职手续", url="https://审批系统地址/onboarding", sort_order=5), - ApprovalLink(category="HR", title="离职手续", url="https://审批系统地址/offboarding", sort_order=6), - ApprovalLink(category="行政", title="办公用品申领", url="https://审批系统地址/office-supplies", sort_order=7), - ApprovalLink(category="财务", title="报销申请", url="https://审批系统地址/reimbursement", sort_order=8), + # v0.5.2:一站式运维平台真实工单链接(域名 devops.dc.servyou-it.com,已实现企微免登录) + # v0.5.3 更新:去掉 "IT设备升级与硬件维修" (申请单冲突,后续移除) + ApprovalLink(category="IT", title="零信任(原VPN)账号申请", + url="https://devops.dc.servyou-it.com/ITSM/workflow/service/createTicket?name=%E5%91%98%E5%B7%A5%E9%9B%B6%E4%BF%A1%E4%BB%BB%EF%BC%88%E5%8E%9FVPN%EF%BC%89%E8%B4%A6%E5%8F%B7%E7%94%B3%E8%AF%B7IT", + sort_order=1), + ApprovalLink(category="IT", title="活动与会议技术支持", + url="https://devops.dc.servyou-it.com/ITSM/workflow/service/createTicket?name=%E6%B4%BB%E5%8A%A8%E4%B8%8E%E4%BC%9A%E8%AE%AE%E6%8A%80%E6%9C%AF%E6%94%AF%E6%8C%81", + sort_order=2), + # sort_order=3 故意空缺:旧版本是"IT设备升级与硬件维修",已与一站式运维平台冲突,不再提供 + ApprovalLink(category="IT", title="员工IT支持与故障报修", + url="https://devops.dc.servyou-it.com/ITSM/workflow/service/createTicket?name=%E5%91%98%E5%B7%A5IT%E6%94%AF%E6%8C%81%E4%B8%8E%E6%95%85%E9%9A%9C%E6%8A%A5%E4%BF%AE", + sort_order=4), + ApprovalLink(category="IT", title="终端设备网络准入申请", + url="https://devops.dc.servyou-it.com/ITSM/workflow/service/createTicket?name=%E7%BB%88%E7%AB%AF%E8%AE%BE%E5%A4%87%E7%BD%91%E7%BB%9C%E5%87%86%E5%85%A5%E7%94%B3%E8%AF%B7", + sort_order=5), + ApprovalLink(category="IT", title="公共邮箱账号申请", + url="https://devops.dc.servyou-it.com/ITSM/workflow/service/createTicket?name=%E5%85%AC%E5%85%B1%E9%82%AE%E7%AE%B1%E8%B4%A6%E5%8F%B7%E7%94%B3%E8%AF%B7", + sort_order=6), + # HR / 行政 / 财务 占位(待后续接入真实流程) + ApprovalLink(category="HR", title="入职手续", url="https://审批系统地址/onboarding", sort_order=7), + ApprovalLink(category="HR", title="离职手续", url="https://审批系统地址/offboarding", sort_order=8), + ApprovalLink(category="行政", title="办公用品申领", url="https://审批系统地址/office-supplies", sort_order=9), + ApprovalLink(category="财务", title="报销申请", url="https://审批系统地址/reimbursement", sort_order=10), ] db.add_all(links) diff --git a/backend/app/services/security_comparison.py b/backend/app/services/security_comparison.py new file mode 100644 index 0000000..9a066de --- /dev/null +++ b/backend/app/services/security_comparison.py @@ -0,0 +1,149 @@ +""" +终端安全对比服务 - 火绒 vs 联软 + +功能: +1. 获取未安装火绒的电脑清单 +2. 定时任务推送 +3. 手动触发 + +依赖: +- 联软 LV7000: get_dev_all_info() +- 火绒企业版: list_terminals() + +比对逻辑:按主机名精确匹配 +""" + +from datetime import datetime +from typing import Optional +import logging + +from app.integrations.huorong.client import HuorongClient +from app.integrations.lianruan.client import LianruanClient + +logger = logging.getLogger(__name__) + + +class TerminalSecurityComparison: + """终端安全对比服务""" + + def __init__(self): + self.huorong = HuorongClient() + self.lianruan = LianruanClient() + + async def close(self): + """关闭连接""" + await self.huorong.close() + await self.lianruan.close() + + async def get_no_huorong_devices(self) -> list[dict]: + """获取未安装火绒的电脑清单(按主机名匹配)""" + logger.info("开始比对终端安全数据...") + + # 1. 获取联软所有设备 + lianruan_devices = await self._get_all_lianruan_devices() + logger.info(f"联软设备数: {len(lianruan_devices)}") + + # 2. 获取火绒所有终端 + huorong_devices = await self._get_all_huorong_devices() + logger.info(f"火绒终端数: {len(huorong_devices)}") + + # 3. 构建火绒主机名集合(转小写匹配) + huorong_hostnames = { + dev.get("hostname", "").lower() + for dev in huorong_devices + if dev.get("hostname") + } + + # 4. 比对:联软有,火绒无 = 未安装火绒 + no_huorong = [] + for dev in lianruan_devices: + # 联软用 strdevname (计算机名) + hostname = dev.get("strdevname", "").lower() + if hostname and hostname not in huorong_hostnames: + no_huorong.append({ + "hostname": dev.get("strdevname"), + "ip": dev.get("strip1"), # 联软IP字段 + "useraccount": dev.get("strusername"), # 用户名 + "dept": dev.get("strdeptname"), # 部门 + "last_login": dev.get("dtlastlogin"), + "osver": dev.get("strosver"), + "status": dev.get("strstatus"), + }) + + logger.info(f"未安装火绒设备数: {len(no_huorong)}") + return no_huorong + + async def _get_all_lianruan_devices(self) -> list[dict]: + """获取联软所有设备""" + # TODO: 分页获取全部设备 + result = await self.lianruan.get_dev_all_info() + if result and hasattr(result, 'devices') and result.devices: + # 转换为字典列表 + return [d.model_dump() if hasattr(d, 'model_dump') else d for d in result.devices] + return [] + + async def _get_all_huorong_devices(self) -> list[dict]: + """获取火绒所有终端(分页获取)""" + all_devices = [] + page = 1 + per_page = 200 + + while True: + result = await self.huorong.list_terminals(page=page, per_page=per_page) + clients = result.get("clients", []) + if not clients: + break + + for c in clients: + # 火绒字段:hostname, computer_name, ip_addr, local_ip + all_devices.append({ + "hostname": c.get("hostname") or c.get("computer_name"), + "ip": c.get("ip_addr") or c.get("local_ip"), + "status": c.get("stat"), + }) + + # 检查是否还有更多 + if len(clients) < per_page: + break + page += 1 + + return all_devices + + async def compare_summary(self) -> dict: + """比对汇总数据""" + lianruan_devices = await self._get_all_lianruan_devices() + huorong_devices = await self._get_all_huorong_devices() + no_huorong = await self.get_no_huorong_devices() + + return { + "lianruan_count": len(lianruan_devices), + "huorong_count": len(huorong_devices), + "no_huorong_count": len(no_huorong), + "compliance_rate": f"{len(huorong_devices)/len(lianruan_devices)*100:.1f}%" if lianruan_devices else "N/A", + "generated_at": datetime.now().isoformat(), + } + + +class ComparisonTaskConfig: + """定时任务配置""" + + def __init__(self): + self.tasks: dict[str, dict] = {} + + def add_task(self, task_id: str, config: dict): + self.tasks[task_id] = config + + def get_task(self, task_id: str) -> Optional[dict]: + return self.tasks.get(task_id) + + def list_tasks(self) -> list[dict]: + return [{"task_id": k, **v} for k, v in self.tasks.items()] + + def delete_task(self, task_id: str) -> bool: + if task_id in self.tasks: + del self.tasks[task_id] + return True + return False + + +comparison_task_config = ComparisonTaskConfig() diff --git a/backend/app/services/wecom_service.py b/backend/app/services/wecom_service.py index 359d83b..91e2714 100644 --- a/backend/app/services/wecom_service.py +++ b/backend/app/services/wecom_service.py @@ -463,6 +463,101 @@ class WecomService: logger.error(f"获取部门成员网络错误: dept_id={department_id}, error={e}") raise Exception(f"获取部门成员网络错误: {e}") from e + # -------------------------------------------------------------------------- + # JS-SDK 票据 (v0.5.4:应急页身份检测用) + # -------------------------------------------------------------------------- + async def get_jsapi_ticket(self) -> str: + """获取企微 JS-SDK 票据 jsapi_ticket。 + + 对应企微API: + GET https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=TOKEN + + jsapi_ticket 用于计算 JS-SDK 签名(sha1),让前端 wx.config/wx.agentConfig 鉴权通过。 + 有效期 7200 秒,缓存到 Redis(提前 300 秒刷新)。 + + Returns: + str: jsapi_ticket 字符串 + + Raises: + Exception: 获取失败 + """ + cache_key = "wecom:jsapi_ticket" + + # 1. Redis 缓存 + if self.redis: + try: + cached = await self.redis.get(cache_key) + if cached: + logger.debug("从缓存获取 jsapi_ticket") + return cached.decode("utf-8") + except Exception as e: + logger.warning(f"Redis 读取 jsapi_ticket 失败(降级): {e}") + + # 2. 调用企微 API + access_token = await self.get_access_token() + url = f"https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token={access_token}" + + try: + response = await self.client.get(url) + result = response.json() + + if result.get("errcode", 0) != 0: + logger.error( + f"获取 jsapi_ticket 失败: " + f"errcode={result.get('errcode')}, errmsg={result.get('errmsg')}" + ) + raise Exception(f"获取 jsapi_ticket 失败: {result.get('errmsg')}") + + ticket = result.get("ticket", "") + expires_in = result.get("expires_in", 7200) + + # 3. 缓存到 Redis(TTL = expires_in - 300s) + cache_ttl = max(expires_in - 300, 60) + if self.redis: + try: + await self.redis.setex(cache_key, cache_ttl, ticket) + except Exception as e: + logger.warning(f"Redis 写入 jsapi_ticket 失败(降级): {e}") + + logger.info(f"jsapi_ticket 获取成功,缓存 TTL={cache_ttl}秒") + return ticket + + except httpx.HTTPError as e: + logger.error(f"获取 jsapi_ticket 网络错误: {e}") + raise Exception(f"企微API网络错误: {e}") from e + + @staticmethod + def generate_jsapi_signature( + ticket: str, nonce_str: str, timestamp: int, url: str + ) -> str: + """生成 JS-SDK 签名(sha1)。 + + 对应企微JS-SDK签名算法: + 1. 拼接:jsapi_ticket={ticket}&noncestr={nonce_str}×tamp={timestamp}&url={url} + 2. sha1(拼接字符串) + + 注意: + - url 不含 # 及其后面部分 + - url 不含 ? + - url 是前端调用 wx.config 的页面 URL + + Args: + ticket: jsapi_ticket + nonce_str: 随机字符串(前端生成,16位) + timestamp: 当前时间戳(秒) + url: 当前页面 URL(不含 # 后面) + + Returns: + str: sha1 签名字符串(40 字符) + """ + import hashlib + + # 拼接签名字符串 + raw = f"jsapi_ticket={ticket}&noncestr={nonce_str}×tamp={timestamp}&url={url}" + # sha1 哈希 + signature = hashlib.sha1(raw.encode("utf-8")).hexdigest() + return signature + # -------------------------------------------------------------------------- # 上传临时素材 # -------------------------------------------------------------------------- diff --git a/deploy-h5.tar.bak-Mock b/deploy-h5.tar.bak-Mock new file mode 100644 index 0000000000000000000000000000000000000000..61d0a157e9d05dc529d9e2209a9f7be0304805bc GIT binary patch literal 626688 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%0A1q=+M?e1y)r)vyxD@+oC6Na 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 ri^H|{dNbCl&EZrlAXtIFaTltG`-1yH **目标服务器**:`10.80.0.136`(公司内网) +> **目标服务器**:`10.90.5.110`(公司内网,**2026-06-15 起替代 10.80.0.136**) > **域名**:`itsupport.servyou.com.cn` > **访问方式**:通过堡垒机 `10.212.189.210:2222`(用户 `sxn`,OTP 动态口令认证) > **Docker**:已安装 @@ -12,7 +12,7 @@ | 条件 | 状态 | 验证命令 | |------|------|---------| -| Linux 服务器 10.80.0.136 | ✅ 已确认 | — | +| Linux 服务器 10.90.5.110(替代旧 10.80.0.136) | ✅ 已确认 | 2026-06-15 起使用 | | Docker 已安装 | ✅ 已确认 | `docker --version` | | Docker Compose V2 | 待确认 | `docker compose version` | | 端口 80 未被占用 | 待确认 | `ss -tlnp \| grep :80` | @@ -29,17 +29,22 @@ ### 2.2 连接方式 -```bash -# 方式一:ssh -J 一步跳转(推荐) -# -J 指定跳板机,ssh 会自动帮你跳转 -# 堡垒机端口 2222,需要输入 OTP 动态口令 -ssh -J sxn@10.212.189.210:2222 sxn@10.80.0.136 +**PuTTY 客户端(用户实际使用)**: +- 打开 PuTTY +- Host Name(IP 地址):`10.212.189.210` +- Port:`2222` +- Connection type:SSH +- Saved Sessions:起名(如 `wecom-bastion`)→ Save +- 点 Open +- 用户 `sxn` + 密码 +- **堡垒机内再跳目标机**: + ```bash + ssh sxn@10.90.5.110 + ``` -# 方式二:先登录堡垒机,再手动跳转 -ssh -p 2222 sxn@10.212.189.210 -# 输入 OTP 动态口令 +> **OpenSSH `ssh -J` 方式不再使用**(用户已确认用 PuTTY,2026-06-15) # 登录成功后: -ssh sxn@10.80.0.136 +ssh sxn@10.90.5.110 ``` ### 2.3 配置 SSH 快捷方式(推荐) @@ -55,7 +60,7 @@ Host bastion # 智能IT支持服务台服务器 Host itdesk - HostName 10.80.0.136 + HostName 10.90.5.110 User sxn ProxyJump bastion ``` @@ -78,7 +83,7 @@ scp file itdesk:/opt/ # 文件传输也会自动走堡垒机 # 上传单个文件 scp -o "ProxyJump=sxn@10.212.189.210:2222" \ it-smart-desk-server-deploy.zip \ - sxn@10.80.0.136:/opt/ + sxn@10.90.5.110:/opt/ # 如果已配置 ~/.ssh/config: scp it-smart-desk-server-deploy.zip itdesk:/opt/ @@ -96,7 +101,7 @@ scp -P 2222 it-smart-desk-server-deploy.zip sxn@10.212.189.210:/tmp/ ssh -p 2222 sxn@10.212.189.210 # 步骤3:从堡垒机传到目标服务器 -scp /tmp/it-smart-desk-server-deploy.zip sxn@10.80.0.136:/opt/ +scp /tmp/it-smart-desk-server-deploy.zip sxn@10.90.5.110:/opt/ ``` --- @@ -133,17 +138,18 @@ npm install && npm run build # 在开发机上执行 scp -o "ProxyJump=sxn@10.212.189.210:2222" \ it-smart-desk-server-deploy.zip \ - sxn@10.80.0.136:/tmp/ + sxn@10.90.5.110:/tmp/ ``` > 上传到 `/tmp/` 而非 `/opt/`,因为普通用户对 `/opt/` 没有写权限 -### 步骤 3:SSH 登录服务器并解压 +### 步骤 3:登录服务器并解压 + +**PuTTY 登录**(见 §2.2): +- Host:`10.212.189.210`,Port:`2222`,SSH +- 堡垒机内再 `ssh sxn@10.90.5.110` ```bash -# 登录目标服务器 -ssh -J sxn@10.212.189.210:2222 sxn@10.80.0.136 - # 切换 root(普通用户对 /opt 无写权限) sudo -i @@ -237,7 +243,7 @@ docker compose logs --tail 50 postgres 需要联系公司 IT 运维,在公司 DNS 上添加 A 记录: ``` -itsupport.servyou.com.cn A 10.80.0.136 +itsupport.servyou.com.cn A 10.90.5.110 ``` **DNS 未生效前**,可以通过本地 hosts 文件测试: @@ -246,7 +252,7 @@ itsupport.servyou.com.cn A 10.80.0.136 # Windows: C:\Windows\System32\drivers\etc\hosts # macOS/Linux: /etc/hosts # 添加一行: -10.80.0.136 itsupport.servyou.com.cn +10.90.5.110 itsupport.servyou.com.cn ``` > 注意:修改 hosts 文件后,浏览器可能有 DNS 缓存。Chrome 可访问 `chrome://net-internals/#dns` 清除缓存,或用无痕窗口测试。 @@ -324,11 +330,11 @@ cd frontend-agent && npm run build # 2. 上传到服务器(通过堡垒机) scp -o "ProxyJump=sxn@10.212.189.210:2222" \ -r frontend-h5/dist/ \ - sxn@10.80.0.136:/opt/wecom-it-desk/frontend-h5/dist/ + sxn@10.90.5.110:/opt/wecom-it-desk/frontend-h5/dist/ scp -o "ProxyJump=sxn@10.212.189.210:2222" \ -r frontend-agent/dist/ \ - sxn@10.80.0.136:/opt/wecom-it-desk/frontend-agent/dist/ + sxn@10.90.5.110:/opt/wecom-it-desk/frontend-agent/dist/ # 3. 重载 Nginx(不需要重启整个服务) ssh itdesk # 如果已配置 SSH 快捷方式 @@ -344,7 +350,7 @@ docker exec wecom_it_nginx nginx -s reload # 1. 上传新代码到服务器 scp -o "ProxyJump=sxn@10.212.189.210:2222" \ -r backend/ \ - sxn@10.80.0.136:/opt/wecom-it-desk/backend/ + sxn@10.90.5.110:/opt/wecom-it-desk/backend/ # 2. 重新构建并启动 ssh itdesk @@ -400,8 +406,8 @@ docker exec wecom_it_nginx cat /usr/share/nginx/html/itagent/index.html | grep / nslookup itsupport.servyou.com.cn # 如果 DNS 未配置,临时用 IP 直接访问 -curl http://10.80.0.136/itdesk/ -curl http://10.80.0.136/api/health +curl http://10.90.5.110/itdesk/ +curl http://10.90.5.110/api/health ``` ### Mock 登录返回 401 @@ -428,7 +434,7 @@ curl -X POST http://localhost/api/h5/mock-login \ ### 方式一:公司统一 SSL 终端(推荐) ``` -客户端 → HTTPS → 公司SSL终端(F5/网关) → HTTP → 10.80.0.136:80 +客户端 → HTTPS → 公司SSL终端(F5/网关,公网 115.236.188.3) → HTTP → 10.90.5.110:80 ``` 不需要在本服务器上配置证书。联系运维配置 SSL 终端即可。 @@ -441,7 +447,7 @@ curl -X POST http://localhost/api/h5/mock-login \ ## 十一、与 NAS 部署的差异 -| 维度 | NAS 部署(10.80.0.136 旧) | 新服务器部署(10.80.0.136 新) | +| 维度 | NAS 部署(10.80.0.136,已下线) | 新服务器部署(10.90.5.110,2026-06-15 起) | |------|---------------------------|-------------------------------| | 容器数量 | 5个(含 cloudflared) | 4个(无 cloudflared) | | 外网访问 | Cloudflare Tunnel | 公司 DNS 直连 | diff --git a/deploy-server/nginx/nginx.conf b/deploy-server/nginx/nginx.conf index 23ae517..c59c3ee 100644 --- a/deploy-server/nginx/nginx.conf +++ b/deploy-server/nginx/nginx.conf @@ -27,6 +27,21 @@ http { access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log warn; + # ------------------------------------------------------------------ + # 真实 IP 还原(2026-06-15 v0.5.1 修复) + # ------------------------------------------------------------------ + # 问题:公司有 WAF/堡垒机/反向代理,nginx 看到的 $remote_addr + # 是代理 IP(不在白名单),allow/deny 因此误判 403 + # 修法:信任内网段代理透传的 X-Forwarded-For 头,用真实 IP 做白名单 + # 注意:set_real_ip_from 是"我信任的代理",不是"我允许的客户端" + # 必须精确,否则攻击者可伪造 X-Forwarded-For 绕过白名单 + set_real_ip_from 10.0.0.0/8; # 内网 A 类(代理/WAF 出口) + set_real_ip_from 172.16.0.0/12; # 内网 B 类 + set_real_ip_from 192.168.0.0/16; # 内网 C 类 + set_real_ip_from 10.212.0.0/16; # VPN 网段 + real_ip_header X-Forwarded-For; # 从 X-Forwarded-For 取最后一个非信任 IP + real_ip_recursive on; # 递归剥离已信任代理 IP + # ------------------------------------------------------------------ # 基础配置 # ------------------------------------------------------------------ @@ -60,29 +75,58 @@ http { # 如果公司有统一 SSL 终端(如 F5/Nginx 反代),此服务器只需监听 80 # 如果需要本机 HTTPS,取消下方 server 块注释,并配置证书路径 # ================================================================= + # HTTP — 80 端口强制 301 跳 HTTPS + # ================================================================= server { listen 80; server_name itsupport.servyou.com.cn; + # ACME http-01 验证用(如果以后用 Let's Encrypt) + location /.well-known/acme-challenge/ { + root /usr/share/nginx/html; + } + + # 其他全部 301 跳 https + location / { + return 301 https://$host$request_uri; + } + } + + # ================================================================= + # HTTPS — 443 端口(主服务) + # ================================================================= + server { + listen 443 ssl; + http2 on; + server_name itsupport.servyou.com.cn; + + # SSL 证书(通配符 *.servyou.com.cn,fullchain 含 leaf+intermediate+root) + ssl_certificate /etc/nginx/ssl/itsupport.servyou.com.cn.crt; + ssl_certificate_key /etc/nginx/ssl/itsupport.servyou.com.cn.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 1d; + # ------------------------------------------------------------------ # 安全头 # ------------------------------------------------------------------ - # 基础安全头 add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; - + # CSP 收紧: 去掉 unsafe-inline(生产不需要,只有 dev HMR 需要) add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-eval' https://res.wx.qq.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https: http:; connect-src 'self' https://qyapi.weixin.qq.com wss://*; font-src 'self' data:;" always; - + # 隐私与跨域控制 add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always; add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Embedder-Policy "require-corp" always; add_header Cross-Origin-Resource-Policy "same-origin" always; - + # 隐藏服务器版本 server_tokens off; @@ -150,7 +194,7 @@ http { allow 10.212.0.0/16; deny all; - proxy_pass http://backend_api/; + proxy_pass http://backend_api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -195,29 +239,10 @@ http { # 此路径已包含在 /api/ 的代理规则中,无需单独配置 # ------------------------------------------------------------------ - # 默认路径 — 重定向到 H5 员工端 + # 默认路径 — 重定向到统一入口 # ------------------------------------------------------------------ location = / { - return 302 /itdesk/; + return 302 /itportal/; } } - - # ================================================================= - # HTTPS 配置(按需启用) - # ================================================================= - # 如果需要本机直接提供 HTTPS(不走公司统一 SSL 终端), - # 取消下方注释并配置 SSL 证书路径 - # - # server { - # listen 443 ssl; - # server_name itsupport.servyou.com.cn; - # - # ssl_certificate /etc/nginx/ssl/itsupport.servyou.com.cn.crt; - # ssl_certificate_key /etc/nginx/ssl/itsupport.servyou.com.cn.key; - # ssl_protocols TLSv1.2 TLSv1.3; - # ssl_ciphers HIGH:!aNULL:!MD5; - # - # # 其余 location 配置与上方 HTTP server 相同 - # ... - # } } diff --git a/deploy-server/package.py b/deploy-server/package.py index 5b664d4..52adcb0 100644 --- a/deploy-server/package.py +++ b/deploy-server/package.py @@ -40,6 +40,8 @@ INCLUDE_MAP = { "deploy-server/nginx/nginx.conf": f"{PACKAGE_PREFIX}/nginx/nginx.conf", "frontend-h5/dist": f"{PACKAGE_PREFIX}/frontend-h5/dist", "frontend-agent/dist": f"{PACKAGE_PREFIX}/frontend-agent/dist", + "frontend-portal/dist": f"{PACKAGE_PREFIX}/frontend-portal/dist", + "frontend-admin/dist": f"{PACKAGE_PREFIX}/frontend-admin/dist", "backend": f"{PACKAGE_PREFIX}/backend", } @@ -75,6 +77,9 @@ def run_cmd(cmd: str, cwd: Path | None = None) -> bool: def should_exclude(path: Path) -> bool: """判断文件/目录是否应排除""" + # 路径中任何一段是 uploads 目录就排除(隐私 P0:真实用户上传文件不进部署包) + if "uploads" in path.parts: + return True name = path.name if name in {"__pycache__", ".pytest_cache", ".venv", "venv", ".git", ".env", "node_modules"}: return True @@ -121,6 +126,32 @@ def build_frontends(): sys.exit(1) print(" ✅ 坐席工作台构建完成") + # 统一入口 Portal + portal_dir = PROJECT_ROOT / "frontend-portal" + if (portal_dir / "package.json").exists(): + print("构建统一入口 Portal...") + if not run_cmd("npm install --quiet", cwd=portal_dir): + print(" ⚠ npm install 失败,尝试继续...") + if not run_cmd("npm run build", cwd=portal_dir): + print(" ❌ Portal 端构建失败!") + sys.exit(1) + print(" ✅ Portal 端构建完成") + else: + print(" ⏭ Portal 端未实现,跳过") + + # 管理后台 Admin + admin_dir = PROJECT_ROOT / "frontend-admin" + if (admin_dir / "package.json").exists(): + print("构建管理后台 Admin...") + if not run_cmd("npm install --quiet", cwd=admin_dir): + print(" ⚠ npm install 失败,尝试继续...") + if not run_cmd("npm run build", cwd=admin_dir): + print(" ❌ Admin 端构建失败!") + sys.exit(1) + print(" ✅ Admin 端构建完成") + else: + print(" ⏭ Admin 端未实现,跳过") + def create_package(): """创建部署包 zip""" @@ -181,13 +212,13 @@ def main(): print(" 后续步骤:") print("=" * 50) print(f""" - 1. 上传部署包到服务器(通过堡垒机): - scp -o "ProxyJump=sxn@10.212.189.210:2222" \\ - {ZIP_FILENAME} \\ - sxn@10.80.0.136:/tmp/ + 1. 上传部署包到服务器(通过堡垒机 / PuTTY PSCP): + pscp -load wecom-bastion {ZIP_FILENAME} sxn@10.90.5.110:/tmp/ + # 或堡垒机内 scp: + # scp {ZIP_FILENAME} sxn@10.90.5.110:/tmp/ - 2. SSH 登录服务器(通过堡垒机): - ssh -J sxn@10.212.189.210:2222 sxn@10.80.0.136 + 2. PuTTY 登录服务器: + - Host 10.212.189.210 Port 2222 → 用户 sxn → 堡垒机内 ssh sxn@10.90.5.110 3. 在服务器上执行: sudo cp /tmp/{ZIP_FILENAME} /opt/ @@ -201,7 +232,7 @@ def main(): ./deploy.sh 4. 配置 DNS(联系 IT 运维): - itsupport.servyou.com.cn → 10.80.0.136 + itsupport.servyou.com.cn → 10.90.5.110 5. 浏览器验证: http://itsupport.servyou.com.cn/itdesk/ diff --git a/diagnose-500.b64 b/diagnose-500.b64 new file mode 100644 index 0000000..f5cc51b --- /dev/null +++ b/diagnose-500.b64 @@ -0,0 +1 @@ +IyEvYmluL2Jhc2gKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIC9pdGRlc2svIDUwMCDplJnor6/or4rmlq3ohJrmnKwKIyDlnKjnlJ/kuqfmnI3liqHlmaggMTAuODAuMC4xMzYg5LiK6LeRKFNTSCDnmbvlvZXlkI4pOgojICAgY2QgL29wdC93ZWNvbS1pdC1kZXNrCiMgICBiYXNoIGRpYWdub3NlLTUwMC5zaCA+IC90bXAvZGlhZy5sb2cgMj4mMQojICAgY2F0IC90bXAvZGlhZy5sb2cKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKZWNobyAiPT09PT09PT09PSAxLiDlrrnlmajnirbmgIEgPT09PT09PT09PSIKZG9ja2VyIGNvbXBvc2UgcHMKCmVjaG8gIiIKZWNobyAiPT09PT09PT09PSAyLiAvb3B0L3dlY29tLWl0LWRlc2sg55uu5b2V57uT5p6EID09PT09PT09PT0iCmxzIC1sYSAvb3B0L3dlY29tLWl0LWRlc2svIDI+JjEgfCBoZWFkIC0yMAplY2hvICItLS0gZnJvbnRlbmQtaDUvZGlzdCAtLS0iCmxzIC1sYSAvb3B0L3dlY29tLWl0LWRlc2svZnJvbnRlbmQtaDUvZGlzdC8gMj4mMSB8IGhlYWQgLTEwCmVjaG8gIi0tLSBmcm9udGVuZC1oNS9kaXN0L2Fzc2V0cyAtLS0iCmxzIC1sYSAvb3B0L3dlY29tLWl0LWRlc2svZnJvbnRlbmQtaDUvZGlzdC9hc3NldHMvIDI+JjEgfCBoZWFkIC0xMAplY2hvICItLS0gZnJvbnRlbmQtYWdlbnQvZGlzdC9hc3NldHMgLS0tIgpscyAtbGEgL29wdC93ZWNvbS1pdC1kZXNrL2Zyb250ZW5kLWFnZW50L2Rpc3QvYXNzZXRzLyAyPiYxIHwgaGVhZCAtMTAKZWNobyAiLS0tIGZyb250ZW5kLXBvcnRhbC9kaXN0L2Fzc2V0cyAtLS0iCmxzIC1sYSAvb3B0L3dlY29tLWl0LWRlc2svZnJvbnRlbmQtcG9ydGFsL2Rpc3QvYXNzZXRzLyAyPiYxIHwgaGVhZCAtMTAKZWNobyAiLS0tIGZyb250ZW5kLWFkbWluL2Rpc3QvYXNzZXRzIC0tLSIKbHMgLWxhIC9vcHQvd2Vjb20taXQtZGVzay9mcm9udGVuZC1hZG1pbi9kaXN0L2Fzc2V0cy8gMj4mMSB8IGhlYWQgLTEwCgplY2hvICIiCmVjaG8gIj09PT09PT09PT0gMy4gbmdpbngg5a655Zmo5YaF5paH5Lu25qOA5p+lID09PT09PT09PT0iCmRvY2tlciBjb21wb3NlIGV4ZWMgbmdpbnggbHMgLWxhIC91c3Ivc2hhcmUvbmdpbngvaHRtbC8gMj4mMSB8IGhlYWQgLTIwCmVjaG8gIi0tLSAvdXNyL3NoYXJlL25naW54L2h0bWwvaXRkZXNrIC0tLSIKZG9ja2VyIGNvbXBvc2UgZXhlYyBuZ2lueCBscyAtbGEgL3Vzci9zaGFyZS9uZ2lueC9odG1sL2l0ZGVzay8gMj4mMSB8IGhlYWQgLTEwCmVjaG8gIi0tLSAvdXNyL3NoYXJlL25naW54L2h0bWwvaXRkZXNrL2Fzc2V0cyAtLS0iCmRvY2tlciBjb21wb3NlIGV4ZWMgbmdpbnggbHMgLWxhIC91c3Ivc2hhcmUvbmdpbngvaHRtbC9pdGRlc2svYXNzZXRzLyAyPiYxIHwgaGVhZCAtMTAKZWNobyAiLS0tIC91c3Ivc2hhcmUvbmdpbngvc3NsLyAtLS0iCmRvY2tlciBjb21wb3NlIGV4ZWMgbmdpbnggbHMgLWxhIC9ldGMvbmdpbngvc3NsLyAyPiYxIHwgaGVhZCAtMTAKCmVjaG8gIiIKZWNobyAiPT09PT09PT09PSA0LiBuZ2lueCDphY3nva7lrp7pmYXnlJ/mlYjniYjmnKwo5aS06YOoIDUwIOihjCk9PT09PT09PT09Igpkb2NrZXIgY29tcG9zZSBleGVjIG5naW54IGNhdCAvZXRjL25naW54L25naW54LmNvbmYgMj4mMSB8IGhlYWQgLTUwCgplY2hvICIiCmVjaG8gIj09PT09PT09PT0gNS4gbmdpbngg5a655Zmo56uv5Y+j55uR5ZCsID09PT09PT09PT0iCmRvY2tlciBjb21wb3NlIGV4ZWMgbmdpbnggbmV0c3RhdCAtdGxucCAyPiYxIHwgaGVhZCAtMTAKZWNobyAiKOayoSBuZXRzdGF0IOeUqCBzczopIgpkb2NrZXIgY29tcG9zZSBleGVjIG5naW54IHNzIC10bG5wIDI+JjEgfCBoZWFkIC0xMAoKZWNobyAiIgplY2hvICI9PT09PT09PT09IDYuIOebtOaOpSBjdXJsIOa1i+ivleWQhOi3r+W+hCA9PT09PT09PT09IgplY2hvICItLS0gL2l0ZGVzay8gKOWuueWZqOWGhSkgLS0tIgpkb2NrZXIgY29tcG9zZSBleGVjIG5naW54IGN1cmwgLWtzSSBodHRwczovL2xvY2FsaG9zdC9pdGRlc2svIDI+JjEgfCBoZWFkIC0yMAplY2hvICItLS0gL2l0ZGVzay8gKOWuueWZqOWkluS4u+acuiA0NDMpIC0tLSIKY3VybCAta3NJIGh0dHBzOi8vbG9jYWxob3N0OjQ0My9pdGRlc2svIDI+JjEgfCBoZWFkIC0yMAplY2hvICItLS0gL2l0cG9ydGFsLyAtLS0iCmN1cmwgLWtzSSBodHRwczovL2xvY2FsaG9zdDo0NDMvaXRwb3J0YWwvIDI+JjEgfCBoZWFkIC0yMAplY2hvICItLS0gL2l0ZGVzay9hc3NldHMvICjmjqIgNDA0KSAtLS0iCmN1cmwgLWtzSSBodHRwczovL2xvY2FsaG9zdDo0NDMvaXRkZXNrL2Fzc2V0cy8gMj4mMSB8IGhlYWQgLTIwCgplY2hvICIiCmVjaG8gIj09PT09PT09PT0gNy4g5Li75py65a6e6ZmFIFVSTCDln5/lkI0gPT09PT09PT09PSIKY3VybCAta3NJIGh0dHBzOi8vaXRzdXBwb3J0LnNlcnZ5b3UuY29tLmNuL2l0ZGVzay8gMj4mMSB8IGhlYWQgLTIwCmVjaG8gIi0tLSIKY3VybCAta3NJIGh0dHBzOi8vaXRzdXBwb3J0LnNlcnZ5b3UuY29tLmNuL2l0cG9ydGFsLyAyPiYxIHwgaGVhZCAtMjAKZWNobyAiLS0tIgpjdXJsIC1rc0kgaHR0cHM6Ly9pdHN1cHBvcnQuc2VydnlvdS5jb20uY24vaXRhZ2VudC8gMj4mMSB8IGhlYWQgLTIwCmVjaG8gIi0tLSIKY3VybCAta3NJIGh0dHBzOi8vaXRzdXBwb3J0LnNlcnZ5b3UuY29tLmNuL2l0YWRtaW4vIDI+JjEgfCBoZWFkIC0yMAoKZWNobyAiIgplY2hvICI9PT09PT09PT09IDguIG5naW54IGFjY2VzcyBsb2cg5pyA6L+RIDMwIOihjCjmib4gNTAwIOivt+axgik9PT09PT09PT09Igpkb2NrZXIgY29tcG9zZSBleGVjIG5naW54IHRhaWwgLTMwIC92YXIvbG9nL25naW54L2FjY2Vzcy5sb2cgMj4mMQplY2hvICIiCmVjaG8gIj09PT09PT09PT0gOS4gbmdpbnggZXJyb3IgbG9nIOacgOi/kSAzMCDooYwgPT09PT09PT09PSIKZG9ja2VyIGNvbXBvc2UgZXhlYyBuZ2lueCB0YWlsIC0zMCAvdmFyL2xvZy9uZ2lueC9lcnJvci5sb2cgMj4mMQoKZWNobyAiIgplY2hvICI9PT09PT09PT09IDEwLiBiYWNrZW5kIOWuueWZqOWBpeW6tyA9PT09PT09PT09Igpkb2NrZXIgY29tcG9zZSBwcyBiYWNrZW5kCmVjaG8gIi0tLSBiYWNrZW5kIGhlYWx0aCBlbmRwb2ludCAtLS0iCmRvY2tlciBjb21wb3NlIGV4ZWMgYmFja2VuZCBjdXJsIC1rcyBodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL2hlYWx0aCAyPiYxIHwgaGVhZCAtNQoKZWNobyAiIgplY2hvICI9PT09PT09PT09IDExLiDnnIvkuIDkuIvlkI7nq6/orr/pl64gL2FwaS9oNS9tZSAoSDUg5ZCv5Yqo5pe25Lya6LCDKT09PT09PT09PT0iCmVjaG8gIi0tLSAvYXBpL2g1L21lIOaXoCB0b2tlbiAtLS0iCmN1cmwgLWtzIC1pIC1YIEdFVCBodHRwczovL2l0c3VwcG9ydC5zZXJ2eW91LmNvbS5jbi9hcGkvaDUvbWUgMj4mMSB8IGhlYWQgLTEwCg== \ No newline at end of file diff --git a/diagnose-500.sh b/diagnose-500.sh new file mode 100644 index 0000000..6e25467 --- /dev/null +++ b/diagnose-500.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# ============================================================================= +# /itdesk/ 500 错误诊断脚本 +# 在生产服务器 10.90.5.110 上跑(PuTTY 登录后): +# cd /opt/wecom-it-desk +# bash diagnose-500.sh > /tmp/diag.log 2>&1 +# cat /tmp/diag.log +# ============================================================================= + +echo "========== 1. 容器状态 ==========" +docker compose ps + +echo "" +echo "========== 2. /opt/wecom-it-desk 目录结构 ==========" +ls -la /opt/wecom-it-desk/ 2>&1 | head -20 +echo "--- frontend-h5/dist ---" +ls -la /opt/wecom-it-desk/frontend-h5/dist/ 2>&1 | head -10 +echo "--- frontend-h5/dist/assets ---" +ls -la /opt/wecom-it-desk/frontend-h5/dist/assets/ 2>&1 | head -10 +echo "--- frontend-agent/dist/assets ---" +ls -la /opt/wecom-it-desk/frontend-agent/dist/assets/ 2>&1 | head -10 +echo "--- frontend-portal/dist/assets ---" +ls -la /opt/wecom-it-desk/frontend-portal/dist/assets/ 2>&1 | head -10 +echo "--- frontend-admin/dist/assets ---" +ls -la /opt/wecom-it-desk/frontend-admin/dist/assets/ 2>&1 | head -10 + +echo "" +echo "========== 3. nginx 容器内文件检查 ==========" +docker compose exec nginx ls -la /usr/share/nginx/html/ 2>&1 | head -20 +echo "--- /usr/share/nginx/html/itdesk ---" +docker compose exec nginx ls -la /usr/share/nginx/html/itdesk/ 2>&1 | head -10 +echo "--- /usr/share/nginx/html/itdesk/assets ---" +docker compose exec nginx ls -la /usr/share/nginx/html/itdesk/assets/ 2>&1 | head -10 +echo "--- /usr/share/nginx/ssl/ ---" +docker compose exec nginx ls -la /etc/nginx/ssl/ 2>&1 | head -10 + +echo "" +echo "========== 4. nginx 配置实际生效版本(头部 50 行)==========" +docker compose exec nginx cat /etc/nginx/nginx.conf 2>&1 | head -50 + +echo "" +echo "========== 5. nginx 容器端口监听 ==========" +docker compose exec nginx netstat -tlnp 2>&1 | head -10 +echo "(没 netstat 用 ss:)" +docker compose exec nginx ss -tlnp 2>&1 | head -10 + +echo "" +echo "========== 6. 直接 curl 测试各路径 ==========" +echo "--- /itdesk/ (容器内) ---" +docker compose exec nginx curl -ksI https://localhost/itdesk/ 2>&1 | head -20 +echo "--- /itdesk/ (容器外主机 443) ---" +curl -ksI https://localhost:443/itdesk/ 2>&1 | head -20 +echo "--- /itportal/ ---" +curl -ksI https://localhost:443/itportal/ 2>&1 | head -20 +echo "--- /itdesk/assets/ (探 404) ---" +curl -ksI https://localhost:443/itdesk/assets/ 2>&1 | head -20 + +echo "" +echo "========== 7. 主机实际 URL 域名 ==========" +curl -ksI https://itsupport.servyou.com.cn/itdesk/ 2>&1 | head -20 +echo "---" +curl -ksI https://itsupport.servyou.com.cn/itportal/ 2>&1 | head -20 +echo "---" +curl -ksI https://itsupport.servyou.com.cn/itagent/ 2>&1 | head -20 +echo "---" +curl -ksI https://itsupport.servyou.com.cn/itadmin/ 2>&1 | head -20 + +echo "" +echo "========== 8. nginx access log 最近 30 行(找 500 请求)==========" +docker compose exec nginx tail -30 /var/log/nginx/access.log 2>&1 +echo "" +echo "========== 9. nginx error log 最近 30 行 ==========" +docker compose exec nginx tail -30 /var/log/nginx/error.log 2>&1 + +echo "" +echo "========== 10. backend 容器健康 ==========" +docker compose ps backend +echo "--- backend health endpoint ---" +docker compose exec backend curl -ks http://localhost:8000/api/health 2>&1 | head -5 + +echo "" +echo "========== 11. 看一下后端访问 /api/h5/me (H5 启动时会调)==========" +echo "--- /api/h5/me 无 token ---" +curl -ks -i -X GET https://itsupport.servyou.com.cn/api/h5/me 2>&1 | head -10 diff --git a/fix-prod.b64 b/fix-prod.b64 new file mode 100644 index 0000000..4a0c0d8 --- /dev/null +++ b/fix-prod.b64 @@ -0,0 +1 @@ +IyEvYmluL2Jhc2gKc2V0ICtlICAgIyBjb2xsZWN0IGV2ZXJ5dGhpbmcsIGRvbid0IGJhaWwKCmVjaG8gJyMjIyMjIyMjIyMjIyBTVEVQIDE6IExvY2F0ZSBwcm9qZWN0IGRpcmVjdG9yeSAjIyMjIyMjIyMjIyMnCmNkIC9vcHQvd2Vjb20taXQtZGVzayAyPiYxCmVjaG8gIkN1cnJlbnQgZGlyOiAkKHB3ZCkiCmxzIC1sYSBkb2NrZXItY29tcG9zZS55bWwgMj4mMQplY2hvICcnCgplY2hvICcjIyMjIyMjIyMjIyMgU1RFUCAyOiBEaWFnbm9zZSAoUkVBRC1PTkxZKSAjIyMjIyMjIyMjIyMnCmVjaG8gJy0tLSBBbGwgd2Vjb21faXRfIGNvbnRhaW5lcnMgLS0tJwpkb2NrZXIgcHMgLWEgLS1mb3JtYXQgInRhYmxlIHt7Lk5hbWVzfX1cdHt7LlN0YXR1c319IiB8IGdyZXAgLUUgIndlY29tX2l0X3xOQU1FUyIKZWNobyAnJwplY2hvICctLS0gRGlzayBzcGFjZSAtLS0nCmRmIC1oIC9vcHQgMj4mMQplY2hvICcnCmVjaG8gJy0tLSBiYWNrZW5kIGxhc3QgNjAgbG9nIGxpbmVzIC0tLScKZG9ja2VyIGxvZ3Mgd2Vjb21faXRfYmFja2VuZCAtLXRhaWwgNjAgMj4mMQplY2hvICcnCmVjaG8gJy0tLSBiYWNrZW5kIGludGVybmFsIGhlYWx0aCBjaGVjayAtLS0nCmRvY2tlciBleGVjIHdlY29tX2l0X2JhY2tlbmQgY3VybCAtcyAtbyAtIC13ICJcbkhUVFBfQ09ERTogJXtodHRwX2NvZGV9XG4iIC0tbWF4LXRpbWUgNSBodHRwOi8vbG9jYWxob3N0OjgwMDAvaGVhbHRoIDI+JjEKZWNobyAnJwoKZWNobyAnIyMjIyMjIyMjIyMjIFNURVAgMzogUmVzdGFydCBmcm9tIGNvcnJlY3QgZGlyZWN0b3J5ICMjIyMjIyMjIyMjIycKY2QgL29wdC93ZWNvbS1pdC1kZXNrCmRvY2tlciBjb21wb3NlIHVwIC1kIDI+JjEKZWNobyAnJwplY2hvICdXYWl0aW5nIDE1cyBmb3Igc2VydmljZXMgdG8gc3RhYmlsaXplLi4uJwpzbGVlcCAxNQplY2hvICcnCmVjaG8gJy0tLSBDb250YWluZXJzIGFmdGVyIHJlc3RhcnQgLS0tJwpkb2NrZXIgcHMgLWEgLS1mb3JtYXQgInRhYmxlIHt7Lk5hbWVzfX1cdHt7LlN0YXR1c319IiB8IGdyZXAgLUUgIndlY29tX2l0X3xOQU1FUyIKZWNobyAnJwoKZWNobyAnIyMjIyMjIyMjIyMjIFNURVAgNDogRW5kLXRvLWVuZCB2ZXJpZmljYXRpb24gIyMjIyMjIyMjIyMjJwplY2hvICctLS0gYmFja2VuZCAvaGVhbHRoIC0tLScKY3VybCAtcyAtbyAtIC13ICJcbkhUVFBfQ09ERTogJXtodHRwX2NvZGV9XG4iIC0tbWF4LXRpbWUgNSBodHRwOi8vbG9jYWxob3N0OjgwMDAvaGVhbHRoCmVjaG8gJycKZWNobyAnLS0tIG5naW54IHJvdXRlcyAoZXhwZWN0IDIwMC8zMDEvMzAyKSAtLS0nCmZvciBwYXRoIGluIC8gL2l0YWdlbnQvIC9pdGg1LyAvaXRhZG1pbi87IGRvCiAgY29kZT0kKGN1cmwgLXMgLW8gL2Rldi9udWxsIC13ICIle2h0dHBfY29kZX0iIC0tbWF4LXRpbWUgNSAiaHR0cDovL2xvY2FsaG9zdCR7cGF0aH0iKQogIGVjaG8gIiAgJHBhdGggLT4gSFRUUCAkY29kZSIKZG9uZQplY2hvICcnCmVjaG8gJyMjIyMjIyMjIyMjIyBET05FICMjIyMjIyMjIyMjIycKZWNobyAnUGFzdGUgQUxMIG91dHB1dCBhYm92ZSBiYWNrIHRvIENsYXVkZSBmb3IgZGlhZ25vc2lzJwo= \ No newline at end of file diff --git a/fix-prod.s1 b/fix-prod.s1 new file mode 100644 index 0000000..81fd801 --- /dev/null +++ b/fix-prod.s1 @@ -0,0 +1 @@ +IyEvYmluL2Jhc2gKc2V0ICtlICAgIyBjb2xsZWN0IGV2ZXJ5dGhpbmcsIGRvbid0IGJhaWwKCmVjaG8gJyMjIyMjIyMjIyMjIyBTVEVQIDE6IExvY2F0ZSBwcm9qZWN0IGRpcmVjdG9yeSAjIyMjIyMjIyMjIyMnCmNkIC9vcHQvd2Vjb20taXQtZGVzayAyPiYxCmVjaG8gIkN1cnJlbnQgZGlyOiAkKHB3ZCkiCmxzIC1sYSBkb2NrZXItY29tcG9zZS55bWwgMj4mMQplY2hvICcnCgplY2hvICcjIyMjIyMjIyMjIyMgU1RFUCAyOiBEaWFnbm9zZSAoUkVBRC1PTkxZKSAjIyMjIyMjIyMjIyMnCmVjaG8gJy0tLSBBbGwgd2Vjb21faXRfIGNvbnRhaW5lcnMgLS0tJwpkb2NrZXIgcHMgLWEgLS1mb3JtYXQgInRhYmxlIHt7Lk5hbWVzfX1cdHt7LlN0YXR1c319IiB8IGdyZXAgLUUgIndlY29tX2l0X3xOQU1FUyIKZWNobyAnJwplY2hvICctLS0gRGlzayBzcGFjZSAtLS0nCmRmIC1oIC9vcHQgMj4mMQplY2hvICcnCmVjaG8gJy0tLSBiYWNrZW5kIGxhc3QgNjAgbG9nIGxpbmVzIC0tLScKZG9ja2VyIGxvZ3Mgd2Vjb21faXRfYmFja2VuZCAtLXRhaWwgNjAgMj4mMQplY2hvICcnCmVjaG8gJy0tLSBiYWNrZW5kIGludGVybmFsIGhlYWx0aCBjaGVjayAtLS0nCmRvY2tlciBleGVjIHdlY29tX2l0X2JhY2tlbmQgY3VybCAtcyAtbyAtIC13ICJcbkhUVFBfQ09ERTogJXtodHRwX2NvZGV9XG4iIC0tbWF4LXRpbWUgNSBodHRwOi8vbG9jYWxob3N0OjgwMDAvaGVhbHRoIDI+JjEKZWNobyAnJwoKZWNobyAnIyMjIyMjIyMjIyMjIFNURVAgMzogUmVzdGFydCBmcm9tIGNvcnJlY3QgZGlyZWN0b3J5 \ No newline at end of file diff --git a/fix-prod.s2 b/fix-prod.s2 new file mode 100644 index 0000000..90571d2 --- /dev/null +++ b/fix-prod.s2 @@ -0,0 +1 @@ +ICMjIyMjIyMjIyMjIycKY2QgL29wdC93ZWNvbS1pdC1kZXNrCmRvY2tlciBjb21wb3NlIHVwIC1kIDI+JjEKZWNobyAnJwplY2hvICdXYWl0aW5nIDE1cyBmb3Igc2VydmljZXMgdG8gc3RhYmlsaXplLi4uJwpzbGVlcCAxNQplY2hvICcnCmVjaG8gJy0tLSBDb250YWluZXJzIGFmdGVyIHJlc3RhcnQgLS0tJwpkb2NrZXIgcHMgLWEgLS1mb3JtYXQgInRhYmxlIHt7Lk5hbWVzfX1cdHt7LlN0YXR1c319IiB8IGdyZXAgLUUgIndlY29tX2l0X3xOQU1FUyIKZWNobyAnJwoKZWNobyAnIyMjIyMjIyMjIyMjIFNURVAgNDogRW5kLXRvLWVuZCB2ZXJpZmljYXRpb24gIyMjIyMjIyMjIyMjJwplY2hvICctLS0gYmFja2VuZCAvaGVhbHRoIC0tLScKY3VybCAtcyAtbyAtIC13ICJcbkhUVFBfQ09ERTogJXtodHRwX2NvZGV9XG4iIC0tbWF4LXRpbWUgNSBodHRwOi8vbG9jYWxob3N0OjgwMDAvaGVhbHRoCmVjaG8gJycKZWNobyAnLS0tIG5naW54IHJvdXRlcyAoZXhwZWN0IDIwMC8zMDEvMzAyKSAtLS0nCmZvciBwYXRoIGluIC8gL2l0YWdlbnQvIC9pdGg1LyAvaXRhZG1pbi87IGRvCiAgY29kZT0kKGN1cmwgLXMgLW8gL2Rldi9udWxsIC13ICIle2h0dHBfY29kZX0iIC0tbWF4LXRpbWUgNSAiaHR0cDovL2xvY2FsaG9zdCR7cGF0aH0iKQogIGVjaG8gIiAgJHBhdGggLT4gSFRUUCAkY29kZSIKZG9uZQplY2hvICcnCmVjaG8gJyMjIyMjIyMjIyMjIyBET05FICMjIyMjIyMjIyMjIycKZWNobyAnUGFzdGUgQUxMIG91dHB1dCBhYm92ZSBiYWNrIHRvIENsYXVkZSBmb3IgZGlhZ25vc2lzJwo= \ No newline at end of file diff --git a/fix-prod.sh b/fix-prod.sh new file mode 100644 index 0000000..31e4bfc --- /dev/null +++ b/fix-prod.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set +e # collect everything, don't bail + +echo '############ STEP 1: Locate project directory ############' +cd /opt/wecom-it-desk 2>&1 +echo "Current dir: $(pwd)" +ls -la docker-compose.yml 2>&1 +echo '' + +echo '############ STEP 2: Diagnose (READ-ONLY) ############' +echo '--- All wecom_it_ containers ---' +docker ps -a --format "table {{.Names}}\t{{.Status}}" | grep -E "wecom_it_|NAMES" +echo '' +echo '--- Disk space ---' +df -h /opt 2>&1 +echo '' +echo '--- backend last 60 log lines ---' +docker logs wecom_it_backend --tail 60 2>&1 +echo '' +echo '--- backend internal health check ---' +docker exec wecom_it_backend curl -s -o - -w "\nHTTP_CODE: %{http_code}\n" --max-time 5 http://localhost:8000/health 2>&1 +echo '' + +echo '############ STEP 3: Restart from correct directory ############' +cd /opt/wecom-it-desk +docker compose up -d 2>&1 +echo '' +echo 'Waiting 15s for services to stabilize...' +sleep 15 +echo '' +echo '--- Containers after restart ---' +docker ps -a --format "table {{.Names}}\t{{.Status}}" | grep -E "wecom_it_|NAMES" +echo '' + +echo '############ STEP 4: End-to-end verification ############' +echo '--- backend /health ---' +curl -s -o - -w "\nHTTP_CODE: %{http_code}\n" --max-time 5 http://localhost:8000/health +echo '' +echo '--- nginx routes (expect 200/301/302) ---' +for path in / /itagent/ /ith5/ /itadmin/; do + code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "http://localhost${path}") + echo " $path -> HTTP $code" +done +echo '' +echo '############ DONE ############' +echo 'Paste ALL output above back to Claude for diagnosis' diff --git a/frontend-admin/package-lock.json b/frontend-admin/package-lock.json index 9f18a10..5928341 100644 --- a/frontend-admin/package-lock.json +++ b/frontend-admin/package-lock.json @@ -23,6 +23,10 @@ "typescript": "^5.5.0", "vite": "^5.3.0", "vue-tsc": "^2.0.0" + }, + "engines": { + "node": ">=20.0.0 <21.0.0", + "pnpm": ">=9.0.0" } }, "node_modules/@alloc/quick-lru": { diff --git a/frontend-admin/src/types/index.ts b/frontend-admin/src/types/index.ts index 0f33f3a..44711ee 100644 --- a/frontend-admin/src/types/index.ts +++ b/frontend-admin/src/types/index.ts @@ -37,6 +37,9 @@ export interface Agent { today_resolved?: number created_at: string updated_at: string + // OTP 二次验证(P0-#5 坐席本地密码配套) + otp_enabled?: number // 0/1, 是否启用 OTP + otp_secret?: string // OTP 密钥(敏感) } /** 坐席状态 */ @@ -340,6 +343,7 @@ export interface HuorongTerminalDetail { version: string // 火绒客户端版本 is_online: boolean // 在线状态 last_connect_time?: number // 最后连接时间(Unix时间戳) + group_id?: number | string // 分组ID(_info2 可能返回) // 硬件信息(可选,_info2 返回) cpu?: string memory?: string diff --git a/frontend-admin/src/views/TerminalSecurity.vue b/frontend-admin/src/views/TerminalSecurity.vue index e074359..9f0925c 100644 --- a/frontend-admin/src/views/TerminalSecurity.vue +++ b/frontend-admin/src/views/TerminalSecurity.vue @@ -417,7 +417,7 @@ const tabs = [ // ========================================================================== // 状态 // ========================================================================== -const activeTab = ref<'terminals' | 'leaks' | 'virus'>('terminals') +const activeTab = ref('terminals') const loading = ref(false) const connectionError = ref('') @@ -675,7 +675,7 @@ function loadDemoVirusEvents(): void { // ========================================================================== // 标签页切换 // ========================================================================== -function switchTab(tab: 'terminals' | 'leaks' | 'virus'): void { +function switchTab(tab: string): void { activeTab.value = tab currentPage.value = 1 searchQuery.value = '' diff --git a/frontend-agent/package-lock.json b/frontend-agent/package-lock.json index d571085..bbd4282 100644 --- a/frontend-agent/package-lock.json +++ b/frontend-agent/package-lock.json @@ -22,6 +22,10 @@ "typescript": "^5.5.0", "vite": "^5.3.0", "vue-tsc": "^2.0.0" + }, + "engines": { + "node": ">=20.0.0 <21.0.0", + "pnpm": ">=9.0.0" } }, "node_modules/@babel/helper-string-parser": { diff --git a/frontend-agent/src/router/index.ts b/frontend-agent/src/router/index.ts index 498c28e..6b7f03a 100644 --- a/frontend-agent/src/router/index.ts +++ b/frontend-agent/src/router/index.ts @@ -5,7 +5,8 @@ // 包括: // 1. /login → 登录页(简单的用户名密码表单) // 2. /workspace → 坐席工作台(需要认证) -// 3. / → 重定向到 /workspace +// 3. /agent-preview → v0.5.4 BC/DR 应急页坐席视图(公开) +// 4. / → 重定向到 /workspace // ============================================================================= import { createRouter, createWebHistory } from 'vue-router' @@ -33,6 +34,13 @@ const routes = [ component: () => import('@/views/Workspace.vue'), meta: { title: '坐席工作台', requiresAuth: true }, }, + // v0.5.4 BC/DR 应急页坐席视图 + { + path: '/agent-preview', + name: 'AgentPreview', + component: () => import('@/views/AgentPreviewView.vue'), + meta: { title: '坐席助手', requiresAuth: false }, + }, ] // -------------------------------------------------------------------------- @@ -74,6 +82,13 @@ router.beforeEach((to, _from, next) => { const requiresAuth = to.meta.requiresAuth !== false // 默认需要认证 const token = localStorage.getItem('agent_token') + // v0.5.4 BC/DR 应急页(agent-preview)不需 Portal token + // 它的鉴权由 /emergency 入口的企微 JS-SDK 完成 + if (to.name === 'AgentPreview') { + next() + return + } + if (requiresAuth && !token) { // 需要认证但没有 token,跳转到 Portal 统一入口 window.location.href = '/itportal/' diff --git a/frontend-agent/src/views/AgentPreviewView.vue b/frontend-agent/src/views/AgentPreviewView.vue new file mode 100644 index 0000000..569979e --- /dev/null +++ b/frontend-agent/src/views/AgentPreviewView.vue @@ -0,0 +1,207 @@ + + + + + + + diff --git a/frontend-agent/src/views/Workspace.vue b/frontend-agent/src/views/Workspace.vue index d203f87..7724d17 100644 --- a/frontend-agent/src/views/Workspace.vue +++ b/frontend-agent/src/views/Workspace.vue @@ -186,6 +186,16 @@ function onRightResizeEnd(): void { // ============================================================================ onMounted(async () => { + // 修复 v0.5.1: 企微点坐席直接打开 /itagent/ 时,URL 没 ?token= + // 路由守卫虽然会跳到 /itportal/,但在这之前 axios 已经发了请求 → 弹 401 + // 这里在 onMounted 第一行主动检查 token,没 token 立刻跳 portal,避免 401 弹错 + const hasAgentToken = localStorage.getItem('agent_token') + const hasPortalToken = localStorage.getItem('portal_token') + if (!hasAgentToken && !hasPortalToken) { + window.location.href = '/itportal/' + return + } + // 初始化主题 themeStore.initTheme() // 初始化坐席信息 diff --git a/frontend-h5/components.d.ts b/frontend-h5/components.d.ts index 8a8c75e..2e74b88 100644 --- a/frontend-h5/components.d.ts +++ b/frontend-h5/components.d.ts @@ -32,6 +32,7 @@ declare module 'vue' { VanEmpty: typeof import('vant/es')['Empty'] VanField: typeof import('vant/es')['Field'] VanIcon: typeof import('vant/es')['Icon'] + VanLoading: typeof import('vant/es')['Loading'] VanPopup: typeof import('vant/es')['Popup'] } } diff --git a/frontend-h5/index.html b/frontend-h5/index.html index 1f8ef76..b344a08 100644 --- a/frontend-h5/index.html +++ b/frontend-h5/index.html @@ -8,10 +8,50 @@ 智能IT支持服务台 + +
+ +
+ +
智能IT支持服务台
+
正在加载...
+
+
diff --git a/frontend-h5/package-lock.json b/frontend-h5/package-lock.json index 9465e8b..0dfb25a 100644 --- a/frontend-h5/package-lock.json +++ b/frontend-h5/package-lock.json @@ -23,6 +23,10 @@ "unplugin-vue-components": "^0.27.0", "vite": "^5.3.0", "vue-tsc": "^2.0.0" + }, + "engines": { + "node": ">=20.0.0 <21.0.0", + "pnpm": ">=9.0.0" } }, "node_modules/@antfu/utils": { diff --git a/frontend-h5/src/App.vue b/frontend-h5/src/App.vue index 08cb9e9..890f222 100644 --- a/frontend-h5/src/App.vue +++ b/frontend-h5/src/App.vue @@ -8,23 +8,58 @@ diff --git a/frontend-h5/src/components/chat/CallAgentModal.vue b/frontend-h5/src/components/chat/CallAgentModal.vue index cb26570..4f9e00b 100644 --- a/frontend-h5/src/components/chat/CallAgentModal.vue +++ b/frontend-h5/src/components/chat/CallAgentModal.vue @@ -28,7 +28,7 @@
🔔 -

摇传菜铃呼叫人工坐席...

+

呼叫人工坐席帮助...

diff --git a/frontend-h5/src/main.ts b/frontend-h5/src/main.ts index 4d23dac..a5fd2e8 100644 --- a/frontend-h5/src/main.ts +++ b/frontend-h5/src/main.ts @@ -34,10 +34,26 @@ app.use(router) // 不需要在这里手动注册,减小打包体积 // -------------------------------------------------------------------------- -// 挂载应用到 DOM +// v0.5.2:挂载应用 + 显式关闭骨架屏(避免 :empty 选择器失效) // -------------------------------------------------------------------------- +// 1. 记录挂载开始时间(用于最小显示时间) +const mountStart = Date.now() +// 2. 最小显示时间 500ms(防止 Vue 太快挂载导致骨架屏"闪一下看不见") +const MIN_SKELETON_DISPLAY_MS = 500 + app.mount('#app') +// 3. 挂载完成后,主动给 body 加 .app-loaded 类名,触发 CSS 隐藏骨架屏 +// 比之前用 :empty 选择器更可靠(尤其在 Vue mount < 100ms 的情况下) +const elapsed = Date.now() - mountStart +if (elapsed >= MIN_SKELETON_DISPLAY_MS) { + document.body.classList.add('app-loaded') +} else { + setTimeout(() => { + document.body.classList.add('app-loaded') + }, MIN_SKELETON_DISPLAY_MS - elapsed) +} + // -------------------------------------------------------------------------- // 企微 OAuth2 授权检查(已迁移至路由守卫 router/index.ts) // -------------------------------------------------------------------------- diff --git a/frontend-h5/src/router/index.ts b/frontend-h5/src/router/index.ts index b5052b9..1b3f084 100644 --- a/frontend-h5/src/router/index.ts +++ b/frontend-h5/src/router/index.ts @@ -10,6 +10,14 @@ import { createRouter, createWebHistory } from 'vue-router' +// v0.5.2 优化:ChatView 是 99% 用户唯一访问的页面,改用静态 import +// 之前用 () => import() 懒加载,首次访问要二次下载 301KB 的 ChatView chunk +// → 表现为白屏→突然全显示 +import ChatView from '@/views/ChatView.vue' +// v0.5.4 BC/DR 应急页(身份检测 + H5 右栏) +import EmergencyDispatcher from '@/views/EmergencyDispatcher.vue' +import H5PreviewView from '@/views/H5PreviewView.vue' + // -------------------------------------------------------------------------- // 企微环境检测工具函数 // -------------------------------------------------------------------------- @@ -33,8 +41,8 @@ const routes = [ { path: '/', name: 'ChatView', - // 懒加载:首次访问时才加载组件,减小首屏体积 - component: () => import('@/views/ChatView.vue'), + // v0.5.2:首页静态引入,避免 301KB chunk 二次下载导致白屏 + component: ChatView, meta: { title: 'IT智能服务台', requiresAuth: true }, }, { @@ -49,6 +57,19 @@ const routes = [ component: () => import('@/views/WeworkOnly.vue'), meta: { title: '请在企业微信中打开', requiresAuth: false }, }, + // v0.5.4 BC/DR 应急页(身份检测 + 员工右栏视图) + { + path: '/emergency', + name: 'EmergencyDispatcher', + component: EmergencyDispatcher, + meta: { title: '应急身份检测', requiresAuth: false }, + }, + { + path: '/h5-preview', + name: 'H5Preview', + component: H5PreviewView, + meta: { title: '员工自助', requiresAuth: false }, + }, // 404 兜底:未匹配的路径重定向到首页 { path: '/:pathMatch(.*)*', @@ -67,8 +88,14 @@ const router = createRouter({ // 路由守卫 — 企微环境检测 + 认证检查 // -------------------------------------------------------------------------- router.beforeEach(async (to, _from, next) => { - // WeworkOnly 页面和 Login 页面不需要企微检测 - if (to.name === 'WeworkOnly' || to.name === 'Login') { + // v0.5.4 应急页(身份检测 + 预览页)不需要企微 OAuth2 认证 + // 由 EmergencyDispatcher 自己调企微 JS-SDK 检测角色 + if ( + to.name === 'WeworkOnly' || + to.name === 'Login' || + to.name === 'EmergencyDispatcher' || + to.name === 'H5Preview' + ) { next() return } diff --git a/frontend-h5/src/views/EmergencyDispatcher.vue b/frontend-h5/src/views/EmergencyDispatcher.vue new file mode 100644 index 0000000..6af559b --- /dev/null +++ b/frontend-h5/src/views/EmergencyDispatcher.vue @@ -0,0 +1,234 @@ + + + + + + + diff --git a/frontend-h5/src/views/H5PreviewView.vue b/frontend-h5/src/views/H5PreviewView.vue new file mode 100644 index 0000000..dcefe66 --- /dev/null +++ b/frontend-h5/src/views/H5PreviewView.vue @@ -0,0 +1,224 @@ + + + + + + + diff --git a/frontend-portal/package-lock.json b/frontend-portal/package-lock.json index 2e287b1..88bab3d 100644 --- a/frontend-portal/package-lock.json +++ b/frontend-portal/package-lock.json @@ -20,6 +20,10 @@ "typescript": "^5.5.0", "vite": "^5.3.0", "vue-tsc": "^2.0.0" + }, + "engines": { + "node": ">=20.0.0 <21.0.0", + "pnpm": ">=9.0.0" } }, "node_modules/@babel/helper-string-parser": { diff --git a/frontend-portal/src/views/PortalSelect.vue b/frontend-portal/src/views/PortalSelect.vue index 9858c48..f4b3619 100644 --- a/frontend-portal/src/views/PortalSelect.vue +++ b/frontend-portal/src/views/PortalSelect.vue @@ -123,7 +123,7 @@