# 2026-06-12 工作记录

## H5端邀请功能WebSocket事件实现

### 后端改动
1. **ws_manager.py** — 扩展 ConnectionManager 支持H5员工连接：
   - 新增 `employee_connections: Dict[str, WebSocket]` 员工连接映射表
   - 新增 `connect_employee()` / `disconnect_employee()` 员工连接注册/注销
   - 新增 `send_to_employee()` / `broadcast_to_employees()` 员工定向/批量推送
   - 新增 `is_employee_online()` 在线状态检查

2. **session_service.py** — 邀请相关事件广播：
   - `_broadcast_participant_change()` 广播给坐席 + 推送给相关H5员工
   - 事件类型：participant_invited / joined / removed / left / new_message

3. **H5前端 composable** — 新增 `useH5WebSocket.ts`：
   - 与坐席端 `useWebSocket.ts` 对齐
   - 端点：`/ws/h5/{employee_id}?token=xxx`
   - 认证：Redis `employee:token:{token}` → employee_id 一致性校验
   - 降级策略：WS断连→3秒轮询；WS重连→停止轮询

4. **后端 OAuth2 接口** — 支持 code 换身份流程：
   - `GET /api/h5/oauth/authorize` — 获取授权URL
   - `POST /api/h5/oauth/callback` — code 换 token + 员工信息
   - Token 存入 Redis（8小时TTL）

---

## 企微环境限制部署 — 方案B验证通过（21:46-21:54）

### 部署过程
- 5个部署包通过堡垒机上传到 `/tmp/`：deploy-h5.tar / deploy-agent.tar / deploy-admin.tar / deploy-backend.tar / deploy.sh
- 执行 `bash /tmp/deploy.sh`，完整流程：备份 → 解压前端 → 更新后端 → 关闭Mock登录 → 重建镜像 → 重启容器 → 健康检查
- Mock登录已关闭：`MOCK_LOGIN_ENABLED=false` ✅

### 验证结果
- ✅ 外部浏览器访问 `https://itsupport.servyou.com.cn/itdesk/` → 拦截页面「请在企业微信中打开」
- ✅ 企微桌面端工作台 → IT支持服务 → 自动进入H5页面，显示「IT智能服务台」+「坐席在线」
- ✅ 后端OAuth2接口UA校验（authorize/callback）已生效
- ✅ localhost开发环境自动豁免检测

### 涉及文件
- 新增：`frontend-h5/src/views/WeworkOnly.vue`（拦截页面）
- 修改：`frontend-h5/src/router/index.ts`（路由守卫UA检测）
- 修改：`backend/app/api/h5.py`（OAuth2接口UA校验）
- 新增：`deploy-server/deploy.sh`（一键部署脚本）

---

## 安全风险评估与修复（21:00-22:00）

### 安全审计结果
对项目进行全面安全审计，发现 17 项安全风险（3严重/5高/5中/4低）。

### 已完成的修复（严重+高风险）
1. **C-1**: `.env.example` 替换为占位符值
2. **C-2**: `config.py` 移除硬编码 Dify API Key（默认值改为空字符串）
3. **H-1**: `deploy-server/docker-compose.yml` Mock 登录默认值 `true` → `false`
4. **H-2**: 坐席企微验证降级放行修复（新注册必须验证，已注册才允许降级）
5. **H-3**: H5 端 `X-Employee-Id` 明文头仅在 `mock_login_enabled=true` 时允许
6. **H-4**: WebSocket 认证 Redis 降级放行修复（故障时拒绝连接）
7. **H-5**: 添加 slowapi 速率限制（登录10/min，Mock登录5/min，OAuth回调20/min）

### 遇到的问题
- Windows `python` 命令指向 Microsoft Store 占位符，实际 Python 路径：`C:\Users\simon\AppData\Local\Programs\Python\Python312\python.exe`
- slowapi 的 `Limiter()` 会尝试读取 `.env` 文件，Windows GBK 编码无法解码中文注释，需加 `env_file=None` 参数

### 待处理（中/低风险）
- Redis 设置密码、PostgreSQL 强密码、CORS 收紧、Nginx CSP/HSTS 安全头等

