1075 lines
46 KiB
Markdown
1075 lines
46 KiB
Markdown
|
|
# 企微智能 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` 时显示 `<el-empty description="请从左侧选择..." />` 占位,根本没有 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 发布前
|