# 20260803 优化清单（更新于 20260804）

## 一、验收测试清单（问题 1-3）

### 问题 1：保存不提示成功，重新进入记录丢失
- **根因**：acceptance-test.html 使用 localStorage 按验收人姓名保存（STORAGE_PREFIX + name），但在 iframe 中 localStorage 可能因跨域限制无法写入。autoSave() 静默执行无反馈，saveCurrent() 虽有 showToast 但用户可能未看到。
- **修复方向**：
  1. 保存按钮增加明显 toast 提示
  2. 检查 iframe 中 localStorage 是否可用，不可用时降级到服务端存储
  3. 进入页面时自动加载已保存的验收人记录
- **优先级**：P1 高

### 问题 2：无提交按钮，重新进入记录不显示
- **根因**：acceptance-test.html 只有「保存」「下载」「打印」按钮，没有「提交」功能。重新进入时需手动在验收人输入框输入姓名触发 loadSaved，但用户可能不知道这个操作。
- **修复方向**：
  1. 增加「提交验收报告」按钮，将数据发送到后端持久化
  2. 页面加载时自动显示已保存的验收人列表供选择
  3. 优化交互流程，进入时自动加载上次记录
- **优先级**：P1 高

### 问题 3：总体结论不应手动勾选
- **根因**：当前 conclusion-section 中总体结论是 radio 按钮手动选择（acceptance-test.html:592-598），updateStats() 已计算了通过/失败/部分通过/未测试数量，但未自动推导结论。
- **修复方向**：移除手动 radio，根据测试结果自动计算：通过率 100% → 通过，有 fail → 不通过，仅有 partial → 有条件通过。汇总主要问题从 fail/partial 的备注中提取。
- **优先级**：P1 高

## 二、花名册导入（问题 4-5、11）

### 问题 4：导入错误不提示具体内容
- **根因**：Settings.tsx:1077-1127 的导入结果已有错误详情展示（result.errors 数组，最多显示前 10 条），但仅在导入后显示。如果用户跳过「预览」直接导入，错误信息只在结果区域展示，可能被忽略。预览功能（handlePreview）已有完整错误展示。
- **修复方向**：
  1. 导入失败时增加醒目 toast 提示「有 N 条错误，请查看详情」
  2. 错误区域默认展开，不折叠
  3. 增加「跳过错误行，仅导入正常行」选项
- **优先级**：P1 高

### 问题 5：按人为员工办理入职提示乱码
- **根因**：WorkProcess.tsx:453-456 中表单数据以 key 原始字段名显示（如 employeeName、idCardNumber），未做中文标签映射。generateDocument() 生成的文书内容是中文，但 formData 的 key 是英文，显示为「乱码」感。
- **修复方向**：在 WorkProcess.tsx 的表单信息展示区域增加字段名中文映射表，将 employeeName → 员工姓名、idCardNumber → 身份证号 等。
- **优先级**：P0 紧急

### 问题 11：导入后无员工ID显示
- **根因**：import.routes.ts:326-327 导入成功后 result.details 记录了 { sheet, row, name, status: 'success', message: '导入成功' }，但未返回 employeeId。前端 Settings.tsx:1077-1086 只显示「成功导入 N 人」，不显示具体 ID。
- **修复方向**：
  1. 后端导入时在 result.details 中加入 employeeId
  2. 前端结果展示中增加员工 ID 列
  3. 花名册列表中确保 ID 列可见
- **优先级**：P1 高

## 三、工资薪税（问题 6-7）

### 问题 6：批量选择部分人员 + 个税未算出
- **根因**：
  - 批量选人：Money.tsx 已有 mode: 'custom' 和 CustomEmployeeSelector 组件（Money.tsx:331-333），支持按部门筛选、搜索、勾选员工。但用户可能不知道此功能。
  - 个税未算出：payroll.service.ts:230-256 使用累计预扣法，需要已归档批次的历史数据来计算累计应纳税所得额。如果是首次使用或当月无已归档批次，ytdTaxableIncome 可能 ≤ 5000 起征点，导致个税为 0。税前工资超 5000 但个税为 0 的原因可能是：①累计减除费用（5000×月数）后应纳税所得额 ≤ 0；②社保公积金扣除后剩余 ≤ 5000/月。
- **修复方向**：
  1. UI 上更突出「自定义选择员工」模式
  2. 个税计算增加明细展示，让用户看到「累计收入 - 累计减除 - 累计社保 = 应纳税所得额」，理解为何个税为 0
  3. 检查是否有 bug 导致 ytdTaxableIncome 计算错误
- **优先级**：P1 高

### 问题 7：个人保费与实缴一致 + 手动调整
- **根因**：payroll.service.ts:165-206 社保计算基于 socialInsuranceConfig 配置表的比例自动计算。如果配置比例与实际社保局核定金额有差异，无法自动匹配。overrideSocial 参数已支持手动覆盖（payroll2.routes.ts:462-472），但前端可能未暴露此编辑入口。
- **修复方向**：
  1. 工资表条目编辑界面增加「个人社保」「个人公积金」可编辑字段
  2. 显示「系统计算值」和「实际缴纳值」对比，允许手动调整差异
  3. 增加「匹配参保地政策」自动拉取配置功能
- **优先级**：P2 中

## 四、审批流程（问题 8）

