# 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(更新为失败状态) **编译状态**: ✅ 成功 **测试状态**: 待测试