员工端 App — CUJ 关键用户旅程

关键用户旅程 | 24 个页面 - 9 个 CUJ - 37+ E2E 测试

CUJ 总览

CUJ 优先级 描述 触发点 业务价值 E2E 测试状态
E-CUJ-1 P0 每日打卡签到/签退 员工到达工作地点 薪资准确性、考勤追踪 已覆盖
E-CUJ-2 P0 查看我的排班 员工查看每周排班 团队协调 已覆盖
E-CUJ-3 P0 登录认证 + PIN 设置 首次登录或会话过期 安全门控 已覆盖
E-CUJ-4 P1 我的服务与预约 员工查看分配的服务 服务交付、小费/评价追踪 已覆盖
E-CUJ-5 P1 换班与请假申请 员工需要调整排班 灵活性、减少缺勤 已覆盖
E-CUJ-6 P1 团队聊天与消息 员工需要与团队沟通 团队协作、减少沟通失误 已覆盖
E-CUJ-7 P2 查看公告 管理层发布公告 信息传达、制度合规 已覆盖
E-CUJ-8 P2 查看报表(仅限管理员) 管理员需要绩效数据 数据驱动决策、绩效监控 已覆盖
E-CUJ-9 P2 个人资料与设置 员工管理个人资料/通知 自助服务、通知控制 已覆盖

E-CUJ-1: 每日打卡签到/签退 P0

触发点 员工到达工作地点
业务价值 薪资准确性、考勤追踪
E2E 测试状态 已覆盖

用户流程

flowchart TD A["首页"] --> B["打卡页签"] B --> C{"当前状态"} C -->|"未签到"| D["签到按钮"] C -->|"已签到"| E["签退 / 休息按钮"] D --> F["提交签到"] F --> G["成功: 状态更新"] E --> H["签退 / 开始休息"] H --> I["状态更新"] B --> J["查看考勤记录"] J --> K["补卡申请"] K --> L["提交补卡"]

BDD 场景

场景 1.1: 签到
Given 员工已登录且尚未签到
When 员工点击打卡页签
Then 显示"签到"按钮
When 员工点击"签到"
Then 创建一条签到记录
And 状态变更为"已签到"
And 出现"签退"和"休息"按钮
场景 1.2: 签退
Given 员工已签到
When 员工点击"签退"
Then 签退时间被记录
And 状态变更为"未签到"
And 计算总工作时长
场景 1.3: 查看考勤记录
Given 员工在当前薪资周期内有打卡记录
When 员工导航到 个人资料 > 考勤记录
Then 显示所有考勤条目
And 每条记录显示日期、签到/签退时间和总工时
场景 1.4: 补卡申请
Given 员工有一次漏打卡记录
When 员工导航到 个人资料 > 考勤记录 > 补卡申请
And 输入缺失的日期、时间和原因
And 提交申请
Then 补卡申请显示为"待审批"状态
And 申请已发送给管理层审批
测试文件:
integration_test/t03_time_clock_test.dart (4 个场景)
integration_test/t12_clock_deep_test.dart (6 个场景)

E-CUJ-2: 查看我的排班 P0

触发点 员工查看每周排班
业务价值 团队协调
E2E 测试状态 已覆盖

用户流程

flowchart TD A["首页"] --> B["排班页签"] B --> C["本周视图"] C --> D["每日班次卡片"] D --> E{"操作"} E --> F["查看上一周"] E --> G["查看下一周"] E --> H["切换团队视图"] F --> C G --> C H --> I["团队排班表格"]

BDD 场景

场景 2.1: 查看每周排班
Given 员工已登录
And 员工本周被分配了 3 个班次
When 员工点击排班页签
Then 显示本周日程(周一至周日)
And 每天显示班次时间段或"休息日"
And 今天的日期高亮显示
场景 2.2: 切换周次
Given 员工正在查看本周排班
When 员工点击下一周箭头
Then 排班切换到下一周
When 员工点击上一周箭头
Then 排班切换到上一周
测试文件:
integration_test/t05_schedule_view_test.dart (3 个场景)
integration_test/t17_schedule_deep_test.dart (5 个场景)

E-CUJ-3: 登录认证 + PIN 设置 P0

触发点 首次登录或会话过期
业务价值 安全门控
E2E 测试状态 已覆盖