---

## 统一入口架构设计（22:00-22:40）

### 设计决策
- **统一入口**：所有用户必须通过企微工作台 → IT智能服务台应用进入
- **路由选择页**：独立页面 `/itportal/`，卡片选择 UI
- **角色体系**：user（默认）/ agent（企微标签映射）/ admin（手动绑定）
- **Token 统一**：合并为 `user:token:{token}`，包含角色信息
- **管理端访问控制**：仅限内网/VPN 访问，Nginx IP 白名单
- **坐席端改造**：支持企微桌面端 + 独立浏览器扫码登录
- **API 认证**：保留独立 API Key 通道，与用户认证分离

### 技术设计文档
已创建 `docs/统一入口技术设计文档.md`，包含：
- 系统架构图、角色路由逻辑
- 数据库设计（roles/user_roles/role_mapping_rules 表）
- API 设计（Portal API、角色管理 API、认证中间件）
- 前端设计（Portal Vue 应用、角色选择 UI、坐席端改造）
- 安全设计（认证安全、角色安全、API 安全）
- 实施计划（4阶段，约66工时）

### 用户确认的关键决策
- 企微标签配置：用户是企微超管，可直接创建标签组
- eHR 对接：先用企微标签映射，eHR 后续补充
- 管理端紧急通道：保留管理员密码登录，仅内网/VPN 访问，需二次验证（待设计）
- 坐席端使用场景：支持企微桌面端 + 独立浏览器扫码登录

---

## 统一入口 Phase 1 实施（23:00-00:00）

### 已完成的工作
1. **数据库模型** — 创建角色系统三张表：
   - `roles` — 角色定义表（user/agent/admin）
   - `user_roles` — 用户角色关联表（支持多角色）
   - `role_mapping_rules` — 角色映射规则表（企微标签/eHR字段 → 角色）
   - Alembic 迁移脚本：`007_role_system.py`（含预置数据）

2. **Pydantic Schema** — `schemas/role.py`，包含：
   - RoleResponse / UserRoleResponse
   - RoleAssignRequest / RoleRevokeRequest
   - RoleMappingRuleRequest / RoleMappingRuleResponse
   - PortalUserInfo / SwitchRoleRequest / SwitchRoleResponse

3. **API 端点**：
   - `portal.py` — Portal 统一入口 API（获取角色、切换角色、获取入口URL）
   - `admin_roles.py` — 管理后台角色管理 API（CRUD、分配/撤销、映射规则管理）
   - `router.py` — 注册新路由

4. **服务层**：
   - `role_mapping_service.py` — 角色映射服务（企微标签 → 角色）
   - `token_service.py` — 统一 Token 服务（创建、验证、切换角色、兼容旧格式）

5. **认证中间件** — `dependencies.py`，包含：
   - `get_current_user` — 统一认证依赖（支持新旧 Token 格式）
   - `require_role` — 角色验证装饰器
   - `require_admin` — 管理员权限验证装饰器

6. **坐席认证改造** — `agents.py`：
   - `get_current_agent` 支持新旧两种 Token 格式
   - 坐席登录使用统一 Token 服务创建 Token

### 文件清单
**新增文件**：
- `backend/app/models/role.py`
- `backend/app/models/user_role.py`
- `backend/app/models/role_mapping_rule.py`
- `backend/app/schemas/role.py`
- `backend/app/services/role_mapping_service.py`
- `backend/app/services/token_service.py`
- `backend/app/api/portal.py`
- `backend/app/api/admin_roles.py`
- `backend/alembic/versions/007_role_system.py`

**修改文件**：
- `backend/app/models/__init__.py` — 注册新模型
- `backend/app/api/router.py` — 注册新路由
- `backend/app/api/agents.py` — 认证改造
- `backend/app/dependencies.py` — 统一认证中间件

### 下一步
- 运行 Alembic 迁移创建表
- 测试新 API 端点
- 开始 Phase 2：路由选择页前端开发

---

## 安全风险修复（08:00-08:30）

### 安全审计结果
对项目进行安全风险评估，发现 22 项安全风险（4严重/6高/7中/5低）。

