Files
wecom_it_smart_desk/docs/07-项目管理/任务说明书/任务说明书-132-坐席端待办事项移至右栏底部.md
T
Simon 44e77dcb0e chore(docs): docs/ 目录全面重新编号 + 重组
**重构前**(旧编号 02-11):
- docs/02-产品需求/      → 00 产品规划/PRD
- docs/03-技术架构/      → 01-05 子目录散落
- docs/04-原型设计/      → 01-02 产品设计(HTML 原型)
- docs/05-原型设计/      → screens/
- docs/06-测试素材/      → 02-E2E / 03-功能 / 04-版本测试
- docs/07-项目管理/      → 任务说明书/日报/计划
- docs/08-安全审计/      → 审计报告
- docs/09-堡垒运维/      → toolbox / deploy
- docs/10-项目管理/      → 任务说明书(重复)
- docs/11-历史归档/      → deploy-nas-archived

**重构后**(新编号 00-07,语义化):
- docs/00-产品开发流程与文档管理规范.md
- docs/00-版本迭代总览.md
- docs/01-产品文档/      (PRD/原型/认证/会话/AI 服务/坐席/集成)
- docs/02-技术文档/      (技术方案/架构图/重构记录/前端改造/实现配置)
- docs/03-测试文档/      (E2E/功能用例/版本报告/缺陷单)
- docs/04-运维文档/      (部署运维/运维指南)
- docs/05-运营文档/      (品牌推广/用户手册)
- docs/06-安全审计/      (审计报告)
- docs/07-项目管理/      (任务说明书/日报/计划/看板)

**净收益**:
- 目录编号与产品文档管理规范对齐(按文档阶段 01-07 编号)
- 消除 02-产品需求 与 10-项目管理 的编号重叠
- 子目录按文档类型分组(如 01-产品文档/00-产品规划、01-产品文档/01-认证与登录)
- 把运维/安全/项目管理从 0X 散落改为 04/06/07

合计 494 文件 + 78495 行 / - 14076 行
2026-08-03 18:46:55 +08:00