用户流程

flowchart TD A["启动 App"] --> B["启动页"] B --> C{"有会话?"} C -->|"否"| D["登录页"] C -->|"是"| E{"有 PIN?"} E -->|"否"| F["PIN 设置页"] E -->|"是"| G["PIN 输入页"] D --> H["输入邮箱/密码"] H --> I["API: POST /auth/employee/login"] I --> J{"成功?"} J -->|"是"| K["将 JWT 存入 SecureStorage"] K --> F F --> L["创建 4 位 PIN"] L --> M["确认 PIN"] M --> N["将 PIN 存入数据库"] N --> O["跳转到首页"] G --> P["输入 PIN"] P --> Q{"PIN 正确?"} Q -->|"是"| O Q -->|"否"| R["显示错误"]

BDD 场景

场景 3.1: 首次登录 + PIN 设置
Given 员工从未登录过
When 员工启动 App
Then 显示登录页面
When 员工输入有效的邮箱和密码
And 点击"登录"
Then JWT 令牌存入 SecureStorage
And 显示 PIN 设置页面
When 员工输入 4 位 PIN 并确认
Then PIN 存入数据库
And 员工跳转到首页
场景 3.2: 再次登录 - PIN 验证
Given 员工已设置过 PIN
And 存有有效的 JWT
When 员工启动 App
Then 显示 PIN 输入页面
When 员工输入正确的 PIN
Then 员工直接跳转到首页
测试文件:
integration_test/t01_auth_flow_test.dart (真实后端, 2 个场景)
integration_test/mock/t01_auth_flow_test.dart (Mock API, 2 个场景)
integration_test/mock/t02_pin_setup_test.dart (Mock API, 3 个场景)

E-CUJ-4: 我的服务与预约 P1

触发点 员工查看分配的服务
业务价值 服务交付、小费/评价追踪
E2E 测试状态 已覆盖

用户流程

flowchart TD A["首页"] --> B["我的服务页签"] B --> C["服务列表"] C --> D{"筛选/搜索"} D --> E["按状态筛选"] D --> F["按服务名搜索"] C --> G["点击服务卡片"] G --> H["服务详情页"] H --> I{"操作"} I --> J["查看客户信息"] I --> K["提交小费"] I --> L["查看评价"] K --> M["输入小费金额"] M --> N["保存小费"]

BDD 场景

场景 4.1: 查看服务列表
Given 员工已登录
And 员工今日有 5 个分配的服务
When 员工点击"我的服务"页签
Then 列表中显示全部 5 个服务
And 每张卡片显示服务名称、客户姓名、时间和状态
场景 4.2: 提交小费
Given 员工正在查看一个已完成服务的详情
When 员工点击"小费"区域
And 输入小费金额 $15.00
And 点击"保存"
Then 小费已记录
And 显示成功提示
测试文件:
integration_test/t04_my_services_test.dart (3 个场景)
integration_test/t13_service_detail_test.dart (4 个场景)
integration_test/t14_review_tip_flow_test.dart (4 个场景)
integration_test/t16_services_filter_test.dart (3 个场景)

E-CUJ-5: 换班与请假申请 P1

触发点 员工需要调整排班
业务价值 灵活性、减少缺勤
E2E 测试状态 已覆盖

用户流程

flowchart TD A["排班页签"] --> B["换班/请假按钮"] B --> C["申请列表"] C --> D{"申请类型"} D --> E["创建换班申请"] D --> F["创建请假申请"] E --> G["选择要换的班次"] G --> H["选择目标员工"] H --> I["输入原因"] I --> J["提交换班申请"] J --> K["状态: 待处理"] F --> L["选择日期范围"] L --> M["输入请假原因"] M --> N["提交请假申请"] N --> O["状态: 待审批"]

BDD 场景

场景 5.1: 创建换班申请
Given 员工在周三有一个班次
When 员工导航到 排班 > 换班/请假
And 点击"创建换班申请"
And 选择周三的班次
And 选择一位同事
And 输入原因"需要去看诊"
And 提交申请
Then 换班申请显示为"待处理"状态
场景 5.2: 创建请假申请
Given 员工希望请假
When 员工导航到 排班 > 换班/请假
And 点击"创建请假申请"
And 选择开始日期(12月20日)和结束日期(12月22日)
And 输入原因"家庭旅行"
And 提交申请
Then 请假申请显示为"待审批"状态
测试文件:
integration_test/t08_swap_leave_test.dart (4 个场景)
integration_test/t15_swap_leave_create_test.dart (5 个场景)

