fix: 修复员工端离职申请创建时缺少checklist和type字段导致内部错误; 新增E2E测试场景文档

This commit is contained in:
selfrelease
2026-08-01 19:05:20 +08:00
parent b0942f3e61
commit 787897e6d3
3 changed files with 2627 additions and 0 deletions
+3
View File
@@ -792,9 +792,12 @@ router.post('/resignation/submit', portalAuth, async (req: any, res, next) => {
const record = await (prisma as any).terminationRecord.create({
data: {
employeeId, orgId,
type: 'RESIGNATION',
reason: 'RESIGNATION',
resignationReason: reason,
terminationDate: new Date(expectedDate),
status: 'PENDING_APPROVAL',
checklist: [],
remark: `员工自主申请:${reason}${remark ? ';备注:' + remark : ''}`,
createdBy: employeeId,
},
+707
View File
@@ -0,0 +1,707 @@
# TurboHR 企业全流程端到端测试场景
> **场景背景**:模拟一家新企业「上海明远制造有限公司」从零开始使用 TurboHR 的完整过程。
> 包括:平台创建租户 → 企业管理员首次登录 → 企业配置 → 线下数据导入 → 日常操作 → 月度闭环 → 员工端使用
> **测试环境**: https://on.hr8ai.top
> **日期范围**: 2026-08-01 ~ 2026-08-31
---
## 角色与账号
| 角色 | 手机号 | 密码 | 说明 |
|------|--------|------|------|
| 平台超管 | `superadmin` | (平台管理端密码) | SUPER_ADMIN,创建租户 |
| 企业管理员 | `13900005555` | `Init123456` | 新建租户的管理员 |
| HR 李萍 | `13900006666` | `Hr123456` | 企业内新增的 HR 用户 |
| 员工 张伟 | `13900007777` | (初始密码/验证码) | 生产车间,通过导入创建 |
| 员工 王芳 | `13900007888` | (初始密码/验证码) | 行政部,通过导入创建 |
---
## 阶段一:租户创建与初始化
### E2E-001 平台管理员创建新企业
| 项目 | 内容 |
|------|------|
| **角色** | 平台超管(SUPER_ADMIN |
| **Input** | POST `/api/v1/auth/platform-login` `{ phone: "superadmin", password: "xxx" }` |
| **Process** | 1. 平台超管登录 → 2. 进入 `/platform/orgs` → 3. 点击「新建组织」→ 4. 填写企业信息并提交 |
| **Input(创建组织)** | POST `/api/v1/platform/orgs` `{ name: "上海明远制造有限公司", contactName: "刘明远", contactPhone: "13900005555", adminName: "刘明远", adminPhone: "13900005555", adminPassword: "Init123456", city: "上海", plan: "PRO", maxEmployees: 50, payrollFrequency: 1 }` |
| **Output** | HTTP 201`{ success: true, data: { id: "org-new-id", name: "上海明远制造有限公司", plan: "PRO", maxEmployees: 50 } }` |
| **验证** | 组织列表中出现「上海明远制造有限公司」,套餐 PRO,员工上限 50 |
### E2E-002 企业管理员首次登录
| 项目 | 内容 |
|------|------|
| **角色** | 企业管理员(刘明远) |
| **Input** | POST `/api/v1/auth/login` `{ phone: "13900005555", password: "Init123456" }` |
| **Process** | 1. 访问登录页 → 2. 输入手机号和初始密码 → 3. 点击登录 |
| **Output** | HTTP 200`{ success: true, data: { user: { id: "u-new", name: "刘明远", role: "ADMIN", phone: "13900005555" }, accessToken: "jwt-xxx", refreshToken: "jwt-refresh-xxx" } }` |
| **验证** | 跳转至 `/dashboard`,仪表盘显示空数据(0 员工、0 待办、0 风险) |
### E2E-003 完善企业信息
| 项目 | 内容 |
|------|------|
| **角色** | 企业管理员 |
| **Input** | PUT `/api/v1/settings/org` `{ name: "上海明远制造有限公司", contactName: "刘明远", contactPhone: "13900005555", city: "上海", payrollFrequency: 1, retirementReminderEnabled: true }` |
| **Process** | 进入 `/settings` → 企业信息 → 修改/完善信息 → 保存 |
| **Output** | HTTP 200`{ success: true }` |
| **验证** | 设置页显示更新后的企业名称「上海明远制造有限公司」,城市「上海」,发薪次数 1 次/月 |
### E2E-004 添加 HR 用户
| 项目 | 内容 |
|------|------|
| **角色** | 企业管理员 |
| **Input** | POST `/api/v1/settings/users` `{ name: "李萍", phone: "13900006666", password: "Hr123456", role: "HR" }` |
| **Process** | 进入 `/settings` → 用户管理 → 点击「添加用户」→ 填写 HR 信息 → 保存 |
| **Output** | HTTP 201`{ success: true, data: { id: "u-hr", name: "李萍", phone: "13900006666", role: "HR" } }` |
| **验证** | 用户列表显示 2 人:刘明远(ADMIN)、李萍(HR) |
### E2E-005 HR 用户登录验证
| 项目 | 内容 |
|------|------|
| **角色** | HR(李萍) |
| **Input** | POST `/api/v1/auth/login` `{ phone: "13900006666", password: "Hr123456" }` |
| **Process** | 退出管理员账号 → 用 HR 账号登录 |
| **Output** | HTTP 200`{ success: true, data: { user: { name: "李萍", role: "HR" } } }` |
| **验证** | 成功登录,跳转至 `/dashboard`,HR 角色可访问花名册、考勤、薪酬等模块 |
---
## 阶段二:线下数据导入
### E2E-006 批量导入员工花名册
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | `FormData { file: 明远制造_花名册.xlsx }` |
| **文件内容** | Excel 包含以下列:姓名、性别、身份证号、手机号、部门、岗位、入职日期、月薪、合同类型、合同开始、合同结束 |
| **示例数据** | 张伟, 男, 310101199001011234, 13900007777, 生产车间, 操作工, 2022-03-01, 8000, 固定期限, 2022-03-01, 2025-02-28 |
| | 王芳, 女, 310102199505052345, 13900007888, 行政部, 行政专员, 2023-06-01, 9000, 固定期限, 2023-06-01, 2026-05-31 |
| | 陈强, 男, 310103199207073456, 13900007999, 生产车间, 技术员, 2021-01-01, 10000, 无固定期限, 2021-01-01, |
| | 赵敏, 女, 310104199808084567, 13900008000, 质检部, 质检员, 2024-01-01, 8500, 固定期限, 2024-01-01, 2027-12-31 |
| **Process** | 进入 `/roster` → 点击「批量导入」→ 上传 Excel 文件 → 确认导入 |
| **Output** | HTTP 200`{ success: true, data: { total: 4, success: 4, failed: 0, errors: [] } }` |
| **验证** | 花名册列表显示 4 名员工,部门分布:生产车间 2 人、行政部 1 人、质检部 1 人 |
### E2E-007 验证导入数据完整性
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/employees?page=1&pageSize=10` |
| **Process** | 进入花名册 → 逐条检查员工信息 |
| **Output** | `{ data: [{ id: "e1", name: "张伟", gender: "男", phone: "13900007777", department: "生产车间", position: "操作工", hireDate: "2022-03-01", monthlySalary: 8000, contractType: "FIXED", contractStart: "2022-03-01", contractEnd: "2025-02-28", status: "ACTIVE" }, { id: "e2", name: "王芳", ... }, { id: "e3", name: "陈强", ... }, { id: "e4", name: "赵敏", ... }], pagination: { total: 4 } }` |
| **验证** | 4 名员工信息与导入文件一致,状态均为 ACTIVE |
### E2E-008 手动补充员工档案详情
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | PUT `/api/v1/employees/e1` `{ emergencyContact: "张父", emergencyPhone: "13800001111", bank: "工商银行", account: "6222020100011234", address: "上海市浦东新区测试路100号", education: "高中", nativePlace: "安徽合肥" }` |
| **Process** | 花名册 → 点击「张伟」→ 员工详情 → 编辑档案 → 补充紧急联系人、银行账户、地址等 → 保存 |
| **Output** | HTTP 200`{ success: true }` |
| **验证** | 员工详情页显示完整的档案信息 |
### E2E-009 导入考勤数据
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | `FormData { file: 明远制造_考勤_2026-07.xlsx, month: "2026-07" }` |
| **文件内容** | Excel 包含:员工姓名、日期、上班打卡、下班打卡、状态 |
| **示例数据** | 张伟, 2026-07-01, 08:50, 18:10, 正常; 张伟, 2026-07-02, 09:05, 18:00, 迟到; 王芳, 2026-07-01, 08:45, 18:30, 正常; ... |
| **Process** | 进入 `/attendance` → 点击「导入考勤」→ 选择月份 2026-07 → 上传文件 → 确认 |
| **Output** | HTTP 200`{ success: true, data: { total: 88, success: 86, failed: 2, errors: [{ row: 45, message: "2026-07-15 为周末,非排班日" }, { row: 88, message: "下班打卡时间早于上班打卡" }] } }` |
| **验证** | 考勤列表显示 2026-07 月数据,统计:张伟迟到 1 次,王芳全勤 |
### E2E-010 配置考勤班次
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/attendance/shifts` `{ name: "白班", startTime: "08:00", endTime: "17:00", restMinutes: 60, color: "#4CAF50" }` |
| **Process** | 进入 `/attendance` → 班次管理 → 新建班次 → 填写信息 → 保存 |
| **Output** | HTTP 201`{ success: true, data: { id: "shift1", name: "白班", startTime: "08:00", endTime: "17:00" } }` |
| **验证** | 班次列表显示「白班」 |
### E2E-011 分配班次
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/attendance/shift-assignments` `{ employeeId: "e1", shiftId: "shift1", startDate: "2026-08-01", endDate: "2026-08-31" }` |
| **Process** | 考勤 → 排班 → 选择员工张伟 → 分配白班 → 保存 |
| **Output** | HTTP 201`{ success: true }` |
| **验证** | 排班表显示张伟 8 月全月白班 |
---
## 阶段三:社保与薪酬配置
### E2E-012 配置社保公积金
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/social/config` `{ city: "上海", effectiveFrom: "2026-07-01", type: "social", baseMin: 7384, baseMax: 36921, pension: { emp: 8, corp: 16 }, medical: { emp: 2, corp: 10 }, unemployment: { emp: 0.5, corp: 0.5 }, injury: { emp: 0, corp: 0.26 }, maternity: { emp: 0, corp: 1 } }` |
| **Process** | 进入 `/social-insurance` → 社保配置 → 新建配置 → 选择城市「上海」→ 填写基数和比例 → 保存 |
| **Output** | HTTP 201`{ success: true, data: { id: "sc1", city: "上海", isCurrent: true } }` |
| **验证** | 社保配置页显示上海当前生效配置,下限 7384,上限 36921 |
### E2E-013 配置公积金
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/social/config` `{ city: "上海", effectiveFrom: "2026-07-01", type: "housing", baseMin: 2800, baseMax: 36921, empRate: 7, corpRate: 7, supplementRate: 0 }` |
| **Process** | 社保公积金页 → 公积金配置 tab → 新建 → 填写 → 保存 |
| **Output** | HTTP 201`{ success: true, data: { id: "hc1", city: "上海", type: "housing", isCurrent: true } }` |
| **验证** | 公积金配置显示上海当前配置,个人 7%,企业 7% |
### E2E-014 创建薪酬模板
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/payroll/templates` `{ name: "明远制造标准模板", items: [{ name: "基本工资", type: "INCOME", formula: "monthlySalary", taxable: true }, { name: "岗位津贴", type: "INCOME", formula: "500", taxable: true }, { name: "交通补贴", type: "INCOME", formula: "200", taxable: false }, { name: "社保个人", type: "DEDUCT", formula: "socialEmp", taxable: false }, { name: "公积金个人", type: "DEDUCT", formula: "housingEmp", taxable: false }, { name: "个人所得税", type: "DEDUCT", formula: "tax", taxable: false }] }` |
| **Process** | 进入 `/money` → 薪酬模板 → 新建模板 → 添加薪资项 → 保存 |
| **Output** | HTTP 201`{ success: true, data: { id: "pt1", name: "明远制造标准模板" } }` |
| **验证** | 模板列表显示「明远制造标准模板」,包含 6 个薪资项 |
---
## 阶段四:制度发布与员工端启用
### E2E-015 创建考勤管理制度
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/policies` `{ title: "上海明远制造考勤管理制度", category: "考勤", content: "第一章 总则\n第一条 为规范公司考勤管理...\n第二章 工作时间\n第二条 工作时间为每日8:00-17:00,午休1小时...\n第三章 请假\n第三条 请假需提前1天通过系统提交..." }` |
| **Process** | 进入 `/policies` → 新建制度 → 填写标题、分类、正文 → 保存草稿 |
| **Output** | HTTP 201`{ success: true, data: { id: "p1", title: "上海明远制造考勤管理制度", status: "DRAFT", currentStep: 1 } }` |
| **验证** | 制度列表显示草稿状态,当前步骤 1/4(起草) |
### E2E-016 推进民主程序
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | 依次调用:POST `/api/v1/policies/p1/advance-step` `{ step: 2, note: "已组织全体职工讨论" }` → POST `/api/v1/policies/p1/advance-step` `{ step: 3, note: "已与工会代表协商一致" }` → POST `/api/v1/policies/p1/advance-step` `{ step: 4, note: "已通过企业微信公示5个工作日" }` |
| **Process** | 制度详情 → 依次完成「讨论」「协商」「公示」三个步骤,每步添加备注 → 发布 |
| **Output** | 每步返回 HTTP 200 `{ success: true }`,最终 currentStep = 4status = `PUBLISHED` |
| **验证** | 制度状态变为「已发布」,4 个步骤全部完成 |
### E2E-017 生成员工端自动登录令牌
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/portal/auto-login-token` `{ employeeId: "e1" }` |
| **Process** | 花名册 → 点击「张伟」→ 更多操作 → 「生成员工端登录链接」 |
| **Output** | HTTP 200`{ success: true, data: { token: "auto-login-xxx-e1", url: "/portal/auto-login?token=auto-login-xxx-e1" } }` |
| **验证** | 生成可分享的员工端登录链接 |
### E2E-018 员工首次登录员工端
| 项目 | 内容 |
|------|------|
| **角色** | 员工(张伟) |
| **Input** | GET `/api/v1/portal/auto-login?token=auto-login-xxx-e1` |
| **Process** | 员工通过手机浏览器打开链接 → 自动登录 |
| **Output** | HTTP 200`{ success: true, data: { employee: { id: "e1", name: "张伟", department: "生产车间" }, token: "portal-token-xxx" } }` |
| **验证** | 跳转至 `/portal/home`,首页显示张伟的个人信息概览 |
### E2E-019 员工查看并确认制度
| 项目 | 内容 |
|------|------|
| **角色** | 员工(张伟) |
| **Input** | 1. GET `/api/v1/portal/policies` → 2. GET `/api/v1/portal/policies/p1` → 3. POST `/api/v1/portal/policies/p1/read` |
| **Process** | 员工端 → 制度 tab → 查看考勤管理制度 → 阅读完毕 → 点击「已阅读」 |
| **Output** | 第一步:`[{ id: "p1", title: "上海明远制造考勤管理制度", read: false }]`;第三步:HTTP 200 `{ success: true }` |
| **验证** | 制度列表中该制度标记为已读,管理端阅读统计显示张伟已读 |
### E2E-020 员工查看合同
| 项目 | 内容 |
|------|------|
| **角色** | 员工(张伟) |
| **Input** | GET `/api/v1/portal/contract` |
| **Process** | 员工端 → 合同 tab → 查看合同信息 |
| **Output** | `{ contract: { id: "c1", type: "FIXED", startDate: "2022-03-01", endDate: "2025-02-28", status: "EXPIRED", monthlySalary: 8000 } }` |
| **验证** | 显示合同已过期(2025-02-28 到期),状态 EXPIRED |
---
## 阶段五:日常操作(8月)
### E2E-021 仪表盘风险检查
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/dashboard` |
| **Process** | 登录后查看仪表盘 |
| **Output** | `{ greeting: "上午好!今天有 2 件事需要处理", stats: { employeeCount: 4, highRiskCount: 1, todoCount: 2 }, todos: [{ id: "r1", type: "CONTRACT", priority: "URGENT", title: "张伟的合同已过期,请尽快续签", employeeName: "张伟", deadline: "2026-08-15" }, { id: "r2", type: "CONTRACT", priority: "MEDIUM", title: "王芳的合同将于2027-05-31到期", employeeName: "王芳" }] }` |
| **验证** | 仪表盘显示 4 名员工,1 条紧急待办(张伟合同过期),1 条中等待办(王芳合同即将到期) |
### E2E-022 处理合同续签待办
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | 1. PATCH `/api/v1/dashboard/todos/r1/resolve` → 2. PUT `/api/v1/employees/e1` `{ contractType: "FIXED", contractStart: "2025-03-01", contractEnd: "2028-02-28", monthlySalary: 9000 }` |
| **Process** | 1. 仪表盘 → 点击张伟的待办 → 标记已处理 → 2. 进入花名册 → 张伟详情 → 编辑合同信息 → 续签 3 年,月薪调整为 9000 → 保存 |
| **Output** | 第一步:HTTP 200 `{ success: true }`;第二步:HTTP 200 `{ success: true }` |
| **验证** | 待办消失,张伟合同状态更新为正常(2025-03-01 至 2028-02-28),月薪 9000 |
### E2E-023 录入考勤(8月每日)
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/attendance/daily` `{ employeeId: "e1", date: "2026-08-01", checkIn: "07:55", checkOut: "17:05", shiftId: "shift1", status: "NORMAL", overtime: 0 }` |
| **Process** | 考勤 → 每日考勤 → 逐日录入或批量导入 8 月考勤数据 |
| **Output** | HTTP 201`{ success: true }` |
| **验证** | 考勤月报显示张伟 8 月出勤 22 天,迟到 0 次 |
### E2E-024 请假审批
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/attendance/leave` `{ employeeId: "e2", type: "事假", startDate: "2026-08-10", endDate: "2026-08-12", reason: "家中有事", days: 3 }` |
| **Process** | 考勤 → 请假记录 → 新建请假 → 选择王芳 → 事假 3 天 → 提交 |
| **Output** | HTTP 201`{ success: true, data: { id: "lv1", status: "APPROVED" } }` |
| **验证** | 请假记录显示王芳 8 月 10-12 日事假,考勤统计扣除 3 天出勤 |
### E2E-025 发布考勤月报
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/attendance/monthly-report/publish` `{ month: "2026-08" }` |
| **Process** | 考勤 → 月度报表 → 选择 2026-08 → 确认数据无误 → 点击「发布」 |
| **Output** | HTTP 200`{ success: true }` |
| **验证** | 考勤月报状态变为「已发布」,员工端可查看当月考勤 |
---
## 阶段六:月度薪酬闭环(8月发薪)
### E2E-026 创建发薪批次
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/payroll/batches` `{ month: "2026-08", templateId: "pt1", name: "2026年8月工资", payDate: "2026-09-10" }` |
| **Process** | 进入 `/money` → 发薪批次 → 新建批次 → 选择月份 8 月 → 选择模板「明远制造标准模板」→ 设置发薪日 → 保存 |
| **Output** | HTTP 201`{ success: true, data: { id: "b1", month: "2026-08", status: "DRAFT", employeeCount: 4 } }` |
| **验证** | 批次列表显示 8 月发薪批次,状态 DRAFT,包含 4 名员工 |
### E2E-027 计算工资
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/payroll/batches/b1/calculate` |
| **Process** | 发薪批次 → 选择 8 月批次 → 点击「计算」→ 系统自动计算所有员工工资 |
| **Output** | HTTP 200`{ success: true, data: { results: [{ employeeId: "e1", employeeName: "张伟", baseSalary: 9000, allowance: 500, transport: 200, grossPay: 9700, socialEmp: 759.36, housingEmp: 630, tax: 421.32, netPay: 7889.32 }, { employeeId: "e2", employeeName: "王芳", baseSalary: 9000, allowance: 500, transport: 200, grossPay: 9700, socialEmp: 759.36, housingEmp: 630, tax: 421.32, netPay: 7889.32, leaveDeduction: 966.67, adjustedNetPay: 6922.65 }, { employeeId: "e3", employeeName: "陈强", baseSalary: 10000, allowance: 500, transport: 200, grossPay: 10700, socialEmp: 830.72, housingEmp: 700, tax: 533.28, netPay: 8636.00 }, { employeeId: "e4", employeeName: "赵敏", baseSalary: 8500, allowance: 500, transport: 200, grossPay: 9200, socialEmp: 712.64, housingEmp: 595, tax: 371.52, netPay: 7520.84 }] } }` |
| **验证** | 4 名员工工资计算完成,王芳因事假 3 天扣除 966.67 元,个税按累计预扣法计算 |
### E2E-028 个税试算
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/payroll/tax-trial` `{ employeeId: "e1", month: "2026-08", grossPay: 9700, socialEmp: 759.36, housingEmp: 630, specialDeduction: 0, accumulatedIncome: 67900, accumulatedTaxPaid: 2946.24 }` |
| **Process** | 薪酬 → 个税试算 → 选择张伟 → 输入累计数据 → 计算 |
| **Output** | `{ tax: 421.32, accumulatedIncome: 77600, accumulatedTax: 3367.56, accumulatedTaxPaid: 2946.24, thisMonthTax: 421.32 }` |
| **验证** | 个税计算结果与发薪批次中一致 |
### E2E-029 提交审批
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/payroll/batches/b1/submit` |
| **Process** | 发薪批次 → 确认数据 → 点击「提交审批」 |
| **Output** | HTTP 200`{ success: true }`。状态变为 `PENDING_APPROVAL` |
| **验证** | 批次状态变为待审批 |
### E2E-030 管理员审批发薪
| 项目 | 内容 |
|------|------|
| **角色** | 企业管理员(刘明远) |
| **Input** | POST `/api/v1/payroll/batches/b1/approve` `{ comment: "核对无误,同意发放" }` |
| **Process** | 管理员登录 → 薪酬 → 发薪批次 → 查看 8 月批次 → 审批通过 |
| **Output** | HTTP 200`{ success: true }`。状态变为 `APPROVED` |
| **验证** | 批次状态变为已审批,工资条生成 |
### E2E-031 员工查看工资条
| 项目 | 内容 |
|------|------|
| **角色** | 员工(张伟) |
| **Input** | GET `/api/v1/portal/payslip?month=2026-08` |
| **Process** | 员工端 → 工资条 tab → 选择 2026-08 |
| **Output** | `{ id: "ps1", month: "2026-08", baseSalary: 9000, allowance: 500, transport: 200, grossPay: 9700, socialEmp: 759.36, housingEmp: 630, tax: 421.32, netPay: 7889.32, confirmed: false }` |
| **验证** | 工资条显示完整明细,实发 7889.32 元,状态未确认 |
### E2E-032 员工确认工资条
| 项目 | 内容 |
|------|------|
| **角色** | 员工(张伟) |
| **Input** | POST `/api/v1/portal/payslip/ps1/confirm` |
| **Process** | 员工端 → 工资条 → 点击「确认无误」 |
| **Output** | HTTP 200`{ success: true }` |
| **验证** | 工资条状态变为 CONFIRMED |
---
## 阶段七:社保月度办理
### E2E-033 查看社保月度变动
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/social/monthly-changes?month=2026-08` |
| **Process** | 进入 `/social-insurance` → 月度办理 → 选择 2026-08 |
| **Output** | `{ additions: [{ employeeId: "e1", employeeName: "张伟", reason: "已参保", base: 9000 }, { employeeId: "e2", employeeName: "王芳", reason: "已参保", base: 9000 }, { employeeId: "e3", employeeName: "陈强", reason: "已参保", base: 10000 }, { employeeId: "e4", employeeName: "赵敏", reason: "已参保", base: 8500 }], reductions: [], current: [...] }` |
| **验证** | 4 名员工均在参保列表中,无减员 |
### E2E-034 完成社保月度办理
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/social/monthly-process/complete` `{ month: "2026-08", type: "social" }` |
| **Process** | 社保页 → 月度办理 → 确认增减员无误 → 点击「完成社保办理」 |
| **Output** | HTTP 200`{ success: true }` |
| **验证** | 社保办理状态变为已完成 |
### E2E-035 完成公积金月度办理
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/social/monthly-process/complete` `{ month: "2026-08", type: "housing" }` |
| **Process** | 社保页 → 公积金 tab → 月度办理 → 点击「完成公积金办理」 |
| **Output** | HTTP 200`{ success: true }` |
| **验证** | 公积金办理状态变为已完成 |
---
## 阶段八:风险检查与合规
### E2E-036 用工体检诊断
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/dashboard/health-check` |
| **Process** | 进入 `/tools/health-check` → 点击「开始诊断」 |
| **Output** | `{ year: 2026, totalScore: 90, level: "healthy", dimensions: { contract: 100, salary_social: 100, attendance: 100, policy: 80, termination: 100, evidence: 60 }, summary: "整体用工合规状况良好,建议完善证据链管理" }` |
| **验证** | 6 维度评分显示,总分 90,等级 healthy,证据链维度较低(60 分) |
### E2E-037 保存体检诊断
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/dashboard/health-check/save` |
| **Process** | 诊断结果页 → 点击「保存诊断报告」 |
| **Output** | HTTP 200`{ success: true, data: { id: "hc-new", year: 2026, totalScore: 90 } }` |
| **验证** | 诊断历史中出现 2026 年记录 |
### E2E-038 AI 顾问咨询
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/ai/consultation` `{ type: "CHAT", question: "我们公司有员工合同过期了未续签,有什么法律风险?" }` |
| **Process** | 进入 `/ai-assistant` → 输入问题 → 发送 |
| **Output** | `{ conversationId: "conv-e2e", answer: "根据《劳动合同法》第十条和第八十二条,已建立劳动关系未同时订立书面劳动合同的,应当自用工之日起一个月内订立。超过一个月未续签的,应当向劳动者每月支付二倍工资。建议您尽快为合同过期的员工续签劳动合同...", confidence: 0.92, sources: [{ title: "劳动合同法第十条", url: "" }, { title: "劳动合同法第八十二条", url: "" }] }` |
| **验证** | AI 回答包含法律依据和操作建议,置信度 > 0.9 |
---
## 阶段九:新员工入职流程
### E2E-039 创建入职工作流程
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/work-processes` `{ type: "ONBOARDING", title: "8月新员工入职-孙磊", data: { name: "孙磊", phone: "13900008888", department: "生产车间", position: "操作工", hireDate: "2026-08-15", salary: 8000, contractType: "FIXED", contractEnd: "2029-08-14" } }` |
| **Process** | 进入 `/work-process` → 新建 → 选择类型「入职」→ 填写新员工信息 → 保存 |
| **Output** | HTTP 201`{ success: true, data: { id: "wp1", title: "8月新员工入职-孙磊", type: "ONBOARDING", status: "DRAFT" } }` |
| **验证** | 工作流程列表显示新入职流程 |
### E2E-040 生成入职链接并发送
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/portal/auto-login-token` `{ employeeId: "e-new" }`(系统自动创建员工记录后) |
| **Process** | 工作流程详情 → 点击「生成入职链接」→ 将链接发送给新员工 |
| **Output** | `{ success: true, data: { token: "onboarding-token-sunlei", url: "/portal/onboarding?token=onboarding-token-sunlei" } }` |
| **验证** | 生成入职链接 |
### E2E-041 新员工填写入职信息
| 项目 | 内容 |
|------|------|
| **角色** | 新员工(孙磊) |
| **Input** | 1. GET `/api/v1/portal/onboarding/onboarding-token-sunlei` → 2. POST `/api/v1/portal/onboarding` `{ token: "onboarding-token-sunlei", name: "孙磊", gender: "男", idCard: "310105200001015678", phone: "13900008888", bank: "建设银行", account: "6227000100025678", emergencyContact: "孙母", emergencyPhone: "13800002222", address: "上海市闵行区测试路200号" }` |
| **Process** | 新员工打开链接 → 查看入职须知 → 填写个人信息 → 提交 |
| **Output** | 第一步:`{ orgName: "上海明远制造有限公司", position: "操作工", expectedHireDate: "2026-08-15" }`;第二步:HTTP 200 `{ success: true, message: "入职信息提交成功" }` |
| **验证** | 入职信息提交成功 |
### E2E-042 新员工上传入职文件
| 项目 | 内容 |
|------|------|
| **角色** | 新员工(孙磊) |
| **Input** | `FormData { file: 身份证正面.jpg }``FormData { file: 体检报告.pdf }` |
| **Process** | 入职页面 → 文件上传 → 上传身份证照片和体检报告 |
| **Output** | HTTP 200`{ success: true, data: { url: "/uploads/onboarding/id-front.jpg" } }` |
| **验证** | 文件上传成功 |
### E2E-043 HR 审核入职
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/work-processes/wp1/submit` |
| **Process** | 工作流程 → 入职流程 → 检查新员工提交的信息和文件 → 确认无误 → 提交 |
| **Output** | HTTP 200`{ success: true }`。状态变为 `SUBMITTED` |
| **验证** | 入职流程完成,花名册新增孙磊(5 名员工),合同自动创建 |
---
## 阶段十:解聘流程
### E2E-044 创建解聘草稿
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/termination/draft` `{ employeeId: "e3", reason: "协商解除", reasonDetail: "公司业务调整,岗位裁撤", lastDay: "2026-08-31" }` |
| **Process** | 进入 `/termination` → 新建解聘 → 选择陈强 → 选择原因「协商解除」→ 填写最后工作日 → 保存 |
| **Output** | HTTP 201`{ success: true, data: { id: "td1", employeeId: "e3", employeeName: "陈强", reason: "协商解除", status: "DRAFT" } }` |
| **验证** | 解聘列表显示陈强的草稿 |
### E2E-045 解聘风险评估
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/termination/assess/e3?reason=协商解除` |
| **Process** | 解聘详情 → 点击「风险评估」 |
| **Output** | `{ riskLevel: "LOW", riskScore: 15, factors: [{ factor: "入职年限", description: "入职5.5年", impact: "medium" }, { factor: "合同状态", description: "无固定期限合同", impact: "medium" }, { factor: "协商解除", description: "双方协商一致", impact: "low" }], recommendations: ["建议支付N经济补偿(5.5个月)", "签署协商解除协议", "办理社保减员"] }` |
| **验证** | 风险等级 LOW,建议支付 5.5 个月补偿 |
### E2E-046 查看解聘清单
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/termination/checklist/协商解除?employeeId=e3` |
| **Process** | 解聘详情 → 查看「办理清单」 |
| **Output** | `{ items: [{ id: "cl1", title: "签署解除协议", required: true, completed: false }, { id: "cl2", title: "支付经济补偿(5.5个月×10000=55000元)", required: true, completed: false }, { id: "cl3", title: "工作交接", required: true, completed: false }, { id: "cl4", title: "社保公积金减员", required: true, completed: false }, { id: "cl5", title: "出具离职证明", required: true, completed: false }] }` |
| **验证** | 清单包含 5 项必须操作 |
### E2E-047 更新解聘草稿
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | PUT `/api/v1/termination/draft/td1` `{ compensation: 55000, compensationMonths: 5.5, lastDay: "2026-08-31", checklist: [{ id: "cl1", completed: true }, { id: "cl2", completed: true }, { id: "cl3", completed: true }] }` |
| **Process** | 解聘详情 → 填写补偿金额 55000 → 逐项勾选已完成清单项 → 保存 |
| **Output** | HTTP 200`{ success: true }` |
| **验证** | 草稿更新成功,3/5 清单项已完成 |
### E2E-048 提交解聘审批
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/termination/draft/td1/submit` |
| **Process** | 解聘详情 → 确认信息 → 点击「提交审批」 |
| **Output** | HTTP 200`{ success: true }`。状态变为 `PENDING_APPROVAL` |
| **验证** | 解聘状态变为待审批 |
### E2E-049 管理员审批解聘
| 项目 | 内容 |
|------|------|
| **角色** | 企业管理员(刘明远) |
| **Input** | POST `/api/v1/termination/draft/td1/approve` `{ comment: "同意协商解除,补偿金额合理" }` |
| **Process** | 管理员登录 → 解聘管理 → 查看陈强解聘申请 → 审批通过 |
| **Output** | HTTP 200`{ success: true }`。状态变为 `APPROVED` |
| **验证** | 解聘状态变为已审批 |
### E2E-050 执行解聘
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | POST `/api/v1/termination/draft/td1/execute` |
| **Process** | 解聘详情 → 完成剩余清单项(社保减员、离职证明)→ 点击「执行解聘」 |
| **Output** | HTTP 200`{ success: true }`。状态变为 `EXECUTED` |
| **验证** | 陈强员工状态变为 `RESIGNED`,社保公积金自动减员,花名册显示 4 名在职员工 |
---
## 阶段十一:月末检查与审计
### E2E-051 查看薪酬仪表盘
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/salary/dashboard?year=2026` |
| **Process** | 进入 `/money` → 薪酬分析 → 查看 2026 年数据 |
| **Output** | `{ year: 2026, monthly: [{ month: "2026-08", totalPay: 34200, avgPay: 8550, headcount: 4 }], departmentSalary: [{ department: "生产车间", avgSalary: 8500 }, { department: "行政部", avgSalary: 9000 }, { department: "质检部", avgSalary: 8500 }], salaryDistribution: [{ range: "8K-10K", count: 4 }], yoyChange: 0 }` |
| **验证** | 8 月总薪酬 34200 元,平均 8550 元,4 名员工 |
### E2E-052 查看审计日志
| 项目 | 内容 |
|------|------|
| **角色** | 企业管理员 |
| **Input** | GET `/api/v1/audit?page=1&pageSize=20` |
| **Process** | 进入 `/audit` → 查看操作日志 |
| **Output** | `{ data: [{ id: "al1", entity: "EMPLOYEE", action: "IMPORT", operator: "李萍", target: "批量导入4名员工", timestamp: "2026-08-01T09:30:00Z" }, { id: "al2", entity: "PAYROLL", action: "APPROVE", operator: "刘明远", target: "2026年8月工资批次", timestamp: "2026-08-28T14:00:00Z" }, { id: "al3", entity: "TERMINATION", action: "EXECUTE", operator: "李萍", target: "陈强协商解除", timestamp: "2026-08-31T16:00:00Z" }], pagination: { total: 25 } }` |
| **验证** | 审计日志完整记录了导入、审批、解聘等关键操作 |
### E2E-053 导出花名册
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/export/roster?status=ACTIVE` |
| **Process** | 花名册 → 点击「导出」→ 选择在职员工 → 下载 |
| **Output** | HTTP 200,下载 `花名册_2026-08-31.xlsx`,包含 4 条在职员工记录(陈强已离职) |
| **验证** | 导出文件包含 4 名在职员工,不含已离职的陈强 |
### E2E-054 导出工资条
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/export/payslip?batchId=b1` |
| **Process** | 薪酬 → 8 月批次 → 点击「导出工资条」→ 下载 |
| **Output** | HTTP 200,下载 `工资条_2026-08.xlsx`,包含 4 条工资明细 |
| **验证** | 导出文件包含 4 名员工的完整工资明细 |
---
## 阶段十二:员工离职申请(员工端发起)
### E2E-055 员工提交离职申请
| 项目 | 内容 |
|------|------|
| **角色** | 员工(王芳) |
| **Input** | POST `/api/v1/portal/resignation/submit` `{ reason: "个人发展", expectedLastDay: "2026-09-30", description: "感谢公司三年培养,因个人职业规划调整申请离职" }` |
| **Process** | 员工端 → 离职申请 → 填写离职原因和期望最后工作日 → 提交 |
| **Output** | HTTP 201`{ success: true, data: { id: "rg1", status: "PENDING" } }` |
| **验证** | 离职申请提交成功,状态待处理 |
### E2E-056 HR 查看离职申请
| 项目 | 内容 |
|------|------|
| **角色** | HR |
| **Input** | GET `/api/v1/portal/resignation/status`(或管理端查看) |
| **Process** | 管理端 → 解聘管理 → 查看员工发起的离职申请 |
| **Output** | `[{ id: "rg1", employeeName: "王芳", reason: "个人发展", expectedLastDay: "2026-09-30", status: "PENDING", submittedAt: "2026-08-31T10:00:00Z" }]` |
| **验证** | 离职申请列表显示王芳的申请 |
### E2E-057 员工撤回离职申请
| 项目 | 内容 |
|------|------|
| **角色** | 员工(王芳) |
| **Input** | POST `/api/v1/portal/resignation/rg1/withdraw` |
| **Process** | 员工端 → 离职申请 → 点击「撤回」 |
| **Output** | HTTP 200`{ success: true }`。状态变为 `WITHDRAWN` |
| **验证** | 离职申请状态变为已撤回 |
---
## 全流程验证检查清单
| # | 检查项 | 预期结果 | 实际结果 |
|---|--------|----------|----------|
| 1 | 租户创建成功 | 组织列表可见,管理员可登录 | ☐ |
| 2 | 企业信息配置完成 | 设置页显示完整企业信息 | ☐ |
| 3 | HR 子账号可登录 | HR 角色可访问各功能模块 | ☐ |
| 4 | 花名册导入成功 | 4 名员工数据完整 | ☐ |
| 5 | 考勤数据导入成功 | 考勤月报数据正确 | ☐ |
| 6 | 社保公积金配置生效 | 上海基数和比例正确 | ☐ |
| 7 | 薪酬模板创建成功 | 模板包含 6 个薪资项 | ☐ |
| 8 | 制度发布流程完整 | 4 步民主程序全部完成 | ☐ |
| 9 | 员工端可登录 | 自动登录成功,首页正常 | ☐ |
| 10 | 员工可查看制度并签收 | 制度标记为已读 | ☐ |
| 11 | 仪表盘风险提示正确 | 合同过期风险准确 | ☐ |
| 12 | 合同续签成功 | 员工合同状态更新 | ☐ |
| 13 | 考勤月报发布成功 | 员工端可查看当月考勤 | ☐ |
| 14 | 发薪批次计算正确 | 工资明细金额准确 | ☐ |
| 15 | 个税计算正确 | 累计预扣法计算无误 | ☐ |
| 16 | 发薪审批流程完整 | HR 提交 → 管理员审批 | ☐ |
| 17 | 员工可查看并确认工资条 | 工资条状态 CONFIRMED | ☐ |
| 18 | 社保月度办理完成 | 社保和公积金均已完成 | ☐ |
| 19 | 用工体检诊断正常 | 总分 ≥ 80,等级 healthy | ☐ |
| 20 | AI 顾问可咨询 | 回答包含法律依据 | ☐ |
| 21 | 新员工入职流程完整 | 入职 → 填信息 → 上传 → 审核 | ☐ |
| 22 | 解聘流程完整 | 草稿 → 风险评估 → 审批 → 执行 | ☐ |
| 23 | 解聘后员工状态正确 | 状态 RESIGNED,社保减员 | ☐ |
| 24 | 审计日志完整 | 关键操作均有记录 | ☐ |
| 25 | 数据导出正确 | 花名册和工资条导出无误 | ☐ |
| 26 | 员工离职申请流程 | 提交 → 查看 → 撤回 | ☐ |
---
## 流程时间线
| 日期 | 操作 | 角色 |
|------|------|------|
| 2026-08-01 09:00 | 平台超管创建租户 | SUPER_ADMIN |
| 2026-08-01 09:15 | 企业管理员首次登录,完善信息 | 刘明远 |
| 2026-08-01 09:30 | 添加 HR 用户 | 刘明远 |
| 2026-08-01 09:45 | HR 登录,批量导入花名册 | 李萍 |
| 2026-08-01 10:00 | 导入 7 月考勤数据 | 李萍 |
| 2026-08-01 10:15 | 配置考勤班次和排班 | 李萍 |
| 2026-08-01 10:30 | 配置社保公积金 | 李萍 |
| 2026-08-01 11:00 | 创建薪酬模板 | 李萍 |
| 2026-08-01 14:00 | 创建考勤管理制度并推进民主程序 | 李萍 |
| 2026-08-01 15:00 | 生成员工端登录链接,员工首次登录 | 李萍 → 张伟 |
| 2026-08-01 15:30 | 员工查看制度并签收 | 张伟 |
| 2026-08-02 09:00 | 查看仪表盘风险,处理合同续签 | 李萍 |
| 2026-08-04~08-30 | 每日录入考勤 | 李萍 |
| 2026-08-10 | 王芳请假 3 天 | 李萍 |
| 2026-08-15 | 新员工孙磊入职 | 李萍 → 孙磊 |
| 2026-08-28 | 创建发薪批次,计算工资,提交审批 | 李萍 |
| 2026-08-28 14:00 | 管理员审批发薪 | 刘明远 |
| 2026-08-29 | 员工查看并确认工资条 | 张伟 |
| 2026-08-30 | 社保公积金月度办理 | 李萍 |
| 2026-08-30 | 用工体检诊断 | 李萍 |
| 2026-08-31 | 陈强协商解除解聘执行 | 李萍 → 刘明远 |
| 2026-08-31 | 导出花名册和工资条 | 李萍 |
| 2026-08-31 17:00 | 王芳提交离职申请后撤回 | 王芳 |
File diff suppressed because it is too large Load Diff