Files
wecom_it_smart_desk/docs/02-技术文档/前端改造/设计-H5用户端实现概览-v1.0.md
T

320 lines
15 KiB
Markdown
Raw Normal View History

# H5用户端原型图 → Vue3代码实现概览
## 完成时间
2026-06-09
## 变更摘要
根据已锁定的原型图 v1.1 修复版,将 H5 用户端设计实现为 Vue3 代码。
## 修改文件清单
### 1. `frontend-h5/src/components/chat/ChatPanel.vue`
- **标题栏重构**:左侧(标题 + 坐席在线/离线状态胶囊) + 右侧(🔔呼叫按钮 + 主题切换)
- **🔔摇铃按钮**:从输入栏移至标题栏(桌面端+手机端统一)
- **排查步骤固定顶部**:从消息列表内移出,固定在标题栏下方、所有消息之上,不随滚动消失
- **移除 InputBar 事件**:不再需要 @call-agent 事件(摇铃直接在 ChatPanel 内控制)
### 2. `frontend-h5/src/components/chat/InputBar.vue`
- **移除摇铃按钮**:删除 🔔 摇铃按钮及相关 CSSbell-btn/bell-icon/bell-idle/bell-ring 动画)
- **工具栏**:😊表情 / 📎文件 / ✂️截图 / 📝快捷申请(2026-07-05移除🖼️图片和📸拍照功能)
- **布局改为两行**:工具栏(上) + 输入行(输入框+发送按钮)(下)
- **方法**handleEmoji/handleFile/handleScreenshot/handleQuickApply
- **引导条文案更新**:"点击标题栏铃铛呼叫 IT 坐席"
### 3. `frontend-h5/src/components/assistant/RightPanel.vue`(新建)
- **三段式面板**:AI推送区 / 常用资源标签页 / 趣味问答
- **AI推送区**3种卡片类型(guide/process/download) + 动态图标+颜色
- **常用资源**:2个Tab(申请流程/必装软件) + 资源列表
- **趣味问答**:题目+4选项+积分+答题结果反馈
- **阶段一静态数据**,阶段二接入 Dify 动态推送
### 4. `frontend-h5/src/views/ChatView.vue`
- **替换右侧面板**AiHelperPanel → RightPanel(三段式面板)
- **响应式断点**:从768px改为500px(与原型图对齐)
- **移动端**<500px 不显示右侧面板
- **拖拽逻辑修复**:只固定左侧宽度,右侧 flex:1 自动填满(消除拖拽后空白)
- **移除浮动按钮**:不再需要移动端AI助手浮动按钮
### 5. `frontend-h5/src/stores/conversation.ts`
- **新增 agentOnline 状态**:默认true,阶段一简化处理
- **暴露到 return 语句**:使组件可以访问
## 构建验证
`npx vite build` 构建成功,无编译错误
---
## H5用户端 v2.0 更新(2026-07-24
### v1.x → v2.0 变更
#### 输入栏重构
- **移除标题栏呼叫按钮**:原标题栏的"呼叫"按钮已移除
- **人工坐席按钮移至输入栏**:位于输入框右侧第一层,三态(disabled/active/urgent
- **新增语音输入按钮**:位于输入框右侧第二层,支持语音转文字
- **按钮状态**
- disabled(🔒 灰色):AI回复<3次,不可点击
- active(🎧 蓝色边框):可点击呼叫人工
- urgent(🚨 红色+脉冲动画):检测到紧急问题
#### 右边栏布局调整
- **设备信息/自助诊断**:保持在顶部,手风琴结构
- **智能推荐**:占据主区域(flex:1),展示更多推荐内容
- **排队等待**:移至底部固定显示,包含位置+积分+答题挑战按钮
#### 原型图
- 新版原型图:`01-产品文档/05-用户端H5/原型-REQ-用户-000-H5用户端-v2.0.html`
- 旧版 v1.0 已删除
---
## 右侧栏布局调整(2026-07-17
### v2.1 → v3.0 变更
#### 布局调整
- **智能推荐位置**:移至自助诊断下方,保持一直显示
- **标题样式统一**:智能推荐使用与设备信息、自助诊断相同的标题样式(图标+文字+箭头)
#### 智能推荐调整
- **取消分类标签**:移除"相关推荐"、"运维提醒"、"常用资源"分区标题
- **保留颜色区分**:仅用边框颜色区分类型
- 🟢 绿色边框:相关推荐
- 🟠 橙色边框:运维提醒
- ⚪ 灰色边框:常用资源
#### 排队卡片调整
- **高度压缩**:压缩至原来50%
- **移除平台统计**:取消四宫格(总活跃/排队/服务/AI)
- **保留内容**:排队位置、前面人数、预计等待时间、积分等级
#### 答题功能
- **答题开关**:位于排队卡片标题栏右侧(绿色胶囊按钮)
- **默认折叠**:点击答题挑战按钮展开答题区域
- **功能**:答对题目可获得积分并靠前排队
- **按钮名称**:答题挑战(原"答题插队"2026-07-17修复)
### 调整后原型图
```
┌──────────────────────────────────────────┐
│ 💻 设备信息 ▾ │ ← 手风琴
├──────────────────────────────────────────┤
│ 🩺 自助诊断 ▸ │ ← 手风琴
├──────────────────────────────────────────┤
│ ⚡ 智能推荐 ▾ │ ← 统一标题样式
│ ┌──────────────────────────────┐ │
│ │ 绿色边框:相关推荐内容 │ │
│ └──────────────────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ 橙色边框:运维提醒内容 │ │
│ └──────────────────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ 灰色边框:常用资源内容 │ │
│ └──────────────────────────────┘ │
├──────────────────────────────────────────┤
│ ⏳ 排队位置 #5 前面4人 LV.3 [答题挑战]│ ← 压缩50%
│ ───────────────────────────────────── │
│ [答题区域 - 默认折叠] │
└──────────────────────────────────────────┘
```
### 相关组件
- `RightPanel.vue` - 调整布局结构
- `DynamicRecommend.vue` - 移除分类标签
- `QueueWaiting.vue` - 压缩高度、新增答题开关
---
## 自助诊断标题栏异常徽章(2026-07-29)
### v2.0 → v2.1 变更
> 与代码 `frontend-h5/src/components/assistant/SelfDiagnosis.vue` 已实现的计数逻辑对齐。
#### 标题栏异常徽章(核心需求)
- **位置**:🩺 图标 + "自助诊断"文字右侧;"一键诊断"按钮左侧
- **样式**:高度 18px 圆角胶囊徽章
- **状态规则**
| 全局异常数 | 显示 | 颜色 | 文案 |
|---|------|------|------|
| 0 个 | 绿色徽章 ✓ 全部正常 | rgba(34,197,94,0.15) + #16a34a | "✓ 全部正常" |
| N≥1 个 | 红色徽章 ⚠ N | var(--color-danger) | hover tooltip "共 N 个待处理异常" |
- **触发**SelfDiagnosis.vue 顶部 header__title 旁新增徽章元素
#### 6 Tab 3×2 网格(替换原简化 2 项列表)
| Tab | 图标 | Mock 异常数 | 状态 |
|---|---|---|---|
| 网络联通 | 🌐 | 0 | 无徽章(diagItems idle 未执行) |
| 账号权限 | 🔑 | 1 | 域账号 5 天到期 |
| 设备硬件 | 🔧 | 1 | 硬盘 SMART 警告 |
| 系统软件 | 💻 | 2 | 系统补丁 2 高危 / 邮件客户端异常 |
| 终端安全 | 🛡️ | 0 | 2 项 pending(接入中)不计入 |
| 合规检查 | 📋 | 1 | 未审批商业软件 |
| **合计** | — | **5** | — |
#### Tab 单徽章(右上角)
- **样式**:右上角 16×16 圆角红色徽章,白色数字 + 红边 2px
- **激活态**:白底红字 + 蓝边(与激活 Tab 颜色协调)
- **无异常**:不显示徽章
#### 一键诊断按钮
- 移动到标题栏右侧
- 检测到异常时 disabled + tooltip 提示"建议先处理后再批量诊断"
#### 异常计数规则(前后端口径统一)
```javascript
// 自助诊断每个 Tab 的异常数
const diagAbnormal = diagItems.filter(
d => d.status === 'warning' || d.status === 'fail'
).length
const riskAbnormal = riskItems.filter(
r => r.level === 'warning' || r.level === 'danger'
).length
const tabBadge = diagAbnormal + riskAbnormal
// 全局总异常数(新增)= 所有 Tab 徽章之和
const totalAbnormal = tabs.reduce((sum, t) => sum + t.badge, 0)
```
#### 不计入异常的口径(避免误报)
- `normal` — 状态正常
- `pending` — 数据接入中(如 SIEM/IDS、联软代理,2026-Q4 完成)
- `idle` — 诊断项未执行(运行后可降级为 warning / fail
### 更新文件
- `docs/01-产品文档/05-用户端H5/原型-REQ-用户-007-自助诊断面板优化-v1.0.html`(已就地升级为 v2.1,含全部交互示例、Tab 徽章、风险项示例、异常口径注解)
- `docs/02-技术文档/前端改造/设计-H5用户端实现概览-v1.0.md`(本文档,追加本节)
### 待前端实现(与原型对齐)
- [ ] SelfDiagnosis.vue 标题栏新增 `totalBadge` 计算属性 + 徽章模板
- [ ] 一键诊断按钮 disabled 条件联动 `totalBadge > 0`
- [ ] 单 Tab 徽章已实现;确认右上角样式与原型一致
- [ ] e2e 验证:异常数变化时徽章颜色/数字刷新
---
## 自助诊断面板 v2.2 → v2.3 升级(2026-07-297 项决策锁定)
> **关联需求**:REQ-用户-007 自助诊断面板优化 v1.0-Frozen
> **关联文档**PRD v1.0-Frozen + 技术方案 v1.0 + 任务说明书 v1.0 + 测试用例 v1.050 条 / 8 大类)
> **原型图**`docs/01-产品文档/05-用户端H5/原型-REQ-用户-007-自助诊断面板优化-v1.0.html`(已就地升级 v2.3
### 7 项决策(一句话摘要)
| # | 决策 | 状态 |
|---|------|------|
| 1 | Tab 文字精简版(网络/账号/设备/系统软件/安全/合规) | ✅ |
| 2 | 异常徽章分级 `5W · 0F` | ✅ |
| 3 | 接入中角标位置 A 文字右侧 | ✅ |
| 4 | Tab 切换只显示当前诊断项(已天然) | ✅ |
| 5 | 移动端 toggle A 顶部双按钮 | ✅ |
| 6 | queue 标题栏合并位置/LV/分 | ✅ |
| 7 | 异常+接入混合 M1 双角标并存 | ✅ |
### 异常徽章 3 优化(标题栏,从 v2.1 升级)
| 优化 | 名称 | 视觉 | 实现位置 |
|------|------|------|---------|
| ① | 分级显示 | `5W · 0F` 双胶囊(warning 暖黄字 + fail 粉字) | `.diag-header__badge--graded` |
| ② | 接入中提示 | Tab 文字右侧灰色斜体 `•N` | `.diag-tab__pending-hint` |
| ③ | 0 异常达标动画 | 绿色脉冲 + `✓ 今日安全` 文字,3 秒渐隐 | `.diag-header__badge--celebrate` |
**5 状态对照表**(原型图自带的对照面板):
1. 分级 `5W · 0F`(当前 Mock
2. 含 fail `2W · 1F`
3. 旧版兼容 `!5`(可选关闭)
4. 达标动画 `✓ 今日安全`
5. 静态正常 `✓ 全部正常`
### 6 Tab 横向并排标签页(替代 3×2 网格按钮)
- **高度**34px(不变)
- **布局**flex 1:1:1:1:1:1 等分
- **激活态**:底部 2px 蓝色下划线 + 文字加粗
- **异常 Tab**:底部额外一条 2px 红色半透明线(双层指示)
- **移动端约束**(关键事实):ChatView.vue:80-89 移动端 <500px 直接 `return false`RightPanel 整个不渲染 → **无需考虑横向滚动/换行**
### 移动端 toggle 切换(核心需求,仅移动端 <500px)
- **方案 A**:顶部双按钮 `💬 对话 / 🩺 信息`
- **桌面端 ≥500px**:维持双栏,不显示 toggle
- **Vue v-show 切换**(不卸载 DOM)保留左对话滚动位置 + 输入栏文本
- **3 方案对比**
- A 顶部双按钮 ⭐ 推荐(直观/单击/状态高亮)
- B 右下 FAB(备选,覆盖对话丢上下文)
- C 底部 Tab Bar(备选,跨端控件位置不一致)
### queue 标题栏合并(决策 ⑥)
**改造前**v2.0):queue-header 只显示 `#5`queue-content 内 QueueWaiting 组件含完整 position-card。
**改造后**v2.3):
```
⏳ 排队等待 | #5 前面4人 | LV.3 | 120分 | 答题挑战
```
- queue-header 内联三件套(`qh-position-inline / qh-lv-inline / qh-points-inline`
- queue-content 只保留答题区,QueueWaiting 组件传 `:show-position="false"` 隐藏 position-card
- 整体高度压缩 ~40px
### 异常 + 接入混合 M1 双角标并存(决策 ⑦)
- 场景:某 Tab 同时有异常(W/F)和接入中(pending)项
- 显示:`安全 1•2`(红数字徽章 + 灰斜体小角标)
- 视觉区隔:颜色(红 vs 灰)+ 字体(标准 vs 斜体小号)
- 计数规则:红数字徽章 = 异常项数;灰斜体小角标 = 接入中项数(不计入异常)
### 涉及文件改动(4 项)
| 文件 | 改动 |
|------|------|
| `src/frontend-h5/src/components/assistant/SelfDiagnosis.vue` | 新增 totalBadge / totalBadgeByLevel / showCelebrate computed + 标题栏模板 |
| `src/frontend-h5/src/components/assistant/QueueWaiting.vue` | 新增 `showPosition?: boolean` prop |
| `src/frontend-h5/src/components/assistant/RightPanel.vue` | queue-header-v3 内联三件套 + 传 `:show-position="false"` |
| `src/frontend-h5/src/views/ChatView.vue` | 移动端 toggle 按钮 + `isMobilePanelOpen` state |
### 验收 e2e5 类场景)
- [ ] 桌面端 ≥500px 双栏正常,异常徽章 `5W · 0F`
- [ ] 移动端 <500px 默认显示左对话,点击 🩺 切换到右栏
- [ ] queue 标题栏显示位置/LV/分;queue-content 内不重复显示
- [ ] 切到"系统软件" Tab 只显示系统相关项
- [ ] Tab "安全" 1 异常 + 2 接入时显示 `安全 1•2`
- [ ] 0 异常时触发"✓ 今日安全"动画 3 秒后渐隐
### 关键代码片段
```typescript
// SelfDiagnosis.vue 新增 computed
const totalBadgeByLevel = computed(() => {
let w = 0, f = 0
tabsData.value.forEach(tab => {
w += tab.diagItems.filter(d => d.status === 'warning').length
w += tab.riskItems.filter(r => r.level === 'warning').length
f += tab.diagItems.filter(d => d.status === 'fail').length
f += tab.riskItems.filter(r => r.level === 'danger').length
})
return { w, f }
})
// QueueWaiting.vue 新增 prop
const props = defineProps<{
showQuiz?: boolean
showPosition?: boolean // 默认 true
}>()
// ChatView.vue toggle
const isMobilePanelOpen = ref(false)
const showRightPanel = computed(() => {
if (!isMobile.value) return true
return isMobilePanelOpen.value
})
```
### 关联文档(REQ-用户-007 完整 4 件套)
- **PRD**`docs/01-产品文档/05-用户端H5/PRD-REQ-用户-007-自助诊断面板优化-v1.0.md`
- **技术方案**`docs/02-技术文档/技术架构/技术方案-REQ-用户-007-自助诊断面板优化-v1.0.md`
- **任务说明书**`docs/07-项目管理/任务说明书/任务说明书-REQ-用户-007-自助诊断面板优化.md`
- **测试用例**`docs/03-测试文档/03-功能测试用例/TC-REQ-用户-007-自助诊断面板优化.md`