E-CUJ-6: 团队聊天与消息 P1

触发点 员工需要与团队沟通
业务价值 团队协作、减少沟通失误、实时协同
E2E 测试状态 已覆盖

用户流程

flowchart TD A["首页"] --> B["消息页签"] B --> C["会话列表"] C --> D["点击会话"] D --> E["聊天页 - 实时 WebSocket"] E --> F{"操作"} F --> G["发送消息"] F --> H["查看输入中指示器"] F --> I["菜单: 静音/退出"] C --> J["浮动按钮: 新建聊天"] J --> K["选择成员"] K --> L["创建单聊或群聊"] B --> M["公告图标"] M --> N["公告页面"]

BDD 场景

场景 6.1: 查看会话列表
Given 员工已登录且有现有会话
When 员工点击消息页签
Then 显示带有未读角标的会话列表
And 每个会话显示最后一条消息预览和时间戳
场景 6.2: 在聊天中发送消息
Given 员工在一个聊天会话中
When 员工输入一条消息并点击发送
Then 消息以气泡形式显示在右侧
And 接收方通过 WebSocket 实时收到消息
场景 6.3: 创建新的群聊
Given 员工点击新建聊天按钮
When 员工选择 3 位团队成员
And 输入群组名称"早班团队"
And 输入第一条消息"早上好团队!"
And 点击"创建群聊"
Then 创建一个新的群组会话
And 员工被重定向到聊天页面
场景 6.4: 静音/退出会话
Given 员工在聊天页面中
When 员工点击静音图标
Then 会话被静音(不再收到推送通知)
When 员工从菜单选择"退出会话"
Then 显示确认弹窗
And 确认后,员工被重定向到消息列表
测试文件:
integration_test/t06_messages_chat_test.dart (5 个场景)
integration_test/t11_chat_realtime_test.dart (3 个场景)

E-CUJ-7: 查看公告 P2

触发点 管理层发布公告
业务价值 信息传达、团队对齐、制度合规
E2E 测试状态 已覆盖

用户流程

flowchart TD A["消息页签"] --> B["公告图标"] B --> C["公告页面"] C --> D["带优先级标识的列表"] D --> E{"优先级"} E -->|"紧急"| F["红色角标"] E -->|"重要"| G["黄色角标"] E -->|"普通"| H["无角标"] D --> I["点击公告"] I --> J["底部弹窗: 完整内容"] J --> K["自动标记为已读"] C --> L["下拉刷新"]

BDD 场景

场景 7.1: 查看公告列表
Given 管理层已发布 5 条公告(2 条紧急, 3 条普通)
When 员工打开公告页面
Then 显示全部 5 条公告
And 紧急公告显示红色"紧急"角标
And 未读公告标题加粗并带有指示点
场景 7.2: 阅读公告详情
Given 有一条未读公告"排班变更通知"
When 员工点击该公告卡片
Then 底部弹窗显示完整内容
And 公告自动标记为已读
And 未读计数减少 1
测试文件:
integration_test/t09_announcements_test.dart (4 个场景)
integration_test/t19_announcements_deep_test.dart (6 个场景)

E-CUJ-8: 查看报表 — 仅限管理员 P2

触发点 管理员需要绩效数据
业务价值 数据驱动决策、绩效监控
E2E 测试状态 已覆盖
注意: 报表页签仅对 manager 及以上角色可见(manager, super_admin, platform_superadmin)

用户流程

flowchart TD A["报表页签"] --> B{"角色检查"} B -->|"管理员+"| C["报表类型选择"] B -->|"普通员工"| D["页签隐藏"] C --> E["KPI 仪表板"] C --> F["经营报表"] C --> G["销售报表"] C --> H["员工绩效"] E --> I["报表数据页"] F --> I G --> I H --> I I --> J["长按复制数据"]

BDD 场景

