Files
LabelChange-server/.trae/docs/BackgroundTasks/02-定时任务执行范围修改说明.md
2026-06-01 16:30:29 +08:00

330 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 定时任务执行范围修改说明
## 修改内容
### 修改目标
将定时任务 `ProcessPendingTasksAsync()` 的执行范围限制为仅处理创建时间在 **2026-05-10** 之后的订单。
### 修改日期
- **修改时间**: 2026-05-14
- **截断日期**: 2026-05-10 00:00:00
---
## 涉及文件修改
### 1. LabelReplaceRepository.cs
**文件路径**: `src/DAL/Repositories/LabelReplaceRepository.cs`
#### 修改的方法:
**1.1 GetNewOrdersWithLabelsAsync()**
```csharp
public async Task<List<string>> GetNewOrdersWithLabelsAsync(int limit)
{
var db = _provider.GetClient();
// 定义截断日期2026-05-10之后
var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);
return await db.Queryable<LabelReplaceEntity>()
.Where(o => !string.IsNullOrEmpty(o.Label))
.Where(o => o.CreatedAt >= cutoffDate) // 新增
.Where(o => !SqlFunc.Subqueryable<LabelPdfCache>()
.Where(c => c.NeutralWaybillNumber == o.NeutralWaybillNumber)
.Any())
.Select(o => o.NeutralWaybillNumber)
.Take(limit)
.ToListAsync();
}
```
**说明**:
- 添加了 `cutoffDate` 变量定义截断日期
- 添加了 `.Where(o => o.CreatedAt >= cutoffDate)` 条件过滤
- 该方法是定时任务获取新订单的主要入口
**1.2 GetAllOrdersWithLabelsAsync()**
```csharp
public async Task<List<LabelReplaceEntity>> GetAllOrdersWithLabelsAsync(int limit = 1000)
{
var db = _provider.GetClient();
var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);
return await db.Queryable<LabelReplaceEntity>()
.Where(lr => !string.IsNullOrEmpty(lr.Label))
.Where(lr => lr.CreatedAt >= cutoffDate) // 新增
.Take(limit)
.ToListAsync();
}
```
**说明**:
- 添加了创建时间过滤条件
- 影响批量解析接口中 `mode=all` 的查询结果
**1.3 GetOrdersWithLabelsByDateRangeAsync()**
```csharp
public async Task<List<LabelReplaceEntity>> GetOrdersWithLabelsByDateRangeAsync(DateTime startDate, DateTime endDate, int limit = 1000)
{
var db = _provider.GetClient();
var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);
// 确保指定的日期范围不低于截断日期
var finalStartDate = startDate < cutoffDate ? cutoffDate : startDate;
return await db.Queryable<LabelReplaceEntity>()
.Where(lr => !string.IsNullOrEmpty(lr.Label)
&& lr.CreatedAt >= finalStartDate // 修改
&& lr.CreatedAt <= endDate)
.Take(limit)
.ToListAsync();
}
```
**说明**:
- 添加了日期范围检查,确保开始日期不低于截断日期
- 影响批量解析接口中 `mode=range` 的查询结果
**1.4 GetOrdersWithLabelsByCustomerAsync()**
```csharp
public async Task<List<LabelReplaceEntity>> GetOrdersWithLabelsByCustomerAsync(int customerId, int limit = 1000)
{
var db = _provider.GetClient();
var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);
return await db.Queryable<LabelReplaceEntity>()
.Where(lr => !string.IsNullOrEmpty(lr.Label)
&& lr.CustomerId == customerId
&& lr.CreatedAt >= cutoffDate) // 新增
.Take(limit)
.ToListAsync();
}
```
**说明**:
- 添加了创建时间过滤条件
- 影响批量解析接口中 `mode=customer` 的查询结果
---
## 工作流程影响
### 定时任务处理流程
定时任务执行时流程如下:
```
ProcessPendingTasksAsync()
├─ GetInvalidCachesAsync()
│ └─ 获取状态=3的无效缓存结合订单表过滤
├─ GetPendingTasksAsync()
│ └─ 获取状态=0和状态=2的待处理缓存
└─ GetNewOrdersWithLabelsAsync() ← 新增时间过滤
└─ 获取订单表中有标签但缓存表无记录的订单
└─ 过滤条件: CreatedAt >= 2026-05-10
```
### 受影响的查询
| 方法 | 影响 | 说明 |
|------|------|------|
| `GetNewOrdersWithLabelsAsync()` | ✅ 直接影响 | 定时任务的新订单获取方法 |
| `GetAllOrdersWithLabelsAsync()` | ✅ 直接影响 | 批量解析 `mode=all` |
| `GetOrdersWithLabelsByDateRangeAsync()` | ✅ 直接影响 | 批量解析 `mode=range` |
| `GetOrdersWithLabelsByCustomerAsync()` | ✅ 直接影响 | 批量解析 `mode=customer` |
---
## API 行为变化
### 批量解析接口 (`/batch-parse`)
**修改前**: 可以处理2026-05-10之前的订单
**修改后**: 只能处理2026-05-10及以后的订单
| 模式 | 说明 | 变化 |
|------|------|------|
| `all` | 处理所有有标签的订单 | ✅ 只处理>=2026-05-10的订单 |
| `range` | 按时间范围处理 | ✅ 开始日期自动调整至2026-05-10 |
| `customer` | 按客户处理 | ✅ 只处理>=2026-05-10的订单 |
| `single` | 单条订单处理 | ❌ 无变化(通过单号直接处理) |
### 示例
**请求 - 按时间范围处理**
```json
{
"mode": "range",
"startDate": "2026-05-01", // 实际从2026-05-10开始
"endDate": "2026-05-15"
}
```
**说明**: startDate 会被自动调整为 2026-05-10因为这是截断日期
---
## 定时任务行为
### 定时任务的新特性
1. **自动时间过滤** - 所有查询都将受到创建时间的限制
2. **历史数据隔离** - 2026-05-10之前的订单不会被自动处理
3. **手动处理支持** - 通过 `mode=single` 可以手动处理任何订单
### 执行间隔
- **间隔**: 5分钟
- **处理范围**: 仅2026-05-10及以后的订单
- **批处理大小**: 100条可配置
---
## 配置参数
### 截断日期定义位置
所有截断日期都定义在数据访问层Repository
```csharp
var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);
```
### 修改截断日期的方法
如需修改截断日期只需更改上述时间值例如改为2026-06-01
```csharp
var cutoffDate = new DateTime(2026, 6, 1, 0, 0, 0);
```
然后重新编译和部署项目。
---
## 数据库影响
### 查询变化
**修改前SQL**:
```sql
SELECT o.NeutralWaybillNumber
FROM label_replace o
WHERE o.Label IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM label_pdf_cache c
WHERE c.NeutralWaybillNumber = o.NeutralWaybillNumber
)
LIMIT 100;
```
**修改后SQL**:
```sql
SELECT o.NeutralWaybillNumber
FROM label_replace o
WHERE o.Label IS NOT NULL
AND o.CreatedAt >= '2026-05-10' -- 新增条件
AND NOT EXISTS (
SELECT 1 FROM label_pdf_cache c
WHERE c.NeutralWaybillNumber = o.NeutralWaybillNumber
)
LIMIT 100;
```
### 性能考虑
- 添加的 `CreatedAt >= cutoffDate` 条件可以利用现有的时间索引
- 预期查询性能无负面影响
- 可能会减少返回结果数量(因为过滤了旧数据)
---
## 兼容性
### 向后兼容性
- ✅ 单条处理模式 (`mode=single`) 不受影响
- ❌ 通过API手动处理时会受到时间限制
### 版本信息
- **修改版本**: v2.1
- **兼容版本**: v2.0如需处理旧数据需升级到v2.1后手动处理)
---
## 测试验证
### 编译验证
✅ 整个项目已成功编译,无新的编译错误
### 功能验证清单
- [ ] 定时任务成功运行每5分钟一次
- [ ] 只处理2026-05-10之后的订单
- [ ] 2026-05-10之前的订单不被处理
- [ ] 批量解析接口在 `mode=all` 时只返回新数据
- [ ] 批量解析接口在 `mode=range` 时正确调整日期范围
- [ ] 批量解析接口在 `mode=customer` 时只返回新客户订单
- [ ] 缓存统计接口统计正确
### 手动测试命令
```bash
# 测试批量解析 - all模式
curl -X POST http://localhost:5002/api/label/batch-parse \
-H "Content-Type: application/json" \
-d '{"mode":"all","limit":10}'
# 测试批量解析 - range模式时间范围自动调整
curl -X POST http://localhost:5002/api/label/batch-parse \
-H "Content-Type: application/json" \
-d '{"mode":"range","startDate":"2026-05-01","endDate":"2026-05-15","limit":10}'
# 测试定时任务状态
curl -X GET http://localhost:5002/api/label/background-service/status
```
---
## 回滚方案
如需恢复到修改前的行为,只需:
1. 移除所有的 `var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);` 定义
2. 移除所有的 `.Where(lr => lr.CreatedAt >= cutoffDate)` 条件
3. 重新编译和部署
---
## 常见问题
### Q: 如何处理2026-05-10之前的订单
A: 使用 `mode=single` 通过单号进行手动处理:
```json
{"mode":"single","waybillNumber":"1Z999AA10123456784"}
```
### Q: 定时任务会处理旧订单吗?
A: 不会。定时任务 (`GetNewOrdersWithLabelsAsync`) 已被限制为仅处理2026-05-10及以后的订单。
### Q: 缓存统计会包含旧数据吗?
A: 是的。`cache-statistics` 接口统计的是缓存表中的所有数据,不受时间限制。
### Q: 如何修改截断日期?
A: 修改所有Repository中的 `new DateTime(2026, 5, 10, 0, 0, 0)` 为新的日期,然后重新编译部署。
---
## 相关文件
- **修改的数据库访问类**: `src/DAL/Repositories/LabelReplaceRepository.cs`
- **定时任务类**: `src/BLL/Services/LabelPdfCacheService.cs`
- **批量解析接口**: `src/CONTROLLER/Controllers/LabelController.cs`
---
**修改完成于**: 2026-05-14
**编译状态**: ✅ 成功
**部署状态**: 等待确认