chore: initial baseline with P0-safety .gitignore
This commit is contained in:
@@ -0,0 +1,413 @@
|
||||
# 2026-06-13 工作记录
|
||||
|
||||
## H5端邀请功能后续开发
|
||||
|
||||
### 后端改动
|
||||
1. **h5.py** — 新增3个H5专用参与者端点(带员工认证):
|
||||
- `POST /h5/conversations/{id}/join` — 被邀请人加入会话(`_get_current_employee` 认证)
|
||||
- `POST /h5/conversations/{id}/leave-participant` — 参与者退出会话(`_get_current_employee` 认证)
|
||||
- `GET /h5/conversations/{id}/participants` — 获取参与者列表(`_get_current_employee` 认证)
|
||||
- 安全校验:employee_id 从 Token 自动获取,无需前端传递,防止冒充
|
||||
|
||||
### H5前端改动
|
||||
2. **api/conversation.ts** — API路径统一为 `/h5/` 前缀:
|
||||
- `joinConversation(conversationId)` — 移除 employeeId 参数,路径改为 `/h5/conversations/{id}/join`
|
||||
- `leaveAsParticipant(conversationId)` — 移除 employeeId 参数,路径改为 `/h5/conversations/{id}/leave-participant`
|
||||
- `getParticipants(conversationId)` — 路径改为 `/h5/conversations/{id}/participants`(独立端点)
|
||||
- `ConversationInfo` 类型新增 `employee_name` 字段
|
||||
|
||||
3. **stores/conversation.ts** — `leaveAsParticipant()` 不再传递 employeeId
|
||||
|
||||
4. **views/ChatView.vue** — `joinConversationApi(inviteId)` 不再传递 eid
|
||||
|
||||
5. **components/chat/ParticipantList.vue** — 修复发起人姓名显示:
|
||||
- 当发起人不是当前用户时,显示 `conv.employee_name`(真实姓名)而非固定的"员工"
|
||||
|
||||
### 编译验证
|
||||
- 后端 py_compile ✅(h5.py)
|
||||
- H5前端 vue-tsc --noEmit ✅
|
||||
- H5前端 vite build ✅
|
||||
|
||||
## 管理后台 — 角色管理界面开发
|
||||
|
||||
### 说明
|
||||
后端 RBAC 角色系统(模型/API/服务/Schema/迁移)已全部完成,但前端管理后台零实现。
|
||||
本次补齐前端角色管理 UI 层。
|
||||
|
||||
### 改动文件
|
||||
|
||||
1. **frontend-admin/src/types/index.ts** — 新增角色管理类型定义:
|
||||
- `Role`(角色信息,含 permissions JSON 数组、user_count)
|
||||
- `UserRole`(用户角色关联,含 source/assigned_by/expires_at)
|
||||
- `UserRoleSource`(来源类型:auto/tag/ehr/manual)
|
||||
- `RoleMappingRule`(映射规则,含 source_type/source_value/priority)
|
||||
- `MappingSourceSource`(映射来源:wecom_tag/ehr_position)
|
||||
- `RoleAssignRequest` / `RoleRevokeRequest` / `RoleMappingRuleRequest`
|
||||
- `ROLE_SOURCE_LABELS` / `MAPPING_SOURCE_LABELS` 常量
|
||||
|
||||
2. **frontend-admin/src/api/admin.ts** — 新增 6 个 API 调用函数:
|
||||
- `getRoles()` — 获取所有角色列表
|
||||
- `assignRole()` — 手动分配角色
|
||||
- `revokeRole()` — 撤销角色
|
||||
- `getRoleMappingRules()` — 获取映射规则
|
||||
- `createRoleMappingRule()` — 创建映射规则
|
||||
- `deleteRoleMappingRule()` — 删除映射规则
|
||||
|
||||
3. **frontend-admin/src/views/Roles.vue** — 新建角色管理页面:
|
||||
- 角色卡片网格(3 个预置角色:用户/坐席/管理员,含用户数+权限数+权限标签)
|
||||
- 用户角色分配表格(employee_id/角色/来源/分配者/时间/操作)
|
||||
- 自动映射规则表格(目标角色/来源类型/匹配值/优先级/状态/操作)
|
||||
- 4 个对话框:分配角色、撤销确认、新建映射规则
|
||||
- Demo fallback 数据(API 不可用时的降级展示)
|
||||
|
||||
4. **frontend-admin/src/router/index.ts** — 新增路由:
|
||||
- `/roles` → `Roles.vue`,meta.title = "角色管理"
|
||||
|
||||
5. **frontend-admin/src/components/Sidebar.vue** — 新增菜单项:
|
||||
- "运营管理" 分组下添加"角色管理"(Key 图标),位于"坐席管理"之后
|
||||
|
||||
### 编译验证
|
||||
- 前端 vite build ✅(Roles-4zcp3cuz.js 13.33 kB,gzip: 4.48 kB)
|
||||
- 仅 @vueuse/core Rollup 注解警告和 chunk 大小警告(非本次引入)
|
||||
|
||||
## 正式服务器部署
|
||||
|
||||
### 迁移修复
|
||||
- **007_role_system.py** — 修复 PostgreSQL 兼容性:`datetime('now')` → `NOW()`
|
||||
- SQLite 的 `datetime('now')` 在 PostgreSQL 中不存在,导致后端启动失败
|
||||
|
||||
### 部署记录
|
||||
- 部署包已生成:`deploy-server/it-smart-desk-server-deploy.zip` (1.48 MB)
|
||||
- 包含:3个前端 dist + 后端代码 + docker-compose.yml + .env + nginx.conf
|
||||
- ⚠️ **服务器文件上传限制**:10.90.5.110 无法使用 scp,只能通过堡垒机手动上传
|
||||
- 部署流程:下载部署包 → 通过堡垒机上传到 /tmp/ → 解压 → docker compose build --no-cache backend → up -d
|
||||
|
||||
---
|
||||
|
||||
## 未完成任务收尾(下午)
|
||||
|
||||
### 任务进度确认
|
||||
- 代码审查确认 #148/#155(H5端邀请功能)**已完整实现**,包括:
|
||||
- ParticipantList.vue 完整组件(展示+退出+确认弹窗)
|
||||
- conversation.ts store(inviteParticipant/leaveAsParticipant/joinConversation)
|
||||
- API层(joinConversation/leaveAsParticipant/getParticipants)
|
||||
- ChatView.vue 邀请链接加入流程
|
||||
- WebSocket 实时推送(participant_invited/joined/removed/left 事件)
|
||||
- 标记 #148、#155 为 completed
|
||||
|
||||
### #151 H5登录Bug修复(4项)
|
||||
1. **isAuthenticated 增加 JWT 过期检查**:新增 `isTokenExpired()` 函数,解析 JWT payload 的 exp 字段,60秒安全余量
|
||||
2. **消除循环依赖**:新建 `utils/authCallback.ts` 独立回调注册中心,打破 api/index.ts ↔ stores/employee.ts 循环依赖
|
||||
3. **并发401去重**:`_authExpiredPromise` 去重锁,首个401获取锁执行处理,后续复用同一Promise
|
||||
4. **Portal Token URL安全加固**:使用 URLSearchParams 精确删除 token/code/state 参数,history.replaceState 立即清除
|
||||
|
||||
### #156 术语替换 + UI风格更新
|
||||
**术语替换**:
|
||||
- "举手"→"招手"(agent 6文件+h5 4文件,约25处)
|
||||
- "铃铛"→"传菜铃"(H5端2文件6处)
|
||||
- "申请"→无需替换(均为业务数据内容)
|
||||
|
||||
**CSS变量体系更新为企微风格**:
|
||||
- `--accent`: #3b82f6 → #07C160(企微绿)
|
||||
- `--bg-primary`: #f5f7fa → #f7f7f7
|
||||
- `--bg-tertiary`: #f0f2f5 → #ededed
|
||||
- `--text-primary`: #1e293b → #191919
|
||||
- `--text-secondary`: #64748b → #666666
|
||||
- `--text-tertiary`: #94a3b8 → #999999
|
||||
- `--border`: #e2e8f0 → #e5e5e5
|
||||
- `--radius`: 6px → 8px, `--radius-lg`: 10px → 12px
|
||||
- H5 `--color-shake-start/end`: 橙色渐变 → 绿色渐变
|
||||
- 深色主题变量保持不变
|
||||
|
||||
### #149 端到端验证
|
||||
- 阻塞已解除(#148/#151已完成)
|
||||
- 待用户在实际环境中执行全链路验证
|
||||
|
||||
### 部署方案讨论
|
||||
- 确认 NAS 测试环境在企微 OAuth2 认证下价值大幅降低
|
||||
- 确定双企微应用方案(正式应用+测试应用),因公司子域名申请困难
|
||||
- 正式上线前:正式=10.90.5.10, 测试=NAS
|
||||
- 正式上线后:正式=高可用架构, 测试=10.90.5.10
|
||||
|
||||
---
|
||||
|
||||
## 部署包打包 + 调试验证指南(11:00)
|
||||
|
||||
### 部署包清单
|
||||
|
||||
| 文件 | 大小 | 内容 |
|
||||
|------|------|------|
|
||||
| deploy-h5.tar | 0.6 MB | frontend-h5/dist/(含JWT过期检查+企微绿风格) |
|
||||
| deploy-agent.tar | 2.0 MB | frontend-agent/dist/(含术语替换+企微绿风格) |
|
||||
| deploy-admin.tar | 1.7 MB | frontend-admin/dist/ |
|
||||
| deploy-portal.tar | 1.53 MB | frontend-portal/dist/ |
|
||||
| deploy-backend.tar | 11.02 MB | backend/ |
|
||||
|
||||
### 调试验证指南
|
||||
- 创建 `docs/调试验证指南_2026-06-13.md`
|
||||
- 包含端到端验证清单(11个验证项)
|
||||
- 包含测试企微应用创建步骤(6个步骤)
|
||||
- 包含环境切换方案和常见问题排查
|
||||
|
||||
---
|
||||
|
||||
## 管理后台 P2 功能开发(晚间)
|
||||
|
||||
### 任务1:仪表盘真实数据
|
||||
- **admin_service.py** — `get_dashboard_overview()` 新增两项真实计算:
|
||||
- `avg_response_time`:从 messages 表计算首条员工消息到首条坐席/AI回复的时间差,最多统计50个会话
|
||||
- `ai_hit_rate`:今日有 AI 实质性回复的会话占比(ai_substantive_reply_count > 0)
|
||||
- 异常处理:计算失败时降级为 "—" 显示
|
||||
|
||||
### 任务2:P2 页面(会话审计/坐席绩效/系统日志)
|
||||
**后端新增 3 组 API:**
|
||||
- `GET /admin/audit/conversations` — 会话审计列表(分页+状态/坐席/关键词/日期范围筛选)
|
||||
- `GET /admin/audit/conversations/{id}` — 会话审计详情(含消息列表,最多200条)
|
||||
- `GET /admin/agent-performance` — 坐席绩效统计(总会话数/已结单/结单率/今日会话)
|
||||
- `GET /admin/system-logs` — 系统日志(配置变更历史,含操作人姓名)
|
||||
|
||||
**前端新增 3 个页面:**
|
||||
- `SessionAudit.vue` — 会话审计页(表格+筛选+详情抽屉,消息按类型着色)
|
||||
- `AgentPerformance.vue` — 坐席绩效页(表格+汇总统计,支持日期范围筛选)
|
||||
- `SystemLogs.vue` — 系统日志页(表格+分页,变更前后值着色对比)
|
||||
|
||||
**路由+侧边栏更新:**
|
||||
- 路由新增 `/session-audit`、`/agent-performance`、`/system-logs`
|
||||
- 侧边栏"监控与数据"分组新增 3 个菜单项
|
||||
|
||||
### 任务3:功能开关增强
|
||||
- `CONFIG_GROUP_MAP` 新增 5 个分组前缀:
|
||||
- `queue_` → 排队策略
|
||||
- `satisfaction_` → 满意度评价
|
||||
- `invite_` → 邀请功能
|
||||
- `notification_` → 通知推送
|
||||
- `security_` → 安全策略
|
||||
|
||||
### 编译验证
|
||||
- 后端 py_compile ✅
|
||||
- 前端 vite build ✅(SessionAudit-D3UWZck-.js 6.40 kB)
|
||||
|
||||
---
|
||||
|
||||
## 统一部署包打包(10:58)
|
||||
|
||||
### 构建结果
|
||||
- 4 个前端全部重建成功(H5/Agent/Admin/Portal),耗时 18 秒
|
||||
- Admin 前端包含新增的 Roles.vue 角色管理页面
|
||||
|
||||
### 部署包清单
|
||||
|
||||
| 文件 | 大小 | 内容 |
|
||||
|------|------|------|
|
||||
| deploy-h5.tar | 0.6 MB | frontend-h5/dist/ |
|
||||
| deploy-agent.tar | 2.0 MB | frontend-agent/dist/ |
|
||||
| deploy-admin.tar | 1.7 MB | frontend-admin/dist/(含角色管理页) |
|
||||
| deploy-portal.tar | 1.5 MB | frontend-portal/dist/ |
|
||||
| deploy-backend.tar | 11.0 MB | backend/(含角色系统全部代码+迁移) |
|
||||
|
||||
### 服务器部署步骤
|
||||
```bash
|
||||
# 1. 清理失败的数据库状态
|
||||
docker compose exec postgres psql -U postgres -d it_smart_desk -c "
|
||||
DROP TABLE IF EXISTS role_mapping_rules CASCADE;
|
||||
DROP TABLE IF EXISTS user_roles CASCADE;
|
||||
DROP TABLE IF EXISTS roles CASCADE;
|
||||
"
|
||||
|
||||
# 2. 通过堡垒机上传 5 个 tar 到 /tmp/
|
||||
|
||||
# 3. 在服务器执行
|
||||
cd /opt/wecom-it-desk
|
||||
cp /tmp/deploy-*.tar ./
|
||||
docker compose down
|
||||
# 解压前端
|
||||
tar -xf deploy-h5.tar -C frontend-h5/
|
||||
tar -xf deploy-agent.tar -C frontend-agent/
|
||||
tar -xf deploy-admin.tar -C frontend-admin/
|
||||
tar -xf deploy-portal.tar -C frontend-portal/
|
||||
# 解压后端(保留 .env)
|
||||
cp backend/.env /tmp/backend-env-backup
|
||||
tar -xf deploy-backend.tar
|
||||
cp /tmp/backend-env-backup backend/.env
|
||||
# 重建并启动
|
||||
docker compose build --no-cache backend
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dify/RAGFlow/千问集成调研(12:39)
|
||||
|
||||
### 现有服务连通性确认(从 10.90.5.110 测试)
|
||||
|
||||
| 服务 | 地址 | 端口 | 状态 |
|
||||
|------|------|------|------|
|
||||
| RAGFlow 前端 | 10.80.0.85 | 8080 | ✅ 200 OK |
|
||||
| RAGFlow API | 10.80.0.85 | 9380 | ✅ 200 OK(Werkzeug) |
|
||||
| 千问模型 | 10.80.0.49 | 5000 | ✅ 已连接 |
|
||||
| Dify | yw-dify.dc.servyou-it.com (10.80.0.240) | 80 | ✅ 307 正常 |
|
||||
|
||||
**结论:所有服务均已连通,无需开通新路由。**
|
||||
|
||||
### 集成现状
|
||||
|
||||
| 组件 | 后端代码 | 需要做什么 |
|
||||
|------|----------|-----------|
|
||||
| Dify | ✅ AIService + WingmanService | 无需改动 |
|
||||
| RAGFlow | ❌ 无客户端代码 | 需开发 RagflowClient |
|
||||
| 千问 | ℹ️ 通过Dify间接调用 | 无需直连 |
|
||||
|
||||
### 交接文档关键信息
|
||||
- 消息链路:企微 → B端智能体 → dify2openai → Dify Workflow → 千问
|
||||
- RAGFlow 知识运营:宋献IT组主导
|
||||
- 模型:Qwen3-30B-A3B-Instruct + bge-m3(向量)
|
||||
- 对接联系人:dify2openai→JG/CF;Dify应急→CF/WT
|
||||
|
||||
---
|
||||
|
||||
## RAGFlow 客户端开发(12:49)
|
||||
|
||||
### 新增文件
|
||||
- `backend/app/integrations/ragflow/__init__.py` — 模块导出
|
||||
- `backend/app/integrations/ragflow/client.py` — RagflowClient 客户端
|
||||
- `test_connection()` — 测试连接
|
||||
- `retrieval()` — 知识检索(核心接口,POST /api/v1/retrieval)
|
||||
- `list_datasets()` — 列出知识库
|
||||
- `create_dataset()` — 创建知识库
|
||||
- `delete_dataset()` — 删除知识库
|
||||
- `list_documents()` — 列出文档
|
||||
- `upload_document()` — 上传文档
|
||||
- `delete_documents()` — 删除文档
|
||||
- `backend/app/integrations/ragflow/models.py` — 数据模型
|
||||
- RetrievalChunk / DocAggregate / RetrievalResult / DatasetInfo / DocumentInfo
|
||||
- `backend/app/integrations/ragflow/exceptions.py` — 异常定义
|
||||
- RagflowError / RagflowConfigError / RagflowAuthError / RagflowApiError / RagflowConnectionError
|
||||
- `backend/app/integrations/ragflow/config.py` — 配置加载器
|
||||
- 从 system_configs 表读取 integration_ragflow_api_url + integration_ragflow_api_key
|
||||
- 默认 API 地址:http://10.80.0.85:9380
|
||||
|
||||
### admin.py 新增端点
|
||||
- `POST /admin/integrations/ragflow/test` — 测试连接
|
||||
- `GET /admin/integrations/ragflow/datasets` — 列出知识库
|
||||
- `POST /admin/integrations/ragflow/retrieval` — 知识检索测试
|
||||
|
||||
### 编译验证
|
||||
- 后端 py_compile ✅(所有 ragflow 模块 + admin.py)
|
||||
|
||||
### 前端更新
|
||||
- `frontend-admin/src/api/admin.ts` — 新增 3 个 RAGFlow API 函数:
|
||||
- `testRagflowConnection()` — 测试连接
|
||||
- `getRagflowDatasets()` — 列出知识库
|
||||
- `ragflowRetrieval()` — 知识检索测试
|
||||
- `frontend-admin/src/views/Integrations.vue` — 更新 handleTest 函数:
|
||||
- 支持 RAGFlow 测试连接(调用 testRagflowConnection)
|
||||
- 测试成功后更新本地状态为 connected
|
||||
- 前端 vite build ✅(Integrations-CFvIx0q8.js 14.51 kB)
|
||||
|
||||
---
|
||||
|
||||
## 修复:消息发送失败 + 截图不可用(15:00)
|
||||
|
||||
### 根因
|
||||
后端 `POST /h5/conversations/current/messages` 抛出异常:
|
||||
```
|
||||
TypeError: AIHandler.__init__() missing 1 required positional argument: 'ai_service'
|
||||
```
|
||||
|
||||
**深层原因**:uvicorn `--reload` 模式下 WatchFiles reloader 缓存了旧的 `dependencies.py` 字节码(之前 `dep_ai_handler()` 没有 `ai_service=AIService()` 参数的版本)。即使清空 `__pycache__` 重启,reloader 仍加载旧缓存。
|
||||
|
||||
**修复**:去掉 `--reload` 标志启动后端即可。`start_backend.py` 已改为 `reload=False`。
|
||||
|
||||
### 影响
|
||||
- 消息发送:后端 500 错误 → 前端超时/失败
|
||||
- 截图功能:截图本身正常(html2canvas + ScreenshotEditor),但上传后发送消息同样失败
|
||||
- Mock 登录:正常(不经过 AIHandler)
|
||||
|
||||
### 验证
|
||||
- Mock login → `code: 0` ✅
|
||||
- Send message → `code: 0`, 返回 user_message + ai_reply ✅
|
||||
- 后端 108 个路由正常注册 ✅
|
||||
|
||||
### 教训
|
||||
- uvicorn `--reload` 的 WatchFiles reloader 可能缓存旧字节码,清 `__pycache__` 不一定有效
|
||||
- 本地开发如果不需要热重载,用 `reload=False` 更可靠
|
||||
|
||||
---
|
||||
|
||||
## AIHandler 初始化问题修复 + 打包部署脚本(23:07)
|
||||
|
||||
### 问题描述
|
||||
后端 `POST /h5/conversations/current/messages` 报错:
|
||||
```
|
||||
TypeError: AIHandler.__init__() missing 1 required positional argument: 'ai_service'
|
||||
```
|
||||
|
||||
### 根因
|
||||
`dependencies.py` 中 `AIHandler()` 调用缺少必需的 `ai_service` 参数。代码重构后 `AIHandler.__init__` 需要传入 `AIService` 实例。
|
||||
|
||||
### 修复内容
|
||||
- `backend/app/dependencies.py` 两处修复:
|
||||
- `get_shared_ai_handler()`: `return AIHandler(ai_service=AIService())`
|
||||
- `dep_ai_handler()`: `return AIHandler(ai_service=AIService())`
|
||||
|
||||
### 数据库修复(已在服务器执行)
|
||||
```sql
|
||||
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS impact_scope VARCHAR(50);
|
||||
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS is_blocking BOOLEAN DEFAULT false;
|
||||
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS emotion_state VARCHAR(50);
|
||||
ALTER TABLE conversations ADD COLUMN IF NOT EXISTS dify_conversation_id VARCHAR(255);
|
||||
```
|
||||
|
||||
### 打包部署脚本
|
||||
新增两个自动化脚本:
|
||||
1. `deploy-server/build-and-deploy.ps1` — PowerShell 脚本,功能:
|
||||
- 打包前端构建产物(frontend-h5/agent/admin/portal dist)
|
||||
- 复制 nginx 配置 + docker-compose.yml + .env
|
||||
- 构建后端 Docker 镜像(包含修复后的代码)
|
||||
- 导出为 `deploy-backend.tar`
|
||||
- 支持 `-Mode deploy` 参数自动上传并部署到服务器
|
||||
|
||||
2. `deploy-server/打包部署.bat` — 一键执行批处理
|
||||
- 不带参数:仅本地打包
|
||||
- 带 `deploy` 参数:打包 + 部署到服务器
|
||||
|
||||
### 下一步
|
||||
需要重新构建后端镜像并部署到服务器:
|
||||
1. 执行 `打包部署.bat deploy` 或手动运行 `build-and-deploy.ps1 -Mode deploy`
|
||||
2. 脚本会自动:构建镜像 → 导出tar → 上传服务器 → 部署
|
||||
|
||||
---
|
||||
|
||||
## 剩余安全风险修复(23:03)
|
||||
|
||||
### 任务说明
|
||||
处理 4 个可在代码层面快速修复的风险项。
|
||||
|
||||
### 修复内容
|
||||
|
||||
#### 1. H-6:角色映射标签验证(高风险)
|
||||
- `role_mapping_service.py` 新增 `_validate_tag_name()` 方法
|
||||
- 验证规则:长度限制 50 字符,过滤禁止的特殊字符 (`<>'"&;\\|%$#@``)
|
||||
- 获取企微标签时过滤不安全的标签名称
|
||||
|
||||
#### 2. M-9:异常信息泄露(中等风险)
|
||||
- `main.py` 两处异常处理器修改
|
||||
- 响应改为通用消息:"服务器内部错误,请稍后重试或联系管理员"
|
||||
- 详细异常信息仅记录到日志
|
||||
|
||||
#### 3. M-10:日志脱敏(中等风险)
|
||||
- 新增 `_mask_sensitive_data()` 脱敏函数(保留前3位)
|
||||
- 已处理:`role_mapping_service.py`(3处)、`admin_roles.py`(4处)
|
||||
|
||||
#### 4. L-7:坐席列表 API 认证(低风险)
|
||||
- `agents.py` 导入 `require_role` 依赖
|
||||
- `/agents` 端点添加 `@require_role("agent", "admin")` 装饰器
|
||||
|
||||
### 风险处理进度
|
||||
| 级别 | 处理率 |
|
||||
|------|--------|
|
||||
| 严重 | 100% (4/4) |
|
||||
| 高风险 | 83% (5/6) |
|
||||
| 中风险 | 57% (4/7) |
|
||||
| 低风险 | 60% (3/5) |
|
||||
| **总计** | **73% (16/22)** |
|
||||
Reference in New Issue
Block a user