# 劳动用工合规助手 — 开发任务清单 > **文档编号**: 2-task.md > **版本**: v1.0 > **日期**: 2026-07-23 > **状态**: 开发中 > **依据**: 0-req.md v3.0 需求规格说明书 / 1-prd.md v1.0 产品需求文档 --- ## 任务总览 | 阶段 | 内容 | 预估工期 | 任务数 | |------|------|---------|--------| | P0 | 项目搭建 + 路由骨架 + Prisma Schema | 2天 | 8 | ✅ 已完成 | | P1 | 认证体系(注册/登录/JWT/路由守卫) | 2天 | 7 | ✅ 已完成 | | P2 | 首页风险总览 + 风险检测引擎 | 2天 | 6 | ✅ 已完成 | | P3 | 合同管理(列表/添加/续签/纸质电子) | 3天 | 10 | ✅ 已完成 | | P4 | 钱的计算(3 Tab 计算器 + 加班费保存 + 工资条管理) | 2天 | 5 | ✅ 已完成 | | P5 | 解聘助手(5步向导 + 禁止检查) | 2天 | 6 | ✅ 已完成 | | P6 | AI 合规顾问(问答/预测/审查/案例 + RAG) | 4天 | 9 | ✅ 已完成 | | P7 | 员工端(密码/验证码登录 + 工资条 + 合同 + 入职填报 + 合同确认) | 3天 | 10 | ✅ 已完成 | | P8 | 系统设置 + 新手引导 + 空状态 | 1天 | 5 | ✅ 已完成 | | P9 | 移动端适配 + 联调 | 2天 | 4 | ✅ 已完成 | | P10 | 部署上线 + 验证 | 1天 | 4 | ⏳ 进行中 | | P11 | 功能补齐(社保公积金 + 到期提醒 + 批量工资条 + Excel导入 + 员工档案附件) | 3天 | 10 | ✅ 已完成 | | **合计** | | **~27天** | **84** | | --- ## P0 — 项目搭建 + 路由骨架 + Prisma Schema(2天) ### 前端 - [x] **T-P0-01** 初始化前端项目 - Vite + React 18 + TypeScript - 安装 TailwindCSS + PostCSS - 配置路径别名 `@/` → `src/` - 安装核心依赖:react-router-dom, axios, zustand, @tanstack/react-query, react-hook-form, zod, lucide-react, qrcode.react - **产出**: `package.json`, `vite.config.ts`, `tailwind.config.ts`, `tsconfig.json` - [x] **T-P0-02** 前端项目结构搭建 - 创建目录结构:`components/`, `pages/`, `hooks/`, `lib/`, `store/`, `types/` - 创建 `App.tsx` 路由骨架(含管理端 + 员工端路由定义) - 创建 `main.tsx` 入口 - 创建 `lib/api.ts`(Axios 实例 + 请求/响应拦截器) - 创建 `types/index.ts`(TypeScript 类型定义) - **产出**: 项目目录结构 + 路由配置 - [x] **T-P0-03** 前端布局组件 - `TopNav.tsx`:顶部导航栏(Logo + 5 Tab + 风险角标 + 用户头像下拉) - `MobileTabBar.tsx`:移动端底部导航 - `PageContainer.tsx`:主内容区容器(max-width 960px 居中) - `ui/Button.tsx`, `ui/Card.tsx`, `ui/Input.tsx`, `ui/Select.tsx`, `ui/Modal.tsx`, `ui/Signal.tsx`, `ui/EmptyState.tsx` - **产出**: 通用组件库 ### 后端 - [x] **T-P0-04** 初始化后端项目 - Node.js + Express + TypeScript - 安装核心依赖:prisma, @prisma/client, zod, jsonwebtoken, bcryptjs, cors, helmet, morgan, express-rate-limit - 配置 ts-node-dev 热重载 - **产出**: `package.json`, `tsconfig.json`, `.env.example` - [x] **T-P0-05** 后端项目结构搭建 - 创建目录结构:`routes/`, `middleware/`, `services/`, `lib/`, `validators/`, `jobs/` - `app.ts`:Express 应用(CORS + helmet + JSON 解析 + 路由挂载) - `index.ts`:服务入口 - **产出**: 后端骨架 + 健康检查接口 `/health` - [x] **T-P0-06** Prisma Schema 编写 - 编写完整 `schema.prisma`:Organization, User, Employee, LaborContract, OvertimeRecord, TerminationRecord, RiskItem, AuditLog, Payslip, OnboardingLink, ContractConfirmLink - 定义所有枚举:Plan, Role, EmployeeStatus, ContractType, SignMethod, RiskType, RiskLevel, RiskStatus, TerminationReason, RiskAssessment, OnboardingStatus, ContractConfirmStatus - 配置 PostgreSQL 数据源 - **产出**: `prisma/schema.prisma` - [x] **T-P0-07** 数据库迁移 + 种子数据 - 运行 `prisma migrate dev` 生成初始迁移 - 编写 `prisma/seed.ts` 种子数据(测试企业 + 员工 + 合同) - 配置 `prisma.ts` 客户端单例 - **产出**: 数据库表结构 + 测试数据 - [x] **T-P0-08** 中间件骨架 - `auth.ts`:JWT 校验中间件(从 Header 提取 Token → 验证 → 注入 req.user) - `orgFilter.ts`:多租户中间件(从 req.user 提取 orgId → 注入 req.orgId) - `errorHandler.ts`:统一错误处理(Zod 错误 → 422,Prisma 错误 → 400,其他 → 500) - `rateLimit.ts`:限流中间件(基于 express-rate-limit) - `auditLog.ts`:审计日志中间件(记录关键操作) - **产出**: 5 个中间件文件 --- ## P1 — 认证体系(2天) - [x] **T-P1-01** 后端:注册接口 - `POST /api/v1/auth/register` - 输入校验(Zod):企业名称、手机号、密码(8位+) - 逻辑:创建 Organization(plan=free, maxEmployees=20)+ User(role=admin, bcrypt 加密) - 返回:Access Token(2h)+ Refresh Token(7d) - 限流:同一 IP 每小时 5 次 - **产出**: `auth.routes.ts` + `auth.service.ts` + `auth.validator.ts` - [x] **T-P1-02** 后端:登录接口 - `POST /api/v1/auth/login` - 输入校验:手机号、密码 - 逻辑:查询 User → bcrypt 比对 → 签发 Token - 限流:同一 IP 每分钟 5 次 - **产出**: 登录逻辑 - [x] **T-P1-03** 后端:Token 刷新 + 当前用户 - `POST /api/v1/auth/refresh`:校验 Refresh Token → 签发新 Access Token - `GET /api/v1/auth/me`:返回当前用户信息 + 组织信息 - **产出**: Token 刷新逻辑 - [x] **T-P1-04** 后端:JWT 工具 - `lib/jwt.ts`:签发/验证 Access Token + Refresh Token - 密钥从环境变量读取 - **产出**: `jwt.ts` - [x] **T-P1-05** 前端:注册页面 - `/register` 页面 - 表单:企业名称、手机号、密码、确认密码 - React Hook Form + Zod 校验 - 注册成功 → 存储 Token → 跳转首页 - **产出**: `Register.tsx` - [x] **T-P1-06** 前端:登录页面 + 路由守卫 - `/login` 页面 - 表单:手机号、密码 - `useAuth` Hook(Zustand store:user, token, isAuthenticated) - `ProtectedRoute`:未登录 → 跳转 `/login` - `PublicRoute`:已登录 → 跳转 `/` - Axios 拦截器:401 → 自动刷新 Token / 跳转登录 - **产出**: `Login.tsx` + `useAuth.ts` + `authStore.ts` + 路由守卫 - [x] **T-P1-07** 前端:忘记密码页面 - `/forgot-password` 页面 - 手机号 + 验证码 + 新密码 - **产出**: `ForgotPassword.tsx` --- ## P2 — 首页风险总览 + 风险检测引擎(2天) - [x] **T-P2-01** 后端:Dashboard 数据聚合接口 - `GET /api/v1/dashboard` - 聚合:员工数、高风险数、待办数、月加班费 - 生成待办列表(从 RiskItem 查询 pending 状态) - 风险分布统计(按 type 分组) - AI 预测数据(从缓存读取,P6 实现) - **产出**: `dashboard.routes.ts` + `dashboard.service.ts` - [x] **T-P2-02** 后端:风险检测引擎 - `lib/riskEngine.ts` - 合同风险检测:未签合同(>30天 🔴 / >365天 视为无固定期限 🔴)、即将到期(≤30天 🟡)、已到期 🔴 - 试用期风险检测:试用期超法定上限 - 加班风险检测:月加班 > 36h - 解聘风险检测:禁止解聘情形(孕期/工伤/医疗期) - 触发时机:数据变更时实时检测 + 定时全量扫描 - **产出**: `riskEngine.ts` - [x] **T-P2-03** 后端:风险 CRUD 接口 - `GET /api/v1/risks`:风险列表(分页 + 类型筛选 + 状态筛选) - `PUT /api/v1/risks/:id`:更新风险状态(resolved / ignored + 备注) - **产出**: `risk.routes.ts` + `risk.service.ts` - [x] **T-P2-04** 后端:定时风险扫描任务 - `jobs/riskScan.ts`:每日凌晨 2:00 全量扫描 - 使用 node-cron 调度 - 扫描所有企业的员工/合同 → 生成/更新 RiskItem - **产出**: `riskScan.ts` - [x] **T-P2-05** 前端:首页风险总览页面 - `/` Dashboard 页面 - 一句话状态("早上好!今天有 N 件事需要处理") - 数字卡片:员工数 / 高风险数 / 待办数 / 月加班费 - 待办列表:每条含风险等级颜色 + 标题 + 「去处理」按钮 - 风险分布进度条(合同/工资/解聘) - AI 风险预测卡片(P6 实现后接入) - **产出**: `Dashboard.tsx` + `TodoList.tsx` + `ProgressBar.tsx` - [x] **T-P2-06** 前端:风险角标组件 - 顶部导航栏红色角标,显示待处理风险总数 - 点击跳转首页 - 数据来源:Dashboard 接口或独立计数接口 - **产出**: `TopNav.tsx` 集成角标 --- ## P3 — 合同管理(3天) - [x] **T-P3-01** 后端:员工 CRUD 接口 - `GET /api/v1/employees`:列表(分页 + 搜索 + 部门筛选) - `POST /api/v1/employees`:添加员工(含合同信息 + AES-256 加密工资) - `GET /api/v1/employees/:id`:详情(含合同 + 风险) - `PUT /api/v1/employees/:id`:编辑 - `DELETE /api/v1/employees/:id`:软删除(status=resigned) - **产出**: `employee.routes.ts` + `employee.service.ts` + `employee.validator.ts` - [x] **T-P3-02** 后端:AES-256 加密工具 - `lib/crypto.ts`:加密/解密工资字段 - 密钥从环境变量 `ENCRYPTION_KEY` 读取 - **产出**: `crypto.ts` - [x] **T-P3-03** 后端:合同状态计算 - `lib/contractStatus.ts` - 输入:signDate, startDate, endDate, contractType, renewalCount, hireDate - 输出:status + statusText + riskLevel - 逻辑:未签/即将到期/已到期/正常/无固定期限 - **产出**: `contractStatus.ts` - [x] **T-P3-04** 后端:试用期合法性校验 - 合同期 < 3月 → 不能约定试用期 - 合同期 3月~1年 → 试用期 ≤ 1月 - 合同期 1~3年 → 试用期 ≤ 2月 - 合同期 ≥ 3年 → 试用期 ≤ 6月 - **产出**: 集成到 `employee.validator.ts` - [x] **T-P3-05** 后端:批量续签接口 - `POST /api/v1/contracts/batch-renew` - 输入:合同 ID 列表 + 新期限 - 逻辑:更新 endDate + renewalCount++ + 重新检测风险 - **产出**: `contract.service.ts` 续签逻辑 - [x] **T-P3-06** 后端:合同附件上传 - `POST /api/v1/contracts/:id/attachment` - 接收 multipart 文件(纸质合同扫描件) - 存储到 Supabase Storage / 本地临时目录 - 更新合同记录 attachmentName + attachmentUrl - **产出**: 文件上传逻辑 - [x] **T-P3-07** 前端:合同管理列表页 - `/contracts` 页面 - 员工合同列表:姓名 / 部门 / 合同状态信号灯 / 到期日 / 操作 - 搜索框 + 部门筛选 - 信号灯组件(🔴🟡🟢) - **产出**: `Contracts.tsx` - [x] **T-P3-08** 前端:添加/编辑员工表单 - 模态框表单 - Step 1 基本信息:姓名*、部门*、手机号、入职日期*、月工资*、性别 - Step 2 合同信息:合同类型*、签订方式(纸质/电子)、签订日期、起止日期、试用期月数、试用期工资 - 纸质合同:显示文件上传按钮 - 电子合同:显示合同编号 + 链接输入 - 试用期实时校验(红色提示) - 特殊标记:孕期/工伤/医疗期 复选框 - **产出**: `EmployeeForm.tsx` - [x] **T-P3-09** 前端:一键续签弹窗 - 选中即将到期的合同 → 点击「续签」 - 弹窗:显示当前合同信息 + 选择新期限 - 确认 → 调用批量续签接口 → 刷新列表 - **产出**: `RenewModal.tsx` - [x] **T-P3-10** 前端:合同详情页/弹窗 - 显示员工信息 + 合同完整信息 + 风险卡片 - 纸质合同:查看扫描件 - 电子合同:查看合同链接 - 操作按钮:编辑 / 续签 / 发送确认二维码(P7 实现) - **产出**: `ContractDetail.tsx` --- ## P4 — 钱的计算(2天) - [x] **T-P4-01** 前端:加班费计算器(含员工关联 + 月份选择 + 保存记录) - `/money` Tab 1 - 输入:月工资、工作日加班小时、休息日加班小时、节假日加班小时 - 公式:hourlyWage = monthlyWage / 21.75 / 8 - weekdayPay = hourlyWage × 1.5 × weekdayHours - weekendPay = hourlyWage × 2.0 × weekendHours - holidayPay = hourlyWage × 3.0 × holidayHours - 实时计算,右侧显示结果 - 总加班 > 36h → 黄色警告 - **产出**: `OvertimeCalculator.tsx` + `lib/calculator.ts` - [x] **T-P4-02** 前端:双倍工资计算器 - `/money` Tab 2 - 输入:月工资、入职日期、合同签订日期(可选) - 公式:未签或超 30 天签订 → 起算入职+1月 → 截止入职+1年或签订日 → 双倍工资差额 - 实时计算 - **产出**: `DoublePayCalculator.tsx` - [x] **T-P4-03** 前端:经济补偿金计算器 - `/money` Tab 3 - 输入:入职日期、离职日期、月平均工资、离职原因、社平工资(选填) - 公式:工作年限 → 补偿月数 → 封顶限制 → 经济补偿金 / 违法解除赔偿金(×2) - 实时计算 - **产出**: `CompensationCalculator.tsx` - [x] **T-P4-04** 后端:加班记录 CRUD + 工资条管理(`payroll.routes.ts`) - `GET /api/v1/overtime`:加班记录列表 - `POST /api/v1/overtime`:添加加班记录 - **产出**: `overtime.routes.ts` + `overtime.service.ts` - [x] **T-P4-05** 前端:计算器工具函数 + 工资条管理 Tab - `lib/calculator.ts`:纯函数,输入输出明确 - 编写单元测试验证计算公式正确性 - 边界用例:0 加班、36h 临界值、社平工资 3 倍封顶 - **产出**: `calculator.ts` + `calculator.test.ts` --- ## P5 — 解聘助手(2天) - [x] **T-P5-01** 后端:解聘记录 CRUD - `GET /api/v1/termination`:解聘记录列表 - `POST /api/v1/termination`:创建解聘记录 - 逻辑:保存向导数据 + 更新员工状态为 resigned + 记录审计日志 - **产出**: `termination.routes.ts` + `termination.service.ts` + `termination.validator.ts` - [x] **T-P5-02** 前端:解聘向导 Step 1 — 选择解聘原因 - `/termination` 页面 - 5 个选项卡片:协商解除 / 员工犯错 / 员工没犯错但干不了 / 公司裁员 / 合同到期不续签 - 每个选项含简短说明 - **产出**: `Termination.tsx` Step 1 - [x] **T-P5-03** 前端:解聘向导 Step 2 — 选择员工 + 禁止情形检查 - 员工选择下拉框(仅在职员工) - 选择后自动检查:isPregnant / isWorkInjured / isInMedicalPeriod - 命中禁止情形 → 红色警告弹窗 + 「我已了解风险,继续操作」 - **产出**: Step 2 + 禁止情形检查逻辑 - [x] **T-P5-04** 前端:解聘向导 Step 3 — 合规检查清单 - 根据解聘原因动态生成检查项 - 协商解除:是否支付补偿金 / 是否签署协议 - 员工犯错:是否有规章制度 / 是否有证据 / 是否通知工会 - 员工没犯错:是否提前30天通知 / 是否经过培训调岗 - 公司裁员:是否提前30天向工会说明 / 是否听取意见 / 是否报劳动部门 - 合同到期:是否提前通知 / 是否支付补偿金 - 每项 ✅/❌ 选择 - **产出**: Step 3 + 动态检查项规则 - [x] **T-P5-05** 前端:解聘向导 Step 4 — 补偿金计算 + Step 5 — 确认提交 - Step 4:自动填充员工工资 + 入职日期 → 计算补偿金(复用 P4 计算逻辑) - Step 5:汇总信息确认 → 提交保存 - 进度条显示 1/5 ~ 5/5 - **产出**: Step 4 + Step 5 - [x] **T-P5-06** 前端:解聘历史记录 - `/termination` 页面底部 - 历史记录列表:员工名 / 解聘日期 / 原因 / 补偿金 / 风险等级 - 点击查看详情 - **产出**: `TerminationHistory.tsx` --- ## P6 — AI 合规顾问(4天) - [x] **T-P6-01** 后端:DashScope SDK 封装 - `lib/dashscope.ts` - 封装通义千问 API 调用(兼容 OpenAI 格式) - 支持 qwen-plus(日常问答)和 qwen-max(复杂任务) - 支持 SSE 流式输出 - API Key 从环境变量 `DASHSCOPE_API_KEY` 读取 - **产出**: `dashscope.ts` - [x] **T-P6-02** 后端:RAG 知识库 — 法律条文向量化 - `services/rag.service.ts` - 收集劳动法/劳动合同法/司法解释/地方条例文本 - 使用 DashScope text-embedding-v2 生成向量 - 存储到 Supabase pgvector - 提供语义搜索接口(输入问题 → 检索相关法条) - **产出**: `rag.service.ts` + 知识库数据 - [x] **T-P6-03** 后端:智能问答接口(SSE) - `POST /api/v1/ai/chat` - 逻辑: 1. 构建系统 Prompt(劳动法专家 + 人话风格) 2. RAG 检索相关法条 3. 注入企业数据上下文(员工数/风险项/合同状态) 4. 调用 qwen-plus SSE 流式返回 - SSE 事件格式:`data: {"type":"chunk","content":"xxx"}` - 结束事件:`data: {"type":"done","legalBasis":"..."}` - **产出**: `ai.routes.ts` + `ai.service.ts` - [x] **T-P6-04** 后端:风险预测接口 - `GET /api/v1/ai/prediction` - 逻辑: 1. 查询未来 30 天到期合同 2. 查询入职满 1 年未签合同员工 3. 分析上月加班趋势 4. 调用 LLM 生成优先级建议 - 缓存 24h - 定时任务:每日凌晨生成 - **产出**: 预测逻辑 + `jobs/aiPrediction.ts` - [x] **T-P6-05** 后端:合同审查接口 - `POST /api/v1/ai/contract-review` - 输入:合同文本(粘贴或文件解析) - 逻辑:调用 qwen-max 逐条分析 → 标注红/黄/绿 + 修改建议 → 合规评分 - **产出**: 合同审查逻辑 - [x] **T-P6-06** 后端:案例匹配接口 - `POST /api/v1/ai/case-match` - 输入:争议情况描述 - 逻辑:text-embedding-v2 向量化 → pgvector 检索 top 5 → qwen-max 分析败诉概率 - **产出**: 案例匹配逻辑 - [x] **T-P6-07** 后端:AI 使用次数限制 - 中间件:每次 AI 请求前检查当月已用次数 - 按 `orgId + 月份 + 类型` 统计 - free: 10 问答 / 3 审查 / 3 案例 - pro: 100 / 20 / 20 - enterprise: 无限 - 超限 → 429 + 提示升级 - **产出**: AI 限流中间件 - [x] **T-P6-08** 前端:AI 顾问页面 — 智能问答 - `/ai-assistant` 页面 - 聊天界面:消息列表 + 输入框 - 预设问题快捷按钮("试用期最长多久?" "未签合同怎么办?") - SSE 流式接收:逐字显示打字机效果 - 法律依据折叠展示 - 多轮对话(保留上下文 messages) - **产出**: `AIAssistant.tsx` 聊天 Tab - [x] **T-P6-09** 前端:AI 顾问页面 — 合同审查 + 案例匹配 - 合同审查 Tab:文本框粘贴合同 / 文件上传 → 提交 → 逐条标注展示 + 合规评分 - 案例匹配 Tab:描述争议情况 → 提交 → 相似案例卡片列表 + 败诉概率 + 赔偿预估 - **产出**: 合同审查 Tab + 案例匹配 Tab --- ## P7 — 员工端(3天) - [x] **T-P7-01** 后端:员工端认证(密码登录 + 验证码登录) - `POST /api/v1/portal/auth/login`:手机号 + 密码(bcrypt 校验员工密码) - `POST /api/v1/portal/auth/send-code`:发送验证码(v1.0 页面内显示,存 Redis/内存) - `POST /api/v1/portal/auth/verify`:验证码登录 - `POST /api/v1/portal/auth/change-password`:修改密码 - 员工 Token 与管理端 Token 区分(role=employee) - **产出**: `portal.routes.ts` 认证部分 + `portal.service.ts` - [x] **T-P7-02** 后端:员工端工资条接口 - `GET /api/v1/portal/payslip`:工资条列表(按月) - `GET /api/v1/portal/payslip/:month`:指定月工资明细 - `POST /api/v1/portal/payslip/:month/confirm`:确认已阅(记录时间 + IP) - 数据隔离:只能查看自己的工资条 - **产出**: 工资条接口 - [x] **T-P7-03** 后端:员工端合同查看接口 - `GET /api/v1/portal/contract`:当前员工的合同信息(只读) - 包含:合同类型、期限、试用期、工资、扫描件/电子链接、签署确认记录 - **产出**: 合同查看接口 - [x] **T-P7-04** 后端:入职填报接口 - `GET /api/v1/portal/onboarding/:token`:根据 token 获取填报信息(企业名等) - `POST /api/v1/portal/onboarding/:token`:提交填报数据 - Token 校验:有效性 + 过期检查(24h) - 提交后状态 → PENDING,HR 审核后 → APPROVED(创建 Employee) - `POST /api/v1/employees/:id/generate-onboarding-qr`:管理端生成填报 token - **产出**: 入职填报接口 + OnboardingLink 表操作 - [x] **T-P7-05** 后端:合同确认接口 - `GET /api/v1/portal/contract-confirm/:token`:根据 token 获取合同信息 - `POST /api/v1/portal/contract-confirm/:token`:确认签署(记录时间 + IP + 设备) - Token 校验:有效性 + 过期检查(7天) - 确认后更新合同状态 + ContractConfirmLink 状态 - `POST /api/v1/contracts/:id/generate-confirm-qr`:管理端生成确认 token - **产出**: 合同确认接口 + ContractConfirmLink 表操作 - [x] **T-P7-06** 后端:二维码生成服务 - `services/qrcode.service.ts` - 生成 token + 构建完整 URL(如 `https://xxx/portal/onboarding?token=xxx`) - 返回 URL 供前端生成二维码图片 - **产出**: `qrcode.service.ts` - [x] **T-P7-07** 前端:员工端登录页面 - `/portal/login` 页面 - 双 Tab 切换:[密码登录] [验证码登录] - 密码登录:手机号 + 密码 - 验证码登录:手机号 → 获取验证码 → 输入验证码 - v1.0 验证码页面内弹窗显示 - **产出**: `PortalLogin.tsx` - [x] **T-P7-08** 前端:员工端工资条页面 - `/portal/payslip` 页面 - 月份选择器 - 工资明细卡片:基本工资 + 加班费拆分(工作日/休息日/节假日)+ 应发合计 - 「确认已阅」按钮 - 空状态:暂无工资记录 - **产出**: `Payslip.tsx` - [x] **T-P7-09** 前端:员工端合同查看 + 入职填报 + 合同确认页面 - `/portal/contract`:合同信息只读展示 + 扫描件查看 + 签署记录 + 到期提示 - `/portal/onboarding`:入职填报表单(姓名/手机号/身份证/银行卡等)+ 提交 - `/portal/contract-confirm`:合同信息展示 + 查看合同文件 + 勾选确认 + 签署 - Token 失效页面:链接已过期提示 - **产出**: `MyContract.tsx` + `Onboarding.tsx` + `ContractConfirm.tsx` - [x] **T-P7-10** 前端:管理端二维码生成弹窗 - 合同管理页:「生成填报二维码」按钮 → 弹窗显示二维码图片 + 可复制链接 - 合同详情页:「生成确认二维码」按钮 → 弹窗显示二维码图片 + 可复制链接 - 使用 qrcode.react 生成二维码 - 保存二维码图片功能 - **产出**: `QRCodeModal.tsx` --- ## P8 — 系统设置 + 新手引导 + 空状态(1天) - [x] **T-P8-01** 后端:系统设置接口 - `GET /api/v1/settings/org`:企业信息 - `PUT /api/v1/settings/org`:更新企业信息(名称、城市) - `GET /api/v1/settings/users`:用户列表 - `POST /api/v1/settings/users`:添加用户 - `PUT /api/v1/settings/users/:id`:编辑用户 - `DELETE /api/v1/settings/users/:id`:移除用户 - **产出**: `settings.routes.ts` + `settings.service.ts` - [x] **T-P8-02** 前端:系统设置页面 - `/settings` 页面,3 个子 Tab - 企业信息:名称、城市选择(联动最低工资/社平工资默认值) - 用户管理:用户列表 + 添加/编辑/移除 + 角色分配(admin/hr/viewer) - 套餐信息:当前套餐 + 已用人数 + 上限 + 升级按钮 - **产出**: `Settings.tsx` - [x] **T-P8-03** 前端:新手引导弹窗 - 首次登录显示 3 步引导 - Step 1:"这里看风险"(指向首页 Tab) - Step 2:"这里管合同"(指向合同 Tab) - Step 3:"这里算钱"(指向算钱 Tab) - localStorage 记录已看过 - **产出**: `OnboardingGuide.tsx` - [x] **T-P8-04** 前端:空状态组件 - 首页无员工:插图 + 「添加第一个员工」按钮 - 合同列表无数据:插图 + 「还没有员工,点这里添加」 - 无风险:绿色大勾 + 「✅ 暂无风险,继续保持!」 - AI 顾问无对话:欢迎语 + 预设问题 - 解聘无历史:插图 + 文字 - 员工端无工资条/合同:插图 + 文字 - 链接失效:过期提示 - **产出**: `EmptyState.tsx` 各场景 - [x] **T-P8-05** 前端:全局配色 + 样式规范 - TailwindCSS 配色:主色 #2563EB、危险 #DC2626、警告 #F59E0B、安全 #16A34A、背景 #F8FAFC - 字体:系统字体栈 - 圆角:rounded-lg(卡片)/ rounded-md(按钮) - 阴影:shadow-sm(卡片) - **产出**: `tailwind.config.ts` 完整配置 --- ## P9 — 移动端适配 + 联调(2天) - [x] **T-P9-01** 前端:响应式适配 - 桌面 ≥1280px:顶部导航 + 960px 居中 - 平板 768-1279px:顶部导航 + 全宽 - 手机 375-767px:底部 Tab Bar + 全宽 - 合同列表 → 移动端卡片式 - 计算器 → 移动端上下排列 - AI 聊天 → 移动端全屏 - 员工端 → 移动端优先(员工主要用手机) - **产出**: 响应式样式 - [x] **T-P9-02** 前端:员工端移动端优化 - 员工端以移动端为主场景 - 大按钮、大字体、简洁布局 - 扫码后自动适配手机屏幕 - 工资条卡片式展示 - 合同信息折叠展开 - **产出**: 员工端移动端样式 - [x] **T-P9-03** 全栈:端到端联调 - 注册 → 登录 → 添加员工 → 查看首页 → 合同管理 → 计算 → 解聘 → AI 问答 → 员工端登录 → 工资条 → 入职填报 → 合同确认 - 多租户隔离测试:A 企业无法访问 B 企业数据 - 员工端隔离测试:员工只能查看自己的数据 - Token 过期自动刷新测试 - **产出**: 联调问题清单 + 修复 - [x] **T-P9-04** 全栈:性能优化 - 前端:路由懒加载(React.lazy + Suspense) - 前端:API 请求缓存(React Query staleTime 配置) - 后端:数据库索引(orgId + 常用查询字段) - 后端:API 响应压缩(compression 中间件) - **产出**: 性能优化 --- ## P10 — 部署上线 + 验证(1天) - [x] **T-P10-01** 后端:部署配置(`netlify.toml` + `.env.example`) - 配置 Railway 项目 - 环境变量配置:DATABASE_URL, JWT_SECRET, DASHSCOPE_API_KEY, ENCRYPTION_KEY, SUPABASE_URL, CORS_ORIGIN - 运行 Prisma migrate deploy - 健康检查验证 - **产出**: 后端线上地址 - [x] **T-P10-02** 前端:部署到 Netlify(`netlify.toml` 已配置) - 配置 Vercel 项目 - 环境变量配置:VITE_API_URL - 构建配置:`npm run build` - 路由重写配置(SPA fallback) - **产出**: 前端线上地址 - [ ] **T-P10-03** 数据库:Neon/Supabase 配置 - 创建 PostgreSQL 数据库 - 启用 pgvector 扩展(AI 模块用) - 配置连接池 - 运行迁移 - 导入 RAG 知识库数据 - **产出**: 数据库线上环境 - [ ] **T-P10-04** 验收测试 - 按 1-prd.md 第 10 章验收标准逐项验证 - 功能验收:注册/登录/首页/合同/计算/解聘/AI/员工端/设置 - 非功能验收:性能/安全/响应式/兼容/数据隔离 - 修复发现的问题 - **产出**: 验收报告 --- ## 依赖关系 ``` P0 ──→ P1 ──→ P2 ──→ P3 ──→ P4(纯前端,可与 P3 并行) │ ├──→ P5(依赖 P3 员工数据 + P4 补偿金计算) │ ├──→ P6(依赖 P0 数据库 + P2 风险数据) │ ├──→ P7(依赖 P3 合同数据 + P0 数据库) │ └──→ P8(依赖 P1 认证) P9(依赖 P2~P8 全部完成) P10(依赖 P9 完成) ``` **可并行任务**: - P4(钱的计算)纯前端计算,可在 P3 完成后与 P5/P6 并行 - P8(系统设置)可在 P6/P7 期间并行 --- ## 技术栈速查 | 层 | 技术 | |-----|------| | 前端框架 | React 18 + Vite + TypeScript | | 前端样式 | TailwindCSS | | 前端路由 | React Router v6 | | 状态管理 | Zustand(认证)+ TanStack Query(服务端数据)| | 表单 | React Hook Form + Zod | | 二维码 | qrcode.react | | 图标 | lucide-react | | 后端框架 | Express + TypeScript | | ORM | Prisma | | 数据库 | PostgreSQL(Neon/Supabase)+ pgvector | | 认证 | JWT(Access + Refresh)| | 加密 | bcrypt(密码)+ AES-256(工资)| | AI | 通义千问 Qwen(DashScope API)| | Embedding | DashScope text-embedding-v2 | | 部署 | Vercel(前端)+ Railway(后端)| --- ## 环境变量清单 ```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=... # 存储 SUPABASE_URL=... SUPABASE_KEY=... # 部署 PORT=3000 CORS_ORIGIN=https://your-app.vercel.app # 前端 VITE_API_URL=https://your-backend.railway.app ``` --- ## P11 — 功能补齐(3天) > **目标**: 补齐中小企业 HR 实际使用中的关键缺失功能 ### 后端 - [x] **T-P11-01** 后端:社保公积金计算器 - Prisma 模型 `SocialInsuranceConfig`(养老/医疗/失业/工伤/生育/公积金 比例 + 基数上下限) - `social.routes.ts`:GET/PUT 配置 + POST 计算 - 支持基数封顶/保底逻辑 - **产出**: `social.routes.ts` + `SocialInsuranceConfig` 模型 - [x] **T-P11-02** 后端:到期提醒通知服务 - Prisma 模型 `NotificationSetting`(通知开关 + 提前天数 + 微信Webhook + 邮箱) - Prisma 模型 `NotificationLog`(通知记录) - `notification.routes.ts`:GET/PUT 设置 + GET 日志 + POST 手动检查 - 支持企业微信 Webhook 推送 - **产出**: `notification.routes.ts` + `NotificationSetting` + `NotificationLog` 模型 - [x] **T-P11-03** 后端:批量生成工资条 - `POST /api/v1/payroll/payslip/batch-generate` - 自动遍历所有在职员工,关联加班记录,一键生成全员工资条 - 支持传入津贴/扣款映射 - **产出**: `payroll.routes.ts` 新增接口 - [x] **T-P11-04** 后端:Excel/CSV 批量导入加班数据 - `POST /api/v1/payroll/overtime/batch` - 接收数组格式加班数据,批量 upsert - 前端解析 CSV 按员工姓名匹配 - **产出**: `payroll.routes.ts` 新增接口 - [x] **T-P11-05** 后端:员工档案附件管理 - Prisma 模型 `EmployeeAttachment`(文件名/类型/URL/大小) - `attachment.routes.ts`:GET 列表 + POST 添加 + DELETE 删除 - 支持身份证/银行卡/合同扫描件/学历证书/其他分类 - **产出**: `attachment.routes.ts` + `EmployeeAttachment` 模型 ### 前端 - [x] **T-P11-06** 前端:社保公积金计算器 Tab - Money 页面新增「社保公积金」Tab - `SocialInsuranceCalculator` 组件:输入缴费基数 → 计算五险一金明细 - 支持企业/个人比例配置(可展开配置面板) - 表格展示各险种比例、企业缴纳、个人缴纳 - **产出**: `Money.tsx` 新增 `SocialInsuranceCalculator` 组件 - [x] **T-P11-07** 前端:批量生成工资条 UI - PayslipManager 新增「一键全员生成」按钮 - 调用 `batch-generate` 接口,自动关联加班费 - **产出**: `Money.tsx` PayslipManager 增强 - [x] **T-P11-08** 前端:CSV 批量导入加班数据 - OvertimeCalculator 新增「批量导入加班数据(CSV)」按钮 - 前端解析 CSV(姓名,工作日加班,休息日加班,节假日加班,月份) - 按员工姓名自动匹配 employeeId - **产出**: `Money.tsx` OvertimeCalculator 增强 - [x] **T-P11-09** 前端:员工档案附件管理 UI - Contracts 页面点击员工行打开右侧抽屉 - `EmployeeDetailDrawer` 组件:展示员工基本信息 + 合同信息 + 附件管理 - 支持文件上传(FileReader → base64)和删除 - 附件分类:身份证/银行卡/合同扫描件/学历证书/其他 - **产出**: `Contracts.tsx` 新增 `EmployeeDetailDrawer` 组件 - [x] **T-P11-10** 前端:通知设置页面 - Settings 页面新增「通知设置」Tab - `NotificationSettings` 组件:合同到期提醒/未签提醒/加班超时/工资条通知开关 - 提前提醒天数配置 - 企业微信 Webhook 配置 - 邮件通知配置 - 手动触发合同到期检查 + 通知日志展示 - **产出**: `Settings.tsx` 新增 `NotificationSettings` 组件