using System; using System.Collections.Generic; using System.Threading.Tasks; using MDL.Models; using DAL.Interfaces; using DB.Database; using SqlSugar; namespace DAL.Repositories { /// /// 面单PDF缓存的数据访问实现类 /// public class LabelPdfCacheRepository : ILabelPdfCacheRepository { private readonly ISqlSugarProvider _provider; /// /// 构造函数 /// /// SqlSugar数据库提供程序 public LabelPdfCacheRepository(ISqlSugarProvider provider) { _provider = provider; } /// /// 根据中性面单单号获取缓存记录 /// /// 中性面单单号 /// 缓存记录实体 public async Task GetByWaybillNumberAsync(string waybillNumber) { var db = _provider.GetClient(); return await db.Queryable() .Where(c => c.NeutralWaybillNumber == waybillNumber) .FirstAsync(); } /// /// 创建缓存记录 /// /// 缓存实体 /// 创建的记录ID public async Task CreateAsync(LabelPdfCache entity) { var db = _provider.GetClient(); // 确保表存在 if (!db.DbMaintenance.IsAnyTable("label_pdf_cache")) { db.CodeFirst.InitTables(typeof(LabelPdfCache)); } // 设置时间戳 entity.CreatedTime = DateTime.UtcNow; entity.UpdatedTime = DateTime.UtcNow; // 插入数据并返回自增ID return await db.Insertable(entity).ExecuteReturnIdentityAsync(); } /// /// 更新缓存记录 /// /// 缓存实体 /// 更新是否成功 public async Task UpdateAsync(LabelPdfCache entity) { var db = _provider.GetClient(); entity.UpdatedTime = DateTime.UtcNow; return await db.Updateable(entity).ExecuteCommandAsync() > 0; } /// /// 标记缓存为失效状态 /// /// 中性面单单号 /// 操作是否成功 public async Task InvalidateCacheAsync(string waybillNumber) { var db = _provider.GetClient(); var existing = await db.Queryable() .Where(c => c.NeutralWaybillNumber == waybillNumber) .FirstAsync(); if (existing == null) { return false; } existing.Status = 3; // 3=已失效 existing.UpdatedTime = DateTime.UtcNow; return await db.Updateable(existing).ExecuteCommandAsync() > 0; } /// /// 获取待处理的缓存任务列表 /// /// 最大重试次数 /// 最大返回数量 /// 待处理的缓存记录列表 public async Task> GetPendingTasksAsync(int maxRetryCount, int limit) { var db = _provider.GetClient(); return await db.Queryable() .Where(c => c.Status == 0 || (c.Status == 2 && c.RetryCount < maxRetryCount)) .Where(c => SqlFunc.Subqueryable() .Where(l => l.NeutralWaybillNumber == c.NeutralWaybillNumber && !string.IsNullOrEmpty(l.Label)) .Any()) .OrderBy(c => c.CreatedTime, OrderByType.Asc) .Take(limit) .ToListAsync(); } /// /// 获取订单表中新的有标签订单(缓存表中不存在的) /// /// 最大返回数量 /// 新订单的面单号列表 public async Task> GetNewOrdersWithLabelsAsync(int limit) { var db = _provider.GetClient(); return await db.Queryable() .Where(o => !string.IsNullOrEmpty(o.Label)) .Where(o => !SqlFunc.Subqueryable() .Where(c => c.NeutralWaybillNumber == o.NeutralWaybillNumber) .Any()) .Select(o => o.NeutralWaybillNumber) .Take(limit) .ToListAsync(); } /// /// 获取需要重新处理的失效缓存列表 /// /// 最大返回数量 /// 失效的缓存记录列表 public async Task> GetInvalidCachesAsync(int limit) { var db = _provider.GetClient(); return await db.Queryable() .Where(c => c.Status == 3) .Where(c => SqlFunc.Subqueryable() .Where(l => l.NeutralWaybillNumber == c.NeutralWaybillNumber && !string.IsNullOrEmpty(l.Label)) .Any()) .OrderBy(c => c.UpdatedTime, OrderByType.Asc) .Take(limit) .ToListAsync(); } /// /// 异步更新条码信息 /// /// 中性面单单号 /// 条码号 /// 条码类型 /// 识别置信度 /// 更新是否成功 public async Task UpdateBarcodeInfoAsync(string waybillNumber, string barcodeNumber, byte barcodeType, int confidence) { var db = _provider.GetClient(); var existing = await db.Queryable() .Where(c => c.NeutralWaybillNumber == waybillNumber) .FirstAsync(); if (existing == null) { return false; } existing.BarcodeNumber = barcodeNumber; existing.BarcodeType = barcodeType; existing.BarcodeConfidence = confidence; existing.BarcodeExtractTime = DateTime.UtcNow; existing.UpdatedTime = DateTime.UtcNow; return await db.Updateable(existing).ExecuteCommandAsync() > 0; } } }