### 问题 8：休假审批需要审批流程
- **现状**：系统中没有独立的休假审批模块和审批流引擎。WorkProcess 有简单的状态流转（DRAFT → PENDING → APPROVED/REJECTED），但不是通用审批流。
- **修复方向**：需要新建审批流模块，包括：
  1. 审批流配置（审批节点、审批人、条件）
  2. 休假申请提交
  3. 审批进度追踪
  4. 审批通知
- **优先级**：P3 规划（较大的功能开发，建议单独规划）

## 五、证明开具（问题 9）

### 问题 9：证明开具添加自定义模板
- **现状**：work-process.service.ts:247-275 的 generateDocument 只支持 INCOME_CERT 和 LEAVING_CERT 两种硬编码模板。EnterpriseTemplate 模块支持自定义模板（Templates.tsx），但 WorkProcess 的证明开具未调用企业模板。
- **修复方向**：
  1. WorkProcess 证明开具功能关联 EnterpriseTemplate 表，允许选择企业自定义模板
  2. 支持变量替换（{{employeeName}} 等）
  3. 允许用户新建模板并分类管理
- **优先级**：P2 中

## 六、工作台布局（问题 10）

### 问题 10：工作台内容杂乱，需分区分类
- **现状**：Dashboard.tsx 已有 Tab 分区（概览/风险提醒/月度任务），TaskCenter 也按分类分组展示。但概览 Tab 下内容较多（统计卡片、任务中心、成本分析、活动统计等）可能显得杂乱。
- **修复方向**：
  1. 概览 Tab 按「待办事项」「人力概览」「薪税概览」「合规风险」分区展示，用卡片或分隔线区分
  2. 增加折叠/展开功能
  3. 调整信息密度，次要信息收起
- **优先级**：P2 中
- **状态**：✅ 已完成（20260803）— 已拆分为 5 个 Tab（概览/风险提醒/月度任务/人力成本/人员分析），支持 Tab 级别和区域级别的显示设置

## 七、离职操作（问题 12-13）

### 问题 12：离职操作全选填，可跳过必填项
- **根因**：Termination.tsx:527-534 的 canProceed() 函数中，step 2/3/4 都直接 return true，没有校验必填项。termination.schema.ts 的 schema 中只有 employeeId 和 reason 是必填，其他字段都可选。
- **修复方向**：
  1. step 1（解聘方式）增加 terminationDate 必填校验（已有）
  2. step 2（合规检查）要求至少勾选所有 suggestionType: 'required' 的检查项
  3. step 3（费用结算）如果有补偿金，要求确认金额
  4. step 4（工作交接）要求至少完成关键交接项
- **优先级**：P1 高

### 问题 13：补偿金手动修改后确认阶段仍显示系统预估
- **根因**：Termination.tsx:536-547 的 handleSave() 使用 costResult?.totalSeverance（系统计算值），而非用户可能手动调整后的值。handleSaveDraft() 使用 costResult?.grandTotal，也未考虑手动调整。compAdjustments 状态存在但未在保存时正确应用到最终补偿金。
- **修复方向**：
  1. 保存时使用 costResult.grandTotal + compAdjustments 的合计值
  2. 确认步骤显示「系统预估 ¥X + 手动调整 ¥Y = 实际补偿 ¥Z」
  3. 后端 createDraft/updateDraft 已支持 compensationBreakdown.adjustments，前端需正确传递
- **优先级**：P0 紧急

## 八、用工文本模板（问题 14）

### 问题 14：用工文本模板优化为公司统一版本
- **现状**：work-process.service.ts 的 generateDocument 使用硬编码模板，EnterpriseTemplate 表支持自定义但未关联。
- **修复方向**：与问题 9 同一方案——将 WorkProcess 的文书生成改为从 EnterpriseTemplate 表读取模板内容，支持变量替换，管理员可统一维护模板版本。
- **优先级**：P2 中

## 优先级汇总

| 优先级 | 问题 | 原因 | 状态 |
|--------|------|------|------|
| P0 紧急 | 5、13 | 功能性 bug，影响业务正确性 | 问题5已完成，问题13待修复 |
| P1 高 | 1、2、3、4、6、11、12 | 用户体验差或操作不完整 | 待修复 |
| P2 中 | 7、9、10、14 | 功能增强和优化 | 问题10已完成 |
| P3 规划 | 8 | 新功能开发，需单独规划 | 待规划 |

---

## 20260804 新增修复记录

### 已完成项

| 编号 | 修复内容 | 涉及文件 |
|------|----------|----------|
| 花名册搜索 | 身份证号搜索结果被前端二次过滤清空，增加 `idCardMasked` 匹配 | `frontend/src/pages/Roster.tsx:267` |
| Header 企业名称 | TopNav 增加企业名称显示，复用 `settingsApi.org()` 查询 | `frontend/src/components/layout/TopNav.tsx` |
| 问题5 | WorkProcess 表单字段英文 key 已增加中文标签映射 | `frontend/src/pages/WorkProcess.tsx` |

### 新增优化清单（详见 docs/20260804-优化.md）

基于用户反馈的 23 项问题全面审查，已生成独立文档：`docs/20260804-优化.md`

**P0 紧急（待修复）**：
- 发薪按钮无效（`window.location.hash` 跳转不兼容 BrowserRouter）
- 用工办理需姓名检索替代 UUID 输入
- 填写界面增加直接提交按钮
- 风险中心跳转后不自动筛选

**已确认无需修改**：
- 身份证号搜索（后端已实现，前端 bug 已修复）
- 多附件上传（已支持）
- 休假审批流程（已有完整模块）