### 已完成的修复（Phase 1）

1. **CR-1**: 验证 `dependencies.py` 完整性 → 文件完整，无需修复
2. **CR-2**: 统一 Token 格式并确保向后兼容 → 修改 `token_service.py`
3. **CR-3**: Portal API 改用新认证中间件 → 修改 `portal.py`、`admin_roles.py`
4. **CR-4**: 修复坐席登录 Redis 连接管理 → 修改 `agents.py`
5. **H-8**: 添加映射规则输入验证 → 修改 `schemas/role.py`

### 创建的文档
- `docs/风险跟踪表.md` — 风险跟踪管理文档，包含 22 项风险的详细信息和处理计划

### 风险关联开发任务
已建立风险与开发任务的关联关系，后续开发涉及风险项目时，与风险项目一并处理并更新状态。

### 待处理风险
- **高风险**: H-7（角色分配权限验证）、H-9（Token绑定IP）、H-10（管理端IP白名单）、H-11（WS Token头传递）
- **中风险**: M-6~M-12（Token迁移、缓存、速率限制、异常处理、日志脱敏、密码强度等）
- **低风险**: L-5~L-9（CSP/HSTS、CORS、API认证、Nginx配置、前端配置）

---

## Phase 2：Portal 前端应用（08:44-09:00）

### 已完成的工作
1. **创建 frontend-portal Vue 应用**：
   - 基于 Element Plus（与坐席端/管理端一致）
   - 基础路径：`/itportal/`
   - 开发端口：5176
   - 状态管理：Pinia
   - 路由：vue-router 4

2. **目录结构**：
   ```
   frontend-portal/
   ├── package.json
   ├── vite.config.ts
   ├── tsconfig.json
   ├── index.html
   ├── .env / .env.development / .env.production
   └── src/
       ├── main.ts
       ├── App.vue
       ├── api/
       │   ├── index.ts (axios 实例)
       │   └── portal.ts (Portal API)
       ├── router/
       │   └── index.ts
       ├── stores/
       │   └── portal.ts (Pinia Store)
       └── views/
           ├── PortalSelect.vue (角色选择页)
           └── PortalLoading.vue (加载中页)
   ```

3. **核心功能**：
   - 角色选择页面（卡片选择 UI）
   - 用户信息展示
   - Token 管理（localStorage）
   - 角色切换（跳转到对应端）
   - 响应式布局（支持移动端）

### 下一步
- 安装依赖并测试前端应用
- 集成到 Docker 构建
- 部署到服务器

---

## 重要提醒（10:15）

### 测试环境限制
- **本地开发环境无法完成企微 OAuth2 认证**
- 所有登录相关验证必须在生产服务器 `10.90.5.110` 上进行
- 前端都通过企微认证，不支持独立登录页面

---

## 部署清单（10:51）

### 本次更新成果（可部署）
- **后端**：角色系统（3张表+迁移脚本）、统一Token服务、角色管理API、安全修复
- **前端**：Portal 统一入口应用（`frontend-portal/`）
- **部署脚本**：已包含 Portal 部署逻辑

### 待部署验证
- Portal 角色选择页
- OAuth2 认证流程
- Token 传递和验证
- 角色切换功能
- 数据库迁移

---

## 安全风险修复（15:20）

### 本次修复的 6 项风险
1. **H-7**: 角色分配权限验证（禁止给自己分配）→ `admin_roles.py`
2. **H-10**: 管理端 Nginx IP 白名单配置 → `nginx.conf`
3. **M-11**: PostgreSQL 更换强密码 → `.env.example`
4. **M-12**: Redis 设置密码 → `docker-compose.yml` + `.env.example`
5. **L-5**: Nginx 添加 CSP/HSTS 安全头 → `nginx.conf`
6. **L-6**: 收紧 CORS 配置 → `main.py`

### 风险处理进度
- 严重风险：4/4 已处理（100%）
- 高风险：4/6 已处理（67%）
- 中风险：2/7 已处理（29%）
- 低风险：2/5 已处理（40%）
- **总处理率：55%**
