# 劳动用工合规助手 — 产品需求文档 (PRD) > **文档编号**: 1-prd.md > **版本**: v1.0 > **日期**: 2026-07-23 > **状态**: 草案 > **依据**: 0-req.md v3.0 需求规格说明书 --- ## 1. 产品概述 ### 1.1 产品定位 面向中小企业的**极简用工合规 SaaS 工具**,聚焦劳动仲裁三大高发领域(合同签订、工资加班费、解聘),辅以 AI 合规顾问,帮助企业事前预防、事中管控、事后追溯用工风险。 ### 1.2 产品愿景 > 「让每个中小企业都有一个用得起的劳动法顾问」 ### 1.3 核心价值主张 | 价值 | 说明 | |------|------| | 极简易用 | 三看三不用原则,不需要培训,打开就会用 | | 自动合规 | 风险自动检测 + 人话提示,不用懂法也能合规 | | AI 顾问 | 通义千问驱动,随时问、自动查、提前预警 | | 安全可靠 | SaaS 云端存储,数据隔离,多设备访问 | ### 1.4 目标用户 | 用户角色 | 企业规模 | 使用频率 | 核心诉求 | |---------|---------|---------|---------| | 老板兼管 HR | 10-30人 | 每周1-2次 | 快速了解风险,解聘时算钱 | | 行政兼 HR | 30-80人 | 每天5分钟 | 合同到期提醒,每月算加班费 | | 初级 HR | 80-200人 | 日常使用 | 合同管理,工资计算,解聘流程 | --- ## 2. 用户故事 ### 2.1 认证与注册 | 编号 | 用户故事 | 验收标准 | |------|---------|---------| | US-AUTH-01 | 作为企业管理者,我想注册账号,这样我就能开始使用系统管理用工合规 | 输入企业名称+手机号+密码 → 创建组织+管理员账号 → 自动登录跳转首页 | | US-AUTH-02 | 作为用户,我想用手机号和密码登录,这样我能安全访问我的数据 | 输入手机号+密码 → 校验通过 → 返回 JWT Token → 跳转首页 | | US-AUTH-03 | 作为管理员,我想添加 HR 用户,这样我的同事也能操作系统 | 设置页 → 用户管理 → 输入姓名+手机号+角色 → 创建成功 | | US-AUTH-04 | 作为用户,我想找回密码,这样我忘记密码时还能登录 | 忘记密码 → 输入手机号 → 验证码重置 → 重新登录 | ### 2.2 首页风险总览 | 编号 | 用户故事 | 验收标准 | |------|---------|---------| | US-HOME-01 | 作为用户,我想打开首页就知道有没有风险,这样我不用到处翻找 | 顶部一句话:「今天有 X 件事需要处理」 | | US-HOME-02 | 作为用户,我想看到具体待办事项,这样我知道该先处理什么 | 待办列表:信号灯+一句话描述+「去处理」按钮 | | US-HOME-03 | 作为用户,我想看到风险分布,这样我知道哪类问题最多 | 进度条展示合同/工资/解聘三类风险数量 | | US-HOME-04 | 作为用户,当没有风险时我想看到安心提示,这样我知道一切正常 | 显示绿色「✅ 暂无风险,继续保持!」 | | US-HOME-05 | 作为用户,我想看到 AI 风险预测,这样我能提前防范 | 首页下方展示 AI 预测的未来30天风险卡片 | ### 2.3 合同管理 | 编号 | 用户故事 | 验收标准 | |------|---------|---------| | US-CON-01 | 作为 HR,我想添加员工和合同信息,这样系统帮我管理合规 | 添加按钮 → 分步表单(基本信息→合同信息)→ 保存成功 | | US-CON-02 | 作为 HR,我想看到所有员工的合同状态,这样我一眼就知道谁有问题 | 列表5列:姓名/部门/入职日期/合同状态(信号灯)/操作 | | US-CON-03 | 作为 HR,当合同即将到期时我想收到提醒,这样我不会忘记续签 | 到期前30天列表出现「续签」按钮 + 首页待办提醒 | | US-CON-04 | 作为 HR,我想一键续签合同,这样我不用填一堆表单 | 点击「续签」→ 弹窗确认期限+签订方式 → 确认 → 状态变绿 | | US-CON-05 | 作为 HR,我想选择纸质或电子合同签订方式,这样符合实际操作 | 添加/续签时可选「纸质合同」或「电子合同」 | | US-CON-06 | 作为 HR,当员工入职很久没签合同时我想被提醒,这样避免双倍工资赔偿 | 入职超1个月未签 → 🔴 红色状态 + 首页待办 | | US-CON-07 | 作为 HR,我想搜索员工,这样快速找到某人的合同 | 搜索框输入姓名 → 实时筛选列表 | | US-CON-08 | 作为 HR,我想批量续签即将到期的合同,这样不用一个个点 | 全选 → 批量续签 → 弹窗确认 → 批量更新 | ### 2.4 钱的计算 | 编号 | 用户故事 | 验收标准 | |------|---------|---------| | US-MONEY-01 | 作为 HR,我想计算加班费,这样我知道该付多少 | 输入月工资+加班小时数 → 实时显示各类加班费明细+合计 | | US-MONEY-02 | 作为 HR,当加班超过法定上限时我想被提醒,这样避免违法 | 月加班超36小时 → 结果区显示黄色警告 | | US-MONEY-03 | 作为 HR,我想计算未签合同的双倍工资,这样我知道风险金额 | 输入月工资+入职日期+签订状态 → 显示起止日期+赔偿金额 | | US-MONEY-04 | 作为 HR,我想计算经济补偿金,这样解聘时知道该赔多少 | 输入入职/离职日期+月工资+原因 → 显示工作年限+补偿金+赔偿金(×2) | | US-MONEY-05 | 作为 HR,我想关联员工自动填入工资,这样不用手动输入 | 选择员工 → 月工资自动填入 | ### 2.5 解聘助手 | 编号 | 用户故事 | 验收标准 | |------|---------|---------| | US-TERM-01 | 作为 HR,我想一步步完成解聘流程,这样不会漏掉步骤 | 5步向导:选原因→选员工→合规检查→算钱→确认 | | US-TERM-02 | 作为 HR,当解聘原因不同时我想看到对应的检查项,这样有针对性 | Step 3 根据Step 1选择动态展示检查项 | | US-TERM-03 | 作为 HR,当员工属于禁止解聘情形时我想被警告,这样避免违法解聘 | 选员工后自动检查孕期/工伤/医疗期 → 红色警告弹窗 | | US-TERM-04 | 作为 HR,我想看到解聘历史记录,这样可以追溯 | 解聘助手页面底部展示历史记录列表 | | US-TERM-05 | 作为 HR,即使有未通过检查项我也想保存记录,这样尊重我的决策 | Step 5 显示红色警告但不阻止保存 | ### 2.6 AI 合规顾问 | 编号 | 用户故事 | 验收标准 | |------|---------|---------| | US-AI-01 | 作为用户,我想用大白话问劳动法问题,这样不用自己查法条 | 聊天界面输入问题 → AI 流式回答 + 法律依据 + 关联本企业数据 | | US-AI-02 | 作为用户,我想看到 AI 预测的未来风险,这样提前防范 | 首页 AI 风险预测卡片,展示未来30天预计风险 | | US-AI-03 | 作为 HR,我想让 AI 审查合同条款,这样知道有没有违法 | 粘贴/上传合同文本 → 逐条审查 + 红/黄/绿标注 + 合规评分 | | US-AI-04 | 作为 HR,我想匹配相似仲裁案例,这样评估败诉风险 | 输入争议情况 → 展示相似案例 + 败诉概率 + 赔偿预估 | | US-AI-05 | 作为用户,AI 回答时我想看到打字机效果,这样体验更好 | SSE 流式输出,逐字显示 | ### 2.7 系统设置 | 编号 | 用户故事 | 验收标准 | |------|---------|---------| | US-SET-01 | 作为管理员,我想设置企业地区,这样系统用对的最低工资标准 | 设置→企业信息→选择城市 → 自动填入最低工资/社平工资默认值 | | US-SET-02 | 作为管理员,我想管理用户和权限,这样控制谁能看谁能改 | 设置→用户管理→添加/移除用户→分配角色 | | US-SET-03 | 作为管理员,我想查看当前套餐和人数限制,这样知道是否需要升级 | 设置→套餐信息→显示当前套餐+已用人数+上限 | ### 2.8 员工端 | 编号 | 用户故事 | 验收标准 | |------|---------|---------| | US-EMP-01 | 作为员工,我想用手机号+密码登录,这样不用等验证码 | 输入手机号+密码→登录成功→跳转工资条 | | US-EMP-02 | 作为员工,我想用手机号+验证码登录,这样不用记密码 | 输入手机号→获取验证码→输入验证码→登录成功→跳转工资条 | | US-EMP-03 | 作为员工,我想扫描 HR 发的二维码直接进入员工端,这样不用手动输入网址 | 扫码→打开员工端登录页→选择登录方式→登录 | | US-EMP-04 | 作为员工,我想查看月度工资条,这样知道工资明细 | 选择月份→显示基本工资+加班费拆分+应发合计 | | US-EMP-05 | 作为员工,我想确认已阅工资条,这样 HR 知道我看过了 | 点击「确认已阅」→记录时间+IP→HR端显示已确认 | | US-EMP-06 | 作为员工,我想查看我的合同信息,这样了解合同条款 | 我的合同页→显示合同类型/期限/试用期/工资/扫描件 | | US-EMP-07 | 作为员工,HR 发二维码让我填报入职信息,这样不用 HR 手动录入 | 扫码→填写姓名/身份证/银行卡等→提交→HR审核入库 | | US-EMP-08 | 作为员工,HR 发二维码让我确认电子合同,这样完成签署确认 | 扫码→查看合同内容→勾选确认→点击签署→记录时间+IP | | US-EMP-09 | 作为 HR,我想生成入职填报二维码发给员工,这样通过微信即可发送 | 添加员工时选「生成填报二维码」→显示二维码+链接→保存图片/复制链接 | | US-EMP-10 | 作为 HR,我想生成合同确认二维码发给员工,这样完成电子合同签署 | 合同详情→生成确认二维码→微信发给员工→员工确认后状态自动更新 | | US-EMP-11 | 作为 HR,我想查看员工工资条确认状态,这样知道谁还没看 | 合同/工资管理→显示各员工确认状态(已确认/未确认) | --- ## 3. 用户流程 ### 3.1 新用户注册流程 ``` 访问网站 → 注册页 │ ├─ 输入企业名称 ├─ 输入手机号 ├─ 输入密码 ├─ 点击注册 │ ├─ 创建 Organization + Admin User ├─ 自动登录,返回 JWT Token │ └─ 跳转首页(空状态) │ ├─ 显示新手引导弹窗(3步) └─ 显示「添加第一个员工」引导卡片 ``` ### 3.2 日常使用流程 ``` 登录 → 首页风险总览 │ ├─ 有待办? → 点击「去处理」→ 跳转对应模块 → 处理 → 返回首页 │ ├─ 无待办? → 查看AI风险预测 → 了解未来风险 │ └─ 日常操作: ├─ 合同管理 → 添加员工/续签/查看详情 ├─ 钱的计算 → 切换Tab计算加班费/双倍工资/补偿金 ├─ 解聘助手 → 5步向导完成解聘 └─ AI顾问 → 问答/合同审查/案例匹配 ``` ### 3.3 合同到期续签流程 ``` 首页待办显示「🟡 XX合同还有20天到期」 │ └─ 点击「去续签」→ 合同管理页 │ └─ 点击「续签」→ 弹窗 │ ├─ 确认新期限(默认3年) ├─ 选择签订方式(默认沿用上次) ├─ 确认新到期日 │ └─ 点击「确认续签」 │ ├─ 更新合同记录 ├─ 状态变 🟢 正常 ├─ 风险项自动消除 └─ 首页待办减少 ``` ### 3.4 解聘流程 ``` 解聘助手 → Step 1: 选择解聘原因 │ └─ Step 2: 选择员工 │ ├─ 自动检查禁止解聘情形 ├─ 触发?→ 红色警告 → 用户确认继续 │ └─ Step 3: 合规检查(根据原因动态展示) │ └─ Step 4: 自动计算补偿金 │ └─ Step 5: 确认汇总 │ ├─ 有未通过项?→ 红色警告(不阻止) ├─ 点击保存 │ └─ 生成解聘记录 ├─ 员工状态变更为离职 ├─ 记录存档 └─ 审计日志记录 ``` ### 3.5 AI 智能问答流程 ``` AI顾问页 → 输入问题(或点击预设问题) │ ├─ 前端构建上下文: │ ├─ 当前企业数据摘要(员工数/风险项/合同状态) │ └─ RAG 检索相关法律条文 │ ├─ 调用 DashScope API(qwen-plus) │ ├─ SSE 流式返回 │ ├─ 逐字显示回答 │ └─ 显示完成后附法律依据(可折叠) │ └─ 支持多轮对话(保留上下文) ``` ### 3.6 员工入职填报流程 ``` HR 管理端 → 添加员工 → 选择「生成填报二维码」 │ ├─ 生成一次性 token(24h 有效) ├─ 页面显示二维码图片 + 可复制链接 │ └─ HR 通过微信发送给员工(二维码图片或链接) │ └─ 员工扫码/点击链接 → 填报页面 │ ├─ 填写姓名/手机号/身份证/银行卡等 ├─ 提交 │ └─ 信息进入「待审核」状态 │ └─ HR 管理端收到通知 │ ├─ 审核 → 通过 → 正式入库 │ ├─ 创建 Employee 记录 │ └─ token 失效 │ └─ 审核 → 驳回 → 员工重新填报 ``` ### 3.7 电子合同签署确认流程 ``` HR 管理端 → 录入电子合同 → 点击「生成确认二维码」 │ ├─ 生成一次性 token(7天有效) ├─ 页面显示二维码图片 + 可复制链接 │ └─ HR 通过微信发送给员工(二维码图片或链接) │ └─ 员工扫码/点击链接 → 合同确认页面 │ ├─ 查看合同内容(类型/期限/试用期/工资) ├─ 查看合同文件(如有链接) ├─ 勾选「我已阅读,确认签署」 ├─ 点击「确认签署」 │ └─ 系统记录:确认时间 + IP + 设备信息 │ └─ HR 端合同状态自动更新为「已确认签署」 ├─ token 失效 └─ 审计日志记录 ``` --- ## 4. 功能规格 ### 4.1 认证模块 #### 4.1.1 注册 - **页面**: `/register` - **输入**: 企业名称、手机号、密码(8位以上)、确认密码 - **校验**: 手机号格式、密码长度、手机号未被注册 - **处理**: 创建 Organization(plan=free, maxEmployees=20)+ User(role=admin)+ bcrypt 加密密码 - **输出**: JWT Token + 跳转首页 - **限流**: 同一 IP 每小时最多 5 次注册 #### 4.1.2 登录 - **页面**: `/login` - **输入**: 手机号、密码 - **校验**: 手机号存在、密码匹配 - **输出**: Access Token(2h)+ Refresh Token(7d) - **限流**: 同一 IP 每分钟最多 5 次登录 #### 4.1.3 Token 刷新 - **接口**: `POST /api/v1/auth/refresh` - **输入**: Refresh Token - **输出**: 新 Access Token - **逻辑**: 校验 Refresh Token 有效性 → 签发新 Access Token ### 4.2 首页风险总览 #### 4.2.1 数据聚合接口 - **接口**: `GET /api/v1/dashboard` - **返回数据**: ```json { "success": true, "data": { "greeting": "早上好!今天有 3 件事需要处理", "stats": { "employeeCount": 12, "highRiskCount": 2, "todoCount": 3, "monthlyOvertimePay": 8000 }, "todos": [ { "id": "risk_001", "level": "high", "title": "张三入职35天未签合同", "actionUrl": "/contracts?employee=张三" } ], "riskDistribution": { "contract": 5, "salary": 2, "termination": 1 }, "aiPrediction": { "risks": [...], "suggestion": "本周优先处理合同到期和未签问题" } } } ``` #### 4.2.2 风险检测引擎 - **触发时机**: 数据变更时实时检测 + 每日凌晨定时全量扫描 - **检测规则**: 见 0-req.md 4.3.3 / 4.4.4 合规检查规则 - **风险生命周期**: `pending` → `resolved`(自动/手动)/ `ignored`(手动) ### 4.3 合同管理模块 #### 4.3.1 API 规格 | 接口 | 方法 | 路径 | 说明 | |------|------|------|------| | 员工列表 | GET | `/api/v1/employees` | 支持分页、搜索、部门筛选 | | 添加员工 | POST | `/api/v1/employees` | 含合同信息 | | 员工详情 | GET | `/api/v1/employees/:id` | 含合同+风险信息 | | 编辑员工 | PUT | `/api/v1/employees/:id` | 更新员工+合同信息 | | 删除员工 | DELETE | `/api/v1/employees/:id` | 软删除(status=resigned) | | 批量续签 | POST | `/api/v1/contracts/batch-renew` | 批量续签合同 | | 上传附件 | POST | `/api/v1/contracts/:id/attachment` | 上传纸质合同扫描件 | #### 4.3.2 合同状态自动计算 ``` 输入:signDate, startDate, endDate, contractType, renewalCount, hireDate 输出:status + statusText + riskLevel 逻辑: if signDate == null: daysSinceHire = today - hireDate if daysSinceHire > 365: → "已视为无固定期限" 🔴 elif daysSinceHire > 30: → "未签合同(X天)" 🔴 else: → "未签合同(X天)" 🟡 elif endDate != null: daysToExpire = endDate - today if daysToExpire < 0: → "已到期未续签" 🔴 elif daysToExpire <= 30: → "即将到期(X天)" 🟡 else: → "正常" 🟢 else: → "无固定期限" 🟢 ``` #### 4.3.3 试用期合法性校验 ``` 规则(劳动合同法第19条): 合同期 < 3个月 → 不能约定试用期 合同期 3个月~1年 → 试用期 ≤ 1个月 合同期 1年~3年 → 试用期 ≤ 2个月 合同期 ≥ 3年 → 试用期 ≤ 6个月 校验时机:添加/编辑合同时实时校验 校验失败:红色提示「X年期合同试用期最多Y个月,当前Z个月不合法」 ``` ### 4.4 钱的计算模块 #### 4.4.1 加班费计算 - **页面**: `/money` Tab 1 - **输入**: 月工资、工作日加班小时、休息日加班小时、节假日加班小时 - **计算**: 纯前端实时计算,无需调后端 - **公式**: ``` hourlyWage = monthlyWage / 21.75 / 8 weekdayPay = hourlyWage * 1.5 * weekdayHours weekendPay = hourlyWage * 2.0 * weekendHours holidayPay = hourlyWage * 3.0 * holidayHours total = weekdayPay + weekendPay + holidayPay ``` - **预警**: 总加班小时 > 36 → 黄色警告 #### 4.4.2 双倍工资计算 - **页面**: `/money` Tab 2 - **输入**: 月工资、入职日期、合同签订日期(可选,默认未签订) - **计算**: 纯前端实时计算 - **公式**: ``` if 未签订 or 签订日期 - 入职日期 > 30天: 起算日 = 入职日 + 1个月 截止日 = 入职日 + 1年(如未签订)或 签订日期 月数 = min(截止日 - 起算日 的月数, 11) 双倍工资差额 = 月工资 × 月数 ``` #### 4.4.3 经济补偿金计算 - **页面**: `/money` Tab 3 - **输入**: 入职日期、离职日期、月平均工资、离职原因、当地社平工资(选填) - **计算**: 纯前端实时计算 - **公式**: ``` 工作年限 = (离职日期 - 入职日期) 转换为年月 满1年 → 1个月工资 满6个月不满1年 → 1个月工资 不满6个月 → 0.5个月工资 补偿月数 = 向上取整(工作年限月数 / 12) 或 半月 if 社平工资 > 0 and 月工资 > 社平工资 × 3: 月工资 = 社平工资 × 3 补偿月数 = min(补偿月数, 12) 经济补偿金 = 月工资 × 补偿月数 违法解除赔偿金 = 经济补偿金 × 2 ``` ### 4.5 解聘助手模块 #### 4.5.1 解聘向导状态管理 ```typescript interface TerminationWizardState { step: 1 | 2 | 3 | 4 | 5; reason: 'negotiated' | 'fault' | 'nonfault' | 'layoff' | 'expired' | null; employeeId: string | null; terminationDate: string | null; checklist: { item: string; passed: boolean; remark?: string; }[]; compensation: number; riskLevel: 'safe' | 'warning' | 'danger'; } ``` #### 4.5.2 动态检查项规则 | 解聘原因 | 检查项 | |---------|--------| | 协商解除 | 是否支付经济补偿金、是否签署协商解除协议 | | 员工犯错 | 是否有规章制度依据、是否有证据材料、是否通知工会 | | 员工没犯错但干不了 | 是否提前30天通知或支付代通知金、是否经过培训/调岗 | | 公司裁员 | 是否提前30天向工会说明、是否听取职工意见、是否报劳动部门 | | 合同到期不续签 | 是否提前通知、是否支付经济补偿金 | #### 4.5.3 禁止解聘情形检查 - **触发**: Step 2 选择员工后自动检查 - **检查字段**: `employee.isPregnant` / `employee.isWorkInjured` / `employee.isInMedicalPeriod` - **交互**: 弹出红色警告框 + 「我已了解风险,继续操作」确认按钮 - **不阻止流程**: 用户确认后可继续 ### 4.6 AI 合规顾问模块 #### 4.6.1 智能问答 - **页面**: `/ai-assistant` - **接口**: `POST /api/v1/ai/chat`(SSE 流式) - **请求**: ```json { "messages": [ {"role": "user", "content": "试用期最长可以约定几个月?"} ], "context": { "orgId": "xxx", "employeeCount": 12, "riskItems": [...] } } ``` - **后端处理**: 1. 构建系统 Prompt(劳动法专家角色 + 人话风格要求) 2. RAG 检索相关法律条文(pgvector 语义搜索) 3. 注入企业数据上下文 4. 调用 DashScope API(qwen-plus) 5. SSE 流式返回前端 - **响应**: SSE 事件流 ``` data: {"type": "chunk", "content": "根据"} data: {"type": "chunk", "content": "《劳动合同法》"} data: {"type": "chunk", "content": "第19条"} ... data: {"type": "done", "legalBasis": "《劳动合同法》第19条"} ``` #### 4.6.2 风险预测 - **触发**: 每日凌晨定时任务 + 首页加载时读取缓存 - **接口**: `GET /api/v1/ai/prediction` - **逻辑**: 1. 查询未来30天将到期的合同 2. 查询入职将满1年未签合同的员工 3. 分析上月加班趋势变化 4. 调用 LLM 生成优先级建议 - **缓存**: 结果存 Redis / 内存缓存,24h 有效 #### 4.6.3 合同审查 - **页面**: `/ai-assistant` 子 Tab - **接口**: `POST /api/v1/ai/contract-review` - **输入**: 合同文本(粘贴或文件上传解析) - **后端处理**: 1. 调用 qwen-max 分析合同条款 2. 逐条标注红/黄/绿 + 修改建议 3. 计算合规评分(0-100) - **输出**: ```json { "success": true, "data": { "score": 72, "items": [ {"level": "red", "clause": "试用期6个月", "issue": "超过法定上限", "suggestion": "调整为2个月"}, {"level": "yellow", "clause": "竞业限制", "issue": "未约定补偿标准", "suggestion": "约定月补偿不低于离职前12个月平均工资的30%"} ] } } ``` #### 4.6.4 案例匹配 - **页面**: `/ai-assistant` 子 Tab - **接口**: `POST /api/v1/ai/case-match` - **输入**: 争议情况描述 - **后端处理**: 1. 将描述向量化(DashScope text-embedding-v2) 2. pgvector 检索相似案例(top 5) 3. 调用 qwen-max 分析败诉概率和赔偿预估 - **输出**: 相似案例列表 + 败诉概率 + 赔偿预估 + 建议 #### 4.6.5 使用次数限制 - **中间件**: 每次 AI 请求前检查当月已用次数 - **计数**: Redis / 数据库按 `orgId + 月份 + 类型` 统计 - **超限**: 返回 `429 Too Many Requests` + 提示升级套餐 --- ## 5. 页面规格 ### 5.1 页面清单 **管理端**: | 页面 | 路由 | 访问控制 | 布局 | |------|------|---------|------| | 登录 | `/login` | 公开 | 居中卡片 | | 注册 | `/register` | 公开 | 居中卡片 | | 忘记密码 | `/forgot-password` | 公开 | 居中卡片 | | 风险总览 | `/` | 登录 | 顶部导航 + 主内容 | | 合同管理 | `/contracts` | 登录 | 顶部导航 + 主内容 | | 钱的计算 | `/money` | 登录 | 顶部导航 + 主内容 | | 解聘助手 | `/termination` | 登录 | 顶部导航 + 主内容 | | AI 合规顾问 | `/ai-assistant` | 登录 | 顶部导航 + 主内容 | | 系统设置 | `/settings` | 登录(admin) | 顶部导航 + 主内容 | **员工端**: | 页面 | 路由 | 访问控制 | 布局 | |------|------|---------|------| | 员工登录 | `/portal/login` | 公开 | 居中卡片 | | 工资条 | `/portal/payslip` | 员工Token | 极简布局 | | 我的合同 | `/portal/contract` | 员工Token | 极简布局 | | 入职填报 | `/portal/onboarding` | Token链接 | 极简布局 | | 合同确认 | `/portal/contract-confirm` | Token链接 | 极简布局 | ### 5.2 响应式断点 | 断点 | 宽度 | 布局变化 | |------|------|---------| | 桌面 | ≥1280px | 顶部导航 + 960px 居中内容 | | 平板 | 768-1279px | 顶部导航 + 全宽内容 | | 手机 | 375-767px | 底部 Tab Bar + 全宽内容 | ### 5.3 空状态设计 | 场景 | 展示内容 | |------|---------| | 首页无员工 | 插图 + 「添加第一个员工」按钮 + 示例截图 | | 合同列表无数据 | 插图 + 「还没有员工,点这里添加」按钮 | | 无风险 | 绿色大勾 + 「✅ 暂无风险,继续保持!」 | | AI 顾问无对话 | 欢迎语 + 预设问题快捷按钮 | | 解聘无历史记录 | 插图 + 「还没有解聘记录」文字 | | 员工端无工资条 | 插图 + 「暂无工资记录」文字 | | 员工端无合同 | 插图 + 「暂无合同信息,请联系 HR」文字 | | 入职填报链接失效 | 提示「链接已过期,请联系 HR 重新发送」 | | 合同确认链接失效 | 提示「链接已过期,请联系 HR 重新发送」 | --- ## 6. API 规格 ### 6.1 统一规范 - **前缀**: `/api/v1/` - **认证**: `Authorization: Bearer ` - **响应格式**: ```json { "success": true, "data": {}, "error": null } ``` - **错误格式**: ```json { "success": false, "data": null, "error": { "code": "VALIDATION_ERROR", "message": "手机号格式不正确" } } ``` - **分页**: `?page=1&pageSize=20` → 返回 `{ items: [], total: 100, page: 1, pageSize: 20 }` ### 6.2 API 清单 | 模块 | 方法 | 路径 | 说明 | |------|------|------|------| | 认证 | POST | `/auth/register` | 注册 | | 认证 | POST | `/auth/login` | 登录 | | 认证 | POST | `/auth/refresh` | 刷新 Token | | 认证 | GET | `/auth/me` | 获取当前用户 | | Dashboard | GET | `/dashboard` | 首页数据聚合 | | 员工 | GET | `/employees` | 员工列表 | | 员工 | POST | `/employees` | 添加员工 | | 员工 | GET | `/employees/:id` | 员工详情 | | 员工 | PUT | `/employees/:id` | 编辑员工 | | 员工 | DELETE | `/employees/:id` | 删除员工(软删除) | | 合同 | POST | `/contracts/batch-renew` | 批量续签 | | 合同 | POST | `/contracts/:id/attachment` | 上传扫描件 | | 加班 | GET | `/overtime` | 加班记录列表 | | 加班 | POST | `/overtime` | 添加加班记录 | | 解聘 | GET | `/termination` | 解聘记录列表 | | 解聘 | POST | `/termination` | 创建解聘记录 | | 风险 | GET | `/risks` | 风险列表 | | 风险 | PUT | `/risks/:id` | 更新风险状态 | | AI | POST | `/ai/chat` | 智能问答(SSE) | | AI | GET | `/ai/prediction` | 风险预测 | | AI | POST | `/ai/contract-review` | 合同审查 | | AI | POST | `/ai/case-match` | 案例匹配 | | 设置 | GET | `/settings/org` | 企业信息 | | 设置 | PUT | `/settings/org` | 更新企业信息 | | 设置 | GET | `/settings/users` | 用户列表 | | 设置 | POST | `/settings/users` | 添加用户 | | 设置 | PUT | `/settings/users/:id` | 编辑用户 | | 设置 | DELETE | `/settings/users/:id` | 移除用户 | | 员工端 | POST | `/portal/auth/login` | 手机号+密码登录 | | 员工端 | POST | `/portal/auth/send-code` | 发送验证码(v1.0 页面内显示) | | 员工端 | POST | `/portal/auth/verify` | 验证码登录 | | 员工端 | POST | `/portal/auth/change-password` | 修改密码 | | 员工端 | GET | `/portal/payslip` | 工资条列表 | | 员工端 | GET | `/portal/payslip/:month` | 指定月工资明细 | | 员工端 | POST | `/portal/payslip/:month/confirm` | 确认已阅工资条 | | 员工端 | GET | `/portal/contract` | 我的合同信息 | | 员工端 | GET | `/portal/onboarding/:token` | 获取入职填报信息 | | 员工端 | POST | `/portal/onboarding/:token` | 提交入职填报 | | 员工端 | GET | `/portal/contract-confirm/:token` | 获取合同确认信息 | | 员工端 | POST | `/portal/contract-confirm/:token` | 确认签署合同 | | 管理端 | POST | `/employees/:id/generate-onboarding-qr` | 生成入职填报二维码 | | 管理端 | POST | `/contracts/:id/generate-confirm-qr` | 生成合同确认二维码 | | 管理端 | GET | `/payslip/confirm-status` | 工资条确认状态 | --- ## 7. 数据库设计 ### 7.1 Prisma Schema 概要 ```prisma // 核心表 model Organization { id String @id @default(cuid()) name String plan Plan @default(FREE) maxEmployees Int @default(20) city String? createdAt DateTime @default(now()) users User[] employees Employee[] contracts LaborContract[] overtimeRecords OvertimeRecord[] terminations TerminationRecord[] riskItems RiskItem[] auditLogs AuditLog[] } model User { id String @id @default(cuid()) orgId String org Organization @relation(fields: [orgId], references: [id]) phone String @unique email String? passwordHash String name String role Role @default(ADMIN) createdAt DateTime @default(now()) lastLoginAt DateTime? } // 业务表 model Employee { id String @id @default(cuid()) orgId String org Organization @relation(fields: [orgId], references: [id]) name String department String hireDate DateTime monthlySalary String // AES-256 加密存储 status EmployeeStatus @default(ACTIVE) gender String? isPregnant Boolean @default(false) isInMedicalPeriod Boolean @default(false) isWorkInjured Boolean @default(false) phone String? createdBy String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt contracts LaborContract[] overtimeRecords OvertimeRecord[] terminations TerminationRecord[] } model LaborContract { id String @id @default(cuid()) orgId String org Organization @relation(fields: [orgId], references: [id]) employeeId String employee Employee @relation(fields: [employeeId], references: [id]) signDate DateTime? startDate DateTime endDate DateTime? contractType ContractType signMethod SignMethod @default(PAPER) contractYears Int @default(3) probationMonths Int @default(0) probationSalary Int @default(0) renewalCount Int @default(0) attachmentName String? attachmentUrl String? electronicContractNo String? electronicContractUrl String? createdBy String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } // 其余表参考 0-req.md 第5章数据模型 ``` ### 7.2 枚举定义 ```prisma enum Plan { FREE PRO ENTERPRISE } enum Role { ADMIN HR VIEWER } enum EmployeeStatus { ACTIVE RESIGNED } enum ContractType { FIXED UNFIXED UNSIGNED } enum SignMethod { PAPER ELECTRONIC } enum RiskType { CONTRACT SALARY TERMINATION } enum RiskLevel { HIGH MEDIUM LOW } enum RiskStatus { PENDING RESOLVED IGNORED } enum TerminationReason { NEGOTIATED FAULT NONFAULT LAYOFF EXPIRED } enum RiskAssessment { SAFE WARNING DANGER } enum OnboardingStatus { PENDING APPROVED REJECTED } enum ContractConfirmStatus { UNCONFIRMED CONFIRMED EXPIRED } // 员工端扩展表 model Payslip { id String @id @default(cuid()) orgId String employeeId String employee Employee @relation(fields: [employeeId], references: [id]) month String // YYYY-MM baseSalary Decimal // 基本工资 overtimePay Decimal // 加班费合计 weekdayOvertimePay Decimal weekendOvertimePay Decimal holidayOvertimePay Decimal totalPay Decimal // 应发合计 confirmedAt DateTime? // 员工确认时间 confirmedIp String? // 确认 IP createdAt DateTime @default(now()) @@unique([employeeId, month]) } model OnboardingLink { id String @id @default(cuid()) orgId String employeeId String? // 关联员工(审核通过后关联) token String @unique // 一次性 token status OnboardingStatus @default(PENDING) phone String // 员工手机号 expiresAt DateTime // 24h 有效 submittedAt DateTime? // 员工提交时间 submittedData Json? // 员工填报数据 reviewedBy String? // 审核人 userId reviewedAt DateTime? // 审核时间 createdAt DateTime @default(now()) } model ContractConfirmLink { id String @id @default(cuid()) orgId String contractId String token String @unique // 一次性 token status ContractConfirmStatus @default(UNCONFIRMED) employeePhone String // 员工手机号 expiresAt DateTime // 7天有效 confirmedAt DateTime? // 员工确认时间 confirmedIp String? // 确认 IP confirmedDevice String? // 设备信息 createdAt DateTime @default(now()) } ``` --- ## 8. 前端架构 ### 8.1 项目结构 ``` frontend/ ├── src/ │ ├── main.tsx # 入口 │ ├── App.tsx # 路由定义 │ ├── components/ # 通用组件 │ │ ├── layout/ │ │ │ ├── TopNav.tsx # 顶部导航 │ │ │ ├── MobileTabBar.tsx # 移动端底部导航 │ │ │ └── PageContainer.tsx │ │ ├── ui/ │ │ │ ├── Button.tsx │ │ │ ├── Card.tsx │ │ │ ├── Signal.tsx # 信号灯组件 │ │ │ ├── Modal.tsx │ │ │ ├── Input.tsx │ │ │ ├── Select.tsx │ │ │ ├── DatePicker.tsx │ │ │ └── EmptyState.tsx │ │ └── shared/ │ │ ├── RiskCard.tsx │ │ ├── TodoList.tsx │ │ └── ProgressBar.tsx │ ├── pages/ │ │ ├── auth/ │ │ │ ├── Login.tsx │ │ │ ├── Register.tsx │ │ │ └── ForgotPassword.tsx │ │ ├── Dashboard.tsx │ │ ├── Contracts.tsx │ │ ├── Money.tsx │ │ ├── Termination.tsx │ │ ├── AIAssistant.tsx │ │ ├── Settings.tsx │ │ └── portal/ │ │ ├── PortalLogin.tsx # 员工端登录 │ │ ├── Payslip.tsx # 工资条 │ │ ├── MyContract.tsx # 我的合同 │ │ ├── Onboarding.tsx # 入职填报 │ │ └── ContractConfirm.tsx # 合同确认 │ ├── hooks/ │ │ ├── useAuth.ts │ │ ├── useApi.ts │ │ └── useRiskEngine.ts │ ├── lib/ │ │ ├── api.ts # Axios 实例 + 拦截器 │ │ ├── calculator.ts # 纯前端计算逻辑 │ │ ├── riskEngine.ts # 风险检测引擎 │ │ └── utils.ts │ ├── store/ │ │ └── authStore.ts # Zustand 状态管理 │ └── types/ │ └── index.ts # TypeScript 类型定义 ├── package.json ├── vite.config.ts ├── tailwind.config.ts └── tsconfig.json ``` ### 8.2 状态管理 - **认证状态**: Zustand(user, token, isAuthenticated) - **服务端数据**: TanStack Query(React Query)缓存 + 自动刷新 - **表单状态**: React Hook Form + Zod 校验 - **AI 对话**: 本地 useState 管理消息列表 + SSE 流式追加 ### 8.3 路由守卫 ```typescript // ProtectedRoute:未登录 → 跳转 /login // AdminRoute:非 admin → 跳转 / // PublicRoute:已登录 → 跳转 / ``` --- ## 9. 后端架构 ### 9.1 项目结构 ``` backend/ ├── src/ │ ├── index.ts # 入口 │ ├── app.ts # Express 应用 │ ├── routes/ │ │ ├── auth.routes.ts │ │ ├── employee.routes.ts │ │ ├── contract.routes.ts │ │ ├── overtime.routes.ts │ │ ├── termination.routes.ts │ │ ├── risk.routes.ts │ │ ├── ai.routes.ts │ │ ├── settings.routes.ts │ │ └── portal.routes.ts # 员工端路由 │ ├── middleware/ │ │ ├── auth.ts # JWT 校验 │ │ ├── orgFilter.ts # 多租户 orgId 注入 │ │ ├── rateLimit.ts # 限流 │ │ ├── errorHandler.ts # 统一错误处理 │ │ └── auditLog.ts # 审计日志 │ ├── services/ │ │ ├── auth.service.ts │ │ ├── employee.service.ts │ │ ├── contract.service.ts │ │ ├── risk.service.ts │ │ ├── ai.service.ts # DashScope 调用 │ │ ├── rag.service.ts # RAG 检索 │ │ ├── portal.service.ts # 员工端服务 │ │ └── qrcode.service.ts # 二维码生成 │ ├── lib/ │ │ ├── prisma.ts # Prisma 客户端 │ │ ├── jwt.ts # JWT 工具 │ │ ├── crypto.ts # AES-256 加解密 │ │ └── dashscope.ts # 通义千问 SDK 封装 │ ├── validators/ │ │ ├── auth.validator.ts # Zod schema │ │ ├── employee.validator.ts │ │ └── ... │ └── jobs/ │ ├── riskScan.ts # 定时风险扫描 │ └── aiPrediction.ts # 定时 AI 预测 ├── prisma/ │ ├── schema.prisma │ └── migrations/ ├── package.json └── .env ``` ### 9.2 环境变量 ```env # 数据库 DATABASE_URL=postgresql://... # JWT JWT_SECRET=... JWT_REFRESH_SECRET=... # DashScope (通义千问) DASHSCOPE_API_KEY=sk-xxx DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/api/v1 # 加密 ENCRYPTION_KEY=... # AES-256 工资字段加密 # 存储 SUPABASE_URL=... SUPABASE_KEY=... # 二维码(前端生成,无需后端服务) # 使用 qrcode.react 库在前端直接生成 # 部署 PORT=3000 CORS_ORIGIN=https://your-app.vercel.app ``` --- ## 10. 验收标准 ### 10.1 功能验收 | 模块 | 验收项 | 验收标准 | |------|--------|---------| | 注册 | 手机号注册 | 输入合法信息 → 创建成功 → 自动登录 | | 登录 | 密码登录 | 正确密码 → 返回 Token;错误密码 → 提示错误 | | 首页 | 数据聚合 | 登录后 → 显示员工数/风险数/待办/分布 | | 合同 | 添加员工 | 4项必填 → 保存成功 → 列表显示 | | 合同 | 信号灯状态 | 未签合同→🔴;即将到期→🟡;正常→🟢 | | 合同 | 一键续签 | 点击续签→确认→状态变绿→风险消除 | | 合同 | 纸质/电子 | 选择纸质→显示上传按钮;选择电子→显示编号/链接输入 | | 钱的计算 | 加班费实时计算 | 输入数字→右侧结果实时更新 | | 钱的计算 | 加班超时预警 | 总小时>36→黄色警告 | | 解聘 | 5步向导 | 每步显示进度条→下一步→最终保存 | | 解聘 | 禁止情形检查 | 选孕期员工→红色警告弹窗 | | AI | 智能问答 | 输入问题→流式回答→附法律依据 | | AI | 合同审查 | 粘贴合同→逐条标注→合规评分 | | AI | 案例匹配 | 输入情况→相似案例→败诉概率 | | 设置 | 用户管理 | admin可添加用户→分配角色 | | 员工端 | 密码登录 | 输入手机号+密码→登录成功 | | 员工端 | 验证码登录 | 输入手机号→收到验证码→登录成功 | | 员工端 | 扫码进入 | HR 发二维码→员工扫码→打开员工端 | | 员工端 | 工资条查看 | 选择月份→显示工资明细→确认已阅 | | 员工端 | 合同查看 | 显示合同信息+扫描件+签署记录 | | 员工端 | 入职填报 | 扫码→填写信息→提交→HR审核入库 | | 员工端 | 合同确认 | 扫码→查看合同→勾选确认→记录时间IP | | 管理端 | 生成填报二维码 | 添加员工→选生成二维码→显示二维码+链接→微信发送 | | 管理端 | 生成确认二维码 | 合同详情→生成确认二维码→微信发送→员工确认后状态更新 | ### 10.2 非功能验收 | 类别 | 验收标准 | |------|---------| | 性能 | 首屏加载 < 2s,API 响应 < 500ms,AI 首 token < 3s | | 安全 | 密码 bcrypt 加密,工资 AES-256 加密,JWT 认证,orgId 隔离 | | 响应式 | 桌面/平板/手机三端可用,导航自适应 | | 兼容 | Chrome/Edge/Safari 最新版正常 | | 数据隔离 | A 企业用户无法访问 B 企业数据 | | 员工端隔离 | 员工只能查看自己的数据,不能查看他人 | | 链接安全 | 入职/确认链接含一次性 token,过期失效 | --- ## 11. 发布计划 ### 11.1 v1.0 发布范围 | 阶段 | 内容 | 预估工期 | |------|------|---------| | P0 | 项目搭建 + 路由骨架 + Prisma Schema | 2天 | | P1 | 认证体系(注册/登录/JWT/路由守卫) | 2天 | | P2 | 首页风险总览 + 风险检测引擎 | 2天 | | P3 | 合同管理(列表/添加/续签/纸质电子) | 3天 | | P4 | 钱的计算(3 Tab 计算器) | 2天 | | P5 | 解聘助手(5步向导 + 禁止检查) | 2天 | | P6 | AI 合规顾问(问答/预测/审查/案例 + RAG) | 4天 | | P7 | 员工端(验证码登录 + 工资条 + 合同 + 入职填报 + 合同确认) | 3天 | | P8 | 系统设置 + 新手引导 + 空状态 | 1天 | | P9 | 移动端适配 + 联调 | 2天 | | P10 | 部署上线 + 验证 | 1天 | | **合计** | | **~24天** | ### 11.2 后续版本 | 版本 | 内容 | 预估 | |------|------|------| | v2.0 | 社保公积金模块 | +2周 | | v3.0 | 人力成本分析 + 员工自助门户增强(考勤/请假) | +3周 | --- ## 12. 风险与对策 | 风险 | 影响 | 对策 | |------|------|------| | 通义千问 API 不稳定 | AI 功能不可用 | 降级为规则引擎回答 + 重试机制 | | 法律规则地区差异大 | 计算结果不准 | 提供城市选择 + 默认值 + 用户可修改 | | RAG 知识库构建耗时 | P6 延期 | 先用 Prompt 内嵌法条,后续再建向量库 | | 中小企业付费意愿低 | 商业化困难 | free 套餐足够基础使用,AI 功能促付费 | | 数据安全合规要求 | 法律风险 | 数据加密 + 身份证号加密存储 + 隐私协议 | | 员工端使用率低 | 功能闲置 | HR 主动生成二维码通过微信发给员工,降低使用门槛 |