Files
wecom_it_smart_desk/KNOWLEDGE.md
T

46 KiB

企微智能 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)

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/distfrontend-admin/dist
  • 补:should_exclude 排除 uploads/(隐私不打包)
  • 补:build_frontends 加 portal + admin 端构建

13. 运维操作

13.1 一键部署

# 打包
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 日常运维

# 查看服务状态
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 索引(已沉淀)


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-pitfallredis-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.vueonMounted 第一行先检查 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 发布前