# 送洗记录作废接口实现总结
## 📋 概述
为送洗记录(清洗流水表 `lq_laundry_flow`)添加了作废接口,可以将记录标记为无效(`F_IsEffective = 0`),同时可以修改备注说明作废原因。
## ✅ 数据安全性验证
### 1. 送洗记录在计算中的使用情况
#### 1.1 工资计算中的使用
**店长工资计算** (`LqStoreManagerSalaryService`):
- 使用条件:`F_IsEffective = 1` 且 `F_FlowType = 0`(只统计送出的记录)
- 字段:`F_TotalPrice`(总费用)
- 用途:计算洗毛巾费用,用于毛利计算
**主任工资计算** (`LqDirectorSalaryService`):
- 使用条件:`F_IsEffective = 1` 且 `F_FlowType = 0`(只统计送出的记录)
- 字段:`F_TotalPrice`(总费用)
- 用途:计算洗毛巾费用,用于毛利计算
**事业部总经理工资计算** (`LqBusinessUnitManagerSalaryService`):
- 使用条件:`F_IsEffective = 1` 且 `F_FlowType = 0`(只统计送出的记录)
- 字段:`F_TotalPrice`(总费用)
- 用途:计算洗毛巾费用,用于毛利计算
#### 1.2 股份计算中的使用
**门店股份统计** (`LqShareStatisticsStoreService`):
- 使用条件:`F_IsEffective = 1` 且 `F_SendTime >= startDate AND F_SendTime <= endDate`
- 字段:`F_TotalPrice`(总费用)
- 用途:计算主营成本-毛巾(`CostTowel`)
- 说明:虽然代码中没有显式过滤 `F_FlowType = 0`,但由于使用了 `F_SendTime` 字段(只有送出记录才有此字段),逻辑上只统计送出记录
### 2. 安全性结论
✅ **所有计算逻辑都使用了 `F_IsEffective = 1` 的条件**
- 工资计算:使用 `F_IsEffective = 1` 条件
- 股份计算:使用 `F_IsEffective = 1` 条件
- 费用统计:使用 `F_IsEffective = 1` 条件
✅ **作废操作是安全的**
- 将记录的 `F_IsEffective` 设置为 0(无效)后,这些记录不会被任何计算逻辑统计
- 作废后的记录仍保留在数据库中,可以通过列表查询查看,但不会参与任何统计计算
## 🔧 实现内容
### 1. DTO类
创建了 `LqLaundryFlowCancelInput.cs`:
```csharp
public class LqLaundryFlowCancelInput
{
///
/// 记录ID
///
[Required(ErrorMessage = "记录ID不能为空")]
public string Id { get; set; }
///
/// 备注(作废原因等说明)
///
public string Remark { get; set; }
}
```
### 2. 接口实现
在 `LqLaundryFlowService.cs` 中添加了 `Cancel` 接口:
- **接口路径**:`POST /api/Extend/LqLaundryFlow/Cancel`
- **功能**:
1. 将记录的 `F_IsEffective` 设置为 0(无效)
2. 更新备注字段,添加作废标记和作废原因
3. 检查记录是否存在
4. 检查记录是否已经作废
5. 如果作废的是送出记录,检查是否有对应的送回记录(如果有,不允许单独作废送出记录)
### 3. 接口特性
- ✅ **安全性检查**:检查记录是否存在、是否已经作废
- ✅ **业务逻辑检查**:送出记录如果有对应的送回记录,不允许单独作废
- ✅ **备注处理**:如果提供了备注,追加到原备注;如果没有提供,添加默认作废标记
- ✅ **错误处理**:完善的异常处理和错误提示
## 📝 接口使用说明
### 请求示例
```json
POST /api/Extend/LqLaundryFlow/Cancel
Content-Type: application/json
{
"id": "记录ID",
"remark": "作废原因说明(可选)"
}
```
### 响应示例
```json
{
"message": "作废成功",
"id": "记录ID",
"remark": "原备注\n[作废]作废原因说明"
}
```
### 错误情况
1. **记录ID为空**:返回 "记录ID不能为空"
2. **记录不存在**:返回 "送洗记录不存在"
3. **记录已作废**:返回 "该记录已经作废"
4. **送出记录有对应送回记录**:返回 "该送出记录已有对应的送回记录,不能单独作废送出记录。如需作废,请先作废对应的送回记录"
## 🔍 备注处理逻辑
1. **如果提供了备注**:
- 如果原备注不为空:`原备注\n[作废]新备注`
- 如果原备注为空:`[作废]新备注`
2. **如果没有提供备注**:
- 如果原备注为空:`[作废]`
- 如果原备注不为空:`原备注\n[作废]`
## ⚠️ 注意事项
1. **作废后不影响已有计算**:
- 作废操作只影响后续的计算
- 已经计算完成的工资、股份等数据不会因为作废而自动重新计算
- 如需更新已计算的数据,需要重新执行相应的计算流程
2. **送出记录和送回记录的关系**:
- 如果送出记录有对应的送回记录,需要先作废送回记录,才能作废送出记录
- 这是为了保持数据的一致性和完整性
3. **作废后的数据查询**:
- 作废后的记录仍保留在数据库中
- 列表查询可以通过 `IsEffective` 参数筛选有效/无效记录
- 默认情况下,列表查询可以显示所有记录(包括作废的)
## 📊 影响范围
### ✅ 不受影响的计算
- ✅ 费用计算:使用 `F_IsEffective = 1` 条件
- ✅ 成本计算:使用 `F_IsEffective = 1` 条件
- ✅ 工资计算:使用 `F_IsEffective = 1` 条件
- ✅ 股份计算:使用 `F_IsEffective = 1` 条件
### ✅ 受影响的查询
- ✅ 列表查询:可以通过 `IsEffective` 参数筛选
- ✅ 统计查询:只统计 `F_IsEffective = 1` 的记录
## 📋 总结
1. ✅ 接口实现完成:作废接口已实现,可以安全地作废送洗记录
2. ✅ 数据安全性验证:所有计算逻辑都使用了 `F_IsEffective = 1` 条件,作废是安全的
3. ✅ 业务逻辑检查:实现了完善的业务逻辑检查,确保数据一致性
4. ✅ 备注处理:实现了灵活的备注处理逻辑,可以记录作废原因
**结论**:送洗记录作废接口可以安全使用,不会对费用计算、成本计算、工资计算、股份计算等产生数据问题。