# 2026-06-23 工作日志

## 修复截图发送超时Bug

### 问题分析
截图发送流程：html2canvas截取 → 裁剪选区 → 上传图片(60s超时) → 发送消息(10s超时)
- 前端 apiClient 默认超时10秒，对图片/文件消息发送过短
- 坐席端发消息时，即使是image类型也创建Redis连接（不必要）
- H5端消息发送会触发AI/Dify处理，可能超过10秒

### 修改内容

**前端（4个文件）：**
1. `frontend-agent/src/api/message.ts` — sendMessage 超时 10s→30s
2. `frontend-h5/src/api/conversation.ts` — sendMessage 超时 10s→30s
3. `frontend-agent/src/api/index.ts` — apiClient 默认超时 10s→20s
4. `frontend-h5/src/api/index.ts` — apiClient 默认超时 10s→20s

**后端（1个文件）：**
5. `backend/app/api/messages.py` — 非text消息跳过Redis连接（image/file等不调用企微API推送）

### 编译验证
- frontend-agent: vite build ✅ (4.63s)
- frontend-h5: vite build ✅ (1.75s)
- backend: py_compile ✅

---

## 修复员工端消息不显示Bug + 后端WS广播

### 问题分析
用户报告：员工端消息发送后没有出现在会话列表里。

**根因发现**：
1. **字段名不匹配**：后端 MessageResponse 返回 `id`/`sender_type`，但 H5 前端 Message 接口期望 `message_id`/`message_type`
2. **Vue 渲染失败**：`MessageBubble` 使用 `:key="msg.message_id"`，但后端返回的是 `id`，导致所有 key 为 undefined
3. **消息类型丢失**：`message_type` 为 undefined，CSS class 错误（如 `message-bubble--undefined`）
4. **WS handleNewMessage 错误**：使用了 `data.msg_type`（content type: text/image/file）而非 `data.sender_type`（sender type: employee/agent/ai）

### 修改内容

**H5前端（2个文件）：**
1. `frontend-h5/src/api/conversation.ts` — 新增 `mapMessage()`/`mapMessages()` 映射函数：
   - `id` → `message_id`
   - `sender_type` → `message_type`
   - `sendMessage()` 和 `pollMessages()` 返回数据经过映射

2. `frontend-h5/src/stores/conversation.ts` — 修复 `handleNewMessage()`：
   - `message_type` 从 `data.msg_type`（text/image）改为 `data.sender_type`（employee/agent/ai）
   - 同时正确映射 `msg_type`（content type）

**后端（1个文件）：**
3. `backend/app/api/h5.py` — 新增 WebSocket 广播：
   - 导入 `ws_manager`
   - 员工发消息后向坐席端推送 `new_message` 事件（用户消息 + AI回复）
   - 同时推送 `conversation_updated` 事件（状态变更）
   - 异常捕获：WS广播失败不阻塞消息存储

### 核心原理
后端 `MessageResponse` schema（`app/schemas/message.py`）定义的字段名是 `id`/`sender_type`，这是与坐席端（Agent）对齐的格式。H5 前端有自己独立的 `Message` 接口（`message_id`/`message_type`），需要在 API 层做字段映射。

### 编译验证
- frontend-h5: vite build ✅ (1.70s)
- backend: py_compile ✅

### 服务重启
- 使用 `uvicorn app.main:app --reload` 重启后端
- 工作目录：`D:\资料\03-项目开发\wecom_it_smart_desk\backend`

### 启动问题修复
重启过程中遇到多个问题并逐一修复：

1. **slowapi 模块缺失** → 安装 `slowapi==0.1.9`
2. **slowapi 0.1.9 不支持 `env_file` 参数** → 移除 `env_file=None`（3个文件）
   - `backend/app/api/agents.py`
   - `backend/app/api/h5.py`
   - `backend/app/main.py`
3. **缺少依赖注入函数** → 在 `dependencies.py` 中新增：
   - `get_shared_redis()` / `get_shared_wecom_service()` / `get_shared_ai_handler()`
   - `dep_redis()` / `dep_wecom_service()` / `dep_ai_handler()` / `dep_wingman_service()`
   - `init_shared_services()` / `cleanup_shared_services()`
