上传源代码版本

This commit is contained in:
Im-Jenisson
2026-06-01 16:30:29 +08:00
commit b2a9b7d3c2
462 changed files with 104365 additions and 0 deletions

View File

@@ -0,0 +1,416 @@
# 实施检查清单与决策指南
**日期**: 2026-05-13
---
## 🎯 核心决策点
### 决策1PDF渲染库选择
根据您项目特点物流标签系统PDF包含复杂图形和条码以下是三种方案对比
#### 方案A: GhostScript.NET (⭐ 推荐)
**参数**
```csharp
dotnet add package Ghostscript.NET
// 需要系统预装 Ghostscript 或从nuget获取
```
**优点**
- ✅ 行业标准,全球数百万用户
- ✅ 支持任何有效的PDF
- ✅ 渲染质量最高
- ✅ 性能稳定50-200ms/页)
- ✅ 已被物流/打印行业广泛采用
**缺点**
- ❌ 需要系统部署Ghostscript
- ❌ 首次安装配置较复杂
**适用场景**:生产环境、大规模部署
**示例代码**
```csharp
private Bitmap? ConvertPdfFirstPageToBitmap(byte[] pdfBytes)
{
try
{
// 1. 将字节流写入临时文件
var tempPath = Path.Combine(Path.GetTempPath(), $"pdf_{Guid.NewGuid()}.pdf");
File.WriteAllBytes(tempPath, pdfBytes);
// 2. 使用GhostScript渲染
var rasterizer = new GhostscriptRasterizer();
rasterizer.Open(tempPath);
// 200 DPI, 获取第0页
Image image = rasterizer.GetPage(200, 200, 0);
var bitmap = new Bitmap(image);
rasterizer.Close();
File.Delete(tempPath);
return bitmap;
}
catch (Exception ex) { ... }
}
```
---
#### 方案B: SelectPdf (用于快速验证)
**参数**
```csharp
dotnet add package SelectPdf
// 个人开发免费许可
```
**优点**
- ✅ 纯.NET库无外部依赖
- ✅ API简单易用
- ✅ 个人开发免费
- ✅ 支持批量转换
**缺点**
- ❌ 商业收费(企业)
- ❌ 某些高级功能需付费
**适用场景**:快速验证、开发测试
---
#### 方案C: iTextSharp (成本最低)
**参数**
```csharp
dotnet add package iTextSharp
// 开源AGPL许可
```
**优点**
- ✅ 完全开源
- ✅ 广泛使用
- ✅ 文档完善
**缺点**
- ❌ 社区版不支持PDF渲染
- ❌ 专业版需商业许可
**适用场景**:不适合此项目(不支持渲染)
---
### 🔴 **选择建议**
对于您的物流标签系统,**强烈推荐 GhostScript.NET**
**理由**
1. 物流行业事实标准Ghostscript 是PDF打印业标准
2. 标签PDF常包含高保真图形/二维码,需要高质量渲染
3. 性能满足实时需求(<200ms
4. 可靠性已验证全球工业级应用
**风险最低**
---
## ✅ 缓存流程确认
### 当前问题流程 ❌
```
下载 → 验证 → 条码识别❌ → 不缓存 → 失败
```
### 改进流程 ✅
**您的要求**"只要验证了pdf的有效性不管是否能够提取出二维码和一维码的内容都要将数据缓存"
**执行流程**
```
下载PDF字节流
验证(页数=1, 大小<900KB
├─ 验证失败 → 记录失败,不缓存
▼ 验证成功
【立即缓存 ⭐】
└─ SaveCacheAsync(pdfBytes, Status=Success)
└─ 返回给用户 ✅
↓ (同时后台异步)
异步条码识别
├─ 成功 → 更新BarcodeNumber字段
└─ 失败 → 日志记录PDF缓存保持有效 ✅
```
**确认要点**
- [ ] 验证通过 立即缓存 无需等待条码识别
- [ ] 条码识别异步执行 不阻塞用户请求
- [ ] 识别失败 PDF缓存仍然有效 打印业务不中断
---
## 📋 字段需求最终确认
### 必需字段(已确认)
```csharp
public long Id { get; set; }
public string NeutralWaybillNumber { get; set; } // ✅ 中性面单号
public byte[]? PdfBytes { get; set; } // ✅ PDF二进制内容
public int? PageCount { get; set; } // ✅ 页数(应该=1
public int? FileSize { get; set; } // ✅ 文件大小
public byte Status { get; set; } // ✅ 缓存状态
public int RetryCount { get; set; } // ✅ 重试次数
public DateTime? LastRetryTime { get; set; } // ✅ 最后重试时间
public string? ErrorMessage { get; set; } // ✅ 错误信息
public DateTime CreatedTime { get; set; } // ✅ 创建时间
public DateTime UpdatedTime { get; set; } // ✅ 更新时间
```
### 标签关联字段(您要求添加)
```csharp
public string? FinalMileTrackingNumber { get; set; } // ✅ 尾程跟踪单号
public string? CustomerId { get; set; } // ✅ 客户ID
```
### 条码识别字段(新增,用于后续扩展)
```csharp
public string? BarcodeNumber { get; set; } // ✅ 识别的条码号
public byte BarcodeType { get; set; } // ✅ 条码类型0=无, 1=1D, 2=2D
public int? BarcodeConfidence { get; set; } // ✅ 识别置信度
public DateTime? BarcodeExtractTime { get; set; } // ✅ 识别时间
```
**需要添加其他字段吗**比如
- 订单ID
- 原始标签URL
- 渲染质量DPI记录
---
## 🔧 实施步骤详细清单
### Phase 1: 环境准备 📦
- [ ] 1.1 - 在项目中添加 Ghostscript.NET
```bash
cd d:\EPproject\LabelReplaceServer
dotnet add package Ghostscript.NET
```
- [ ] 1.2 - 验证包安装成功
```bash
dotnet restore
```
- [ ] 1.3 - 开发机器验证 Ghostscript 依赖 (可选)
```bash
# 如果包提供了预编译的二进制文件,可能无需单独安装
# 若需要单独安装,访问: https://www.ghostscript.com/download/
```
---
### Phase 2: 代码修改 🔨
#### 修改集合A: LabelPdfCacheService.cs
- [ ] 2A.1 - 在文件头添加 GhostScript 命名空间
```csharp
using Ghostscript.NET;
using Ghostscript.NET.Rasterizer;
```
- [ ] 2A.2 - 修改 `ConvertPdfFirstPageToBitmap()` 方法
- 删除当前的纯白渲染逻辑L461-472
- 集成 GhostScript 进行真实渲染
- 参考长度约30-40行代码
- [ ] 2A.3 - 修改 `ProcessSingleCacheTask()` 方法
- 调整缓存优先级:验证通过 → 立即缓存
- 条码识别改为异步非阻塞
- 预期修改20-30行
- [ ] 2A.4 - 修改 `SaveCacheAsync()` 方法签名
- 让条码字段可选默认值为null
- 添加 `Status` 参数,区分成功/失败缓存
#### 修改集合B: ILabelPdfCacheRepository.cs & LabelPdfCacheRepository.cs
- [ ] 2B.1 - 添加 `UpdateBarcodeAsync()` 方法
```csharp
Task UpdateBarcodeAsync(string waybillNumber, string barcodeNumber,
byte barcodeType, int confidence);
```
#### 修改集合C: LabelController.cs
- [ ] 2C.1 - 调整下载接口缓存逻辑 (L597-621)
- 改为立即保存缓存(验证后)
- 条码识别移至后台异步任务
---
### Phase 3: 数据库验证 💾
- [ ] 3.1 - 检查 `label_pdf_cache` 表结构
```sql
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'label_pdf_cache'
```
- [ ] 3.2 - 验证所有必需列
- [ ] NeutralWaybillNumber唯一索引
- [ ] PdfBytesvarbinary(max)
- [ ] Statustinyint
- [ ] BarcodeNumber, BarcodeType, BarcodeConfidence可选字段
- [ ] 3.3 - 如果缺少字段,执行迁移脚本
```sql
-- 示例,具体根据实际情况调整
ALTER TABLE label_pdf_cache
ADD Status TINYINT DEFAULT 1,
BarcodeNumber NVARCHAR(100) NULL,
BarcodeType TINYINT DEFAULT 0,
BarcodeConfidence INT NULL,
BarcodeExtractTime DATETIME2 NULL;
```
---
### Phase 4: 编译与验证 🔍
- [ ] 4.1 - 清理并重建项目
```bash
dotnet clean
dotnet build
```
- [ ] 4.2 - 检查编译错误
- [ ] 无错误
- [ ] 若有错误,根据报错信息修复
- [ ] 4.3 - 运行代码分析 (如已配置)
```bash
dotnet build /p:TreatWarningsAsErrors=true
```
---
### Phase 5: 单元测试 ✅
- [ ] 5.1 - 单页PDF测试
- 创建简单的单页PDF无复杂图形
- 验证缓存成功条码识别可选
- [ ] 5.2 - 多页PDF测试
- 验证被正确拒绝Status=Failed
- 不应该保存到缓存
- [ ] 5.3 - 超大PDF测试
- >900KB的PDF文件
- 验证被正确拒绝
- [ ] 5.4 - 无效PDF测试
- 被破损的PDF文件
- 验证异常处理不crash
- [ ] 5.5 - 条码识别测试
- 包含清晰条码的标签PDF
- 验证识别成功(可选,需要实际物流标签样本)
- [ ] 5.6 - 集成测试
- 测试完整的下载→验证→缓存→返回流程
- 验证性能指标(缓存延迟<100ms
---
### Phase 6: 部署准备 🚀
- [ ] 6.1 - 准备部署文档
- Ghostscript系统依赖说明
- 数据库迁移脚本
- [ ] 6.2 - 灾难恢复计划
- 如何回滚到之前版本
- 旧缓存数据如何处理
- [ ] 6.3 - 监控配置
- 条码识别失败告警
- 缓存命中率监控
---
## 📊 验收标准
| 检查项 | 成功标准 | 验证方法 |
|--------|--------|--------|
| PDF验证功能 | 正确拒绝多页/超大PDF | 单元测试 |
| 缓存保存 | 验证通过后<100ms内保存 | 性能测试 |
| 条码识别 | 异步执行失败不影响缓存 | 集成测试 |
| PDF渲染 | 不再返回纯白位图 | 视觉检查 |
| 系统可靠性 | 无新的运行时异常 | 负载测试 |
---
## ⚠️ 风险评估与缓解
### 风险1Ghostscript依赖问题
**风险**系统未安装或版本不匹配
**缓解**
- [ ] 使用 nuget 提供的预编译版本自动安装
- [ ] 或在部署文档中明确说明系统要求
### 风险2PDF渲染性能
**风险**渲染大型复杂PDF超时
**缓解**
- [ ] 设置渲染超时建议5秒
- [ ] 添加超时异常处理
- [ ] 异步执行不阻塞主流程
### 风险3数据库容量
**风险**大量PDF字节流撑满数据库
**缓解**
- [ ] 实施数据归档策略>30天自动删除
- [ ] 监控缓存表大小
- [ ] 定期清理过期缓存
### 风险4条码识别准确性
**风险**:物流标签质量差导致识别失败
**缓解**
- [ ] 这是预期行为,失败时日志记录即可
- [ ] PDF缓存仍然有效业务继续进行
---
## 🎯 最后确认清单
**请在您同意以下内容后,回复"确认无误,请开始实施"**
- [ ] PDF渲染方案**GhostScript.NET** ✅
- [ ] 缓存流程:**验证通过 → 立即缓存 → 异步条码识别** ✅
- [ ] 条码失败:**不影响缓存,仅记录日志** ✅
- [ ] 数据库字段:**已确认上述所有字段** ✅
- [ ] 优先级:**缓存可用性 > 条码识别准确性** ✅
**如有任何调整或疑问,请在此指出**
___________________________________________________________________________
---
**准备就绪!** 🚀