258 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 任务说明书:坐席端待办事项移至右栏底部
> **版本**: v1.0 | **日期**: 2026-08-02
---
## 📋 基本信息
| 项目 | 内容 |
|------|------|
| **任务名称** | 坐席端待办事项移至右栏底部 |
| **任务ID** | #132 |
| **优先级** | 🟡 P2 |
| **类型** | 功能开发(UI 布局调整) |
| **状态** | 🔵 进行中 |
| **负责人** | 宋献 |
| **创建日期** | 2026-08-02 |
| **计划完成日期** | 2026-08-02 |
---
## 📥 输入项来源
### 产品需求
| 来源文档 | 相关章节 | 说明 |
|----------|----------|------|
| 原型 v1.1(本文) | 整体布局 | 右栏底部新增待办面板,左栏移除待办面板 |
### 原型设计
| 来源文档 | 页面 | 说明 |
|----------|------|------|
| `docs/01-产品文档/04-坐席工作台/原型-REQ-坐席-000-坐席工作台-v1.1.html` | 坐席工作台 | v1.0→v1.1:待办从左栏底部移至右栏底部(与 AI 推荐、快速回复并列为右栏第三段) |
### 需了解的现有代码(历史现状)
| 模块/文件 | 说明 | 需了解的内容 |
|-----------|------|-------------|
| `src/frontend-agent/src/components/conversation/TodoPanel.vue` | 待办面板组件(待移动的整块) | 内部 `onMounted` 已含初始 `fetchTodoList()` + 60s `setInterval` 自动刷新,`onUnmounted` 清理定时器 |
| `src/frontend-agent/src/components/conversation/ConversationList.vue` | 左栏会话列表 | line 90 `<TodoPanel />`、line 101 `useTodoStore` import、line 103 `TodoPanel` import、line 129 `const todoStore = useTodoStore()`、line 247-249 `onMounted``todoStore.fetchTodoList()`(与 TodoPanel 内部 fetch 重复,移除后由 TodoPanel 自身负责) |
| `src/frontend-agent/src/components/assistant/AiAssistantPanel.vue` | 右栏 AI 助手容器 | flex column 布局;`.ai-training-panel``flex:1; min-height:0; overflow:hidden` 可压缩;`.ai-assistant-panel__empty``flex:1`,有/无会话两种状态均能让位给底部待办 |
| `src/frontend-agent/src/stores/todo.ts` | 待办 Pinia Store | 全局注入,移动组件无需重绑数据 |
---
## 📤 输出成果要求
### 交付物清单
| # | 交付物 | 类型 | 说明 |
|---|--------|------|------|
| 1 | `src/frontend-agent/src/components/assistant/AiAssistantPanel.vue` | 代码 | 右栏底部新增 `<TodoPanel />` 挂载 + import |
| 2 | `src/frontend-agent/src/components/conversation/ConversationList.vue` | 代码 | 移除 `<TodoPanel />` 挂载、`TodoPanel` import、`useTodoStore` import + 实例、空 `onMounted` 块、`onMounted` import、顶部注释中第 3 条 |
| 3 | 坐席端构建产物 | 构建 | `npm run build` 通过 |
| 4 | 浏览器端到端验证 | 测试 | 右栏底部展示待办、左栏不再展示待办、点击待办仍进入任务详情 |
### 代码要求
- 遵循项目代码规范(Composition API + `<script setup lang="ts">`
- 所有新增/修改代码通过 ESLint 检查
- 不改动 TodoPanel 内部逻辑、不改 Pinia store、不改样式
---
## 🔧 验证方式
### 功能验证
| 验证项 | 验证方法 | 预期结果 |
|--------|----------|-----------|
| 右栏底部展示待办 | 浏览器访问坐席工作台(v1.1 原型 + 实际页面双轨核对) | 待办面板出现在右栏底部(AI 推荐 → 训练区 → 待办),左栏不再展示 |
| 待办数据正常加载 | 刷新页面 / 等待 60s | 待办列表初始加载 + 60s 自动刷新(TodoPanel 内部计时器) |
| 点击待办进入详情 | 点击右栏底部任意待办条目 | 中栏切换到任务详情视图(`workspaceView = 'task'` |
| 左栏会话列表不被压缩 | 浏览器访问 | 会话列表区域占满整列高度,无底部空白 |
| 坐席在线统计可见 | 查看右栏待办底部 | "在线 / 忙碌 / 离线" 三项统计正常展示 |
| 拖拽调整右栏宽度 | 拖拽右栏与中栏之间的 resize handle | 待办面板宽度自适应,右栏在 200-560px 区间均不破版 |
### 兼容性验证
| 验证项 | 验证方法 | 预期结果 |
|--------|----------|-----------|
| 无会话选中态 | 未选会话时刷新页面 | 右栏显示"请先选择一个会话"占位 + 底部待办仍可见 |
| 选中会话态 | 选中一个会话 | 右栏显示训练区 Tabs + 底部待办仍可见 |
| 明暗主题切换 | 切换主题 | 待办面板配色跟随主题(复用全局 CSS 变量) |
---
## ✅ 完成标准
### 验收条件
- [x] 代码已提交(commit `b321e3d`2026-08-03
- [x] 坐席端 `npm run build` 通过
- [x] 部署到生产(dist 替换 + `docker restart wecom_it_nginx` + sudo 提权)
- [x] 生产服务验证:HTTP 200 + 主 chunk hash 由 `index-CocFqFmG.js``index-BDGZ_gcJ.js`
- [x] 浏览器端到端验证(用户确认"右下角"正确显示,2026-08-03 09:19
- [x] 原型 v1.1 与实际页面布局一致
- [x] 清理重发(cache poisoning 根治,2026-08-03 09:10
- [x] git commit(含仓库重组,commit `b321e3d`
---
## 📊 工作分解
### 子任务
| 子任务 | 负责人 | 预估工时 | 状态 |
|--------|--------|----------|------|
| AiAssistantPanel.vue 添加 TodoPanel 挂载 | 宋献 | 0.2h | ✅ 已完成 |
| ConversationList.vue 移除 TodoPanel 及相关死代码 | 宋献 | 0.2h | ✅ 已完成 |
| 坐席端 `npm run build`(首版) | 宋献 | 0.1h | ✅ 已完成(7.01s,无新增告警) |
| 打包 + 部署 v3(污染版含旧 chunk | 宋献 | 0.3h | ✅ 已完成 |
| **清理重发**`rm -rf dist` 重建 + 上传干净包 + sudo 替换 + 移除旧 chunk | 宋献 | 0.3h | ✅ 已完成(08-03 09:10 后) |
| 浏览器端到端验证 | 宋献 | 0.2h | ✅ 已完成(用户确认右下角显示) |
| git commit(含仓库重组 `b321e3d` | 宋献 | 0.5h | ✅ 已完成(12,571 文件改动) |
---
## 📞 依赖与阻塞
### 前置依赖
| 依赖任务 | 依赖说明 | 状态 |
|----------|----------|------|
| 无 | 独立任务 | - |
### 阻塞因素
| 阻塞项 | 影响范围 | 解决方案 |
|--------|----------|----------|
| 无 | - | - |
---
## 📈 变更记录
| 日期 | 变更内容 | 变更人 | 说明 |
|------|----------|--------|------|
| 2026-08-02 | 创建任务 | 宋献 | 初始版本;v1.1 原型落地 |
| 2026-08-02 | 代码改动 + build 通过 | 宋献 | 9 处编辑:AiAssistantPanel.vueimport + mount + 注释)+ ConversationList.vue(移除 import / const / onMounted / 模板挂载 / 注释);build 7.01s 通过,无新增告警 |
| 2026-08-02 | 部署成功(含两次失败恢复) | 宋献 | 打包 `packages/frontend-agent-dist-0802.tar.gz` (2.0 MB)jumpserver-V2 上传+sudo+docker restart;主 chunk hash `index-CocFqFmG.js → index-BDGZ_gcJ.js` 验证生效;详见下方部署复盘 |
| 2026-08-03 | 清理重发(cache poisoning 根治) | 宋献 | 用户反馈左下角仍显示待办 → 服务端验证 origin 正确但服务器堆了 3 个旧 Workspace chunk(首版未 `rm -rf dist` 导致 Vite 累积旧 chunk 一起被 tar)→ `rm -rf dist` 重建(5.94s1 Workspace+ 上传干净包(577 KB+ sudo 替换 + restart + 验证:服务器 Workspace=1(旧 3 个清除)、服务 Workspace chunk TodoPanel=0、AiAssistantPanel=1 |
---
## 📎 调整需求说明
### 需求概述
将坐席端「待办事项」面板从 **左栏底部** 移至 **右栏底部**,与 v1.1 原型保持一致。
### 改动点
1. **左栏 `ConversationList.vue`** — 移除:
- 模板末尾 `<TodoPanel />` 挂载(line 90
- `TodoPanel` importline 103
- `useTodoStore` importline 101)及 `const todoStore` 实例(line 129
- `onMounted` 中的 `todoStore.fetchTodoList()`line 247-249,与 TodoPanel 内部 fetch 重复)
- `onMounted` importline 98,移除后不再使用)
- 顶部注释第 3 条 `底部挂载 TodoPanel`line 8
2. **右栏 `AiAssistantPanel.vue`** — 新增:
- `import TodoPanel from '@/components/conversation/TodoPanel.vue'`
- 模板在 v-if/v-else 主体之后、容器 `</div>` 闭合前插入 `<TodoPanel />`
- 依赖已有的 `.ai-training-panel` / `.ai-assistant-panel__empty``flex:1; min-height:0` 让出底部空间,待办面板自身 `flex-shrink:0; max-height:260px` 固定贴底
3. **数据层** — Pinia `todoStore` 全局,无需重绑数据。
### 不做的事
- 不修改 TodoPanel 内部逻辑、样式、数据结构
- 不调整右栏宽度 / resize handle
- 不重构 todoStore
- 不动 backend 接口
---
## 📎 部署复盘(2026-08-02,含三次尝试)
### 真实服务器路径(修正记忆)
-**正确**`/opt/wecom-it-desk/frontend-agent/dist`(扁平布局,无 `src/` 中间层)
- ❌ 错误(记忆中的):`/opt/wecom-it-desk/src/frontend-agent/dist`
- 验证方法:`docker inspect wecom_it_nginx | grep -i frontend-agent | grep Source` → 永远以这个为权威
### 权限模型(关键教训)
- `dist/`**root:root** `drwxr-xr-x`(其它人 r-x**无写**
- 父目录 `frontend-agent/``/opt/wecom-it-desk/``drwxrwxrwx`(可重命名)
- `admin` 用户有**免密 sudo**`sudo -n true` exit 0
- compose mount 是 `:ro`(只读)→ **写入必须走 HOST 端 + sudo**,不能 `docker exec` 写容器内路径
- 因此部署命令模板:`sudo mv ... && sudo mkdir ... && sudo tar ... && sudo mv ... && docker restart ...`
### 三次尝试与教训
1. **v1(失败)**`cd /opt/wecom-it-desk/src/frontend-agent` ENOENT(路径含多余 `src/`)→ 后续 tar 解压错落到 `$HOME/dist`**错误地把 HOME 当成了项目目录**,污染了 home。HTTP 200 是假象(容器继续服务旧 Jul 30 bundle
2. **v2(失败)**:改用正确路径,但未加 sudo → `mv dist dist.bak.0802` 静默失败(admin 无写 root-owned dir),`mkdir dist` EEXIST 静默失败,`tar` 写入 root-owned 只读 dir 失败。`grep AiAssistantPanel` 空 → **我自己造成的假阴性**AiAssistantPanel 是 lazy chunk,不在 index.html 里)
3. **v3(成功)**:用 `docker inspect` 找到真实路径 + `sudo -n true` 验证 sudo 可用 + **绝对路径 + sudo** 替换 → 成功
### 验证方法(部署成功的正确指标)
- ❌ **不**用 `curl HTTP 200`(只代表 nginx 在响应,不一定是新 bundle)
- ❌ **不**用 `grep <组件名> index.html`(组件是 lazy-split chunk,不会出现在 index.html
-**用主 chunk hash 对比**:部署前 `curl .../index.html | grep -o 'assets/[^"]*' | sort -u` 记下旧 hash;部署后跑同样的命令,对比 hash 是否变化。`index-OLD.js → index-NEW.js` = 生效
- ✅ 可选附加:用 `grep -o 'assets/[^"]*' /opt/wecom-it-desk/frontend-agent/dist/index.html` 看宿主机文件,与服务返回对比
### 部署命令模板(已验证)
```bash
# 清理可能的 HOME 污染
cd && rm -rf dist dist.bak.0802
# sudo 替换 root-owned dist(绝对路径)
sudo mv /opt/wecom-it-desk/frontend-agent/dist /opt/wecom-it-desk/frontend-agent/dist.bak.<日期>
sudo mkdir /opt/wecom-it-desk/frontend-agent/dist.new
sudo tar -xzf /tmp/frontend-agent-dist-<日期>.tar.gz -C /opt/wecom-it-desk/frontend-agent/dist.new --strip-components=1
sudo mv /opt/wecom-it-desk/frontend-agent/dist.new /opt/wecom-it-desk/frontend-agent/dist
# 重启 nginxbind mount dentry cache 刷新)
docker restart wecom_it_nginx
# 验证
sleep 6
docker ps --filter name=wecom_it_nginx
curl -s -o /dev/null -w 'itagent_http=%{http_code}\n' http://127.0.0.1/itagent/
curl -s http://127.0.0.1/itagent/index.html | grep -o 'assets/[^"]*' | sort -u
```
### 本次回滚点
- 旧污染版 dist(功能正确但含旧 chunk)备份为 `/opt/wecom-it-desk/frontend-agent/dist.bak.0802_contam`
- 干净版 dist(08-03 重发)备份为 `/opt/wecom-it-desk/frontend-agent/dist.bak.0802`(前次部署后保留)
- 服务器端备份包:
- `/tmp/frontend-agent-dist-0802.tar.gz`2.0 MB,含旧 chunk 的首版)
- `/tmp/frontend-agent-dist-0802-clean.tar.gz`577 KB,干净版)
- 如需回滚到首版:
```bash
sudo mv /opt/wecom-it-desk/frontend-agent/dist /opt/wecom-it-desk/frontend-agent/dist.new
sudo mv /opt/wecom-it-desk/frontend-agent/dist.bak.0802_contam /opt/wecom-it-desk/frontend-agent/dist
docker restart wecom_it_nginx
```
---
## 📎 Cache Poisoning 教训(2026-08-03 清理重发)
### 现象
08-02 晚间 v3 部署后服务端一切正常(main chunk hash 已变,HTTP 200),但 08-03 早晨用户报告"代办事项还在坐席端左下角"。
### 根因(三层 cache poisoning
1. **用户浏览器缓存了旧 index.html**Ctrl+Shift+R 后仍未更新,可能是公司代理/CDN 缓存)
2. **旧 index.html 引用旧 chunk hash**(如 `Workspace-B-lO49Vu.js` 等)
3. **这些旧 chunk 还堆在服务器上**(Vite 不会清空 dist,多次构建累积;首版 tar 把它们一起上传了)→ nginx 返旧 chunk → 旧 TodoPanel mount 代码渲染 → 左下角出现
### 服务端验证(绕过用户缓存)
从服务器本地 `curl http://127.0.0.1/...` 直接拉,绕过浏览器/CDN 缓存:
| 检查 | 结果 | 结论 |
|---|---|---|
| 服务 index.html 引用 | `index-BDGZ_gcJ.js`(新 hash) | ✅ 服务是新入口 |
| 服务 `Workspace-D0Lbi52U.js` 含 TodoPanel | **0** | ✅ 新代码干净 |
| 服务 `AiAssistantPanel-DEzJ9GRb.js` 含 TodoPanel | **1** | ✅ 右栏已挂载 |
| **服务器 Workspace-*.js 数量** | **4 个**(新 1 + 旧 3 | ⚠️ **旧 chunk 是 cache poisoning 的燃料** |
### 清理重发(08-03 09:10
1. `rm -rf src/frontend-agent/dist && npm run build` → 5.94s,仅 1 个 Workspace chunk(无累积)
2. `tar -czf packages/frontend-agent-dist-0802-clean.tar.gz dist` → 577 KBvs 首版 2.0 MB
3. jumpserver-V2 上传(网络恢复后)+ sudo 替换 + restart + 验证
4. 服务器 Workspace chunks = **1**(旧 3 个清除);服务验证全部通过 ✅
### 教训(已沉淀到项目 MEMORY.md)
- **部署前 `rm -rf dist`**Vite/Rollup 不自动清空 dist/assets,多次构建会累积旧 chunk。必须先清再 build。
- **打包前验证 chunk 数**`tar -tzf <tar> | grep -c 'Workspace-'` 应为 1(多个 = 有累积污染)
- **服务端用 `curl 127.0.0.1` 绕过用户缓存**:从服务器本地 curl 是验证部署生效的金标准,不受用户端缓存影响
- **cache poisoning 根治**:清理重发让旧 chunk URL 404,强制浏览器重新拉(即使缓存了旧 index.html,引用 404 的旧 chunk 会触发错误或重新解析)
- **用户立即验证**:无痕窗口 + cache buster URL `https://itsupport.servyou.com.cn/itagent/?v=YYYYMMDD`