4. **RateLimitExceeded 异常处理器中 `Request` 未定义** → 移除类型注解

### 服务状态
- ✅ FastAPI 已启动，运行在 `http://0.0.0.0:8000`
- ✅ 98 个路由已注册
- ✅ SQLite 数据库初始化完成
- ✅ 默认数据初始化完成

---

## Phase 2 路由选择页（Portal）构建与集成

### 背景
`frontend-portal/` 和 `backend/app/api/portal.py` 的代码已经写好，需要构建和集成。

### 已完成工作
1. **Portal 前端构建**：`npm install` + `vite build` ✅ (4.65s)
2. **PortalSelect.vue 增强**：添加 OAuth2 `?code=` 参数处理（调用 `/h5/oauth/callback` 获取 token）
3. **坐席端适配**（已完成）：路由守卫读取 `?token=` 参数，保存到 `agent_token` + `portal_token`
4. **H5端适配**（已完成）：路由守卫读取 `?token=` 参数，保存到 `h5_token`
5. **全量编译验证**：
   - frontend-portal: vite build ✅ (4.65s)
   - frontend-h5: vite build ✅ (2.00s)
   - frontend-agent: vite build ✅ (5.56s)
   - backend portal.py: py_compile ✅
   - backend h5.py: py_compile ✅

### 完整认证流程
1. 用户通过企微工作台点击 IT智能服务台 → 跳转到 `/itportal/`
2. Portal 检测到 `?code=xxx`（OAuth2 回调）→ 调用后端获取 token → 保存到 localStorage
3. Portal 调用 `/api/portal/roles` 获取用户角色列表
4. 如果仅 user 角色 → 自动跳转 `/itdesk/`；多角色 → 显示卡片选择页
5. 用户点击"进入" → Portal 将 token 通过 `?token=xxx` 传递到目标前端
6. 目标前端路由守卫读取 token → 保存到各自的 localStorage key → 正常工作

### Portal 服务配置
- Base path: `/itportal/`
- 开发端口: 5176
- 构建产物: `frontend-portal/dist/`
- 端口映射: 5173(坐席), 5174(H5), 5175(管理), 5176(Portal)

### Phase 2 部署配置完成

**Nginx 配置更新：**
- `nginx/nginx.conf` — 添加 `/itportal/` 路由（本地开发版）
- `deploy-server/nginx.conf` — 添加 `/itportal/` 路由 + 默认路径重定向到 `/itportal/`

**部署脚本更新：**
- `deploy-server/deploy.sh` — 添加 portal 前端部署步骤 + 数据库迁移步骤

**角色管理脚本：**
- `backend/scripts/init_roles.py` — 初始化三个默认角色（user/agent/admin）
- `backend/scripts/assign_role.py` — 用户角色分配/移除/查看工具

**本地开发脚本：**
- `scripts/dev-portal.sh` — Linux/Mac 快速启动脚本
- `scripts/dev-portal.ps1` — Windows PowerShell 快速启动脚本

**数据库状态：**
- roles 表已初始化（3条：user/agent/admin）
- user_roles 表已创建
- 角色分配脚本已测试通过

---

## 部署包打包完成

### 构建结果
- H5 前端: vite build ✅ (1.85s)
- Agent 前端: vite build ✅ (5.12s)
- Admin 前端: vite build ✅ (5.81s)
- Portal 前端: vite build ✅ (4.32s)

### 部署包
- 路径: `deploy-packages/it-smart-desk-deploy-20260613_102148.tar`
- 内容: 4个前端 dist + deploy.sh + nginx.conf + backend-scripts/
- 打包脚本: `deploy-packages/build-and-package.ps1`

### 部署步骤
1. 通过堡垒机上传 tar 包到服务器 `/tmp/`
2. 在服务器执行: `cd /tmp && tar -xf it-smart-desk-deploy-*.tar`
3. 执行部署脚本: `./deploy.sh`
4. 数据库迁移: `cd /opt/wecom-it-desk/backend && alembic upgrade head && python scripts/init_roles.py`
5. 角色分配: `python scripts/assign_role.py <employee_id> agent`