场景 8.1: 访问报表(管理员)
Given 员工以具备对应权限与范围(scope)的账号登录
When 员工点击报表页签
Then 显示 4 种报表类型: KPI、经营、销售、员工绩效
场景 8.2: 查看 KPI 仪表板
Given 用户已登录并拥有对应功能所需权限与范围(scope),在报表页面
When 用户点击"KPI 仪表板"
Then KPI 数据加载并显示
And 数据显示字段数和条目数
场景 8.3: 普通员工不可见报表
Given 员工以无对应权限的普通账号登录
Then 底部导航栏中不显示报表页签
测试文件:
integration_test/t07_reports_test.dart (6 个场景)

E-CUJ-9: 个人资料与设置 P2

触发点 员工管理个人资料/通知
业务价值 自助资料管理、通知控制、会话管理
E2E 测试状态 已覆盖

用户流程

flowchart TD A["个人资料页签"] --> B["设置页面"] B --> C["个人资料卡片"] C --> D["头像、姓名、邮箱、角色"] B --> E{"功能区域"} E --> F["工作: 考勤记录 / 工资单"] E --> G["偏好: 通知 / 语言"] E --> H["关于: 关于 App / 隐私政策"] E --> I["退出登录"] G --> J["通知子页面"] J --> K["渠道开关: Push/邮件/短信"] K --> L["内容开关: 预约/排班/系统/营销"] L --> M["注册推送令牌"] M --> N["保存设置"] I --> O["确认弹窗"] O --> P["清除会话令牌"] P --> Q["跳转到登录页"]

BDD 场景

场景 9.1: 查看个人资料
Given 员工已登录
When 员工点击个人资料页签
Then 资料卡片显示头像、姓名、邮箱和角色标签
场景 9.2: 管理通知偏好
Given 员工在设置页面
When 员工点击"通知"
Then 通知设置页显示渠道开关(Push/邮件/短信)
And 内容偏好开关(预约/排班/系统/营销)
When 员工关闭 Push 通知并保存
Then 设置已持久化
场景 9.3: 退出登录流程
Given 员工在设置页面
When 员工点击"退出登录"
Then 显示确认弹窗
When 员工确认
Then 员工被重定向到登录页面
And 会话令牌已清除
测试文件:
integration_test/t10_settings_profile_test.dart (6 个场景)
integration_test/t18_settings_deep_test.dart (7 个场景)

覆盖率总览

CUJ E2E 测试 Widget 测试 单元测试 状态
E-CUJ-1 每日打卡签到/签退 t03 (4), t12 (6) 3 个 Widget 测试 8 个单元测试 完整
E-CUJ-2 查看我的排班 t05 (3), t17 (5) 2 个 Widget 测试 5 个单元测试 完整
E-CUJ-3 登录认证 + PIN 设置 t01 (2), mock/t01 (2), mock/t02 (3) 4 个 Widget 测试 12 个单元测试 完整
E-CUJ-4 我的服务与预约 t04 (3), t13 (4), t14 (4), t16 (3) 5 个 Widget 测试 7 个单元测试 完整
E-CUJ-5 换班与请假申请 t08 (4), t15 (5) 3 个 Widget 测试 6 个单元测试 完整
E-CUJ-6 团队聊天与消息 t06 (5), t11 (3) 4 个 Widget 测试 10 个单元测试 完整
E-CUJ-7 查看公告 t09 (4), t19 (6) 2 个 Widget 测试 4 个单元测试 完整
E-CUJ-8 查看报表(仅限管理员) t07 (6) 2 个 Widget 测试 3 个单元测试 完整
E-CUJ-9 个人资料与设置 t10 (6), t18 (7) 5 个 Widget 测试 8 个单元测试 完整
关键洞察:
  • 全部 9 个 CUJ 均具有完整的 E2E 测试覆盖(24 个测试文件中的 37+ 测试场景)
  • P0/P1 CUJ 优先获得最深度覆盖(每个 10+ 场景)
  • 仅限管理员的功能(E-CUJ-8)包含基于角色的可见性测试
  • 实时功能(聊天、公告)通过 WebSocket 集成测试覆盖
  • 安全门控(E-CUJ-3)同时包含 Mock 和真实后端测试
  • 测试总计: 37+ E2E 场景 + 30+ Widget 测试 + 63+ 单元测试