# 工资条确认功能方案分析
## 需求概述
**业务流程**:
1. 系统自动计算工资 →
2. 导出Excel进行线下梳理处理 →
3. 导入Excel(包含调整后的数据)→
4. 形成工资条(锁定)给员工查看 →
5. 员工确认工资条 →
6. 确认后工资数据不可再修改
## 现有表结构分析
### 所有工资表共有的字段
- `F_IsLocked` INT - 管理员锁定状态(0=未锁定,1=已锁定)
- `F_CreatorTime` DATETIME - 创建时间
- `F_LastModifyTime` DATETIME - 最后修改时间
- **缺少**:员工确认状态、员工确认时间
### 涉及的工资表(9个)
1. `lq_salary_statistics` - 健康师
2. `lq_tech_teacher_salary_statistics` - 科技部老师
3. `lq_assistant_salary_statistics` - 店助/店助主任
4. `lq_store_manager_salary_statistics` - 店长
5. `lq_director_salary_statistics` - 主任
6. `lq_major_project_teacher_salary_statistics` - 大项目部老师
7. `lq_major_project_director_salary_statistics` - 大项目主管
8. `lq_tech_general_manager_salary_statistics` - 科技部总经理
9. `lq_business_unit_manager_salary_statistics` - 事业部总经理/经理
## 方案对比
### 方案1:在现有表上添加确认字段 ⭐ 推荐
**实现方式**:
- 在每个工资表中添加以下字段:
- `F_EmployeeConfirmStatus` INT DEFAULT 0 COMMENT '员工确认状态(0=未确认,1=已确认)'
- `F_EmployeeConfirmTime` DATETIME NULL COMMENT '员工确认时间'
- `F_EmployeeConfirmRemark` VARCHAR(500) NULL COMMENT '员工确认备注(可选)'
**优点**:
- ✅ 简单直接,符合现有架构
- ✅ 所有数据集中在一个表中,查询方便
- ✅ 不需要维护多表同步
- ✅ 实现成本低,修改范围可控
- ✅ 导出/导入逻辑清晰(保护已确认数据)
**缺点**:
- ⚠️ 导入时需要判断确认状态,已确认的数据不能覆盖
- ⚠️ 如果重新计算工资,需要处理已确认数据的冲突
**关键逻辑**:
1. **导出时**:正常导出,包含确认状态字段
2. **导入时**:
- 如果记录已确认(`F_EmployeeConfirmStatus = 1`),则跳过导入,保持原数据不变
- 如果记录未确认,则可以更新
3. **员工确认**:
- 只能确认未锁定的记录(`F_IsLocked = 0`)
- 确认后将 `F_EmployeeConfirmStatus` 设为 1,记录确认时间
- 确认后自动锁定(`F_IsLocked = 1`),防止后续修改
4. **计算工资**:
- 如果记录已确认,不能重新计算(或需要先解除确认)
- 或者:重新计算时,如果记录已确认,则创建新记录而不是更新旧记录
---
### 方案2:新建独立的工资条确认表
**实现方式**:
- 创建新表 `lq_salary_slip_confirm`,存储已确认的工资条快照
- 表结构:包含所有工资字段 + 确认相关字段
- 确认时将工资统计数据复制到确认表
**优点**:
- ✅ 计算表和确认表职责分离
- ✅ 可以保留确认历史(多次确认)
- ✅ 导出/导入不影响确认状态
**缺点**:
- ❌ 需要维护两个表的同步
- ❌ 查询时需要关联两个表
- ❌ 数据结构复杂,实现成本高
- ❌ 数据冗余,存储空间增加
- ❌ 修改字段时需要同步修改两个表
---
## 推荐方案:方案1(在现有表上添加确认字段)
### 实施步骤
#### 1. 数据库表修改
为所有9个工资表添加确认字段:
```sql
ALTER TABLE lq_salary_statistics
ADD COLUMN F_EmployeeConfirmStatus INT NOT NULL DEFAULT 0 COMMENT '员工确认状态(0=未确认,1=已确认)',
ADD COLUMN F_EmployeeConfirmTime DATETIME NULL COMMENT '员工确认时间',
ADD COLUMN F_EmployeeConfirmRemark VARCHAR(500) NULL COMMENT '员工确认备注';
-- 重复为其他8个表添加相同字段
```
#### 2. 实体类修改
为所有9个工资实体类添加属性:
```csharp
///
/// 员工确认状态(0=未确认,1=已确认)
///
public int EmployeeConfirmStatus { get; set; }
///
/// 员工确认时间
///
public DateTime? EmployeeConfirmTime { get; set; }
///
/// 员工确认备注
///
public string EmployeeConfirmRemark { get; set; }
```
#### 3. 服务类修改
**a. 导入功能修改**(如果存在):
- 导入前检查:如果 `F_EmployeeConfirmStatus = 1`,跳过该记录,不更新
- 或者提示用户:该记录已确认,是否继续(需要管理员权限)
**b. 新增员工确认接口**:
```csharp
[HttpPost("confirm")]
public async Task ConfirmSalary(string id, string employeeId, string remark = null)
{
// 1. 验证记录是否存在
// 2. 验证是否为该员工的工资
// 3. 验证是否已锁定或已确认
// 4. 更新确认状态和时间
// 5. 自动锁定记录(F_IsLocked = 1)
}
```
**c. 计算工资功能修改**:
- 计算前检查:如果记录已确认,需要先解除确认(管理员操作)或创建新记录
**d. 导出功能修改**:
- 导出时包含确认状态字段
#### 4. 前端功能
- 工资条查看页面:显示确认状态
- 确认按钮:员工点击确认后调用确认接口
- 已确认的工资条:显示确认时间和状态,不允许修改
---
## 方案确认
✅ **推荐使用方案1**,原因:
1. 实现简单,符合现有架构
2. 数据集中管理,查询方便
3. 修改范围可控,风险低
4. 满足业务需求:确认后不可修改
---
## 注意事项
1. **导入保护**:已确认的数据不能通过导入覆盖
2. **计算保护**:已确认的数据不能重新计算(或需要管理员解除确认)
3. **权限控制**:只有员工本人可以确认自己的工资条
4. **审计日志**:建议记录确认操作的日志
5. **解锁机制**:已确认的记录如果确实需要修改,需要管理员先解除确认