feat: 完善专家端页面原型,新增视频咨询取消/拒绝页、疾病编辑页,优化多端交互与PRD文档

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 08:50:43 +08:00
co-authored by Claude Opus 4.6
parent fc38844eb9
commit 28bbe3f620
68 changed files with 1934 additions and 979 deletions
+191 -125
View File
@@ -2,30 +2,30 @@
## 模块概述
咨询小助手端为平台客服人员提供移动端工作平台,负责接收员工的初步咨询请求,进行图文对话沟通,并在需要时为员工推荐合适的专家。小助手端仅支持图文咨询,不支持视频咨询。
咨询小助手端为平台客服人员提供移动端工作平台,负责接收员工步咨询请求,进行图文对话沟通,并在需要时为员工推荐合适的专家。小助手端仅支持图文咨询,不支持视频咨询。
### 页面导航结构
```
咨询小助手端
├── 工作台(底部Tab
│ ├── 工作台首页(3分类Tab)
│ │ ├── 待回复 → 图文聊天
│ │ ├── 进行中 → 图文聊天
│ │ └── 已完成 → 咨询完成详情 → 历史对话
├── 图文聊天
│ │ ├── 查看档案 → 员工健康档案
│ │ ├── 结束咨询 → 结束咨询确认弹窗
│ │ └── 推送专家 → 选择专家页 → 返回聊天(发送名片)
│ ├── 工作台首页(3分类Tab + 过滤条件
│ │ ├── 待回复 → 图文聊天(进行中)
│ │ ├── 进行中 → 图文聊天(进行中)
│ │ └── 已完成
│ ├── 已完成 → 图文咨询完成详情 → 历史对话(只读)→ 咨询人健康档案
│ │ └── 已超时 → 图文咨询已超时详情 → 历史对话(只读)→ 咨询人健康档案
├── 知识库(底部Tab
│ ├── 知识库首页4分类Tab
└── 知识详情
├── AI助手(底部Tab,共享模块)
├── 消息(底部Tab,共享模块
│ ├── 知识库首页
│ ├── 知识文章(知识分类-知识列表)→ 知识详情
│ │ └── 规章制度(PDF列表)→ 查看文件
├── AI助手(底部Tab
├── 消息(底部Tab
└── 我的(底部Tab
├── 个人中心主页
│ ├── 咨询统计
── 修改密码
│ ├── 个人信息设置
── 修改密码
│ └── 关于我们
└── 退出登录(确认弹窗)
```
@@ -36,223 +36,287 @@ stateDiagram-v2
[*] --> 待回复 : 员工发起咨询
待回复 --> 进行中 : 小助手首次回复
进行中 --> 进行中 : 推送专家名片
进行中 --> 已完成 : 小助手结束咨询
进行中 --> 已完成 : 任一方结束咨询/有回复但是7天无更新自动变为已完成
进行中 --> 已超时 : 7天首次未回复自动关闭
```
## 页面清单
| 序号 | 文件名 | 页面名称 | 类型 | 所属模块 |
|------|--------|----------|------|----------|
| 1 | workbench/index.html | 工作台首页 | 页面 | 工作台 |
| 2 | workbench/text-chat.html | 图文咨询 | 页面 | 工作台 |
| 3 | workbench/consult-done.html | 咨询完成详情 | 页面 | 工作台 |
| 4 | workbench/employee-profile.html | 员工健康档案 | 页面 | 工作台 |
| 5 | workbench/end-consult-dialog.html | 结束咨询确认弹窗 | 弹窗 | 工作台 |
| 6 | workbench/push-expert.html | 选择专家 | 页面 | 工作台 |
| 7 | knowledge/index.html | 知识库首页 | 页面 | 知识库 |
| 8 | knowledge/detail.html | 知识详情 | 页面 | 知识库 |
| 9 | ../ai-assistant/index.html | AI 助手(共享) | 页面 | AI 助手 |
| 10 | ../message/index.html | 消息列表(共享) | 页面 | 消息 |
| 11 | ../message/contacts.html | 通讯录(共享) | 页面 | 消息 |
| 12 | ../message/im-chat.html | IM 聊天(共享) | 页面 | 消息 |
| 13 | profile/index.html | 个人中心主页 | 页面 | 我的 |
| 14 | profile/stats.html | 咨询统计 | 页面 | 我的 |
| 15 | profile/change-pwd.html | 修改密码 | 页面 | 我的 |
| 序号 | 文件名 | 页面名称 | 所属模块 |
|------|--------|-----|-------|
| 1 | workbench/index.html | 工作台首页 | 工作台 |
| 2 | workbench/text-chat.html | 图文聊天 | 工作台·图文咨询 |
| 3 | workbench/text-chat-done.html | 历史对话(只读) | 工作台·图文咨询 |
| 4 | workbench/text-consult-done.html | 图文咨询完成详情 | 工作台·图文咨询 |
| 5 | workbench/text-consult-timeout.html | 图文咨询已超时详情 | 工作台·图文咨询 |
| 6 | workbench/employee-profile.html | 咨询人健康档案 | 工作台 |
| 7 | workbench/end-consult-dialog.html | 结束咨询确认弹窗 | 工作台 |
| 8 | workbench/push-expert.html | 选择专家 | 工作台 |
| 9 | knowledge/index.html | 知识库首页 | 知识库 |
| 10 | knowledge/detail.html | 知识详情 | 知识库 |
| 11 | ../ai-assistant/index.html | AI 助手 | AI 助手 |
| 12 | ../message/index.html | 消息列表 | 消息 |
| 13 | ../message/contacts.html | 通讯录 | 消息 |
| 14 | ../message/im-chat.html | IM 聊天 | 消息 |
| 15 | profile/index.html | 个人中心主页 | 我的 |
| 16 | profile/edit-profile.html | 个人信息设置 | 我的 |
| 17 | profile/change-pwd.html | 修改密码 | 我的 |
## 逐页说明
---
## 一、工作台模块
### 1. 工作台首页(workbench/index.html
**功能说明:** 小助手工作台入口,展示图文咨询任务队列,按状态分类管理。
![页面截图](screenshots/index.jpg)
**功能说明:** 小助手工作台入口,展示图文咨询任务队列,按状态分类管理,支持多维度过滤筛选。
**业务规则:**
- 头部统计卡片展示:待回复数、进行中数、今日完成数、满意度百分比
- 仅支持图文咨询,无视频咨询Tab
- 分三个子Tab:待回复、进行中、已完成
- 头部展示欢迎语和统计数据:待回复数、进行中数
- 二级 Tab 切换:待回复、进行中、已结束(已完成、已超时)
- 过滤条件栏支持按咨询类型(咨询专家 / 咨询小助手)和专家未回复筛选
- 咨询卡片展示:咨询人头像、姓名、角色标签、最后消息、时间
- 咨询类型标签:咨询专家、咨询小助手
- 已完成面板同时展示已完成和已超时两种终态卡片
**交互说明:**
- 点击待回复/进行中咨询卡片跳转到图文聊天
- 点击已完成咨询卡片跳转到咨询完成详情
- 底部5Tab导航:工作台/知识库/AI助手/消息/我的
- 点击"待回复 / 进行中"咨询卡片跳转到图文聊天
- 点击"已完成"咨询卡片跳转到图文咨询完成详情
- 点击"已超时"咨询卡片:跳转到图文咨询已超时详情页
- 点击过滤条件:动态筛选当前列表
---
### 2. 图文咨询(workbench/text-chat.html
## 二、图文咨询业务线
**功能说明:** 小助手与员工的实时图文对话界面,相比专家端多了"推送专家"功能。
### 2. 图文聊天(workbench/text-chat.html
![页面截图](screenshots/text-chat.jpg)
**功能说明:** 小助手与员工的实时图文对话界面,支持文字、语音、图片发送,提供常用语快捷填充和推送专家功能。
**业务规则:**
- 聊天区分员工消息(左侧白色气泡)和小助手消息(右侧蓝色气泡,机器人头像
- 支持文字、语音、图片三种消息类型
- 常用语面板提供5条预设快捷语
- 导航栏展示咨询人姓名和咨询类型标签(咨询专家蓝色 / 咨询小助手紫色
- 咨询信息条(可折叠)展示:发起时间、咨询人信息、专家信息、查看档案入口。“咨询人档案”按钮需判断当前员工是否选择了咨询档案进行发起咨询,如果没有选择,则按钮置灰,点击时提示Toast“员工未选择咨询人档案”
- 员工消息以左侧白色气泡展示(含咨询卡片),小助手消息以右侧蓝色气泡展示
- 常用语面板支持分类 Tab:全部 / 问候语 / 注意事项 / 结束语/ 引导语
- 媒体选择面板提供:拍照、图库、推送专家三个选项
- 推送专家后,聊天区自动插入专家名片气泡(含头像、姓名、科室、职称、医院、擅长病种)
**交互说明:**
- 点击"查看档案"跳转到员工健康档案
- 点击"结束咨询"跳转到结束咨询确认弹窗
- 点击闪电图标展开/收起常用语面板
- 点击加号展开媒体面板(拍照/图库/推送专家)
- 点击"推送专家"跳转到选择专家页
- 点击咨询人档案卡片或"查看档案"跳转到咨询人健康档案
- 点击右上角"结束咨询"跳转到结束咨询确认弹窗
- 点击"⚡"图标展开 / 收起常用语面板,点击常用语自动填入输入框
- 点击"🎤"图标:切换语音 / 文字输入模式
- 点击"+"图标:展开 / 收起媒体选择面板
- 点击"推送专家":跳转到选择专家页
- 点击"➤"发送按钮:将输入框内容发送为小助手消息气泡
---
### 3. 咨询完成详情workbench/consult-done.html
### 3. 历史对话(只读)workbench/text-chat-done.html
**功能说明:** 展示已完结的员工咨询全部信息,包括咨询统计、评价及健康档案。
![页面截图](screenshots/text-chat-done.jpg)
**功能说明:** 展示已结束图文咨询的历史对话记录,为只读模式,无输入区,底部显示咨询结束说明。
**业务规则:**
- 展示咨询类型(员工咨询)、发起/完成时间、员工评分
- 布局与图文聊天页一致,但无导航栏右上角"结束咨询"按钮,无底部输入区
- 底部固定条显示咨询状态文案:
- 正常完成:「— 本次咨询已结束 —」
- 超时关闭:「— 长时间未回复系统已自动结束本次咨询 —」
- 聊天区末尾展示绿色结束卡片(含完成时间),超时状态下不展示该卡片
**交互说明:**
- 对话内交互与图文聊天页一致
- 返回按钮:跳转到工作台首页
---
### 4. 图文咨询完成详情(workbench/text-consult-done.html
![页面截图](screenshots/text-consult-done.jpg)
**功能说明:** 展示已完成图文咨询的摘要信息,提供查看历史对话和咨询人健康档案的入口。
**业务规则:**
- 顶部员工信息卡展示:头像、姓名、所属部门、"已完成"标签
- 咨询信息区展示:咨询类型、发起时间、结束时间
- 员工评价以黄色引用框展示
- 健康档案分基本信息、生活习惯、身体情况三组
- 咨询人健康档案区支持折叠 / 展开
**交互说明:**
- 点击"查看历史对话记录"跳转到图文聊天页(只读)
- 健康档案支持折叠/展开
- 点击"查看历史对话记录"跳转到历史对话(只读)
- 点击"咨询人健康档案"标题:展开 / 收起档案详情
- 返回按钮:跳转到工作台首页
---
### 4. 员工健康档案workbench/employee-profile.html
### 5. 图文咨询已超时详情workbench/text-consult-timeout.html
**功能说明:** 展示咨询员工的完整健康档案,供小助手参考。
![页面截图](screenshots/text-consult-timeout.jpg)
**功能说明:** 展示因 7 天未回复被系统自动关闭的图文咨询详情,提示超时原因,并提供查看历史记录和健康档案的入口。
**业务规则:**
- 分三组展示:基本信息(姓名、性别/年龄、身高/体重)、生活习惯(吸烟、饮酒、饮食、睡眠)、身体情况(过敏史、遗传史、既往史)
- 过敏史以红色高亮标记
- 顶部员工信息卡展示:头像、姓名、所属部门、"已超时"标签
- 咨询信息区展示:咨询对象、咨询单号、发起时间、结束时间
- 橙色警示卡片展示超时原因:「超过七天无回复,本次咨询已自动关闭。」
**交互说明:**
- 返回按钮跳转到图文聊天页
- 点击"查看历史对话记录":跳转到历史对话(只读)页,
- 点击"咨询人健康档案":跳转到咨询人健康档案页
- 返回按钮:跳转到工作台首页
---
### 5. 结束咨询确认弹窗workbench/end-consult-dialog.html
### 6. 咨询人健康档案workbench/employee-profile.html
**功能说明:** 小助手结束咨询的二次确认弹窗,作为独立HTML页面实现。
![页面截图](screenshots/employee-profile.jpg)
**功能说明:** 展示咨询员工的完整健康档案,供小助手在咨询过程中参考。
**业务规则:**
- 基本信息卡:姓名、关系、性别、年龄、身高、体重
- 生活习惯卡:以标签形式展示,吸烟、饮酒、饮食均衡、睡眠良好
- 身体情况卡:红色高亮标记,过敏史、遗传史、既往史、其他疾病
- 咨询信息卡:问题描述、持续时间、检查资料(图片展示)、就诊经历、期望帮助
**交互说明:**
- 返回按钮:返回来源页面
---
### 7. 结束咨询确认弹窗(workbench/end-consult-dialog.html
![页面截图](screenshots/end-consult-dialog.jpg)
**功能说明:** 小助手结束咨询的二次确认弹窗,作为独立 HTML 页面实现。
**业务规则:**
- 弹窗提示"确认结束与XX的咨询?结束后将无法继续发送消息"
- 半透明蒙层背景
**交互说明:**
- 点击"取消"返回图文聊天页
- 点击"确认结束"跳转到工作台首页
- 点击"取消":关闭弹窗
- 点击"确认结束"跳转到工作台首页
---
### 6. 选择专家(workbench/push-expert.html
### 8. 选择专家(workbench/push-expert.html
![页面截图](screenshots/push-expert.jpg)
**功能说明:** 小助手在咨询中为员工推荐合适的专家,选择后将专家名片发送至聊天会话。
**业务规则:**
- 展示可推荐的专家列表,每位含头像、姓名、医院、科室职称、本月咨询数、擅长病种标签
- 选择专家后数据存入 sessionStorage返回聊天页后自动发送名片气泡
- 选择专家后返回聊天页后自动发送名片气泡
**交互说明:**
- 顶部搜索框支持按姓名/科室搜索
- 点击专家卡片选中并返回图文聊天页
- 顶部搜索框支持按姓名 / 科室搜索
- 点击专家卡片选中并返回图文聊天页
---
### 7. 知识库首页(knowledge/index.html
## 三、知识库模块
**功能说明:** 小助手查阅专业医学知识的参考库,与专家端知识库结构和内容一致。
### 9. 知识库首页(knowledge/index.html
![页面截图](screenshots/knowledge-index.jpg)
**功能说明:** 后续规划,暂时显示”开发中,敬请期待~”。
**业务规则:**
- 4个分类Tab:体检知识、药品知识、疾病知识、保健知识
- 共10条知识条目
**交互说明:**
- 切换分类Tab显示对应知识列表
- 点击知识条目跳转到知识详情
---
### 8. 知识详情(knowledge/detail.html
### 10. 知识详情(knowledge/detail.html
**功能说明:** 展示单条知识的完整内容,由URL参数动态渲染,与专家端内容一致。
![页面截图](screenshots/knowledge-detail.jpg)
**业务规则**
- 共支持9个知识条目的动态渲染
- 每条含概述段落和2-3个主要内容分项
**交互说明:**
- 返回按钮跳转到知识库首页
**功能说明** 后续规划,暂时显示”开发中,敬请期待~”。
---
### 9. 个人中心主页(profile/index.html
## 四、我的模块
### 11. 个人中心主页(profile/index.html
![页面截图](screenshots/profile-index.jpg)
**功能说明:** 小助手个人中心入口,展示用户信息和功能菜单。
**业务规则:**
- 蓝色渐变头部展示小助手头像、姓名、角色标签、所属机构
- 功能菜单分两组:第一组为咨询统计(显示今日完成次数),第二组为修改密码关于我们
- 底部提供退出登录按钮
- 蓝色渐变头部展示小助手头像、姓名、角色标签(咨询小助手)
- 功能菜单:个人信息设置、修改密码关于我们
- 底部提供红色退出登录按钮
**交互说明:**
- 点击"咨询统计"跳转到咨询统计
- 点击"修改密码"跳转到修改密码页
- 点击"退出登录"弹出确认弹窗,确认后退出
- 底部5Tab导航:工作台/知识库/AI助手/消息/我的
- 点击"个人信息设置":跳转到个人信息设置
- 点击"修改密码"跳转到修改密码页
- 点击"退出登录"弹出确认弹窗,确认后退出
---
### 10. 咨询统计profile/stats.html
### 12. 个人信息设置profile/edit-profile.html
**功能说明:** 展示小助手的咨询工作量统计数据。
![页面截图](screenshots/edit-profile.jpg)
**功能说明:** 小助手编辑个人基本信息,支持更换头像和修改姓名。
**业务规则:**
- 数据概览2×2网格:今日完成、本周完成、本月完成、累计完成
- 本月咨询类型仅图文咨询(小助手不支持视频咨询)
- 近7日完成量以柱状图展示,今日高亮
- 头像区支持点击更换(拍照 / 相册选择)
- 姓名输入框可编辑
**交互说明:**
- 返回按钮跳转到个人中心主页
- 点击头像:弹出底部弹窗选择拍照或从相册选择
- 点击"保存":显示 Toast 提示保存成功
- 返回按钮:跳转到个人中心主页
---
### 11. 修改密码(profile/change-pwd.html
### 13. 修改密码(profile/change-pwd.html
![页面截图](screenshots/change-pwd.jpg)
**功能说明:** 小助手修改登录密码。
**业务规则:**
- 表单包含当前密码、新密码(至少8位)、确认新密码三个字段
- 表单包含当前密码、新密码(至少 8 位)、确认新密码三个字段
- 修改成功后弹窗提示
**交互说明:**
- 点击"保存修改"弹出修改成功弹窗
- 弹窗点击"确定"跳转到个人中心主页
- 点击"保存修改"弹出修改成功弹窗
- 弹窗点击"确定"跳转到个人中心主页
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 当前密码 | password | 是 | - |
| 新密码 | password | 是 | 至少8位 |
| 确认新密码 | password | 是 | 与新密码一致 |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|-----------|
| 当前密码 | password | 是 | - |
| 新密码 | password | 是 | 跟当前系统规则一致 |
| 确认新密码 | password | 是 | 与新密码一致 |
---
## 共享模块说明
## 五、AI模块说明
以下模块为专家端和小助手端共用,通过 sessionStorage 的 `appRole` 标记区分当前端,动态设置底部导航栏的工作台返回目标。
### 12. AI 助手(../ai-assistant/index.html
### 14. AI 助手(../ai-assistant/index.html
**功能说明:** AI 智能助手,提供医学知识问答辅助
**功能说明:** 后续规划,暂时显示”开发中,敬请期待~”
**业务规则:**
- AI 回复为系统自动生成
- 底部 Tab 导航中"工作台"按钮根据 `appRole` 动态跳转到对应端的工作台
**交互说明:**
- 底部输入框输入问题,AI 自动回复
- 底部 Tab 导航切换到其他模块
---
### 13. 消息列表(../message/index.html
## 六、消息模块说明
### 15. 消息列表(../message/index.html
**功能说明:** 内部消息模块,展示与其他角色的消息列表。
@@ -261,13 +325,13 @@ stateDiagram-v2
- 每条消息显示联系人头像、姓名、角色标签、最后一条消息预览、时间
**交互说明:**
- 点击消息项跳转到 IM 聊天页
- 点击右上角通讯录图标跳转到通讯录页
- 点击消息项跳转到 IM 聊天页
- 点击右上角通讯录图标跳转到通讯录页
- 底部 Tab 导航切换到其他模块
---
### 14. 通讯录(../message/contacts.html
### 16. 通讯录(../message/contacts.html
**功能说明:** 展示系统内所有可联系的内部人员,支持按角色筛选和姓名搜索。
@@ -276,15 +340,17 @@ stateDiagram-v2
- 支持搜索和角色筛选
**交互说明:**
- 点击联系人跳转到 IM 聊天页
- 返回按钮跳转到消息列表
- 点击联系人跳转到 IM 聊天页
- 返回按钮跳转到消息列表
---
### 15. IM 聊天(../message/im-chat.html
### 17. IM 聊天(../message/im-chat.html
**功能说明:** 与内部人员的即时通讯聊天界面。
**交互说明:**
- 底部输入框输入文字并发送
- 返回按钮跳转到消息列表
- 返回按钮跳转到消息列表
@@ -0,0 +1,88 @@
/**
* 小助手端 APP 页面截图脚本
* 按规范:移除 phone-shell 高度限制、视口 390px、JPEG 85%
*/
import { chromium } from 'playwright';
import { fileURLToPath } from 'url';
import path from 'path';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const screenshotsDir = path.join(__dirname, 'screenshots');
// 小助手端所有页面
const pages = [
// 工作台
{ file: '../../assistant/workbench/index.html', name: 'index' },
{ file: '../../assistant/workbench/text-chat.html', name: 'text-chat' },
{ file: '../../assistant/workbench/text-chat-done.html', name: 'text-chat-done' },
{ file: '../../assistant/workbench/consult-done.html', name: 'consult-done' },
{ file: '../../assistant/workbench/text-consult-done.html', name: 'text-consult-done' },
{ file: '../../assistant/workbench/text-consult-timeout.html', name: 'text-consult-timeout' },
{ file: '../../assistant/workbench/employee-profile.html', name: 'employee-profile' },
{ file: '../../assistant/workbench/end-consult-dialog.html', name: 'end-consult-dialog' },
{ file: '../../assistant/workbench/push-expert.html', name: 'push-expert' },
// 知识库
{ file: '../../assistant/knowledge/index.html', name: 'knowledge-index' },
{ file: '../../assistant/knowledge/detail.html', name: 'knowledge-detail' },
// 个人中心
{ file: '../../assistant/profile/index.html', name: 'profile-index' },
{ file: '../../assistant/profile/edit-profile.html', name: 'edit-profile' },
{ file: '../../assistant/profile/change-pwd.html', name: 'change-pwd' },
];
(async () => {
const browser = await chromium.launch({
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
const context = await browser.newContext({ viewport: { width: 390, height: 844 } });
for (const p of pages) {
const page = await context.newPage();
const filePath = path.resolve(__dirname, p.file);
await page.goto(`file:///${filePath.replace(/\\/g, '/')}`, { waitUntil: 'networkidle' });
// 移除 phone-shell 高度限制、圆角、阴影;展开内容
await page.evaluate(() => {
const shell = document.querySelector('.phone-shell');
if (shell) {
shell.style.height = 'auto';
shell.style.borderRadius = '0';
shell.style.boxShadow = 'none';
shell.style.overflow = 'visible';
}
const content = document.querySelector('.page-content') || document.querySelector('.scroll-content');
if (content) {
content.style.overflow = 'visible';
content.style.maxHeight = 'none';
content.style.height = 'auto';
content.style.flex = 'none';
}
document.body.style.padding = '0';
document.body.style.minHeight = 'auto';
document.body.style.background = '#fff';
});
await page.waitForTimeout(300);
const height = await page.evaluate(() => {
const shell = document.querySelector('.phone-shell');
return shell ? shell.scrollHeight : document.body.scrollHeight;
});
await page.setViewportSize({ width: 390, height: Math.max(height, 200) });
const shell = await page.$('.phone-shell');
const target = shell || page;
await target.screenshot({
path: path.join(screenshotsDir, `${p.name}.jpg`),
type: 'jpeg',
quality: 85,
});
console.log(`${p.name}.jpg`);
await page.close();
}
await browser.close();
console.log(`\n完成!共截取 ${pages.length} 张截图`);
})();
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@@ -50,7 +50,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
</div>
<div style="display:flex;align-items:center;padding:14px 16px;border-bottom:1px solid #f5f5f5;">
<span style="font-size:14px;color:#999;width:80px;flex-shrink:0;">新密码</span>
<input type="password" placeholder="请输入新密码(至少8位)" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
<input type="password" placeholder="请输入新密码" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
</div>
<div style="display:flex;align-items:center;padding:14px 16px;">
<span style="font-size:14px;color:#999;width:80px;flex-shrink:0;">确认新密码</span>
-120
View File
@@ -1,120 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>咨询小助手 - 咨询统计 | 健康长庆原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<!-- [交互] 点击返回: ./index.html -->
<button class="back-btn" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">咨询统计</span>
</div>
<div class="scroll-content" style="padding:16px;">
<!-- 数据概览(2x2网格) -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:14px;">数据概览</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;">
<div style="background:#f0f7ff;border-radius:10px;padding:14px;text-align:center;">
<div style="font-size:26px;font-weight:700;color:#1677ff;">24</div>
<div style="font-size:12px;color:#666;margin-top:3px;">今日完成</div>
</div>
<div style="background:#f6ffed;border-radius:10px;padding:14px;text-align:center;">
<div style="font-size:26px;font-weight:700;color:#52c41a;">102</div>
<div style="font-size:12px;color:#666;margin-top:3px;">本周完成</div>
</div>
<div style="background:#fff7e6;border-radius:10px;padding:14px;text-align:center;">
<div style="font-size:26px;font-weight:700;color:#fa8c16;">436</div>
<div style="font-size:12px;color:#666;margin-top:3px;">本月完成</div>
</div>
<div style="background:#f9f0ff;border-radius:10px;padding:14px;text-align:center;">
<div style="font-size:26px;font-weight:700;color:#722ed1;">2,158</div>
<div style="font-size:12px;color:#666;margin-top:3px;">累计完成</div>
</div>
</div>
</div>
<!-- 本月咨询类型 -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:12px;">本月咨询类型</div>
<div style="display:flex;align-items:center;gap:10px;">
<span style="font-size:13px;color:#666;width:56px;flex-shrink:0;">图文咨询</span>
<div style="flex:1;height:10px;background:#f0f0f0;border-radius:5px;overflow:hidden;">
<div style="width:100%;height:100%;background:#1677ff;border-radius:5px;"></div>
</div>
<span style="font-size:13px;color:#1677ff;font-weight:600;width:36px;text-align:right;">436</span>
</div>
</div>
<!-- 近7日完成量柱状图 -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:12px;">近7日完成量</div>
<div style="display:flex;align-items:flex-end;justify-content:space-between;height:70px;gap:4px;">
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">18</div>
<div style="width:100%;height:45%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/4</div>
</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">22</div>
<div style="width:100%;height:55%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/5</div>
</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">30</div>
<div style="width:100%;height:75%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/6</div>
</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">15</div>
<div style="width:100%;height:38%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/7</div>
</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">28</div>
<div style="width:100%;height:70%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/8</div>
</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">20</div>
<div style="width:100%;height:50%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/9</div>
</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#1677ff;font-weight:600;">24</div>
<div style="width:100%;height:60%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#1677ff;font-weight:600;">今日</div>
</div>
</div>
</div>
<div style="height:16px;"></div>
</div>
</div>
</body>
</html>
@@ -1,119 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>咨询小助手 - 已完成咨询详情 | 健康长庆原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
.tag-gray { background: #f5f5f5; color: #999; }
.profile-collapsible { background: #fff; border-radius: 12px; margin-bottom: 12px; box-shadow: 0 1px 6px rgba(0,0,0,0.06); overflow: hidden; }
</style>
</head>
<body>
<div class="phone-shell">
<!-- 状态栏 -->
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<!-- [交互] 点击返回: ./index.html -->
<button class="back-btn" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">咨询详情</span>
</div>
<!-- 滚动内容 -->
<div class="scroll-content" style="padding:16px;">
<!-- 员工信息卡 -->
<div style="background:#fff;border-radius:16px;padding:20px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="display:flex;align-items:center;gap:14px;margin-bottom:16px;">
<div style="width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,#ffe0e0,#ffb3b3);display:flex;align-items:center;justify-content:center;font-size:28px;">👩</div>
<div>
<div style="font-size:17px;font-weight:700;color:#1a1a1a;">孙丽</div>
<div style="font-size:13px;color:#666;margin-top:2px;">行政部 · 行政专员</div>
</div>
<span class="tag tag-gray" style="margin-left:auto;">已完成</span>
</div>
<!-- 咨询信息 -->
<div style="background:#f7f8fa;border-radius:10px;padding:14px;">
<div style="font-size:13px;font-weight:600;color:#666;margin-bottom:10px;">📋 咨询信息</div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">咨询类型</span><span style="font-size:13px;color:#1a1a1a;">员工咨询</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">发起时间</span><span style="font-size:13px;color:#1a1a1a;">2026-04-08 14:10</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">完成时间</span><span style="font-size:13px;color:#1a1a1a;">2026-04-08 14:38</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;"><span style="font-size:13px;color:#999;">员工评分</span><span style="font-size:13px;color:#fa8c16;font-weight:600;">⭐⭐⭐⭐⭐ 5.0</span></div>
</div>
</div>
<!-- 员工评价 -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:8px;">员工评价</div>
<div style="font-size:13px;color:#666;line-height:1.6;background:#fffbe6;border-radius:8px;padding:12px;border-left:3px solid #faad14;">"小助手回复很及时,解答很专业,帮我解决了体检报告的疑问,非常感谢!"</div>
</div>
<!-- [交互] 点击跳转至: ./text-chat.html 查看历史对话记录 -->
<div onclick="location.href='./text-chat.html'" style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);display:flex;align-items:center;cursor:pointer;">
<span style="font-size:16px;margin-right:10px;">💬</span>
<span style="font-size:14px;color:#1a1a1a;flex:1;">查看历史对话记录</span>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<!-- 咨询人健康档案(可折叠) -->
<div class="profile-collapsible">
<!-- [交互] 点击展开/收起档案 -->
<div onclick="toggleProfile(this)" style="display:flex;justify-content:space-between;align-items:center;padding:14px 16px;cursor:pointer;">
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">📋 咨询人健康档案</span>
<span class="profile-arrow" style="font-size:12px;color:#999;transition:transform 0.2s;"></span>
</div>
<div class="profile-body" style="display:none;padding:0 16px 14px;">
<div style="font-size:12px;font-weight:600;color:#1677ff;margin:4px 0 6px;">基本信息</div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">姓名</span><span style="font-size:13px;color:#1a1a1a;">孙丽</span></div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">性别 / 年龄</span><span style="font-size:13px;color:#1a1a1a;">女 / 26岁</span></div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">身高 / 体重</span><span style="font-size:13px;color:#1a1a1a;">160 cm / 50 kg</span></div>
<div style="font-size:12px;font-weight:600;color:#52c41a;margin:10px 0 6px;">生活习惯</div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">吸烟</span><span style="font-size:13px;color:#1a1a1a;"></span></div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">饮酒</span><span style="font-size:13px;color:#1a1a1a;"></span></div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">饮食喜好</span><span style="font-size:13px;color:#1a1a1a;">清淡</span></div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">睡眠质量</span><span style="font-size:13px;color:#1a1a1a;">良好</span></div>
<div style="font-size:12px;font-weight:600;color:#fa8c16;margin:10px 0 6px;">身体情况</div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">过敏史</span><span style="font-size:13px;color:#1a1a1a;"></span></div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">遗传史</span><span style="font-size:13px;color:#1a1a1a;"></span></div>
<div style="display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid #f5f5f5;"><span style="font-size:13px;color:#999;">既往史</span><span style="font-size:13px;color:#1a1a1a;"></span></div>
<div style="display:flex;justify-content:space-between;padding:6px 0;"><span style="font-size:13px;color:#999;">其他疾病</span><span style="font-size:13px;color:#1a1a1a;"></span></div>
</div>
</div>
<div style="height:16px;"></div>
</div>
</div>
<script>
function toggleProfile(el) {
var card = el.closest('.profile-collapsible');
var body = card.querySelector('.profile-body');
var arrow = card.querySelector('.profile-arrow');
var isOpen = body.style.display !== 'none';
body.style.display = isOpen ? 'none' : 'block';
if (arrow) arrow.style.transform = isOpen ? '' : 'rotate(180deg)';
}
</script>
</body>
</html>
@@ -249,7 +249,12 @@ function goBack() {
'expert-chat': '../../expert/workbench/text-chat.html',
'expert-chat-done': '../../expert/workbench/text-chat-done.html',
'expert-consult-done': '../../expert/workbench/text-consult-done.html',
'expert-consult-timeout': '../../expert/workbench/text-consult-timeout.html'
'expert-consult-timeout': '../../expert/workbench/text-consult-timeout.html',
'expert-video-appt': '../../expert/workbench/video-appt.html',
'expert-video-ongoing': '../../expert/workbench/video-ongoing.html',
'expert-video-done': '../../expert/workbench/video-done.html',
'expert-video-cancelled': '../../expert/workbench/video-cancelled.html',
'expert-video-rejected': '../../expert/workbench/video-rejected.html'
};
location.href = backMap[from] || './text-chat.html';
}
@@ -60,7 +60,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<!-- 咨询信息 -->
<div style="background:#f7f8fa;border-radius:10px;padding:14px;">
<div style="font-size:13px;font-weight:600;color:#666;margin-bottom:10px;">📋 咨询信息</div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">咨询类型</span><span style="font-size:13px;color:#1a1a1a;">图文咨询</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">咨询对象</span><span style="font-size:13px;color:#1a1a1a;">咨询专家</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">发起时间</span><span style="font-size:13px;color:#1a1a1a;">2026-04-08 08:10</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">结束时间</span><span style="font-size:13px;color:#1a1a1a;">2026-04-08 08:40</span></div>
</div>
@@ -64,7 +64,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<!-- 咨询信息 -->
<div style="background:#f7f8fa;border-radius:10px;padding:14px;">
<div style="font-size:13px;font-weight:600;color:#666;margin-bottom:10px;">📋 咨询信息</div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">咨询类型</span><span style="font-size:13px;color:#1a1a1a;">图文咨询</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">咨询对象</span><span style="font-size:13px;color:#1a1a1a;">咨询小助手</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">咨询单号</span><span style="font-size:13px;color:#1a1a1a;">ZX202688552270</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">发起时间</span><span style="font-size:13px;color:#1a1a1a;">2026-04-06 14:20</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">结束时间</span><span style="font-size:13px;color:#1a1a1a;">2026-04-13 14:20</span></div>
+357 -209
View File
@@ -11,23 +11,30 @@
├── 工作台(底部Tab
│ ├── 工作台首页
│ │ ├── 图文咨询
│ │ │ ├── 待回复 → 图文聊天 → 员工档案
│ │ │ ├── 进行中 → 图文聊天
│ │ │ └── 已完成 → 咨询完成详情 → 历史对话
│ │ │ ├── 待回复 → 图文聊天(进行中)
│ │ │ ├── 进行中 → 图文聊天(进行中)
│ │ │ └── 已结束
│ │ │ ├── 已完成 → 图文咨询完成详情 → 历史对话(只读)→ 咨询人健康档案
│ │ │ └── 已超时 → 图文咨询已超时详情 → 历史对话(只读)→ 咨询人健康档案
│ │ └── 视频咨询
│ │ ├── 待确认 → 视频预约确认
│ │ ├── 进行中 → 视频进行中 → 视频通话
│ │ └── 已完成 → 视频完成详情
│ │ ├── 待确认 → 视频预约确认 → 咨询人健康档案
│ │ ├── 待开始 → 视频待开始详情 → 咨询人健康档案
│ │ └── 已结束
│ │ ├── 已完成 → 视频完成详情 → 咨询人健康档案
│ │ ├── 已取消 → 视频已取消详情 → 咨询人健康档案
│ │ └── 已拒绝 → 视频已拒绝详情 → 咨询人健康档案
├── 知识库(底部Tab
│ ├── 知识库首页(4分类Tab
│ └── 知识详情
├── AI助手(底部Tab,共享模块
├── 消息(底部Tab,共享模块
│ ├── 知识库首页(分为知识文章和规章制度
│ └── 知识详情/制度详情
├── AI助手(底部Tab
├── 消息(底部Tab
└── 我的(底部Tab
├── 个人中心
├── 咨询统计 → 全部评价
├── 咨询统计
├── 我的评价
├── 排班设置
├── 编辑资料
├── 个人信息设置
│ └── 擅长疾病选择
└── 修改密码
```
@@ -38,357 +45,498 @@ stateDiagram-v2
state "图文咨询" as TF {
[*] --> 待回复 : 员工发起
待回复 --> 进行中 : 专家首次回复
进行中 --> 已完成 : 任一方结束
进行中 --> 已完成 : 任一方主动结束
进行中 --> 已超时 : 7天无回复自动关闭
}
state "视频咨询" as VF {
[*] --> 待确认 : 员工预约
待确认 --> 已确认 : 专家接受
待确认 --> 已拒绝 : 专家拒绝
已确认 --> 通话中 : 发起视频
通话中 --> 已完成 : 挂断
待确认 --> 待开始 : 专家接受
待确认 --> 已拒绝 : 专家拒绝(填写原因)
待开始 --> 已取消 : 任一方取消预约
待开始 --> 已完成 : 完成通话
}
```
## 页面清单
| 序号 | 文件名 | 页面名称 | 所属模块 |
|------|--------|----------|----------|
| 1 | workbench/index.html | 工作台首页 | 工作台 |
| 2 | workbench/text-chat.html | 图文咨询 | 工作台 |
| 3 | workbench/text-consult-done.html | 咨询完成详情 | 工作台 |
| 4 | workbench/employee-profile.html | 员工健康档案 | 工作台 |
| 5 | workbench/consult-person-detail.html | 咨询人档案详情 | 工作台 |
| 6 | workbench/video-appt.html | 视频预约确认 | 工作台 |
| 7 | workbench/video-call.html | 视频通话 | 工作台 |
| 8 | workbench/video-done.html | 视频完成详情 | 工作台 |
| 9 | workbench/video-ongoing.html | 视频进行中 | 工作台 |
| 10 | knowledge/index.html | 知识库首页 | 知识库 |
| 11 | knowledge/detail.html | 知识详情 | 知识库 |
| 12 | ../ai-assistant/index.html | AI 助手(共享) | AI 助手 |
| 13 | ../message/index.html | 消息列表(共享) | 消息 |
| 14 | ../message/contacts.html | 通讯录(共享) | 消息 |
| 15 | ../message/im-chat.html | IM 聊天(共享) | 消息 |
| 16 | profile/index.html | 个人中心 | 我的 |
| 17 | profile/edit-profile.html | 编辑资料 | 我的 |
| 18 | profile/change-pwd.html | 修改密码 | 我的 |
| 19 | profile/schedule.html | 排班设置 | 我的 |
| 20 | profile/stats.html | 咨询统计 | 我的 |
| 21 | profile/reviews.html | 全部评价 | 我的 |
| 序号 | 文件名 | 页面名称 | 所属模块 |
|------|--------|-------------|-----------------|
| 1 | workbench/index.html | 工作台首页 | 工作台 |
| 2 | workbench/text-chat.html | 图文聊天 | 工作台·图文咨询 |
| 3 | workbench/text-chat-done.html | 历史对话(只读) | 工作台·图文咨询 |
| 4 | workbench/text-consult-done.html | 图文咨询完成详情 | 工作台·图文咨询 |
| 5 | workbench/text-consult-timeout.html | 图文咨询已超时详情 | 工作台·图文咨询 |
| 6 | workbench/video-appt.html | 视频预约确认 | 工作台·视频咨询 |
| 7 | workbench/video-ongoing.html | 视频待开始详情 | 工作台·视频咨询 |
| 8 | workbench/video-done.html | 视频完成详情 | 工作台·视频咨询 |
| 9 | workbench/video-cancelled.html | 视频已取消详情 | 工作台·视频咨询 |
| 10 | workbench/video-rejected.html | 视频已拒绝详情 | 工作台·视频咨询 |
| 11 | knowledge/index.html | 知识库首页 | 知识库 |
| 12 | knowledge/detail.html | 知识详情 | 知识库 |
| 13 | ../ai-assistant/index.html | AI 助手(共享) | AI 助手 |
| 14 | ../message/index.html | 消息列表(共享) | 消息 |
| 15 | ../message/contacts.html | 通讯录(共享) | 消息 |
| 16 | ../message/im-chat.html | IM 聊天(共享) | 消息 |
| 17 | profile/index.html | 个人中心 | 我的 |
| 18 | profile/stats.html | 咨询统计 | 我的 |
| 19 | profile/reviews.html | 我的评价 | 我的 |
| 20 | profile/schedule.html | 排班设置 | 我的 |
| 21 | profile/edit-profile.html | 个人信息设置 | 我的 |
| 22 | profile/edit-diseases.html | 擅长疾病选择 | 我的 |
| 23 | profile/change-pwd.html | 修改密码 | 我的 |
| 24 | ../assistant/workbench/employee-profile.html | 咨询人健康档案 | 工作台已结束图文/视频详情页面 |
## 逐页说明
---
## 一、工作台模块
### 1. 工作台首页(workbench/index.html
**功能说明:** 专家工作台入口,展示当前咨询任务队列,支持图文和视频两类咨询的分类管理。
![页面截图](screenshots/index.jpg)
**功能说明:** 专家工作台入口,展示当前咨询任务队列,支持图文和视频两类咨询的分类管理,右上角提供服务状态控制。
**业务规则:**
- 头部统计卡片展示:图文待回复数、视频待确认数、今日完成数、当前评分
- 服务状态支持"服务中/暂停服务"切换绿色/红色
- 图文咨询分三个子Tab:待回复、进行中、已完成
- 视频咨询分三个Tab:待确认、进行中、已完成
- 头部展示:图文待回复数、视频待确认数
- 服务状态按钮支持"咨询已开启 / 咨询已关闭"切换绿色/红色指示点区分状态
- 一级 Tab 切换图文咨询 / 视频咨询两个面板
- 图文咨询分三个二级 Tab:待回复、进行中、已结束(已完成、已超时)
- 视频咨询分三个二级 Tab:待确认、待开始、已结束(已完成、已拒绝、已取消)
- 底部 5 Tab 导航:工作台 / 知识库 / AI助手 / 消息 / 我的
**交互说明:**
- 一级Tab切换图文咨询/视频咨询
- 点击待回复/进行中咨询卡片跳转到图文聊天
- 点击已完成咨询卡片跳转到咨询完成详情
- 点击视频待确认卡片跳转到视频预约确认
- 点击视频进行中卡片跳转到视频进行中
- 底部5Tab导航:工作台/知识库/AI助手/消息/我的
- 点击服务状态按钮:弹出确认弹窗,确认后切换状态。
- 点击图文"待回复 / 进行中"咨询卡片跳转到图文聊天
- 点击图文"已完成"咨询卡片跳转到图文咨询完成详情
- 点击图文"已超时"咨询卡片跳转到图文咨询已超时详情页
- 点击视频"待确认"咨询卡片跳转到视频预约确认页
- 点击视频"待开始"咨询卡片:跳转到视频待开始详情页
- 点击视频"已完成"咨询卡片:跳转到视频完成详情页
- 点击视频"已取消"咨询卡片:跳转到视频已取消详情页
- 点击视频"已拒绝"咨询卡片:跳转到视频已拒绝详情页
---
### 2. 图文咨询(workbench/text-chat.html
## 二、图文咨询业务线
### 2. 图文聊天(workbench/text-chat.html
![页面截图](screenshots/text-chat.jpg)
**功能说明:** 专家与员工的实时图文对话界面,支持文字、语音、图片发送及常用语快捷填充。
**业务规则:**
- 聊天区分员工消息左侧白色气泡)和专家消息右侧蓝色气泡
- 支持文字、语音、图片三种消息类型
- 常用语面板提供 5 条预设快捷语
- 员工消息左侧白色气泡展示,专家消息右侧蓝色气泡展示
- 如果员工发起咨询时,选择了咨询人档案,则聊天消息为咨询人档案卡片(含姓名、性别/年龄、身高/体重、问题描述‘最多显示两行’、持续时间标签、检查图片‘最多显示三张’)
- 聊天对话支持显示文字、语音、图片、文件、自定义卡片(位置、咨询人档案、体检报告、已结束本次咨询)消息类型
- 常用语面板点击后可直接将常用语赋值到输入框中
- 媒体选择面板提供相册、拍照、文件、位置四个选项
**交互说明:**
- 点击"查看档案"跳转到员工健康档案
- 点击"结束咨询"弹出确认弹窗,确认后返回工作台首页
- 点击闪电图标展开/收起常用语面板
- 点击麦克风切换语音/文字输入模式
- 点击加号展开媒体选择面板(拍照/图库)
- 点击对话中的顶部咨询人档案卡片:跳转到咨询人健康档案
- 点击对话中的位置卡片,进入二级页面,加载高德地图,显示位置信息
- 点击对话中的体检报告卡片,进入二级页面,查看当前体检报告内容(参考体检模块)
- 点击对话中的文件,使用手机中的软件打开文件
- 点击对话中的语音,播放语音
- 点击右上角"结束咨询":弹出确认弹窗,确认后返回工作台首页,并且该对话发出一条“已结束本次咨询”的卡片消息。
- 点击"⚡"图标:展开 / 收起常用语面板,点击常用语自动填入输入框
- 点击"🎤"图标:切换语音 / 文字输入模式
- 点击"+"图标:展开 / 收起媒体选择面板,参考旧业务操作
- 点击发送按钮:将输入框内容发送为专家消息气泡
---
### 3. 咨询完成详情workbench/text-consult-done.html
### 3. 历史对话(只读)workbench/text-chat-done.html
**功能说明:** 展示已完结的图文咨询全部信息,包括咨询统计、员工评价及健康档案。
![页面截图](screenshots/text-chat-done.jpg)
**功能说明:** 展示已结束图文咨询的历史对话记录,为只读模式,无输入区,底部显示咨询结束说明。
**业务规则:**
- 展示咨询类型、发起/完成时间、员工评分
- 员工评价以黄色引用框展示
- 健康档案分基本信息、生活习惯、身体情况三组
- 布局与图文聊天页一致,但无导航栏右上角"结束咨询"按钮,无底部输入区
- 底部固定条显示咨询状态文案:
- 正常完成:「— 本次咨询已结束 —」
- 超时关闭:「— 长时间未回复系统已自动结束本次咨询 —」
**交互说明:**
- 点击"查看历史对话记录"跳转到图文聊天页(只读)
- 健康档案支持折叠/展开
- 返回按钮:跳转到工作台首页
- 对话内交互与图文聊天也面一致
---
### 4. 员工健康档案workbench/employee-profile.html
### 4. 图文咨询完成详情workbench/text-consult-done.html
**功能说明:** 展示咨询员工的完整健康档案,供专家参考。
![页面截图](screenshots/text-consult-done.jpg)
**功能说明:** 展示已完成图文咨询的摘要信息,提供查看历史对话和咨询人健康档案的入口。
**业务规则:**
- 分三组展示:基本信息(姓名、性别/年龄、身高/体重)、生活习惯(吸烟、饮酒、饮食、睡眠)、身体情况(过敏史、遗传史、既往史)
- 过敏史以红色高亮标记
- 顶部员工信息卡展示:头像、姓名、所属单位、"已完成"标签
- 咨询信息区展示:咨询类型、咨询单号、发起时间、结束时间
**交互说明:**
- 返回按钮跳转到图文聊天
- 点击"查看历史对话记录":跳转到历史对话(只读)
- 点击"咨询人健康档案":跳转到咨询人健康档案页
- 返回按钮:跳转到工作台首页
---
### 5. 咨询人档案详情(workbench/consult-person-detail.html
### 5. 图文咨询已超时详情(workbench/text-consult-timeout.html
**功能说明:** 展示咨询人的完整档案信息,包括个人基本信息、生活习惯、身体情况以及本次咨询的健康档案(问题描述、持续时间、检查资料、期望帮助)。
![页面截图](screenshots/text-consult-timeout.jpg)
**功能说明:** 展示因 7 天未回复被系统自动关闭的图文咨询详情,提示超时原因,并提供查看历史记录和健康档案的入口。
**业务规则:**
- 头部展示咨询人头像、姓名、性别/年龄、身高/体重
- 生活习惯以标签形式展示,绿色标签表示良好习惯,橙色标签表示需关注项
- 身体情况以网格布局展示过敏史、遗传史、既往史、其他疾病
- 本次咨询档案展示问题描述、持续时间标签、检查资料图片、期望帮助
- 顶部员工信息卡展示:头像、姓名、所属单位、"已超时"标签
- 咨询信息区展示:咨询类型、咨询单号、发起时间、结束时间
- 橙色警示卡片展示超时原因:「超过七天无回复,本次咨询已自动关闭。」
**交互说明:**
- 返回按钮跳转到上一页(图文聊天页或咨询完成详情页)
- 点击"查看历史对话记录":跳转到历史对话(只读)页
- 点击"咨询人健康档案":跳转到咨询人健康档案页
- 返回按钮:跳转到工作台首页
---
## 三、视频咨询业务线
### 6. 视频预约确认(workbench/video-appt.html
**功能说明:** 展示员工发起的视频咨询预约详情,专家可接受或拒绝。
![页面截图](screenshots/video-appt.jpg)
**功能说明:** 展示员工发起的视频咨询预约详情,专家可接受或拒绝预约。
**业务规则:**
- 预约信息展示预约时间、咨询类型、发起时间
- 附带咨询人健康档案和咨询说明
- 顶部员工信息展示:头像、姓名性别年龄、"待确认"标签
- 黄色预约信息卡展示:预约时间(高亮)、咨询类型、发起时间
- 提供咨询人健康档案入口(点击跳转)
- 底部双按钮:拒绝预约/ 接受预约
**交互说明:**
- 点击"接受预约"弹出确认弹窗,确认后返回工作台首页
- 点击"拒绝预约"拒绝该预约
- 健康档案支持折叠/展开
- 点击"接受预约"弹出确认弹窗,确认后返回工作台首页
- 点击"拒绝预约":弹出拒绝弹窗(含必填原因文本框),填写原因后确认,返回工作台首页
- 点击"咨询人健康档案":跳转到咨询人健康档案页
- 返回按钮:跳转到工作台首页
---
### 7. 视频通话workbench/video-call.html
### 7. 视频待开始详情workbench/video-ongoing.html
**功能说明:** 专家与员工进行视频通话的全屏界面。
![页面截图](screenshots/video-ongoing.jpg)
**功能说明:** 已确认但尚未开始通话的视频咨询详情,显示预约信息并提供发起通话和取消预约的入口。
**业务规则:**
- 全屏深色背景,显示远端画面区、通话时长计时器、本地小窗
- 底部三个控制按钮:麦克风、挂断、摄像头
- 顶部员工信息区展示:头像、姓名、部门职位、"待开始"标签
- 绿色预约信息卡展示:预约时间(高亮)、咨询类型、发起时间、接受时间
- 提供咨询人健康档案入口
- 咨询说明区提示:「请在预约时间内发起视频通话」
- 底部按钮:取消预约和发起视频通话
**交互说明:**
- 点击麦克风切换静音/取消静音
- 点击摄像头切换开关
- 点击挂断弹出确认弹窗,确认后返回工作台首页
- 点击"取消预约":弹出取消弹窗(含必填原因文本框),填写原因后确认,返回工作台首页
- 点击"咨询人健康档案":跳转到咨询人健康档案页
- 点击发起视频通话,打开IM视频通话拨打页面
- 返回按钮:跳转到工作台首页
---
### 8. 视频完成详情(workbench/video-done.html
**功能说明:** 展示已完结视频咨询的详情,包括通话时长、评分评价、健康档案。
![页面截图](screenshots/video-done.jpg)
**功能说明:** 展示已完成视频咨询的详情,包含通话信息和咨询人健康档案入口。
**业务规则:**
- 展示咨询时间段、通话时长、员工评分
- 附带员工评价和健康档案
- 顶部员工信息区展示:头像、姓名性别年龄、"已完成"标签
- 灰色信息卡展示:预约时间、咨询类型、拨打时间、通话时长
- 提供咨询人健康档案入口
**交互说明:**
- 健康档案支持折叠/展开
- 返回按钮跳转到工作台首页
- 点击"咨询人健康档案":跳转到咨询人健康档案页
- 返回按钮跳转到工作台首页
---
### 9. 视频进行中workbench/video-ongoing.html
### 9. 视频已取消详情workbench/video-cancelled.html
**功能说明:** 已确认但尚未开始通话的视频咨询详情,提供发起通话入口。
![页面截图](screenshots/video-cancelled.jpg)
**功能说明:** 展示因员工/专家主动取消而终止的视频咨询详情,包含取消信息和原因。
**业务规则:**
- 预约信息展示预约时间、咨询类型、状态为"已确认"
- 附带健康档案和咨询说明
- 顶部员工信息展示:头像、姓名性别年龄、"已取消"标签
- 灰色信息卡展示:预约时间、咨询类型、取消时间、取消方(员工/专家)
- 灰色左边框引用框展示取消原因
- 提供咨询人健康档案入口
**交互说明:**
- 点击"发起视频通话"跳转到视频通话
- 健康档案支持折叠/展开
- 点击"咨询人健康档案":跳转到咨询人健康档案
- 返回按钮:跳转到工作台首页
---
### 10. 知识库首页(knowledge/index.html
### 10. 视频已拒绝详情(workbench/video-rejected.html
**功能说明:** 专家查阅专业医学知识的参考库,按分类浏览条目列表。
![页面截图](screenshots/video-rejected.jpg)
**功能说明:** 展示专家主动拒绝的视频咨询预约详情,包含拒绝信息和原因。
**业务规则:**
- 4个分类Tab:体检知识、药品知识、疾病知识、保健知识
- 共10条知识条目,每条含图标、标题、摘要
- 顶部员工信息区展示:头像、姓名性别年龄、"已拒绝"红色标签
- 灰色信息卡展示:预约时间、咨询类型、拒绝时间、拒绝方(专家)
- 红色左边框引用框展示专家填写的拒绝原因
- 提供咨询人健康档案入口
**交互说明:**
- 切换分类Tab显示对应知识列表
- 点击知识条目跳转到知识详情(带key参数)
- 点击"咨询人健康档案":跳转到咨询人健康档案页
- 返回按钮:跳转到工作台首页
---
### 11. 知识详情(knowledge/detail.html
## 四、知识库模块
**功能说明:** 展示单条知识的完整内容,由URL参数动态渲染。
### 11. 知识库首页(knowledge/index.html
**业务规则:**
- 共支持9个知识条目的动态渲染
- 每条含概述段落和2-3个主要内容分项
![页面截图](screenshots/knowledge-index.jpg)
**交互说明:**
- 返回按钮跳转到知识库首页
**功能说明:** 等后续“知识普及”模块规划,暂时不做,先显示“开发中,敬请期待~”
---
### 12. AI 助手(共享模块:../ai-assistant/index.html
### 12. 知识详情(knowledge/detail.html
**功能说明:** 专家端和小助手端共用的 AI 智能助手,提供医学知识问答辅助。
![页面截图](screenshots/knowledge-detail.jpg)
**业务规则**
- 通过 sessionStorage 的 `appRole` 标记区分当前端,动态设置底部导航栏的工作台返回目标
- AI 回复为系统自动生成
**交互说明:**
- 底部输入框输入问题,AI 自动回复
- 底部 Tab 导航切换到其他模块
**功能说明** 等后续“知识普及”模块规划
---
### 13. 消息列表(共享模块:../message/index.html
## 五、我的模块
**功能说明:** 专家端和小助手端共用的内部消息模块,展示与其他角色的消息列表。
### 13. 个人中心(profile/index.html
**业务规则:**
- 通过 sessionStorage 的 `appRole` 标记区分当前端
- 消息列表按最新消息时间倒序排列
- 每条消息显示联系人头像、姓名、角色标签、最后一条消息预览、时间
**交互说明:**
- 点击消息项跳转到 IM 聊天页
- 点击右上角通讯录图标跳转到通讯录页
- 底部 Tab 导航切换到其他模块
---
### 14. 通讯录(共享模块:../message/contacts.html
**功能说明:** 展示系统内所有可联系的内部人员,支持按角色筛选和姓名搜索。
**业务规则:**
- 人员按角色分类展示
- 支持搜索和角色筛选
**交互说明:**
- 点击联系人跳转到 IM 聊天页
- 返回按钮跳转到消息列表
---
### 15. IM 聊天(共享模块:../message/im-chat.html
**功能说明:** 与内部人员的即时通讯聊天界面。
**交互说明:**
- 底部输入框输入文字并发送
- 返回按钮跳转到消息列表
---
### 16. 个人中心(profile/index.html
![页面截图](screenshots/profile-index.jpg)
**功能说明:** 专家个人信息中心,展示基础信息及功能入口列表。
**业务规则:**
- 头部展示头像、姓名、科室职称、医院
- 服务状态支持在线/暂停切换
- 功能列表:咨询统计、排班设置、个人信息设置、修改密码、关于我们
- 头部展示头像、姓名、科室职称、所属医院
- 服务状态按钮支持"咨询已开启 / 咨询已关闭"切换(与工作台首页状态联动)
- 功能列表分两组
- 第一组:咨询统计(附今日次数)、我的评价(附综合评分)、排班设置、个人信息设置
- 第二组:修改密码、关于我们
- 底部"退出登录"红色按钮
**交互说明:**
- 点击各功能项跳转到对应页面
- 点击"退出登录"弹出确认弹窗
- 点击"咨询统计":跳转到咨询统计页
- 点击"我的评价":跳转到全部评价页
- 点击"排班设置":跳转到排班设置页
- 点击"个人信息设置":跳转到个人信息设置页
- 点击"修改密码":跳转到修改密码页
- 点击服务状态按钮:弹出确认弹窗,确认后切换状态
- 点击"退出登录":弹出确认弹窗
---
### 17. 编辑资料profile/edit-profile.html
### 14. 咨询统计profile/stats.html
![页面截图](screenshots/stats.jpg)
**功能说明:** 展示专家的多维度咨询数据统计,含月度收益、咨询类型分布和月度趋势折线图。
**业务规则:**
- 月份切换器支持前后月份翻页
- 收益概览展示:已结算收益(绿色)、未结算收益(橙色)
- 咨询类型分布:环形图 + 图例,展示图文/视频咨询次数和占比,以及进行中/已完成拆分
- 月度趋势:折线图,展示当月每日咨询量,今日数据点高亮蓝色,点击数据点弹出详情悬浮卡
**交互说明:**
- 点击"‹ / ›"翻月按钮:切换统计月份
- 点击折线图数据点:在数据点上方弹出悬浮卡,展示当日图文/视频咨询分类数据,点击悬浮卡以外区域:关闭悬浮卡
- 返回按钮:跳转到个人中心
---
### 15. 全部评价(profile/reviews.html
![页面截图](screenshots/reviews.jpg)
**功能说明:** 展示员工对专家的历史评价列表,含综合评分汇总。
**业务规则:**
- 固定头部展示综合评分:大字显示分值(如 4.9)、星级、评价总数
- 右侧星级分布条形图展示 1–5 星各占比
- 评价列表每条含:员工头像(部分匿名)、姓名、评价时间、星级、评价正文
**交互说明:**
- 返回按钮:跳转到咨询统计页
---
### 16. 排班设置(profile/schedule.html
![页面截图](screenshots/schedule.jpg)
**功能说明:** 专家自主设置每周固定排班计划,按星期配置各时段的开诊状态和接诊人数上限。
**业务规则:**
- 顶部"开启视频咨询"总开关,控制是否接受视频咨询预约,开启时显示绿色状态文案
- 每周排班以卡片列表展示(周一~周日),每天一个可折叠卡片
- 卡片折叠状态显示:星期名称 + 开诊时段数摘要(如"4个时段开诊"或"休息"
- 每天分 4 个时段:上午 8:0010:00、上午 10:0012:00、下午 14:0016:00、下午 16:0018:00
- 每个时段独立设置:开诊开关 + 接诊人数(±调节,范围 1–20 人)
- 关闭时段时人数显示"—"且不可编辑
- 默认排班:周一~周五开诊(上午5人、下午4人),周六日休息
- 默认展开周一卡片,其余折叠
- 导航栏右侧"保存"按钮提交排班配置
**交互说明:**
- 点击视频咨询开关:切换开启/关闭状态,文案同步更新
- 点击卡片头部:展开/折叠该天的时段设置
- 点击时段开关:切换该时段开诊/关闭状态
- 点击"−"按钮:人数减 1(最小为 1)
- 点击"+"按钮:人数加 1(最大为 20)
- 点击"保存":提交排班配置
- 返回按钮:跳转到个人中心
---
### 17. 个人信息设置(profile/edit-profile.html
![页面截图](screenshots/edit-profile.jpg)
**功能说明:** 专家编辑个人基本资料、擅长病种和个人简介。
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 头像 | 图片上传 | 否 | 点击相机角标更换 |
| 姓名 | 文本输入 | 是 | - |
| 所属医院 | 文本输入 | 是 | - |
| 科室 | 文本输入 | 是 | - |
| 职称 | 文本输入 | 是 | - |
| 执业年限 | 文本输入 | | - |
| 擅长病种 | 多选标签 | 否 | 10个可选标签,点击切换选中 |
| 个人简介 | 多行文本 | 否 | 最多200字 |
| 个人擅长 | 多行文本 | 否 | 最多300字 |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------------|------|----------------------|
| 头像 | 图片上传 | 否 | 点击相机角标更换 ,支持拍照和图库 |
| 姓名 | 文本输入 | 是 | — |
| 所属医院 | 选择 | 是 | — |
| 科室 | 选择 | 是 | — |
| 职称 | 选择 | 是 | — |
| 擅长疾病 | 标签选择(跳转子页) | | 已选标签只读展示,点击跳转擅长疾病选择页 |
| 个人简介 | 多行文本 | 否 | 最多 300 字 |
| 职业经历 | 多行文本 | 否 | 最多 300 字 |
**交互说明:**
- 点击头像区相机角标:弹出底部弹窗,支持拍照和图库,进行更换头像
- 点击"擅长疾病"区域:跳转到擅长疾病选择页
- 点击导航栏"保存":提交编辑结果
- 返回按钮:跳转到个人中心
---
### 18. 修改密码profile/change-pwd.html
### 18. 擅长疾病选择profile/edit-diseases.html
![页面截图](screenshots/edit-diseases.jpg)
**功能说明:** 专家从按科室分类的疾病标签库中多选擅长病种,保存后同步回个人信息设置页。
**业务规则:**
- 顶部蓝色提示条展示已选数量(实时更新)
- 疾病按科室分类展示:心内科、内分泌科、神经内科、精神心理科、骨科/康复科等
- 每个科室分类支持折叠 / 展开,默认第一个科室展开
- 已选标签显示蓝色填充,未选标签显示灰色背景
**交互说明:**
- 点击科室分类标题:折叠 / 展开该科室疾病标签列表
- 点击疾病标签:切换选中 / 未选中状态,顶部已选数量同步更新
- 点击导航栏"保存":保存已选病种并返回个人信息设置页
- 返回按钮:跳转到个人信息设置页
---
### 19. 修改密码(profile/change-pwd.html
![页面截图](screenshots/change-pwd.jpg)
**功能说明:** 专家修改登录密码。
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 当前密码 | 密码输入 | 是 | - |
| 新密码 | 密码输入 | 是 | 至少8位 |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|---------|
| 当前密码 | 密码输入 | 是 | |
| 新密码 | 密码输入 | 是 | 按系统目前规则 |
| 确认新密码 | 密码输入 | 是 | 须与新密码一致 |
**交互说明:**
- 点击"保存修改"弹出成功提示,确认后返回个人中心
- 点击"保存修改"弹出"修改成功"提示弹窗
- 弹窗点击"确定":跳转到个人中心
- 返回按钮:跳转到个人中心
---
### 19. 排班设置(profile/schedule.html
## 六、AI助手模块
**功能说明:** 专家自主设置接诊日期和时段的接诊人数上限。
### 20. AI 助手(../ai-assistant/index.html
![页面截图](screenshots/ai-assistant.jpg)
**功能说明:** 后续规划,暂时显示”开发中,敬请期待~”。
---
## 七、消息模块
### 21. 消息列表(../message/index.html
![页面截图](screenshots/message-index.jpg)
**功能说明:** 内部消息模块,与当前系统中”咨询专家”、”咨询小助手”、”操作人员”、”专业人员”、”驻场人员”、”健康管理员”进行对话聊天的消息列表。
**业务规则:**
- 月历选择排班日期,已选日期显示蓝色圆形背景
- 时段分上午(09:00-12:00)和下午(14:00-17:00
- 接诊人数支持加减调节,范围1-10人
- 消息列表按最新消息时间倒序排列
- 每条消息显示联系人头像、姓名、角色标签、最后一条消息预览、时间
**交互说明:**
- 点击日期格子切换选中/未选中
- 点击加减按钮调整接诊人数
- 支持前后月份翻页
- 点击消息项:跳转到 IM 聊天页
- 点击右上角通讯录图标:跳转到通讯录页
- 底部 Tab 导航切换到其他模块
---
### 20. 咨询统计(profile/stats.html
### 22. 通讯录(../message/contacts.html
**功能说明:** 展示专家的多维度咨询数据统计。
![页面截图](screenshots/message-contacts.jpg)
**业务规则**
- 数据概览:今日完成、本周完成、本月完成、累计完成
- 本月咨询类型分布:图文/视频占比
- 近7日完成量柱状图
- 综合评分卡:评分、星级、评价数、1-5星分布
**功能说明** 展示系统内所有可联系的内部人员,支持按角色筛选和姓名搜索。
**交互说明:**
- 点击"查看全部评价"跳转到全部评价
- 点击联系人:跳转到 IM 聊天
- 输入名称进行模糊搜索
- 角色分类可收起展开
- 返回按钮:跳转到消息列表
---
### 21. 全部评价(profile/reviews.html
### 23. IM 聊天(../message/im-chat.html
**功能说明:** 展示员工对专家的历史评价列表。
![页面截图](screenshots/message-im-chat.jpg)
**业务规则**
- 顶部统计:评价总数、综合评分
- 评价卡片含:员工头像(脱敏)、姓名、咨询类型标签、时间、星级、评价正文
**功能说明** 与内部人员的即时通讯聊天界面。
**交互说明:**
- 返回按钮跳转到咨询统计页
- 底部输入框输入文字并发送
- 支持语音和输入切换
- 支持拍照和发送图库照片
- 返回按钮:跳转到消息列表
---
## 八、咨询详情共用模块
### 24. 咨询人健康档案(../assistant/workbench/employee-profile.html
![页面截图](screenshots/employee-profile.jpg)
**功能说明:** 展示咨询人的完整健康档案和本次咨询档案,由专家端和小助手端共用。专家端通过图文聊天、各类咨询详情页的"咨询人健康档案"入口跳转至此页面。
**业务规则:**
- 基本信息区展示:姓名、与本人关系、性别、年龄、身高、体重
- 生活习惯区以标签展示:吸烟、饮酒、饮食、睡眠
- 身体情况区展示:过敏史、遗传史、既往史、其他疾病(红色高亮)
- 本次咨询档案区展示:问题描述、持续时间标签、检查资料图片、就诊经历(医院/科室/疾病名称)、期望帮助
+101
View File
@@ -0,0 +1,101 @@
/**
* 专家端 APP 页面截图脚本
* 按规范:移除 phone-shell 高度限制、视口 390px、JPEG 85%
*/
import { chromium } from 'playwright';
import { fileURLToPath } from 'url';
import path from 'path';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const screenshotsDir = path.join(__dirname, 'screenshots');
// 专家端所有页面
const pages = [
// 工作台
{ file: '../../expert/workbench/index.html', name: 'index' },
{ file: '../../expert/workbench/text-chat.html', name: 'text-chat' },
{ file: '../../expert/workbench/text-chat-done.html', name: 'text-chat-done' },
{ file: '../../expert/workbench/text-consult-done.html', name: 'text-consult-done' },
{ file: '../../expert/workbench/text-consult-timeout.html', name: 'text-consult-timeout' },
{ file: '../../expert/workbench/video-appt.html', name: 'video-appt' },
{ file: '../../expert/workbench/video-ongoing.html', name: 'video-ongoing' },
{ file: '../../expert/workbench/video-done.html', name: 'video-done' },
{ file: '../../expert/workbench/video-cancelled.html', name: 'video-cancelled' },
{ file: '../../expert/workbench/video-rejected.html', name: 'video-rejected' },
// 知识库
{ file: '../../expert/knowledge/index.html', name: 'knowledge-index' },
{ file: '../../expert/knowledge/detail.html', name: 'knowledge-detail' },
// 个人中心
{ file: '../../expert/profile/index.html', name: 'profile-index' },
{ file: '../../expert/profile/edit-profile.html', name: 'edit-profile' },
{ file: '../../expert/profile/edit-diseases.html', name: 'edit-diseases' },
{ file: '../../expert/profile/schedule.html', name: 'schedule' },
{ file: '../../expert/profile/stats.html', name: 'stats' },
{ file: '../../expert/profile/reviews.html', name: 'reviews' },
{ file: '../../expert/profile/change-pwd.html', name: 'change-pwd' },
// 共享模块
{ file: '../../ai-assistant/index.html', name: 'ai-assistant' },
{ file: '../../message/index.html', name: 'message-index' },
{ file: '../../message/contacts.html', name: 'message-contacts' },
{ file: '../../message/im-chat.html', name: 'message-im-chat' },
];
(async () => {
const browser = await chromium.launch({
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
const context = await browser.newContext({ viewport: { width: 390, height: 844 } });
for (const p of pages) {
const page = await context.newPage();
const filePath = path.resolve(__dirname, p.file);
await page.goto(`file:///${filePath.replace(/\\/g, '/')}`, { waitUntil: 'networkidle' });
// 移除 phone-shell 高度限制、圆角、阴影;展开内容
await page.evaluate(() => {
const shell = document.querySelector('.phone-shell');
if (shell) {
shell.style.height = 'auto';
shell.style.borderRadius = '0';
shell.style.boxShadow = 'none';
shell.style.overflow = 'visible';
}
const content = document.querySelector('.page-content') || document.querySelector('.scroll-content');
if (content) {
content.style.overflow = 'visible';
content.style.maxHeight = 'none';
content.style.height = 'auto';
content.style.flex = 'none';
}
document.body.style.padding = '0';
document.body.style.minHeight = 'auto';
document.body.style.background = '#fff';
});
// 等待渲染
await page.waitForTimeout(300);
// 获取 phone-shell 实际高度,调整视口
const height = await page.evaluate(() => {
const shell = document.querySelector('.phone-shell');
return shell ? shell.scrollHeight : document.body.scrollHeight;
});
await page.setViewportSize({ width: 390, height: Math.max(height, 200) });
// 截取 phone-shell 元素
const shell = await page.$('.phone-shell');
const target = shell || page;
await target.screenshot({
path: path.join(screenshotsDir, `${p.name}.jpg`),
type: 'jpeg',
quality: 85,
});
console.log(`${p.name}.jpg`);
await page.close();
}
await browser.close();
console.log(`\n完成!共截取 ${pages.length} 张截图`);
})();
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

+99 -10
View File
@@ -31,6 +31,27 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
.tab-item .tab-label { font-size: 10px; color: #999; font-weight: 500; }
.tab-item.active .tab-label { color: #1677ff; }
.tab-badge { position: absolute; top: 2px; right: 18px; background: #ff4d4f; color: #fff; font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 0 4px; }
/* ========== 子分类Tab ========== */
.sub-tabs { display: flex; gap: 8px; padding: 10px 16px; background: #fff; flex-shrink: 0; }
.sub-tab {
font-size: 12px; padding: 4px 14px; border-radius: 16px;
background: #f5f5f5; color: #666; cursor: pointer; transition: all 0.2s;
}
.sub-tab.active { background: #e6f4ff; color: #1677ff; font-weight: 600; }
/* ========== PDF文档条目 ========== */
.pdf-item {
background: #fff; border-radius: 10px; padding: 12px 14px;
display: flex; align-items: center; gap: 10px;
box-shadow: 0 1px 4px rgba(0,0,0,0.06); margin-bottom: 10px; cursor: pointer;
}
.pdf-item__icon {
width: 44px; height: 44px; border-radius: 10px; background: #fff1f0;
display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.pdf-item__info { flex: 1; }
.pdf-item__name { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.pdf-item__meta { font-size: 12px; color: #999; margin-top: 3px; display: flex; gap: 8px; }
</style>
</head>
<body>
@@ -48,14 +69,22 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div style="color:#fff;font-size:20px;font-weight:700;">知识库</div>
</div>
<!-- 分类Tab -->
<div class="seg-tabs" style="background:#fff;">
<div class="seg-tab active" onclick="switchKbTab(this,'kb-exam')">体检知识</div>
<div class="seg-tab" onclick="switchKbTab(this,'kb-drug')">药品知识</div>
<div class="seg-tab" onclick="switchKbTab(this,'kb-disease')">疾病知识</div>
<div class="seg-tab" onclick="switchKbTab(this,'kb-health')">保健知识</div>
<!-- 一级分类Tab -->
<div class="seg-tabs">
<div class="seg-tab active" onclick="switchTopTab(this,'panel-article')">知识文章</div>
<div class="seg-tab" onclick="switchTopTab(this,'panel-rule')">规章制度</div>
</div>
<!-- 知识文章面板 -->
<div id="panel-article" style="flex:1;display:flex;flex-direction:column;overflow:hidden;">
<!-- 子分类Tab -->
<div class="sub-tabs">
<div class="sub-tab active" onclick="switchKbTab(this,'kb-exam')">体检知识</div>
<div class="sub-tab" onclick="switchKbTab(this,'kb-drug')">药品知识</div>
<div class="sub-tab" onclick="switchKbTab(this,'kb-disease')">疾病知识</div>
<div class="sub-tab" onclick="switchKbTab(this,'kb-health')">保健知识</div>
</div>
<!-- 知识条目列表 -->
<div class="scroll-content">
<!-- 体检知识 -->
@@ -146,6 +175,54 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div style="height:16px;"></div>
</div>
</div>
</div><!-- /panel-article -->
<!-- 规章制度面板 -->
<div id="panel-rule" style="display:none;flex:1;overflow-y:auto;background:#f7f8fa;">
<div style="padding:12px 16px 0;">
<div class="pdf-item">
<div class="pdf-item__icon"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M6 2h9l5 5v15H6a2 2 0 01-2-2V4a2 2 0 012-2z" fill="#ff4d4f" opacity="0.15" stroke="#ff4d4f" stroke-width="1.5"/><path d="M15 2v5h5" stroke="#ff4d4f" stroke-width="1.5"/><text x="8" y="17" font-size="7" font-weight="700" fill="#ff4d4f">PDF</text></svg></div>
<div class="pdf-item__info">
<div class="pdf-item__name">员工健康管理办法(2026版)</div>
<div class="pdf-item__meta"><span>PDF · 2.3MB</span><span>2026-01-15</span></div>
</div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div class="pdf-item">
<div class="pdf-item__icon"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M6 2h9l5 5v15H6a2 2 0 01-2-2V4a2 2 0 012-2z" fill="#ff4d4f" opacity="0.15" stroke="#ff4d4f" stroke-width="1.5"/><path d="M15 2v5h5" stroke="#ff4d4f" stroke-width="1.5"/><text x="8" y="17" font-size="7" font-weight="700" fill="#ff4d4f">PDF</text></svg></div>
<div class="pdf-item__info">
<div class="pdf-item__name">职业病防治管理规定</div>
<div class="pdf-item__meta"><span>PDF · 1.8MB</span><span>2025-12-20</span></div>
</div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div class="pdf-item">
<div class="pdf-item__icon"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M6 2h9l5 5v15H6a2 2 0 01-2-2V4a2 2 0 012-2z" fill="#ff4d4f" opacity="0.15" stroke="#ff4d4f" stroke-width="1.5"/><path d="M15 2v5h5" stroke="#ff4d4f" stroke-width="1.5"/><text x="8" y="17" font-size="7" font-weight="700" fill="#ff4d4f">PDF</text></svg></div>
<div class="pdf-item__info">
<div class="pdf-item__name">体检异常结果处置流程</div>
<div class="pdf-item__meta"><span>PDF · 0.9MB</span><span>2025-11-08</span></div>
</div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div class="pdf-item">
<div class="pdf-item__icon"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M6 2h9l5 5v15H6a2 2 0 01-2-2V4a2 2 0 012-2z" fill="#ff4d4f" opacity="0.15" stroke="#ff4d4f" stroke-width="1.5"/><path d="M15 2v5h5" stroke="#ff4d4f" stroke-width="1.5"/><text x="8" y="17" font-size="7" font-weight="700" fill="#ff4d4f">PDF</text></svg></div>
<div class="pdf-item__info">
<div class="pdf-item__name">健康咨询服务管理细则</div>
<div class="pdf-item__meta"><span>PDF · 1.5MB</span><span>2025-10-22</span></div>
</div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div class="pdf-item">
<div class="pdf-item__icon"><svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M6 2h9l5 5v15H6a2 2 0 01-2-2V4a2 2 0 012-2z" fill="#ff4d4f" opacity="0.15" stroke="#ff4d4f" stroke-width="1.5"/><path d="M15 2v5h5" stroke="#ff4d4f" stroke-width="1.5"/><text x="8" y="17" font-size="7" font-weight="700" fill="#ff4d4f">PDF</text></svg></div>
<div class="pdf-item__info">
<div class="pdf-item__name">应急救护操作规范</div>
<div class="pdf-item__meta"><span>PDF · 3.1MB</span><span>2025-09-15</span></div>
</div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 底部Tab栏 -->
<div class="tab-bar">
@@ -178,19 +255,31 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
/* 标记当前角色为专家 */
sessionStorage.setItem('appRole', 'expert');
/**
* 切换一级Tab(知识文章 / 规章制度)
*/
function switchTopTab(el, panelId) {
el.closest('.seg-tabs').querySelectorAll('.seg-tab').forEach(function(t) {
t.classList.remove('active');
});
el.classList.add('active');
var displayMap = { 'panel-article': 'flex', 'panel-rule': 'block' };
['panel-article', 'panel-rule'].forEach(function(id) {
var p = document.getElementById(id);
if (p) p.style.display = id === panelId ? displayMap[id] : 'none';
});
}
/**
* 切换知识库分类Tab
* @param {HTMLElement} el - 被点击的Tab元素
* @param {string} panelId - 对应面板的ID
*/
function switchKbTab(el, panelId) {
// 移除所有Tab的选中状态
el.closest('.seg-tabs').querySelectorAll('.seg-tab').forEach(function(t) {
el.closest('.sub-tabs').querySelectorAll('.sub-tab').forEach(function(t) {
t.classList.remove('active');
});
// 设置当前Tab为选中
el.classList.add('active');
// 切换面板显示
['kb-exam', 'kb-drug', 'kb-disease', 'kb-health'].forEach(function(id) {
var p = document.getElementById(id);
if (p) p.style.display = id === panelId ? 'block' : 'none';
+1 -1
View File
@@ -59,7 +59,7 @@
<!-- 新密码 -->
<div style="display:flex;align-items:center;padding:14px 16px;border-bottom:1px solid #f5f5f5;">
<span style="font-size:14px;color:#999;width:80px;flex-shrink:0;">新密码</span>
<input type="password" placeholder="请输入新密码(至少8位)" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
<input type="password" placeholder="请输入新密码" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
</div>
<!-- 确认新密码 -->
<div style="display:flex;align-items:center;padding:14px 16px;">
@@ -0,0 +1,206 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>擅长疾病 - 个人信息设置 | 健康长庆原型</title>
<style>
/* 公共重置与手机壳样式 */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.nav-right { margin-left: auto; color: #1677ff; font-size: 14px; cursor: pointer; background: none; border: none; font-weight: 500; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 已选提示 */
.selected-hint { padding: 12px 16px; background: #e6f7ff; border-bottom: 1px solid #bae7ff; font-size: 13px; color: #0958d9; display: flex; align-items: center; gap: 6px; }
.selected-hint svg { flex-shrink: 0; }
/* 科室分类 */
.category { margin-bottom: 12px; }
.category-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; background: #fff; cursor: pointer; user-select: none; }
.category-header:active { background: #f5f5f5; }
.category-title { font-size: 15px; font-weight: 600; color: #1a1a1a; display: flex; align-items: center; gap: 8px; }
.category-arrow { width: 14px; height: 14px; transition: transform 0.2s; }
.category-arrow.expanded { transform: rotate(90deg); }
.category-content { display: none; padding: 12px 16px; background: #fff; border-top: 1px solid #f5f5f5; }
.category-content.show { display: block; }
.disease-tags { display: flex; flex-wrap: wrap; gap: 8px; }
.disease-tag { padding: 6px 14px; border-radius: 16px; font-size: 13px; cursor: pointer; transition: all 0.2s; user-select: none; }
.disease-tag.selected { background: #1677ff; color: #fff; border: 1px solid #1677ff; }
.disease-tag:not(.selected) { background: #f5f5f5; color: #666; border: 1px solid #e8e8e8; }
.disease-tag:active { transform: scale(0.95); }
</style>
</head>
<body>
<div class="phone-shell">
<!-- 状态栏 -->
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<!-- [交互] 点击返回: ./edit-profile.html -->
<button class="back-btn" onclick="location.href='./edit-profile.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">擅长疾病</span>
<!-- [交互] 点击保存并返回 -->
<button class="nav-right" onclick="saveAndReturn()">保存</button>
</div>
<!-- 已选提示 -->
<div class="selected-hint">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><circle cx="8" cy="8" r="7" fill="#1677ff"/><path d="M6 8l2 2 4-4" stroke="#fff" stroke-width="1.5" fill="none"/></svg>
<span>已选 <strong id="selected-count">3</strong></span>
</div>
<!-- 内容区域 -->
<div class="scroll-content" style="padding:12px 16px;">
<!-- 心内科 -->
<div class="category">
<div class="category-header" onclick="toggleCategory(this)">
<div class="category-title">
<svg class="category-arrow expanded" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="#666" stroke-width="2"><path d="M3 5l4 4 4-4"/></svg>
心内科
</div>
</div>
<div class="category-content show">
<div class="disease-tags">
<div class="disease-tag selected" onclick="toggleTag(this)">高血压</div>
<div class="disease-tag selected" onclick="toggleTag(this)">冠心病</div>
<div class="disease-tag selected" onclick="toggleTag(this)">心律失常</div>
<div class="disease-tag" onclick="toggleTag(this)">心力衰竭</div>
<div class="disease-tag" onclick="toggleTag(this)">心肌病</div>
<div class="disease-tag" onclick="toggleTag(this)">心绞痛</div>
</div>
</div>
</div>
<!-- 内分泌科 -->
<div class="category">
<div class="category-header" onclick="toggleCategory(this)">
<div class="category-title">
<svg class="category-arrow" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="#666" stroke-width="2"><path d="M3 5l4 4 4-4"/></svg>
内分泌科
</div>
</div>
<div class="category-content">
<div class="disease-tags">
<div class="disease-tag" onclick="toggleTag(this)">糖尿病</div>
<div class="disease-tag" onclick="toggleTag(this)">高脂血症</div>
<div class="disease-tag" onclick="toggleTag(this)">甲状腺疾病</div>
<div class="disease-tag" onclick="toggleTag(this)">痛风</div>
<div class="disease-tag" onclick="toggleTag(this)">骨质疏松</div>
</div>
</div>
</div>
<!-- 神经内科 -->
<div class="category">
<div class="category-header" onclick="toggleCategory(this)">
<div class="category-title">
<svg class="category-arrow" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="#666" stroke-width="2"><path d="M3 5l4 4 4-4"/></svg>
神经内科
</div>
</div>
<div class="category-content">
<div class="disease-tags">
<div class="disease-tag" onclick="toggleTag(this)">脑卒中</div>
<div class="disease-tag" onclick="toggleTag(this)">头痛/偏头痛</div>
<div class="disease-tag" onclick="toggleTag(this)">睡眠障碍</div>
<div class="disease-tag" onclick="toggleTag(this)">帕金森病</div>
<div class="disease-tag" onclick="toggleTag(this)">癫痫</div>
</div>
</div>
</div>
<!-- 精神心理科 -->
<div class="category">
<div class="category-header" onclick="toggleCategory(this)">
<div class="category-title">
<svg class="category-arrow" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="#666" stroke-width="2"><path d="M3 5l4 4 4-4"/></svg>
精神心理科
</div>
</div>
<div class="category-content">
<div class="disease-tags">
<div class="disease-tag" onclick="toggleTag(this)">焦虑抑郁</div>
<div class="disease-tag" onclick="toggleTag(this)">失眠症</div>
<div class="disease-tag" onclick="toggleTag(this)">躯体化障碍</div>
</div>
</div>
</div>
<!-- 骨科/康复科 -->
<div class="category">
<div class="category-header" onclick="toggleCategory(this)">
<div class="category-title">
<svg class="category-arrow" width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="#666" stroke-width="2"><path d="M3 5l4 4 4-4"/></svg>
骨科/康复科
</div>
</div>
<div class="category-content">
<div class="disease-tags">
<div class="disease-tag" onclick="toggleTag(this)">颈椎病</div>
<div class="disease-tag" onclick="toggleTag(this)">腰椎间盘突出</div>
<div class="disease-tag" onclick="toggleTag(this)">关节炎</div>
<div class="disease-tag" onclick="toggleTag(this)">骨折康复</div>
</div>
</div>
</div>
</div>
</div>
<script>
/**
* 切换科室分类展开/收起
* @param {HTMLElement} header - 科室头部元素
*/
function toggleCategory(header) {
const arrow = header.querySelector('.category-arrow');
const content = header.nextElementSibling;
arrow.classList.toggle('expanded');
content.classList.toggle('show');
}
/**
* 切换疾病标签选中状态
* @param {HTMLElement} tag - 标签元素
*/
function toggleTag(tag) {
tag.classList.toggle('selected');
updateSelectedCount();
}
/**
* 更新已选数量
*/
function updateSelectedCount() {
const count = document.querySelectorAll('.disease-tag.selected').length;
document.getElementById('selected-count').textContent = count;
}
/**
* 保存并返回
*/
function saveAndReturn() {
// 实际项目中这里会保存选中的疾病数据
location.href = './edit-profile.html';
}
</script>
</body>
</html>
+15 -24
View File
@@ -70,43 +70,34 @@
<span style="font-size:14px;color:#999;width:70px;flex-shrink:0;">职称</span>
<input type="text" value="主治医师" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
</div>
<div style="display:flex;align-items:center;padding:14px 16px;">
<span style="font-size:14px;color:#999;width:70px;flex-shrink:0;">执业年限</span>
<input type="text" value="12年" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
</div>
</div>
<!-- 擅长病种标签选择 -->
<div style="font-size:13px;font-weight:600;color:#999;margin:0 4px 8px;">擅长病</div>
<div style="background:#fff;border-radius:12px;padding:14px 16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:16px;">
<div style="font-size:12px;color:#999;margin-bottom:10px;">点击选择/取消(可多选)</div>
<div style="display:flex;flex-wrap:wrap;gap:8px;" id="disease-tags">
<!-- 已选中标签(蓝色 -->
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;cursor:pointer;border:1px solid #1677ff;">高血压</div>
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;cursor:pointer;border:1px solid #1677ff;">冠心病</div>
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;cursor:pointer;border:1px solid #1677ff;">心律失常</div>
<!-- 未选中标签(灰色) -->
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;cursor:pointer;border:1px solid #e8e8e8;">心力衰竭</div>
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;cursor:pointer;border:1px solid #e8e8e8;">糖尿病</div>
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;cursor:pointer;border:1px solid #e8e8e8;">高脂血症</div>
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;cursor:pointer;border:1px solid #e8e8e8;">脑卒中</div>
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;cursor:pointer;border:1px solid #e8e8e8;">睡眠障碍</div>
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;cursor:pointer;border:1px solid #e8e8e8;">颈椎病</div>
<div onclick="toggleDiseaseTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;cursor:pointer;border:1px solid #e8e8e8;">焦虑抑郁</div>
<!-- 擅长疾病(只读展示 + 跳转入口) -->
<div style="font-size:13px;font-weight:600;color:#999;margin:0 4px 8px;">擅长</div>
<!-- [交互] 点击跳转: ./edit-diseases.html -->
<div onclick="location.href='./edit-diseases.html'" style="background:#fff;border-radius:12px;padding:14px 16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:16px;cursor:pointer;display:flex;align-items:center;gap:12px;">
<div style="flex:1;display:flex;flex-wrap:wrap;gap:8px;">
<!-- 已选中标签(只读展示 -->
<div style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;border:1px solid #1677ff;">高血压</div>
<div style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;border:1px solid #1677ff;">冠心病</div>
<div style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;border:1px solid #1677ff;">心律失常</div>
</div>
<!-- 右侧箭头 -->
<svg width="8" height="14" viewBox="0 0 8 14" fill="none" stroke="#ccc" stroke-width="2" style="flex-shrink:0;"><path d="M1 1l6 6-6 6"/></svg>
</div>
<!-- 个人简介 -->
<div style="font-size:13px;font-weight:600;color:#999;margin:0 4px 8px;">个人简介</div>
<div style="background:#fff;border-radius:12px;padding:14px 16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:16px;">
<textarea style="width:100%;border:none;font-size:14px;color:#1a1a1a;outline:none;resize:none;line-height:1.7;background:transparent;" rows="4" placeholder="请输入个人简介...">北京协和医院心内科主治医师,从事心血管疾病临床工作12年,具有丰富的临床经验,擅长心血管疾病的综合管理与健康指导。</textarea>
<div style="text-align:right;font-size:11px;color:#bbb;">已输入 68/200 字</div>
<div style="text-align:right;font-size:11px;color:#bbb;">已输入 68/300 字</div>
</div>
<!-- 个人擅长 -->
<div style="font-size:13px;font-weight:600;color:#999;margin:0 4px 8px;">个人擅长</div>
<div style="font-size:13px;font-weight:600;color:#999;margin:0 4px 8px;">职业经历</div>
<div style="background:#fff;border-radius:12px;padding:14px 16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:20px;">
<textarea style="width:100%;border:none;font-size:14px;color:#1a1a1a;outline:none;resize:none;line-height:1.7;background:transparent;" rows="4" placeholder="请描述您的专业擅长方向...">高血压、冠心病、心律失常的诊断与治疗,擅长心血管疾病的综合管理,对职场人群慢性病预防与健康管理有丰富经验。</textarea>
<textarea style="width:100%;border:none;font-size:14px;color:#1a1a1a;outline:none;resize:none;line-height:1.7;background:transparent;" rows="4" placeholder="请描述您的职业经历..."></textarea>
<div style="text-align:right;font-size:11px;color:#bbb;">已输入 62/300 字</div>
</div>
</div>
+38 -8
View File
@@ -56,7 +56,7 @@
</div>
<!-- 服务中按钮 -->
<button onclick="togglePause()" id="pause-btn-mine" style="margin-left:auto;display:flex;align-items:center;gap:6px;background:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4);border-radius:20px;padding:6px 12px;color:#fff;font-size:12px;cursor:pointer;">
<span style="width:7px;height:7px;border-radius:50%;background:#52c41a;display:inline-block;"></span>服务中
<span style="width:7px;height:7px;border-radius:50%;background:#52c41a;display:inline-block;"></span><span id="pause-text">咨询已开启</span>
</button>
</div>
</div>
@@ -71,6 +71,12 @@
<span style="font-size:13px;color:#1677ff;margin-right:8px;">今日 18 次</span>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<!-- [交互] 点击跳转至: ./reviews.html -->
<div onclick="location.href='./reviews.html'" style="display:flex;align-items:center;padding:16px;cursor:pointer;border-bottom:1px solid #f5f5f5;">
<span style="font-size:18px;margin-right:12px;"></span><span style="font-size:15px;color:#1a1a1a;flex:1;">我的评价</span>
<span style="font-size:13px;color:#fa8c16;margin-right:8px;">4.9 分</span>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<!-- [交互] 点击跳转至: ./schedule.html -->
<div onclick="location.href='./schedule.html'" style="display:flex;align-items:center;padding:16px;cursor:pointer;border-bottom:1px solid #f5f5f5;">
<span style="font-size:18px;margin-right:12px;">📅</span><span style="font-size:15px;color:#1a1a1a;flex:1;">排班设置</span>
@@ -112,6 +118,18 @@
</div>
</div>
<!-- 咨询状态切换确认弹窗 -->
<div id="modal-pause" class="modal-center">
<div class="modal-box">
<div class="modal-title" id="pause-modal-title">关闭咨询</div>
<div class="modal-body" id="pause-modal-body">是否要关闭咨询?关闭咨询后,员工无法发起咨询。</div>
<div class="modal-actions">
<button onclick="closeModal('modal-pause')">取消</button>
<button onclick="confirmTogglePause()">确认</button>
</div>
</div>
</div>
<!-- 底部Tab栏,我的为active状态 -->
<div class="tab-bar">
<!-- [交互] 点击跳转至: ../workbench/index.html -->
@@ -152,19 +170,31 @@
let isPaused = false;
/**
* 切换服务状态(服务中/暂停服务)
* 点击按钮时弹窗确认
*/
function togglePause() {
var title = isPaused ? '开启咨询' : '关闭咨询';
var body = isPaused ? '是否要开启咨询?开启咨询后,员工可发起咨询。' : '是否要关闭咨询?关闭咨询后,员工无法发起咨询。';
document.getElementById('pause-modal-title').textContent = title;
document.getElementById('pause-modal-body').textContent = body;
openModal('modal-pause');
}
/**
* 确认切换服务状态
*/
function confirmTogglePause() {
isPaused = !isPaused;
const bg = isPaused ? '#ff4d4f' : '#52c41a';
const text = isPaused ? '暂停服务' : '服务中';
const mineBtn = document.getElementById('pause-btn-mine');
var bg = isPaused ? '#ff4d4f' : '#52c41a';
var text = isPaused ? '咨询已关闭' : '咨询已开启';
var mineBtn = document.getElementById('pause-btn-mine');
if (mineBtn) {
const dot = mineBtn.querySelector('span');
var dot = mineBtn.querySelector('span');
if (dot) dot.style.background = bg;
/* 更新按钮文字 */
mineBtn.childNodes.forEach(function(n) { if (n.nodeType === 3) n.textContent = text; });
var pauseText = document.getElementById('pause-text');
if (pauseText) pauseText.textContent = text;
}
closeModal('modal-pause');
}
/**
+45 -12
View File
@@ -40,10 +40,43 @@
<span class="nav-title">全部评价</span>
</div>
<!-- 顶部统计 -->
<div style="background:#fff;border-bottom:1px solid #f0f0f0;padding:12px 16px;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;">
<span style="font-size:14px;color:#1a1a1a;"><b>1,248</b> 条评价</span>
<span style="font-size:13px;color:#fa8c16;font-weight:600;">⭐ 综合 4.9</span>
<!-- 综合评分 -->
<div style="background:#fff;padding:16px;flex-shrink:0;border-bottom:1px solid #f0f0f0;">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:14px;">综合评分</div>
<div style="display:flex;align-items:center;gap:16px;">
<div style="text-align:center;">
<div style="font-size:40px;font-weight:700;color:#fa8c16;line-height:1;">4.9</div>
<div style="font-size:13px;color:#fa8c16;margin-top:4px;">⭐⭐⭐⭐⭐</div>
<div style="font-size:11px;color:#999;margin-top:3px;">1,248次评价</div>
</div>
<div style="flex:1;">
<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">
<span style="font-size:11px;color:#999;width:14px;">5</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:88%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">88%</span>
</div>
<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">
<span style="font-size:11px;color:#999;width:14px;">4</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:8%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">8%</span>
</div>
<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">
<span style="font-size:11px;color:#999;width:14px;">3</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:3%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">3%</span>
</div>
<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">
<span style="font-size:11px;color:#999;width:14px;">2</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:1%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">1%</span>
</div>
<div style="display:flex;align-items:center;gap:6px;">
<span style="font-size:11px;color:#999;width:14px;">1</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:0%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">0%</span>
</div>
</div>
</div>
</div>
<!-- 评价列表 -->
@@ -53,8 +86,8 @@
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
<div style="display:flex;align-items:center;gap:8px;">
<div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#ffe0e0,#ffb3b3);display:flex;align-items:center;justify-content:center;font-size:15px;">👩</div>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">孙*丽</span>
<span class="tag tag-green" style="font-size:10px;padding:1px 6px;">视频咨询</span>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">匿名评价</span>
<!-- <span class="tag tag-green" style="font-size:10px;padding:1px 6px;">视频咨询</span>-->
</div>
<span style="font-size:12px;color:#bbb;">昨天</span>
</div>
@@ -67,8 +100,8 @@
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
<div style="display:flex;align-items:center;gap:8px;">
<div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:15px;">👨</div>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">*</span>
<span class="tag tag-blue" style="font-size:10px;padding:1px 6px;">图文咨询</span>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">赵磊</span>
<!-- <span class="tag tag-blue" style="font-size:10px;padding:1px 6px;">图文咨询</span>-->
</div>
<span style="font-size:12px;color:#bbb;">2026-04-08</span>
</div>
@@ -81,8 +114,8 @@
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
<div style="display:flex;align-items:center;gap:8px;">
<div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#f6ffed,#b7eb8f);display:flex;align-items:center;justify-content:center;font-size:15px;">👩</div>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">*</span>
<span class="tag tag-green" style="font-size:10px;padding:1px 6px;">视频咨询</span>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">王芳</span>
<!-- <span class="tag tag-green" style="font-size:10px;padding:1px 6px;">视频咨询</span>-->
</div>
<span style="font-size:12px;color:#bbb;">2026-04-07</span>
</div>
@@ -95,8 +128,8 @@
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
<div style="display:flex;align-items:center;gap:8px;">
<div style="width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#fff7e6,#ffd591);display:flex;align-items:center;justify-content:center;font-size:15px;">👨</div>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">*</span>
<span class="tag tag-blue" style="font-size:10px;padding:1px 6px;">图文咨询</span>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">李建</span>
<!-- <span class="tag tag-blue" style="font-size:10px;padding:1px 6px;">图文咨询</span>-->
</div>
<span style="font-size:12px;color:#bbb;">2026-04-06</span>
</div>
+148 -104
View File
@@ -5,7 +5,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人中心 - 排班设置 | 健康长庆原型</title>
<style>
/* 公共重置与手机壳样式 */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
@@ -18,18 +17,52 @@
.nav-right { margin-left: auto; color: #1677ff; font-size: 14px; cursor: pointer; background: none; border: none; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 开关 */
.toggle { position: relative; width: 44px; height: 24px; border-radius: 12px; background: #e0e0e0; cursor: pointer; transition: background .2s; flex-shrink: 0; }
.toggle.on { background: #4cd964; }
.toggle::after { content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.2); transition: transform .2s; }
.toggle.on::after { transform: translateX(20px); }
/* 折叠卡片 */
.day-card { background: #fff; border-radius: 12px; margin: 0 16px 10px; box-shadow: 0 1px 4px rgba(0,0,0,0.05); overflow: hidden; }
.day-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.day-header .day-name { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.day-header .day-summary { font-size: 12px; color: #999; }
.day-header .arrow { width: 16px; height: 16px; color: #ccc; transition: transform .2s; flex-shrink: 0; }
.day-header .arrow.open { transform: rotate(180deg); }
.day-body { max-height: 0; overflow: hidden; transition: max-height .25s ease; }
.day-body.open { max-height: 400px; }
.day-body-inner { padding: 0 16px 14px; }
/* 时段行 */
.slot-row { display: flex; align-items: center; padding: 10px 0; border-top: 1px solid #f5f5f5; }
.slot-row:first-child { border-top: none; }
.slot-info { flex: 1; min-width: 0; }
.slot-period { font-size: 11px; color: #1677ff; font-weight: 500; margin-bottom: 1px; }
.slot-time { font-size: 13px; color: #1a1a1a; }
.slot-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.slot-toggle { position: relative; width: 40px; height: 22px; border-radius: 11px; background: #e0e0e0; cursor: pointer; transition: background .2s; }
.slot-toggle.on { background: #4cd964; }
.slot-toggle::after { content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.2); transition: transform .2s; }
.slot-toggle.on::after { transform: translateX(18px); }
.slot-count { display: flex; align-items: center; gap: 4px; }
.count-btn { width: 26px; height: 26px; border-radius: 50%; border: 1px solid #e8e8e8; background: #fff; font-size: 15px; color: #666; cursor: pointer; display: flex; align-items: center; justify-content: center; line-height: 1; }
.count-btn:active { background: #f5f5f5; }
.count-val { font-size: 15px; font-weight: 700; color: #1677ff; min-width: 18px; text-align: center; }
.count-unit { font-size: 11px; color: #999; }
.slot-row.disabled .slot-time { color: #ccc; }
.slot-row.disabled .slot-period { color: #b8d4ff; }
.slot-row.disabled .count-val { color: #ccc; }
.slot-row.disabled .count-btn { border-color: #f0f0f0; color: #ccc; }
</style>
</head>
<body>
<div class="phone-shell">
<!-- 状态栏 -->
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<!-- [交互] 点击返回: ./index.html -->
<button class="back-btn" onclick="location.href='./index.html'">
@@ -38,112 +71,123 @@
<span class="nav-title">排班设置</span>
<button class="nav-right">保存</button>
</div>
<!-- 内容区域 -->
<div class="scroll-content" style="padding:16px;">
<!-- 日历卡片 -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;">
<span style="font-size:15px;font-weight:600;color:#1a1a1a;">2026年4月</span>
<div style="display:flex;gap:8px;">
<button style="width:28px;height:28px;border-radius:50%;background:#f5f5f5;border:none;font-size:14px;cursor:pointer;"></button>
<button style="width:28px;height:28px;border-radius:50%;background:#f5f5f5;border:none;font-size:14px;cursor:pointer;"></button>
</div>
</div>
<!-- 星期标题行 -->
<div style="display:grid;grid-template-columns:repeat(7,1fr);gap:4px;text-align:center;">
<div style="font-size:11px;color:#999;padding:4px 0;"></div>
<div style="font-size:11px;color:#999;padding:4px 0;"></div>
<div style="font-size:11px;color:#999;padding:4px 0;"></div>
<div style="font-size:11px;color:#999;padding:4px 0;"></div>
<div style="font-size:11px;color:#999;padding:4px 0;"></div>
<div style="font-size:11px;color:#999;padding:4px 0;"></div>
<div style="font-size:11px;color:#999;padding:4px 0;"></div>
<!-- 第一行:1-6日 -->
<div style="padding:6px 0;font-size:13px;color:#ccc;"></div>
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">1</div>
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">2</div>
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">3</div>
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">4</div>
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">5</div>
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">6</div>
<!-- 第二行:7-13日,8号为今天,9/10/12为选中 -->
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">7</div>
<div style="padding:6px 0;font-size:13px;color:#1677ff;background:#e6f4ff;border-radius:50%;font-weight:700;">8</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#fff;background:#1677ff;border-radius:50%;cursor:pointer;font-weight:600;">9</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#fff;background:#1677ff;border-radius:50%;cursor:pointer;font-weight:600;">10</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#1a1a1a;cursor:pointer;">11</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#fff;background:#1677ff;border-radius:50%;cursor:pointer;font-weight:600;">12</div>
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">13</div>
<!-- 第三行:14-20日,15/16/18/19为选中,17为未选中可点击 -->
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">14</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#fff;background:#1677ff;border-radius:50%;cursor:pointer;font-weight:600;">15</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#fff;background:#1677ff;border-radius:50%;cursor:pointer;font-weight:600;">16</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#1a1a1a;cursor:pointer;">17</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#fff;background:#1677ff;border-radius:50%;cursor:pointer;font-weight:600;">18</div>
<div onclick="toggleDay(this)" style="padding:6px 0;font-size:13px;color:#fff;background:#1677ff;border-radius:50%;cursor:pointer;font-weight:600;">19</div>
<div style="padding:6px 0;font-size:13px;color:#1a1a1a;">20</div>
</div>
<div class="scroll-content">
<!-- 开启视频咨询 -->
<div style="background:#fff;padding:14px 16px;display:flex;align-items:center;gap:10px;margin-bottom:10px;">
<span style="font-size:14px;color:#1a1a1a;font-weight:500;">开启视频咨询</span>
<div class="toggle on" onclick="this.classList.toggle('on');var t=this.nextElementSibling;t.textContent=this.classList.contains('on')?'已开启 — 患者可预约视频咨询':'已关闭';t.style.color=this.classList.contains('on')?'#4cd964':'#999';"></div>
<span style="font-size:12px;color:#4cd964;flex:1;">已开启 — 患者可预约视频咨询</span>
</div>
<!-- 时段设置卡片 -->
<div style="background:#fff;border-radius:12px;padding:16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:12px;">时段设置(每日)</div>
<!-- 上午时段 -->
<div style="display:flex;justify-content:space-between;align-items:center;padding:12px 0;border-bottom:1px solid #f5f5f5;">
<div>
<div style="font-size:14px;color:#1a1a1a;">上午 09:00 12:00</div>
<div style="font-size:12px;color:#999;margin-top:2px;">每时段接诊人数</div>
</div>
<div style="display:flex;align-items:center;gap:10px;">
<button onclick="adjustCount(this,-1)" style="width:28px;height:28px;border-radius:50%;background:#f5f5f5;border:none;font-size:16px;cursor:pointer;line-height:1;"></button>
<span id="count-am" style="font-size:16px;font-weight:700;color:#1677ff;min-width:20px;text-align:center;">3</span>
<button onclick="adjustCount(this,1)" style="width:28px;height:28px;border-radius:50%;background:#f5f5f5;border:none;font-size:16px;cursor:pointer;line-height:1;">+</button>
</div>
</div>
<!-- 下午时段 -->
<div style="display:flex;justify-content:space-between;align-items:center;padding:12px 0;">
<div>
<div style="font-size:14px;color:#1a1a1a;">下午 14:00 17:00</div>
<div style="font-size:12px;color:#999;margin-top:2px;">每时段接诊人数</div>
</div>
<div style="display:flex;align-items:center;gap:10px;">
<button onclick="adjustCount(this,-1)" style="width:28px;height:28px;border-radius:50%;background:#f5f5f5;border:none;font-size:16px;cursor:pointer;line-height:1;"></button>
<span id="count-pm" style="font-size:16px;font-weight:700;color:#1677ff;min-width:20px;text-align:center;">3</span>
<button onclick="adjustCount(this,1)" style="width:28px;height:28px;border-radius:50%;background:#f5f5f5;border:none;font-size:16px;cursor:pointer;line-height:1;">+</button>
</div>
</div>
<!-- 标题 -->
<div style="padding:2px 16px 10px;display:flex;align-items:center;gap:6px;">
<span style="width:3px;height:14px;background:#1677ff;border-radius:2px;display:inline-block;"></span>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">每周排班设置</span>
</div>
<!-- 卡片容器 -->
<div id="cardList"></div>
<div style="height:20px;"></div>
</div>
</div>
<script>
/**
* 切换日期选中状态
* 点击已选中的日期取消选中,点击未选中的日期设为选中
* @param {HTMLElement} el - 日期单元格元素
*/
function toggleDay(el) {
var isOn = el.style.background === 'rgb(22, 119, 255)';
el.style.background = isOn ? '' : '#1677ff';
el.style.color = isOn ? '#1a1a1a' : '#fff';
el.style.fontWeight = isOn ? '' : '600';
el.style.borderRadius = isOn ? '' : '50%';
var DAYS = ['周一','周二','周三','周四','周五','周六','周日'];
var SLOTS = [
{ period: '上午', time: '8:00 10:00' },
{ period: '上午', time: '10:00 12:00' },
{ period: '下午', time: '14:00 16:00' },
{ period: '下午', time: '16:00 18:00' }
];
var DATA = DAYS.map(function(_, i) {
var off = i >= 5;
return { slots: SLOTS.map(function(_, si) {
return { on: !off, n: off ? 0 : (si < 2 ? 5 : 4) };
})};
});
var arrowSvg = '<svg class="arrow" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6l4 4 4-4"/></svg>';
function getSummary(di) {
var d = DATA[di], cnt = 0;
d.slots.forEach(function(s) { if (s.on) cnt++; });
return cnt > 0 ? cnt + '个时段开诊' : '休息';
}
/**
* 调整接诊人数(最小1,最大10)
* @param {HTMLElement} btn - 触发按钮
* @param {number} delta - 增减量(+1 或 -1
*/
function adjustCount(btn, delta) {
var sibling = btn.parentElement.querySelector('span[id]');
if (!sibling) return;
var val = parseInt(sibling.textContent) + delta;
if (val < 1) val = 1;
if (val > 10) val = 10;
sibling.textContent = val;
function render() {
var wrap = document.getElementById('cardList');
wrap.innerHTML = '';
DAYS.forEach(function(day, di) {
var card = document.createElement('div');
card.className = 'day-card';
var isOpen = card.dataset.open === '1';
card.innerHTML =
'<div class="day-header" onclick="toggle(' + di + ')">' +
'<div><span class="day-name">' + day + '</span> ' +
'<span class="day-summary">' + getSummary(di) + '</span></div>' +
arrowSvg +
'</div>' +
'<div class="day-body" id="body-' + di + '">' +
'<div class="day-body-inner">' + renderSlots(di) + '</div>' +
'</div>';
wrap.appendChild(card);
});
/* 默认展开周一 */
var first = document.getElementById('body-0');
if (first) { first.classList.add('open'); first.previousElementSibling.querySelector('.arrow').classList.add('open'); }
}
function renderSlots(di) {
var html = '';
DATA[di].slots.forEach(function(s, si) {
var dis = s.on ? '' : ' disabled';
var tCls = s.on ? 'slot-toggle on' : 'slot-toggle';
html += '<div class="slot-row' + dis + '">' +
'<div class="slot-info">' +
'<div class="slot-period">' + SLOTS[si].period + '</div>' +
'<div class="slot-time">' + SLOTS[si].time + '</div>' +
'</div>' +
'<div class="slot-right">' +
'<div class="' + tCls + '" onclick="toggleSlot(' + di + ',' + si + ')"></div>' +
'<div class="slot-count">' +
'<button class="count-btn" ' + (s.on ? '' : 'disabled ') + 'onclick="adj(' + di + ',' + si + ',-1)"></button>' +
'<span class="count-val">' + (s.on ? s.n : '—') + '</span>' +
'<button class="count-btn" ' + (s.on ? '' : 'disabled ') + 'onclick="adj(' + di + ',' + si + ',1)">+</button>' +
'<span class="count-unit">人</span>' +
'</div>' +
'</div></div>';
});
return html;
}
function toggle(di) {
var body = document.getElementById('body-' + di);
var arrow = body.previousElementSibling.querySelector('.arrow');
body.classList.toggle('open');
arrow.classList.toggle('open');
}
function toggleSlot(di, si) {
var s = DATA[di].slots[si];
s.on = !s.on;
if (s.on && s.n === 0) s.n = 3;
refreshCard(di);
}
function adj(di, si, delta) {
var s = DATA[di].slots[si];
if (!s.on) return;
s.n = Math.max(1, Math.min(20, s.n + delta));
refreshCard(di);
}
function refreshCard(di) {
var body = document.getElementById('body-' + di);
var wasOpen = body.classList.contains('open');
body.querySelector('.day-body-inner').innerHTML = renderSlots(di);
var header = body.previousElementSibling;
header.querySelector('.day-summary').textContent = getSummary(di);
if (wasOpen) body.classList.add('open');
}
render();
</script>
</body>
</html>
</html>
+231 -132
View File
@@ -17,6 +17,16 @@
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 数据点悬浮提示框 */
.data-tooltip { position: absolute; background: #fff; border-radius: 8px; padding: 12px; box-shadow: 0 4px 16px rgba(0,0,0,0.15); display: none; z-index: 100; min-width: 160px; }
.data-tooltip::before { content: ''; position: absolute; bottom: -6px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 6px solid #fff; }
.data-tooltip-date { font-size: 13px; font-weight: 600; color: #1a1a1a; margin-bottom: 8px; text-align: center; }
.data-tooltip-item { display: flex; align-items: center; justify-content: space-between; font-size: 12px; margin-bottom: 4px; }
.data-tooltip-item:last-child { margin-bottom: 0; }
.data-tooltip-label { color: #666; display: flex; align-items: center; gap: 4px; }
.data-tooltip-value { font-weight: 600; color: #1a1a1a; }
.data-tooltip-badge { display: inline-block; width: 8px; height: 8px; border-radius: 2px; }
</style>
</head>
<body>
@@ -39,157 +49,246 @@
<!-- 内容区域 -->
<div class="scroll-content" style="padding:16px;">
<!-- 数据概览(2x2网格) -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:14px;">数据概览</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;">
<!-- 今日 - 蓝色 -->
<div style="background:#f0f7ff;border-radius:10px;padding:14px;text-align:center;">
<div style="font-size:26px;font-weight:700;color:#1677ff;">18</div>
<div style="font-size:12px;color:#666;margin-top:3px;">今日完成</div>
</div>
<!-- 本周 - 绿色 -->
<div style="background:#f6ffed;border-radius:10px;padding:14px;text-align:center;">
<div style="font-size:26px;font-weight:700;color:#52c41a;">87</div>
<div style="font-size:12px;color:#666;margin-top:3px;">本周完成</div>
</div>
<!-- 本月 - 橙色 -->
<div style="background:#fff7e6;border-radius:10px;padding:14px;text-align:center;">
<div style="font-size:26px;font-weight:700;color:#fa8c16;">312</div>
<div style="font-size:12px;color:#666;margin-top:3px;">本月完成</div>
</div>
<!-- 累计 - 紫色 -->
<div style="background:#f9f0ff;border-radius:10px;padding:14px;text-align:center;">
<div style="font-size:26px;font-weight:700;color:#722ed1;">1,248</div>
<div style="font-size:12px;color:#666;margin-top:3px;">累计完成</div>
</div>
</div>
</div>
<!-- 本月咨询类型 -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:12px;">本月咨询类型</div>
<!-- 图文咨询进度条 -->
<div style="display:flex;align-items:center;gap:10px;margin-bottom:10px;">
<span style="font-size:13px;color:#666;width:56px;flex-shrink:0;">图文咨询</span>
<div style="flex:1;height:10px;background:#f0f0f0;border-radius:5px;overflow:hidden;">
<div style="width:68%;height:100%;background:#1677ff;border-radius:5px;"></div>
</div>
<span style="font-size:13px;color:#1677ff;font-weight:600;width:36px;text-align:right;">213</span>
<!-- 月度统计 -->
<div style="background:#fff;border-radius:12px;padding:20px;margin-bottom:16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<!-- 月份切换器 -->
<div style="display:flex;align-items:center;justify-content:center;gap:16px;margin-bottom:20px;">
<!-- [交互] 点击切换到上个月 -->
<button onclick="prevMonth()" style="background:none;border:none;color:#1677ff;font-size:18px;cursor:pointer;padding:4px 8px;">
<svg width="8" height="14" viewBox="0 0 8 14" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 1L1 7l6 6"/></svg>
</button>
<div style="font-size:17px;font-weight:600;color:#1a1a1a;min-width:120px;text-align:center;" id="current-month">2026年4月</div>
<!-- [交互] 点击切换到下个月 -->
<button onclick="nextMonth()" style="background:none;border:none;color:#1677ff;font-size:18px;cursor:pointer;padding:4px 8px;">
<svg width="8" height="14" viewBox="0 0 8 14" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 1l6 6-6 6"/></svg>
</button>
</div>
<!-- 视频咨询进度条 -->
<div style="display:flex;align-items:center;gap:10px;">
<span style="font-size:13px;color:#666;width:56px;flex-shrink:0;">视频咨询</span>
<div style="flex:1;height:10px;background:#f0f0f0;border-radius:5px;overflow:hidden;">
<div style="width:32%;height:100%;background:#52c41a;border-radius:5px;"></div>
</div>
<span style="font-size:13px;color:#52c41a;font-weight:600;width:36px;text-align:right;">99</span>
</div>
</div>
<!-- 近7日完成量柱状图 -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:12px;">近7日完成量</div>
<div style="display:flex;align-items:flex-end;justify-content:space-between;height:70px;gap:4px;">
<!-- 4/2: 12 -->
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">12</div>
<div style="width:100%;height:40%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/2</div>
<!-- 收益概览(1x2网格) -->
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:24px;">
<!-- 已结算收益 - 绿色 -->
<div style="background:#f6ffed;border-radius:10px;padding:18px;text-align:center;">
<div style="font-size:13px;color:#666;margin-bottom:6px;">已结算收益</div>
<div style="font-size:26px;font-weight:700;color:#52c41a;">¥8,640</div>
</div>
<!-- 4/3: 15 -->
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">15</div>
<div style="width:100%;height:50%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/3</div>
</div>
<!-- 4/4: 20 -->
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">20</div>
<div style="width:100%;height:67%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/4</div>
</div>
<!-- 4/5: 10 -->
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">10</div>
<div style="width:100%;height:33%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/5</div>
</div>
<!-- 4/6: 22 -->
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">22</div>
<div style="width:100%;height:73%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/6</div>
</div>
<!-- 4/7: 16 -->
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#999;">16</div>
<div style="width:100%;height:53%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#bbb;">4/7</div>
</div>
<!-- 今日: 18(高亮蓝色) -->
<div style="display:flex;flex-direction:column;align-items:center;gap:4px;flex:1;">
<div style="font-size:10px;color:#1677ff;font-weight:600;">18</div>
<div style="width:100%;height:60%;background:#1677ff;border-radius:3px 3px 0 0;"></div>
<div style="font-size:10px;color:#1677ff;font-weight:600;">今日</div>
<!-- 未结算收益 - 橙色 -->
<div style="background:#fff7e6;border-radius:10px;padding:18px;text-align:center;">
<div style="font-size:13px;color:#666;margin-bottom:6px;">未结算收益</div>
<div style="font-size:26px;font-weight:700;color:#fa8c16;">¥2,340</div>
</div>
</div>
</div>
<!-- 综合评分 -->
<div style="background:#fff;border-radius:12px;padding:16px;margin-bottom:12px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;">综合评分</div>
<!-- [交互] 点击跳转至: ./reviews.html -->
<button onclick="location.href='./reviews.html'" style="font-size:12px;color:#1677ff;background:none;border:none;cursor:pointer;">查看全部评价 </button>
</div>
<div style="display:flex;align-items:center;gap:16px;">
<!-- 左侧评分 -->
<div style="text-align:center;">
<div style="font-size:40px;font-weight:700;color:#fa8c16;line-height:1;">4.9</div>
<div style="font-size:13px;color:#fa8c16;margin-top:4px;">⭐⭐⭐⭐⭐</div>
<div style="font-size:11px;color:#999;margin-top:3px;">1,248次评价</div>
</div>
<!-- 右侧星级分布条 -->
<!-- 咨询类型统计(饼状图) -->
<div style="display:flex;align-items:center;gap:24px;margin-bottom:24px;">
<!-- 饼状图 -->
<svg width="130" height="130" viewBox="0 0 100 100" style="flex-shrink:0;">
<!-- 图文咨询:213/(213+99) = 68.3% -->
<circle cx="50" cy="50" r="40" fill="none" stroke="#1677ff" stroke-width="20"
stroke-dasharray="171.5 250" stroke-dashoffset="0" transform="rotate(-90 50 50)"/>
<!-- 视频咨询:99/(213+99) = 31.7% -->
<circle cx="50" cy="50" r="40" fill="none" stroke="#52c41a" stroke-width="20"
stroke-dasharray="79.5 250" stroke-dashoffset="-171.5" transform="rotate(-90 50 50)"/>
<!-- 中心白色圆 -->
<circle cx="50" cy="50" r="28" fill="#fff"/>
<!-- 中心文字 -->
<text x="50" y="48" text-anchor="middle" font-size="18" font-weight="700" fill="#1a1a1a">312</text>
<text x="50" y="60" text-anchor="middle" font-size="10" fill="#999">总咨询</text>
</svg>
<!-- 图例 -->
<div style="flex:1;">
<!-- 5星 88% -->
<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">
<span style="font-size:11px;color:#999;width:14px;">5</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:88%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">88%</span>
<!-- 图文咨询 -->
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;">
<div style="width:14px;height:14px;background:#1677ff;border-radius:3px;flex-shrink:0;"></div>
<div style="flex:1;">
<div style="font-size:14px;color:#666;margin-bottom:2px;">图文咨询</div>
<div style="font-size:22px;font-weight:700;color:#1a1a1a;">213<span style="font-size:12px;font-weight:400;color:#999;margin-left:3px;"></span><span style="font-size:12px;color:#999;margin-left:6px;">(68%)</span></div>
<div style="font-size:11px;color:#999;margin-top:2px;">进行中64 / 已完成149</div>
</div>
</div>
<!-- 4星 8% -->
<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">
<span style="font-size:11px;color:#999;width:14px;">4</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:8%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">8%</span>
<!-- 视频咨询 -->
<div style="display:flex;align-items:center;gap:10px;">
<div style="width:14px;height:14px;background:#52c41a;border-radius:3px;flex-shrink:0;"></div>
<div style="flex:1;">
<div style="font-size:14px;color:#666;margin-bottom:2px;">视频咨询</div>
<div style="font-size:22px;font-weight:700;color:#1a1a1a;">99<span style="font-size:12px;font-weight:400;color:#999;margin-left:3px;"></span><span style="font-size:12px;color:#999;margin-left:6px;">(32%)</span></div>
<div style="font-size:11px;color:#999;margin-top:2px;">进行中20 / 已完成79</div>
</div>
</div>
<!-- 3星 3% -->
<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">
<span style="font-size:11px;color:#999;width:14px;">3</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:3%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">3%</span>
</div>
</div>
<!-- 月度趋势图(折线图 - 30天完整数据) -->
<div style="border-top:1px solid #f0f0f0;padding-top:20px;position:relative;" id="chart-container">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:16px;">月度趋势</div>
<svg width="100%" height="180" viewBox="0 0 340 180" style="overflow:visible;">
<!-- 网格线 -->
<line x1="0" y1="150" x2="340" y2="150" stroke="#f0f0f0" stroke-width="1"/>
<line x1="0" y1="120" x2="340" y2="120" stroke="#f0f0f0" stroke-width="1"/>
<line x1="0" y1="90" x2="340" y2="90" stroke="#f0f0f0" stroke-width="1"/>
<line x1="0" y1="60" x2="340" y2="60" stroke="#f0f0f0" stroke-width="1"/>
<line x1="0" y1="30" x2="340" y2="30" stroke="#f0f0f0" stroke-width="1"/>
<!-- 折线路径(30天数据:8,12,15,20,10,22,16,18,14,19,11,17,13,21,9,23,15,18,12,16,20,14,19,17,15,22,18,16,21,19 -->
<polyline points="5,126 16,108 27,90 38,60 49,138 60,48 71,96 82,78 93,114 104,66 115,132 126,90 137,120 148,54 159,144 170,42 181,90 192,78 203,108 214,96 225,60 236,114 247,66 258,90 269,90 280,48 291,78 302,96 313,54 324,66"
fill="none" stroke="#1677ff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
<!-- 数据点(每5天显示一个点,可点击) -->
<circle cx="5" cy="126" r="3.5" fill="#1677ff" style="cursor:pointer;" onclick="showTooltip(event, 1, 8, 5, 3)"/>
<circle cx="60" cy="48" r="3.5" fill="#1677ff" style="cursor:pointer;" onclick="showTooltip(event, 6, 22, 15, 7)"/>
<circle cx="115" cy="132" r="3.5" fill="#1677ff" style="cursor:pointer;" onclick="showTooltip(event, 11, 11, 7, 4)"/>
<circle cx="170" cy="42" r="3.5" fill="#1677ff" style="cursor:pointer;" onclick="showTooltip(event, 16, 23, 16, 7)"/>
<circle cx="225" cy="60" r="3.5" fill="#1677ff" style="cursor:pointer;" onclick="showTooltip(event, 21, 20, 13, 7)"/>
<circle cx="280" cy="48" r="3.5" fill="#1677ff" style="cursor:pointer;" onclick="showTooltip(event, 26, 22, 15, 7)"/>
<!-- 今日高亮点(17日,可点击) -->
<circle cx="192" cy="78" r="6" fill="#1677ff" stroke="#fff" stroke-width="2.5" style="cursor:pointer;" onclick="showTooltip(event, 17, 18, 12, 6)"/>
<!-- X轴日期标签(每5天显示) -->
<text x="5" y="168" text-anchor="middle" font-size="11" fill="#bbb">1</text>
<text x="60" y="168" text-anchor="middle" font-size="11" fill="#bbb">6</text>
<text x="115" y="168" text-anchor="middle" font-size="11" fill="#bbb">11</text>
<text x="170" y="168" text-anchor="middle" font-size="11" fill="#bbb">16</text>
<text x="192" y="168" text-anchor="middle" font-size="11" fill="#1677ff" font-weight="600"></text>
<text x="225" y="168" text-anchor="middle" font-size="11" fill="#bbb">21</text>
<text x="280" y="168" text-anchor="middle" font-size="11" fill="#bbb">26</text>
<text x="324" y="168" text-anchor="middle" font-size="11" fill="#bbb">30</text>
<!-- 今日数值标签 -->
<text x="192" y="66" text-anchor="middle" font-size="12" fill="#1677ff" font-weight="600">18</text>
<!-- Y轴刻度标签 -->
<text x="-5" y="153" text-anchor="end" font-size="10" fill="#bbb">0</text>
<text x="-5" y="123" text-anchor="end" font-size="10" fill="#bbb">5</text>
<text x="-5" y="93" text-anchor="end" font-size="10" fill="#bbb">10</text>
<text x="-5" y="63" text-anchor="end" font-size="10" fill="#bbb">15</text>
<text x="-5" y="33" text-anchor="end" font-size="10" fill="#bbb">20</text>
</svg>
<!-- 数据详情弹窗 -->
<div id="data-tooltip" class="data-tooltip">
<div class="data-tooltip-date">4月17日</div>
<div class="data-tooltip-item">
<span class="data-tooltip-label"><span class="data-tooltip-badge" style="background:#1677ff;"></span>图文咨询</span>
<span class="data-tooltip-value">12次 (进行中6 / 已完成6)</span>
</div>
<!-- 2星 1% -->
<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">
<span style="font-size:11px;color:#999;width:14px;">2</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:1%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">1%</span>
</div>
<!-- 1星 0% -->
<div style="display:flex;align-items:center;gap:6px;">
<span style="font-size:11px;color:#999;width:14px;">1</span>
<div style="flex:1;height:6px;background:#f0f0f0;border-radius:3px;overflow:hidden;"><div style="width:0%;height:100%;background:#faad14;border-radius:3px;"></div></div>
<span style="font-size:11px;color:#999;width:28px;text-align:right;">0%</span>
<div class="data-tooltip-item">
<span class="data-tooltip-label"><span class="data-tooltip-badge" style="background:#52c41a;"></span>视频咨询</span>
<span class="data-tooltip-value">6次 (进行中2 / 已完成4)</span>
</div>
</div>
</div>
</div>
<!-- 底部间距 -->
<div style="height:16px;"></div>
<div style="height:20px;"></div>
</div>
</div>
<script>
/**
* 切换到上个月
*/
function prevMonth() {
// 实际项目中这里会更新月份数据
alert('切换到上个月(演示)');
}
/**
* 切换到下个月
*/
function nextMonth() {
// 实际项目中这里会更新月份数据
alert('切换到下个月(演示)');
}
/**
* 显示数据点详情弹窗
* @param {Event} event - 点击事件
* @param {number} day - 日期
* @param {number} total - 总咨询次数
* @param {number} textTotal - 图文咨询总数
* @param {number} videoTotal - 视频咨询总数
*/
function showTooltip(event, day, total, textTotal, videoTotal) {
const tooltip = document.getElementById('data-tooltip');
const container = document.getElementById('chart-container');
// 模拟数据:进行中和已完成的分布
const textOngoing = Math.floor(textTotal * 0.3);
const textDone = textTotal - textOngoing;
const videoOngoing = Math.floor(videoTotal * 0.2);
const videoDone = videoTotal - videoOngoing;
// 更新弹窗内容
tooltip.innerHTML = `
<div class="data-tooltip-date">4月${day}日</div>
<div class="data-tooltip-item">
<span class="data-tooltip-label"><span class="data-tooltip-badge" style="background:#1677ff;"></span>图文咨询</span>
<span class="data-tooltip-value">${textTotal}次</span>
</div>
<div style="font-size:11px;color:#999;margin-left:16px;margin-bottom:4px;">进行中${textOngoing} / 已完成${textDone}</div>
<div class="data-tooltip-item">
<span class="data-tooltip-label"><span class="data-tooltip-badge" style="background:#52c41a;"></span>视频咨询</span>
<span class="data-tooltip-value">${videoTotal}次</span>
</div>
<div style="font-size:11px;color:#999;margin-left:16px;">进行中${videoOngoing} / 已完成${videoDone}</div>
`;
// 计算弹窗位置(相对于容器)
const circle = event.target;
const svg = circle.ownerSVGElement;
const svgRect = svg.getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
const circleX = parseFloat(circle.getAttribute('cx'));
const circleY = parseFloat(circle.getAttribute('cy'));
// SVG viewBox 到实际像素的缩放比例
const scaleX = svgRect.width / 340;
const scaleY = svgRect.height / 180;
// 计算实际像素位置
const pixelX = circleX * scaleX;
const pixelY = circleY * scaleY;
// 显示弹窗
tooltip.style.display = 'block';
// 等待渲染后获取弹窗尺寸
setTimeout(() => {
const tooltipWidth = tooltip.offsetWidth;
const tooltipHeight = tooltip.offsetHeight;
// 定位弹窗(在数据点上方居中)
let left = pixelX - tooltipWidth / 2;
let top = pixelY - tooltipHeight - 15; // 15px 为箭头高度 + 间距
// 边界检测:防止超出容器左右边界
const containerWidth = containerRect.width;
if (left < 10) left = 10;
if (left + tooltipWidth > containerWidth - 10) left = containerWidth - tooltipWidth - 10;
// 边界检测:如果上方空间不足,显示在下方
if (top < 0) {
top = pixelY + 15;
// 调整箭头方向(显示在上方)
tooltip.style.setProperty('--arrow-position', 'top');
}
tooltip.style.left = left + 'px';
tooltip.style.top = top + 'px';
}, 0);
}
// 点击其他区域关闭弹窗
document.addEventListener('click', function(e) {
const tooltip = document.getElementById('data-tooltip');
const isCircle = e.target.tagName === 'circle';
if (!isCircle && tooltip.style.display === 'block') {
tooltip.style.display = 'none';
}
});
</script>
</body>
</html>
+46 -16
View File
@@ -48,6 +48,16 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
.cc-preview { font-size: 13px; color: #666; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 210px; }
.cc-time { font-size: 12px; color: #bbb; flex-shrink: 0; }
.unread-dot { width: 8px; height: 8px; border-radius: 50%; background: #ff4d4f; flex-shrink: 0; }
/* 弹窗样式 */
.modal-center { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.modal-center.active { display: flex; }
.modal-box { width: 280px; background: #fff; border-radius: 16px; overflow: hidden; }
.modal-box .modal-title { padding: 20px 20px 8px; font-size: 17px; font-weight: 700; text-align: center; color: #1a1a1a; }
.modal-box .modal-body { padding: 8px 20px 20px; font-size: 14px; color: #666; text-align: center; line-height: 1.6; }
.modal-box .modal-actions { display: flex; border-top: 1px solid #f0f0f0; }
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
.modal-box .modal-actions button:first-child { color: #666; border-right: 1px solid #f0f0f0; }
.modal-box .modal-actions button:last-child { color: #1677ff; font-weight: 600; }
</style>
</head>
<body>
@@ -69,7 +79,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<!-- [交互] 点击切换服务状态 -->
<button id="wb-pause-btn" onclick="togglePause()" style="display:flex;align-items:center;gap:6px;background:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4);border-radius:20px;padding:6px 14px;color:#fff;font-size:13px;cursor:pointer;">
<span id="pause-dot" style="width:8px;height:8px;border-radius:50%;background:#52c41a;display:inline-block;flex-shrink:0;"></span>
<span id="pause-label">开启咨询</span>
<span id="pause-label">咨询已开启</span>
</button>
</div>
<!-- 统计数字 -->
@@ -139,7 +149,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div id="wb-panel-video" style="display:none;flex-direction:column;flex:1;overflow:hidden;">
<div class="seg-tabs">
<div class="seg-tab active" onclick="switchWorkTab(this,'wb-video-pending')">待确认<span class="badge">1</span></div>
<div class="seg-tab" onclick="switchWorkTab(this,'wb-video-ongoing')">进行中<span class="badge" style="background:#fa8c16;">1</span></div>
<div class="seg-tab" onclick="switchWorkTab(this,'wb-video-ongoing')">待开始<span class="badge" style="background:#fa8c16;">1</span></div>
<div class="seg-tab" onclick="switchWorkTab(this,'wb-video-done')">已结束</div>
</div>
<div class="scroll-content">
@@ -156,8 +166,8 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div id="wb-video-ongoing" style="display:none;">
<!-- [交互] 点击跳转至: ./video-ongoing.html -->
<div class="consult-card" onclick="location.href='./video-ongoing.html'">
<div class="cc-top"><div class="cc-avatar" style="background:linear-gradient(135deg,#f6ffed,#b7eb8f);">👩</div><div class="cc-info"><div class="cc-name">刘梅</div><div class="cc-meta">女 · 38岁</div></div><span class="tag tag-green">进行中</span></div>
<div class="cc-bottom"><div class="cc-preview">预约时间:今日 14:0014:30 · 已确认</div><span class="cc-time">14:00</span></div>
<div class="cc-top"><div class="cc-avatar" style="background:linear-gradient(135deg,#f6ffed,#b7eb8f);">👩</div><div class="cc-info"><div class="cc-name">刘梅</div><div class="cc-meta">女 · 38岁</div></div><span class="tag tag-green">待开始</span></div>
<div class="cc-bottom"><div class="cc-preview">预约时间:今日 14:0014:30</div><span class="cc-time">14:00</span></div>
</div>
<div style="height:16px;"></div>
</div>
@@ -166,23 +176,35 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<!-- [交互] 点击跳转至: ./video-done.html -->
<div class="consult-card" onclick="location.href='./video-done.html'">
<div class="cc-top"><div class="cc-avatar" style="background:linear-gradient(135deg,#ffe0e0,#ffb3b3);">👩</div><div class="cc-info"><div class="cc-name">孙丽</div><div class="cc-meta">女 · 29岁</div></div><span class="tag tag-green">已完成</span></div>
<div class="cc-bottom"><div class="cc-preview">⭐⭐⭐⭐⭐ 非常专业,感谢!</div><span class="cc-time">昨天</span></div>
<div class="cc-bottom"><div class="cc-preview">完成时间:2026-03-24 13:34</div></div>
</div>
<!-- [交互] 点击跳转至: ./video-done.html -->
<div class="consult-card" onclick="location.href='./video-done.html'">
<!-- [交互] 点击跳转至: ./video-cancelled.html -->
<div class="consult-card" onclick="location.href='./video-cancelled.html'">
<div class="cc-top"><div class="cc-avatar" style="background:linear-gradient(135deg,#e8f4ff,#bdd7ff);">👨</div><div class="cc-info"><div class="cc-name">周明</div><div class="cc-meta">男 · 33岁</div></div><span class="tag tag-gray">已取消</span></div>
<div class="cc-bottom"><div class="cc-preview">用户取消:临时有会议冲突</div><span class="cc-time">昨天</span></div>
<div class="cc-bottom"><div class="cc-preview">取消时间:2026-03-24 13:34</div></div>
</div>
<!-- [交互] 点击跳转至: ./video-done.html -->
<div class="consult-card" onclick="location.href='./video-done.html'">
<!-- [交互] 点击跳转至: ./video-rejected.html -->
<div class="consult-card" onclick="location.href='./video-rejected.html'">
<div class="cc-top"><div class="cc-avatar" style="background:linear-gradient(135deg,#fff7e6,#ffd591);">👩</div><div class="cc-info"><div class="cc-name">吴静</div><div class="cc-meta">女 · 26岁</div></div><span class="tag tag-red">已拒绝</span></div>
<div class="cc-bottom"><div class="cc-preview">该时段已有其他预约安排</div><span class="cc-time">前天</span></div>
<div class="cc-bottom"><div class="cc-preview">拒绝时间:2026-03-24 13:34</div></div>
</div>
<div style="height:16px;"></div>
</div>
</div>
</div>
<!-- 咨询状态切换确认弹窗 -->
<div id="modal-pause" class="modal-center">
<div class="modal-box">
<div class="modal-title" id="pause-modal-title">关闭咨询</div>
<div class="modal-body" id="pause-modal-body">是否要关闭咨询?关闭咨询后,员工无法发起咨询。</div>
<div class="modal-actions">
<button onclick="closeModal('modal-pause')">取消</button>
<button onclick="confirmTogglePause()">确认</button>
</div>
</div>
</div>
<!-- 底部5Tab导航栏 -->
<div class="tab-bar">
<div class="tab-item active" onclick="location.href='./index.html'"><span class="tab-icon">🏥</span><span class="tab-label">工作台</span><span class="tab-badge">3</span></div>
@@ -237,14 +259,22 @@ function switchWorkTab(el, panelId) {
/* 服务状态切换 */
var isPaused = false;
function togglePause() {
var title = isPaused ? '开启咨询' : '关闭咨询';
var body = isPaused ? '是否要开启咨询?开启咨询后,员工可发起咨询。' : '是否要关闭咨询?关闭咨询后,员工无法发起咨询。';
document.getElementById('pause-modal-title').textContent = title;
document.getElementById('pause-modal-body').textContent = body;
openModal('modal-pause');
}
function confirmTogglePause() {
isPaused = !isPaused;
var bg = isPaused ? '#ff4d4f' : '#52c41a';
var text = isPaused ? '关闭咨询' : '开启咨询';
var dot = document.getElementById('pause-dot');
var label = document.getElementById('pause-label');
if (dot) dot.style.background = bg;
if (label) label.textContent = text;
var text = isPaused ? '咨询已关闭' : '咨询已开启';
document.getElementById('pause-dot').style.background = bg;
document.getElementById('pause-label').textContent = text;
closeModal('modal-pause');
}
function openModal(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
function closeModal(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
</script>
</body>
</html>
@@ -53,7 +53,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div style="width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:28px;">👨</div>
<div>
<div style="font-size:17px;font-weight:700;color:#1a1a1a;">赵磊</div>
<div style="font-size:13px;color:#666;margin-top:2px;">采油一厂 · xxx作业区</div>
<div style="font-size:13px;color:#666;margin-top:2px;">男 · 23岁</div>
</div>
<span class="tag tag-green" style="margin-left:auto;">已完成</span>
</div>
@@ -61,6 +61,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div style="background:#f7f8fa;border-radius:10px;padding:14px;">
<div style="font-size:13px;font-weight:600;color:#666;margin-bottom:10px;">📋 咨询信息</div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">咨询类型</span><span style="font-size:13px;color:#1a1a1a;">图文咨询</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">咨询单号</span><span style="font-size:13px;color:#1a1a1a;">ZX202688552270</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">发起时间</span><span style="font-size:13px;color:#1a1a1a;">2026-04-08 08:10</span></div>
<div style="display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #efefef;"><span style="font-size:13px;color:#999;">结束时间</span><span style="font-size:13px;color:#1a1a1a;">2026-04-08 08:40</span></div>
</div>
@@ -57,7 +57,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div style="width:56px;height:56px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:28px;">👨</div>
<div>
<div style="font-size:17px;font-weight:700;color:#1a1a1a;">赵磊</div>
<div style="font-size:13px;color:#666;margin-top:2px;">采油一厂 · xxx作业区</div>
<div style="font-size:13px;color:#666;margin-top:2px;">男 · 23岁</div>
</div>
<span class="tag tag-orange" style="margin-left:auto;">已超时</span>
</div>
+52 -32
View File
@@ -29,6 +29,10 @@
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
.modal-box .modal-actions button:first-child { color: #666; border-right: 1px solid #f0f0f0; }
.modal-box .modal-actions button:last-child { color: #1677ff; font-weight: 600; }
.reject-reason { width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 8px; font-size: 14px; resize: none; font-family: inherit; line-height: 1.5; outline: none; transition: border-color 0.2s; }
.reject-reason:focus { border-color: #1677ff; }
.reject-reason.error { border-color: #ff4d4f; }
.reject-hint { display: none; font-size: 12px; color: #ff4d4f; text-align: left; margin-top: 4px; }
/* ===== 页面专属样式 ===== */
/* 员工信息区 */
@@ -89,64 +93,66 @@
<div class="user-info">
<div class="user-info__avatar"></div>
<div class="user-info__detail">
<div class="user-info__name">王芳 <span class="tag tag-orange">接受</span></div>
<div class="user-info__dept">人事部 · 员工</div>
<div class="user-info__name">王芳 <span class="tag tag-orange">确认</span></div>
<div class="user-info__dept">女 · 45岁</div>
</div>
</div>
<!-- 预约信息卡 -->
<div class="appt-card">
<div class="appt-card__row">
<span class="appt-card__label">预约时间</span>
<span class="appt-card__value appt-card__value--highlight">今日 14:00-14:30</span>
<span class="appt-card__value appt-card__value--highlight">2026-03-24 15:00-15:30</span>
</div>
<div class="appt-card__row">
<span class="appt-card__label">咨询类型</span>
<span class="appt-card__value">视频咨询</span>
</div>
<div class="appt-card__row">
<span class="appt-card__label">预约时间</span>
<span class="appt-card__label">发起时间</span>
<span class="appt-card__value">2026-04-08 09:30</span>
</div>
</div>
<!-- 健康档案(可折叠) -->
<div class="profile-section">
<div class="profile-section__header" onclick="toggleProfile()">
<!-- [交互] 点击跳转至: ../../assistant/workbench/employee-profile.html?from=expert-video-appt -->
<div class="profile-section" onclick="location.href='../../assistant/workbench/employee-profile.html?from=expert-video-appt'" style="cursor:pointer;">
<div class="profile-section__header">
<span class="profile-section__title">咨询人健康档案</span>
<span class="profile-section__arrow" id="profileArrow"></span>
</div>
<div class="profile-section__body" id="profileBody">
<div class="profile-item"><span class="profile-item__label">姓名</span><span class="profile-item__value">王芳</span></div>
<div class="profile-item"><span class="profile-item__label">性别/年龄</span><span class="profile-item__value">女 / 34岁</span></div>
<div class="profile-item"><span class="profile-item__label">身高/体重</span><span class="profile-item__value">160cm / 58kg</span></div>
<div class="profile-item"><span class="profile-item__label">饮酒情况</span><span class="profile-item__value">偶尔饮酒</span></div>
<div class="profile-item"><span class="profile-item__label">饮食习惯</span><span class="profile-item__value profile-item__value--warn">偏油腻</span></div>
<div class="profile-item"><span class="profile-item__label">睡眠质量</span><span class="profile-item__value">一般</span></div>
<div class="profile-item"><span class="profile-item__label">家族病史</span><span class="profile-item__value profile-item__value--warn">高血压</span></div>
<div class="profile-item"><span class="profile-item__label">异常指标</span><span class="profile-item__value profile-item__value--warn">血脂偏高</span></div>
<span style="font-size:12px;color:#999;">查看详情 </span>
</div>
</div>
<!-- 咨询说明 -->
<div class="consult-note">
<div class="consult-note__title">咨询说明</div>
<div class="consult-note__text">最近体检发现血脂偏高,想咨询一下饮食和生活方式方面需要注意什么,以及是否需要进一步检查。</div>
</div>
</div>
<!-- 底部操作按钮 -->
<div class="bottom-actions">
<button class="bottom-actions__btn bottom-actions__btn--reject">拒绝预约</button>
<button class="bottom-actions__btn bottom-actions__btn--reject" onclick="openRejectModal()">拒绝预约</button>
<button class="bottom-actions__btn bottom-actions__btn--accept" onclick="openModal()">接受预约</button>
</div>
<!-- 拒绝确认弹窗 -->
<div class="modal-center" id="rejectModal">
<div class="modal-box">
<div class="modal-title">拒绝预约</div>
<div class="modal-body">
<p style="margin-bottom:10px;color:#666;">是否确认拒绝王芳的视频咨询预约</p>
<textarea class="reject-reason" id="rejectReason" placeholder="请填写拒绝原因(必填)" rows="3"></textarea>
<p class="reject-hint" id="rejectHint">请填写拒绝原因</p>
</div>
<div class="modal-actions">
<button onclick="closeRejectModal()">取消</button>
<button onclick="confirmReject()">确认拒绝</button>
</div>
</div>
</div>
<!-- 接受确认弹窗 -->
<div class="modal-center" id="confirmModal">
<div class="modal-box">
<div class="modal-title">确认接受</div>
<div class="modal-body">确认接受王芳的视频咨询预约?<br>预约时间:今日 14:00-14:30</div>
<div class="modal-body">确认接受王芳的视频咨询预约?<br>预约时间:2026-03-21 14:00-14:30</div>
<div class="modal-actions">
<button onclick="closeModal()">取消</button>
<button onclick="location.href='./index.html'">确认</button>
<button onclick="location.href='./index.html'">确认</button>
</div>
</div>
</div>
</div>
<script>
/* 打开确认弹窗 */
@@ -157,12 +163,26 @@
function closeModal() {
document.getElementById('confirmModal').classList.remove('active');
}
/* 切换健康档案折叠/展开 */
function toggleProfile() {
var body = document.getElementById('profileBody');
var arrow = document.getElementById('profileArrow');
body.classList.toggle('active');
arrow.classList.toggle('profile-section__arrow--open');
/* 打开拒绝弹窗 */
function openRejectModal() {
document.getElementById('rejectReason').value = '';
document.getElementById('rejectReason').classList.remove('error');
document.getElementById('rejectHint').style.display = 'none';
document.getElementById('rejectModal').classList.add('active');
}
/* 关闭拒绝弹窗 */
function closeRejectModal() {
document.getElementById('rejectModal').classList.remove('active');
}
/* 确认拒绝 */
function confirmReject() {
var reason = document.getElementById('rejectReason').value.trim();
if (!reason) {
document.getElementById('rejectReason').classList.add('error');
document.getElementById('rejectHint').style.display = 'block';
return;
}
location.href = './index.html';
}
</script>
</body>
@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>咨询详情(已取消) - 咨询专家</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
.tag-gray { background: #f5f5f5; color: #999; }
.user-info { padding: 16px; background: #fff; display: flex; align-items: center; gap: 12px; }
.user-info__avatar { width: 48px; height: 48px; border-radius: 50%; background: linear-gradient(135deg, #e8f4ff, #bdd7ff); display: flex; align-items: center; justify-content: center; color: #fff; font-size: 18px; font-weight: 600; flex-shrink: 0; }
.user-info__detail { flex: 1; }
.user-info__name { font-size: 16px; font-weight: 600; color: #1a1a1a; }
.user-info__dept { font-size: 13px; color: #999; margin-top: 2px; }
.done-card { margin: 12px 16px; padding: 14px; border-radius: 12px; background: #fafafa; border: 1px solid #e8e8e8; }
.done-card__row { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: 14px; }
.done-card__label { color: #8c8c8c; }
.done-card__value { color: #1a1a1a; font-weight: 500; }
.reason-card { margin: 12px 16px; padding: 14px 16px; border-radius: 12px; background: #f5f5f5; border-left: 4px solid #bfbfbf; }
.reason-card__title { font-size: 14px; font-weight: 600; color: #1a1a1a; margin-bottom: 6px; }
.reason-card__text { font-size: 13px; color: #666; line-height: 1.6; }
.profile-section { margin: 12px 16px; background: #fff; border-radius: 12px; overflow: hidden; }
.profile-section__header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; cursor: pointer; }
.profile-section__title { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.profile-section__arrow { font-size: 12px; color: #999; transition: transform 0.3s; }
.profile-section__arrow--open { transform: rotate(180deg); }
.profile-section__body { display: none; padding: 0 16px 14px; }
.profile-section__body.active { display: block; }
.profile-item { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f5f5f5; font-size: 13px; }
.profile-item:last-child { border-bottom: none; }
.profile-item__label { color: #8c8c8c; }
.profile-item__value { color: #1a1a1a; }
.profile-item__value--warn { color: #fa8c16; }
.consult-note { margin: 12px 16px; background: #fff; border-radius: 12px; padding: 14px 16px; }
.consult-note__title { font-size: 15px; font-weight: 600; color: #1a1a1a; margin-bottom: 8px; }
.consult-note__text { font-size: 14px; color: #666; line-height: 1.6; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<button class="back-btn" onclick="location.href='./index.html'"> 返回</button>
<span class="nav-title">咨询详情</span>
</div>
<div class="scroll-content">
<div class="user-info">
<div class="user-info__avatar"></div>
<div class="user-info__detail">
<div class="user-info__name">周明 <span class="tag tag-gray">已取消</span></div>
<div class="user-info__dept">男 · 42岁</div>
</div>
</div>
<div class="done-card">
<div class="done-card__row">
<span class="done-card__label">预约时间</span>
<span class="done-card__value">2026-03-24 15:00-15:30</span>
</div>
<div class="done-card__row">
<span class="done-card__label">咨询类型</span>
<span class="done-card__value">视频咨询</span>
</div>
<div class="done-card__row">
<span class="done-card__label">取消时间</span>
<span class="done-card__value">2026-03-24 13:34</span>
</div>
<div class="done-card__row">
<span class="done-card__label">取消方</span>
<span class="done-card__value">员工</span>
</div>
</div>
<div class="reason-card">
<div class="reason-card__title">取消原因</div>
<div class="reason-card__text">临时有紧急会议,无法按时参加视频咨询,后续再重新预约。</div>
</div>
<!-- [交互] 点击跳转至: ../../assistant/workbench/employee-profile.html?from=expert-video-cancelled -->
<div class="profile-section" onclick="location.href='../../assistant/workbench/employee-profile.html?from=expert-video-cancelled'" style="cursor:pointer;">
<div class="profile-section__header">
<span class="profile-section__title">咨询人健康档案</span>
<span style="font-size:12px;color:#999;">查看详情 </span>
</div>
</div>
</div>
</div>
<script>
</script>
</body>
</html>
+24 -34
View File
@@ -78,59 +78,49 @@
<div class="user-info__avatar"></div>
<div class="user-info__detail">
<div class="user-info__name">孙丽 <span class="tag tag-gray">已完成</span></div>
<div class="user-info__dept">行政部 · 行政专员</div>
<div class="user-info__dept">女 · 28岁</div>
</div>
</div>
<!-- 完成信息卡(灰色) -->
<div class="done-card">
<div class="done-card__row">
<span class="done-card__label">咨询时间</span>
<span class="done-card__value">昨天 10:00-10:28</span>
<span class="done-card__label">预约时间</span>
<span class="done-card__value">2026-03-24 15:00-15:30</span>
</div>
<div class="done-card__row">
<span class="done-card__label">咨询类型</span>
<span class="done-card__value">视频咨询</span>
</div>
<div class="done-card__row">
<span class="done-card__label">拨打时间</span>
<span class="done-card__value">2026-03-24 15:00</span>
</div>
<div class="done-card__row">
<span class="done-card__label">通话时长</span>
<span class="done-card__value">28分钟</span>
</div>
<div class="done-card__row">
<span class="done-card__label">员工评分</span>
<span class="done-card__stars">★★★★★ 5.0</span>
</div>
</div>
<!-- 员工评价 -->
<div class="feedback-card">
<div class="feedback-card__title">员工评价</div>
<div class="feedback-card__text">"医生非常专业耐心,详细解答了我关于颈椎保养的问题,给出了很实用的建议,非常感谢!"</div>
</div>
<!-- 健康档案(可折叠) -->
<div class="profile-section">
<div class="profile-section__header" onclick="toggleProfile()">
<!-- <div class="feedback-card">-->
<!-- <div class="feedback-card__title">员工评价</div>-->
<!-- <div class="feedback-card__text">"医生非常专业耐心,详细解答了我关于颈椎保养的问题,给出了很实用的建议,非常感谢!"</div>-->
<!-- </div>-->
<!-- [交互] 点击跳转至: ../../assistant/workbench/employee-profile.html?from=expert-video-done -->
<div class="profile-section" onclick="location.href='../../assistant/workbench/employee-profile.html?from=expert-video-done'" style="cursor:pointer;">
<div class="profile-section__header">
<span class="profile-section__title">咨询人健康档案</span>
<span class="profile-section__arrow" id="profileArrow"></span>
</div>
<div class="profile-section__body" id="profileBody">
<div class="profile-item"><span class="profile-item__label">姓名</span><span class="profile-item__value">孙丽</span></div>
<div class="profile-item"><span class="profile-item__label">性别/年龄</span><span class="profile-item__value">女 / 26岁</span></div>
<div class="profile-item"><span class="profile-item__label">身高/体重</span><span class="profile-item__value">162cm / 50kg</span></div>
<div class="profile-item"><span class="profile-item__label">饮食习惯</span><span class="profile-item__value">清淡饮食</span></div>
<div class="profile-item"><span class="profile-item__label">睡眠质量</span><span class="profile-item__value">一般</span></div>
<div class="profile-item"><span class="profile-item__label">健康问题</span><span class="profile-item__value profile-item__value--warn">颈椎不适</span></div>
<span style="font-size:12px;color:#999;">查看详情 </span>
</div>
</div>
<!-- 咨询说明 -->
<div class="consult-note">
<div class="consult-note__title">咨询说明</div>
<div class="consult-note__text">长期伏案工作导致颈椎不适,想了解日常保养方法和是否需要就医检查。</div>
</div>
<!-- <div class="consult-note">-->
<!-- <div class="consult-note__title">咨询说明</div>-->
<!-- <div class="consult-note__text">长期伏案工作导致颈椎不适,想了解日常保养方法和是否需要就医检查。</div>-->
<!-- </div>-->
</div>
</div>
<script>
/* 切换健康档案折叠/展开 */
function toggleProfile() {
var body = document.getElementById('profileBody');
var arrow = document.getElementById('profileArrow');
body.classList.toggle('active');
arrow.classList.toggle('profile-section__arrow--open');
}
</script>
</body>
</html>
@@ -55,7 +55,24 @@
/* 底部操作栏 */
.bottom-actions { padding: 12px 16px 28px; background: #fff; display: flex; gap: 12px; border-top: 1px solid #f0f0f0; flex-shrink: 0; }
.bottom-actions__btn { flex: 1; height: 48px; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; background: #52c41a; border: none; color: #fff; display: flex; align-items: center; justify-content: center; gap: 8px; }
.bottom-actions__btn { flex: 1; height: 48px; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; border: none; color: #fff; display: flex; align-items: center; justify-content: center; gap: 8px; }
.bottom-actions__btn--cancel { background: #fff; border: 1px solid #ff4d4f; color: #ff4d4f; }
.bottom-actions__btn--call { background: #52c41a; }
/* 弹窗样式 */
.modal-center { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.modal-center.active { display: flex; }
.modal-box { width: 280px; background: #fff; border-radius: 16px; overflow: hidden; }
.modal-box .modal-title { padding: 20px 20px 8px; font-size: 17px; font-weight: 700; text-align: center; color: #1a1a1a; }
.modal-box .modal-body { padding: 8px 20px 20px; font-size: 14px; color: #666; text-align: center; line-height: 1.6; }
.modal-box .modal-actions { display: flex; border-top: 1px solid #f0f0f0; }
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
.modal-box .modal-actions button:first-child { color: #666; border-right: 1px solid #f0f0f0; }
.modal-box .modal-actions button:last-child { color: #1677ff; font-weight: 600; }
.cancel-reason { width: 100%; padding: 10px; border: 1px solid #d9d9d9; border-radius: 8px; font-size: 14px; resize: none; font-family: inherit; line-height: 1.5; outline: none; transition: border-color 0.2s; }
.cancel-reason:focus { border-color: #1677ff; }
.cancel-reason.error { border-color: #ff4d4f; }
.cancel-hint { display: none; font-size: 12px; color: #ff4d4f; text-align: left; margin-top: 4px; }
</style>
</head>
<body>
@@ -76,7 +93,7 @@
<div class="user-info">
<div class="user-info__avatar"></div>
<div class="user-info__detail">
<div class="user-info__name">刘梅 <span class="tag tag-green">进行中</span></div>
<div class="user-info__name">刘梅 <span class="tag tag-green">待开始</span></div>
<div class="user-info__dept">财务部 · 会计</div>
</div>
</div>
@@ -84,54 +101,76 @@
<div class="appt-card">
<div class="appt-card__row">
<span class="appt-card__label">预约时间</span>
<span class="appt-card__value appt-card__value--highlight">今日 14:00-14:30</span>
<span class="appt-card__value appt-card__value--highlight">2026-03-24 15:00-15:30</span>
</div>
<div class="appt-card__row">
<span class="appt-card__label">咨询类型</span>
<span class="appt-card__value">视频咨询</span>
</div>
<div class="appt-card__row">
<span class="appt-card__label">状态</span>
<span class="appt-card__value appt-card__value--highlight">已确认</span>
<span class="appt-card__label">发起时间</span>
<span class="appt-card__value">2026-03-21 09:01</span>
</div>
<div class="appt-card__row">
<span class="appt-card__label">接受时间</span>
<span class="appt-card__value">2026-03-21 10:01</span>
</div>
</div>
<!-- 健康档案(可折叠) -->
<div class="profile-section">
<div class="profile-section__header" onclick="toggleProfile()">
<!-- [交互] 点击跳转至: ../../assistant/workbench/employee-profile.html?from=expert-video-ongoing -->
<div class="profile-section" onclick="location.href='../../assistant/workbench/employee-profile.html?from=expert-video-ongoing'" style="cursor:pointer;">
<div class="profile-section__header">
<span class="profile-section__title">咨询人健康档案</span>
<span class="profile-section__arrow" id="profileArrow"></span>
</div>
<div class="profile-section__body" id="profileBody">
<div class="profile-item"><span class="profile-item__label">姓名</span><span class="profile-item__value">刘梅</span></div>
<div class="profile-item"><span class="profile-item__label">性别/年龄</span><span class="profile-item__value">女 / 31岁</span></div>
<div class="profile-item"><span class="profile-item__label">身高/体重</span><span class="profile-item__value">165cm / 55kg</span></div>
<div class="profile-item"><span class="profile-item__label">饮食习惯</span><span class="profile-item__value">均衡饮食</span></div>
<div class="profile-item"><span class="profile-item__label">睡眠质量</span><span class="profile-item__value">良好</span></div>
<div class="profile-item"><span class="profile-item__label">重大病史</span><span class="profile-item__value"></span></div>
<div class="profile-item"><span class="profile-item__label">异常指标</span><span class="profile-item__value profile-item__value--warn">血脂偏高</span></div>
<span style="font-size:12px;color:#999;">查看详情 </span>
</div>
</div>
<!-- 咨询说明 -->
<div class="consult-note">
<div class="consult-note__title">咨询说明</div>
<div class="consult-note__text">近期体检血脂指标偏高,希望了解日常饮食调整建议及是否需要药物干预</div>
<div class="consult-note__text">请在预约时间内发起视频通话</div>
</div>
</div>
<!-- 底部操作按钮 -->
<div class="bottom-actions">
<button class="bottom-actions__btn" onclick="location.href='./video-call.html'">
<button class="bottom-actions__btn bottom-actions__btn--cancel" onclick="openCancelModal()">取消预约</button>
<button class="bottom-actions__btn bottom-actions__btn--call" >
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2" ry="2"/></svg>
发起视频通话
</button>
</div>
<!-- 取消预约确认弹窗 -->
<div class="modal-center" id="cancelModal">
<div class="modal-box">
<div class="modal-title">取消预约</div>
<div class="modal-body">
<p style="margin-bottom:10px;color:#666;">是否确认取消刘梅的视频咨询预约?</p>
<textarea class="cancel-reason" id="cancelReason" placeholder="请填写取消原因(必填)" rows="3"></textarea>
<p class="cancel-hint" id="cancelHint">请填写取消原因</p>
</div>
<div class="modal-actions">
<button onclick="closeCancelModal()">取消</button>
<button onclick="confirmCancel()">确认取消</button>
</div>
</div>
</div>
</div>
<script>
/* 切换健康档案折叠/展开 */
function toggleProfile() {
var body = document.getElementById('profileBody');
var arrow = document.getElementById('profileArrow');
body.classList.toggle('active');
arrow.classList.toggle('profile-section__arrow--open');
function openCancelModal() {
document.getElementById('cancelReason').value = '';
document.getElementById('cancelReason').classList.remove('error');
document.getElementById('cancelHint').style.display = 'none';
document.getElementById('cancelModal').classList.add('active');
}
function closeCancelModal() {
document.getElementById('cancelModal').classList.remove('active');
}
function confirmCancel() {
var reason = document.getElementById('cancelReason').value.trim();
if (!reason) {
document.getElementById('cancelReason').classList.add('error');
document.getElementById('cancelHint').style.display = 'block';
return;
}
location.href = './index.html';
}
</script>
</body>
@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>咨询详情(已拒绝) - 咨询专家</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
.tag-red { background: #fff1f0; color: #ff4d4f; }
.user-info { padding: 16px; background: #fff; display: flex; align-items: center; gap: 12px; }
.user-info__avatar { width: 48px; height: 48px; border-radius: 50%; background: linear-gradient(135deg, #fff7e6, #ffd591); display: flex; align-items: center; justify-content: center; color: #fff; font-size: 18px; font-weight: 600; flex-shrink: 0; }
.user-info__detail { flex: 1; }
.user-info__name { font-size: 16px; font-weight: 600; color: #1a1a1a; }
.user-info__dept { font-size: 13px; color: #999; margin-top: 2px; }
.done-card { margin: 12px 16px; padding: 14px; border-radius: 12px; background: #fafafa; border: 1px solid #e8e8e8; }
.done-card__row { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: 14px; }
.done-card__label { color: #8c8c8c; }
.done-card__value { color: #1a1a1a; font-weight: 500; }
.reason-card { margin: 12px 16px; padding: 14px 16px; border-radius: 12px; background: #fff1f0; border-left: 4px solid #ff4d4f; }
.reason-card__title { font-size: 14px; font-weight: 600; color: #1a1a1a; margin-bottom: 6px; }
.reason-card__text { font-size: 13px; color: #666; line-height: 1.6; }
.profile-section { margin: 12px 16px; background: #fff; border-radius: 12px; overflow: hidden; }
.profile-section__header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; cursor: pointer; }
.profile-section__title { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.profile-section__arrow { font-size: 12px; color: #999; transition: transform 0.3s; }
.profile-section__arrow--open { transform: rotate(180deg); }
.profile-section__body { display: none; padding: 0 16px 14px; }
.profile-section__body.active { display: block; }
.profile-item { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f5f5f5; font-size: 13px; }
.profile-item:last-child { border-bottom: none; }
.profile-item__label { color: #8c8c8c; }
.profile-item__value { color: #1a1a1a; }
.profile-item__value--warn { color: #fa8c16; }
.consult-note { margin: 12px 16px; background: #fff; border-radius: 12px; padding: 14px 16px; }
.consult-note__title { font-size: 15px; font-weight: 600; color: #1a1a1a; margin-bottom: 8px; }
.consult-note__text { font-size: 14px; color: #666; line-height: 1.6; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<button class="back-btn" onclick="location.href='./index.html'"> 返回</button>
<span class="nav-title">咨询详情</span>
</div>
<div class="scroll-content">
<div class="user-info">
<div class="user-info__avatar"></div>
<div class="user-info__detail">
<div class="user-info__name">吴静 <span class="tag tag-red">已拒绝</span></div>
<div class="user-info__dept">男 · 24岁</div>
</div>
</div>
<div class="done-card">
<div class="done-card__row">
<span class="done-card__label">预约时间</span>
<span class="done-card__value">2026-03-24 15:00-15:30</span>
</div>
<div class="done-card__row">
<span class="done-card__label">咨询类型</span>
<span class="done-card__value">视频咨询</span>
</div>
<div class="done-card__row">
<span class="done-card__label">拒绝时间</span>
<span class="done-card__value">2026-03-24 13:34</span>
</div>
<div class="done-card__row">
<span class="done-card__label">拒绝方</span>
<span class="done-card__value">专家(王医生)</span>
</div>
</div>
<div class="reason-card">
<div class="reason-card__title">拒绝原因</div>
<div class="reason-card__text">该时段已有其他紧急咨询安排,建议员工改约其他时间或选择其他专家。</div>
</div>
<!-- [交互] 点击跳转至: ../../assistant/workbench/employee-profile.html?from=expert-video-rejected -->
<div class="profile-section" onclick="location.href='../../assistant/workbench/employee-profile.html?from=expert-video-rejected'" style="cursor:pointer;">
<div class="profile-section__header">
<span class="profile-section__title">咨询人健康档案</span>
<span style="font-size:12px;color:#999;">查看详情 </span>
</div>
</div>
</div>
</div>
<script>
</script>
</body>
</html>
+2
View File
@@ -286,6 +286,7 @@ const SITE_MAP = [
{file:'text-consult-done.html',label:'咨询完成'},{file:'consult-person-detail.html',label:'咨询人档案'},
{file:'video-appt.html',label:'视频预约'},{file:'video-call.html',label:'视频通话'},
{file:'video-done.html',label:'视频完成'},{file:'video-ongoing.html',label:'视频进行中'},
{file:'video-cancelled.html',label:'视频已取消'},{file:'video-rejected.html',label:'视频已拒绝'},
{file:'employee-profile.html',label:'员工档案'}
]},
{ name:'知识库', dir:'emergency-app/expert/knowledge', pages:[
@@ -293,6 +294,7 @@ const SITE_MAP = [
]},
{ name:'我的', dir:'emergency-app/expert/profile', pages:[
{file:'index.html',label:'个人中心'},{file:'edit-profile.html',label:'编辑资料'},
{file:'edit-diseases.html',label:'擅长疾病'},
{file:'change-pwd.html',label:'修改密码'},{file:'schedule.html',label:'排班设置'},
{file:'stats.html',label:'咨询统计'},{file:'reviews.html',label:'我的评价'}
]}
@@ -121,6 +121,10 @@
<div class="sub-title">本次档案</div>
<div class="archive-block">
<div class="archive-row">
<span class="archive-label">档案名称</span>
<span class="archive-value">久坐腰部疼痛</span>
</div>
<div class="archive-row">
<span class="archive-label">问题描述</span>
<span class="archive-value">久坐后腰部持续酸痛,弯腰时加重,近两周症状明显,影响日常工作和休息。</span>
@@ -137,6 +141,8 @@
</div>
</div>
<div class="archive-row archive-row--divided">
<span class="archive-label">是否前往医院就诊</span>
<span class="archive-value"></span>
<span class="archive-label">医院名称</span>
<span class="archive-value">北京协和医院</span>
<span class="archive-label" style="margin-left:auto;">科室</span>
+1 -1
View File
@@ -378,7 +378,7 @@ window.location.href = '../health-consult/consult-list.html';
面向研发人员的产品需求文档,要求简洁、条理清晰,包含以下结构:
1. **模块概述**:一段话简要说明模块功能 + 页面导航结构树 + 状态流转图(Mermaid)
2. **页面清单**:表格列出所有功能页面、弹窗、内嵌功能页、结果态页面,页面清单根据业务分类(公用的页面不重复罗列)
2. **页面清单**:表格列出所有功能页面、弹窗、内嵌功能页、结果态页面,页面清单根据业务分类(同一个PRD文档内公用的页面不重复罗列)
3. **逐页说明**:自动按业务流程顺序组织,WEB后台按一级菜单顺序分类罗列,APP端按每个业务线分类罗列,每个页面/弹窗/内嵌功能页/结果态页面包含以下维度:
- **页面截图**:在标题下方紧跟截图引用(格式见 7.4)
- **功能说明**:页面用途和核心 UI 元素