chore: docs 结构整改 + compose 双目录对齐(合并重建提交)
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交 (5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。 一、docs 结构整改(整改 #14) 根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入, 随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录 树并存于 docs/,共 791 文件、双分类体系冲突。 修复动作: - b2 同名异主题文件改名迁移保全 9 个 - C 类 39 个孤立文件按主题正确归类 - A/B1 类 222 个重复文件删除(新结构已有内容副本) - 9 个旧独有空目录删除 - 270 处内部引用按 verified 映射改写 - 整改记录 #14 登记于 04-运维文档/部署运维 结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。 残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。 二、compose 双目录对齐(消除踩坑 A) - docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist 改为 src/frontend-*/dist(h5 / agent / admin / terminal) - docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/ - 效果:本地 docker compose up 不再把根目录 stale dist 挂回, 与线上一致,分叉隐患消除(已 docker compose config 校验通过) 防复发铁律: - 重构须提交;仓库修复须 git stash -u 或先 commit - 新结构须 git add 并提交,避免再次 untracked 复活 - H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
# 任务说明书:坐席端待办事项移至右栏底部
|
||||
|
||||
> **版本**: 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.vue(import + 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.94s,1 Workspace)+ 上传干净包(577 KB)+ sudo 替换 + restart + 验证:服务器 Workspace=1(旧 3 个清除)、服务 Workspace chunk TodoPanel=0、AiAssistantPanel=1 |
|
||||
|
||||
---
|
||||
|
||||
## 📎 调整需求说明
|
||||
|
||||
### 需求概述
|
||||
将坐席端「待办事项」面板从 **左栏底部** 移至 **右栏底部**,与 v1.1 原型保持一致。
|
||||
|
||||
### 改动点
|
||||
1. **左栏 `ConversationList.vue`** — 移除:
|
||||
- 模板末尾 `<TodoPanel />` 挂载(line 90)
|
||||
- `TodoPanel` import(line 103)
|
||||
- `useTodoStore` import(line 101)及 `const todoStore` 实例(line 129)
|
||||
- `onMounted` 中的 `todoStore.fetchTodoList()`(line 247-249,与 TodoPanel 内部 fetch 重复)
|
||||
- `onMounted` import(line 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
|
||||
|
||||
# 重启 nginx(bind 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 KB(vs 首版 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`
|
||||
Reference in New Issue
Block a user