205 lines
4.7 KiB
Markdown
205 lines
4.7 KiB
Markdown
# labelBytes 为空时记录缓存失败修改
|
||
|
||
## 修改说明
|
||
|
||
当 PDF 字节流 (`labelBytes`) 为 `null` 或长度为 0 时(表示源文件有问题),直接将缓存状态记录为**失败** (`Status = 2`),而不再尝试进行条码识别。
|
||
|
||
---
|
||
|
||
## 修改位置
|
||
|
||
**文件**: `src/BLL/Services/LabelPdfCacheService.cs`
|
||
**方法**: `ProcessSingleCacheTaskAsync()`
|
||
**行号**: 324-330
|
||
|
||
---
|
||
|
||
## 修改前后对比
|
||
|
||
### 修改前
|
||
```csharp
|
||
byte[] labelBytes;
|
||
// 解析Label内容
|
||
// ... 省略解析代码 ...
|
||
|
||
// 校验PDF页数(直接进行校验,没有检查labelBytes是否为空)
|
||
int pageCount = GetPdfPageCount(labelBytes);
|
||
```
|
||
|
||
### 修改后
|
||
```csharp
|
||
byte[] labelBytes;
|
||
// 解析Label内容
|
||
// ... 省略解析代码 ...
|
||
|
||
// 当labelBytes为null或为空时,标记为失败(源文件有问题)
|
||
if (labelBytes == null || labelBytes.Length == 0)
|
||
{
|
||
var duration = (int)(DateTime.UtcNow - startTime).TotalMilliseconds;
|
||
_logger.LogError("labelBytes is null or empty for waybill: {number}, duration: {duration}ms - 源文件有问题", waybillNumber, duration);
|
||
var newRetryCount = (existingCache?.RetryCount ?? 0) + 1;
|
||
await UpdateCacheStatus(existingCache, waybillNumber, 2, "源文件为空或无效,无法提取条码", newRetryCount, duration);
|
||
return false;
|
||
}
|
||
|
||
// 校验PDF页数
|
||
int pageCount = GetPdfPageCount(labelBytes);
|
||
```
|
||
|
||
---
|
||
|
||
## 关键改动
|
||
|
||
### 1. 新增空值检查
|
||
```csharp
|
||
if (labelBytes == null || labelBytes.Length == 0)
|
||
```
|
||
|
||
### 2. 标记为失败状态
|
||
```csharp
|
||
await UpdateCacheStatus(
|
||
existingCache,
|
||
waybillNumber,
|
||
2, // ✅ Status = 2 (失败)
|
||
"源文件为空或无效,无法提取条码",
|
||
newRetryCount,
|
||
duration
|
||
);
|
||
```
|
||
|
||
### 3. 日志记录为ERROR级别
|
||
```csharp
|
||
_logger.LogError("labelBytes is null or empty for waybill: {number}, duration: {duration}ms - 源文件有问题", waybillNumber, duration);
|
||
```
|
||
|
||
### 4. 增加重试计数
|
||
```csharp
|
||
var newRetryCount = (existingCache?.RetryCount ?? 0) + 1;
|
||
```
|
||
|
||
---
|
||
|
||
## 处理流程
|
||
|
||
### 修改前流程
|
||
```
|
||
获取labelBytes
|
||
↓
|
||
检查PDF页数 ← 可能失败 (如果labelBytes为空)
|
||
↓
|
||
提取条码信息 ← 可能失败
|
||
↓
|
||
保存缓存
|
||
```
|
||
|
||
### 修改后流程
|
||
```
|
||
获取labelBytes
|
||
↓
|
||
【新增】检查labelBytes是否为空或null
|
||
├─ YES: 标记为失败(Status=2)→ 增加重试计数 → 返回false
|
||
└─ NO: 继续
|
||
↓
|
||
检查PDF页数
|
||
↓
|
||
提取条码信息
|
||
↓
|
||
保存缓存
|
||
```
|
||
|
||
---
|
||
|
||
## 缓存状态
|
||
|
||
当 labelBytes 为空时(源文件有问题),缓存记录将被保存为:
|
||
|
||
```
|
||
Status: 2 (失败)
|
||
ErrorMessage: "源文件为空或无效,无法提取条码"
|
||
BarcodeNumber: NULL (无法提取)
|
||
BarcodeType: 0 (无条码)
|
||
BarcodeConfidence: NULL (无置信度)
|
||
RetryCount: 前次重试次数 + 1
|
||
解析耗时: 记录实际耗时(毫秒)
|
||
```
|
||
|
||
### 重试机制
|
||
|
||
- 首次失败: `RetryCount = 1`
|
||
- 第二次失败: `RetryCount = 2`
|
||
- 第三次失败: `RetryCount = 3` → 如果 `RetryCount >= MaxRetryCount (3)`,则标记为最终失败
|
||
|
||
---
|
||
|
||
## 错误信息
|
||
|
||
缓存表中 `error_message` 字段将记录:
|
||
```
|
||
源文件为空或无效,无法提取条码
|
||
```
|
||
|
||
日志中将记录:
|
||
```
|
||
labelBytes is null or empty for waybill: {number}, duration: {duration}ms - 源文件有问题
|
||
```
|
||
|
||
---
|
||
|
||
## 编译验证
|
||
|
||
✅ **编译成功** - 整个项目编译无错误
|
||
|
||
---
|
||
|
||
## 测试验证清单
|
||
|
||
- [ ] labelBytes 为 null 时,缓存状态为 2(失败)
|
||
- [ ] labelBytes.Length 为 0 时,缓存状态为 2(失败)
|
||
- [ ] 缓存记录中 `status` 字段为 2
|
||
- [ ] 缓存记录中 `error_message` 包含 "源文件为空或无效"
|
||
- [ ] `RetryCount` 正确增加
|
||
- [ ] 日志级别为 ERROR
|
||
- [ ] 不会尝试进行条码识别
|
||
- [ ] 返回 false(处理失败)
|
||
|
||
---
|
||
|
||
## 影响范围
|
||
|
||
### 直接影响
|
||
- `ProcessSingleCacheTaskAsync()` 方法
|
||
- 缓存表中新插入的记录(status = 2)
|
||
|
||
### 间接影响
|
||
- 定时任务执行流程
|
||
- batch-parse API 处理流程
|
||
- 缓存统计查询(failedRecords 增加)
|
||
|
||
---
|
||
|
||
## 业务含义
|
||
|
||
### 缓存状态说明
|
||
|
||
| 状态值 | 含义 | 原因 | 是否重试 |
|
||
|--------|------|------|---------|
|
||
| 0 | 待处理 | 刚创建或待重试 | ✅ 会重试 |
|
||
| 1 | 成功 | 成功缓存并识别条码 | ❌ 不重试 |
|
||
| 2 | 失败 | 源文件问题或超过重试次数 | ✅ 最多3次 |
|
||
| 3 | 无效 | 缓存过期或被清理 | ❌ 不重试 |
|
||
|
||
### 源文件问题的情况
|
||
|
||
当出现以下情况时会被记录为失败:
|
||
- 源文件为 null
|
||
- 源文件字节长度为 0
|
||
- 源文件损坏(无法解析)
|
||
- 源文件格式不正确
|
||
|
||
---
|
||
|
||
**修改日期**: 2026-05-14
|
||
**版本**: 1.1(更新为失败状态)
|
||
**编译状态**: ✅ 成功
|
||
**测试状态**: 待测试
|