From c5db5d773b31b8c2d9e3ee4e4c5713495ad3eb30 Mon Sep 17 00:00:00 2001 From: glz <694770232@qq.com> Date: Thu, 25 Jun 2026 18:01:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E9=93=BA=E7=A0=81?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E6=8E=A5=E5=8F=A3=E4=B8=8E=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=EF=BC=8C=E4=BC=98=E5=8C=96=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 调整OSS访问域名从HTTPS改为HTTP 2. 新增宠物默认模板枚举并限制删除默认模板 3. 添加书页铺码回调接口与WebAPI端点 4. 配置Redis、HttpClient与OSS SDK服务 5. 新增打印配置项与回调地址 6. 优化PetService代码格式与宠物模板启停逻辑 7. 完善UpdatePageNoAsync的校验与处理逻辑 --- .../IJournalPageService.cs | 8 +- .../Enum/PetTemplateTypeEnum.cs | 5 ++ .../JournalPageService.cs | 85 ++++++++++++++++++- .../PetService.cs | 13 ++- .../Controllers/JournalController.cs | 12 +++ .../appsettings.json | 2 +- .../Program.cs | 14 +++ .../appsettings.json | 15 +++- 8 files changed, 145 insertions(+), 9 deletions(-) diff --git a/QYZH.InteractiveMagazine.IService/IJournalPageService.cs b/QYZH.InteractiveMagazine.IService/IJournalPageService.cs index 654f4b8..205c86c 100644 --- a/QYZH.InteractiveMagazine.IService/IJournalPageService.cs +++ b/QYZH.InteractiveMagazine.IService/IJournalPageService.cs @@ -21,6 +21,10 @@ public interface IJournalPageService: IBaseService Task DetailAsync(long id); Task DeleteAsync(long id); - - //Task> PageNoArticleAsync(long id); + /// + /// 回调接口-自动铺码, 书页铺码后回调接口,更新书页的点阵码 + /// + /// + /// + Task CallbackPageUpdatePageNo(JournalPagePrintDto journalPagePrintDto); } diff --git a/QYZH.InteractiveMagazine.Models/Enum/PetTemplateTypeEnum.cs b/QYZH.InteractiveMagazine.Models/Enum/PetTemplateTypeEnum.cs index 2a0f4dd..a562f06 100644 --- a/QYZH.InteractiveMagazine.Models/Enum/PetTemplateTypeEnum.cs +++ b/QYZH.InteractiveMagazine.Models/Enum/PetTemplateTypeEnum.cs @@ -7,6 +7,11 @@ namespace QYZH.InteractiveMagazine.Models.Enum; /// public enum PetTemplateTypeEnum { + /// + /// 默认 + /// + [Description("默认")] + Default = 0, /// /// 普通 /// diff --git a/QYZH.InteractiveMagazine.Service/JournalPageService.cs b/QYZH.InteractiveMagazine.Service/JournalPageService.cs index cbcce20..9bd7c93 100644 --- a/QYZH.InteractiveMagazine.Service/JournalPageService.cs +++ b/QYZH.InteractiveMagazine.Service/JournalPageService.cs @@ -1,7 +1,10 @@  +using Aliyun.Acs.Core.Logging; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; using QYZH.InteractiveMagazine.Common.Extensions; +using QYZH.InteractiveMagazine.Common.Helpers; using QYZH.InteractiveMagazine.Infrastructure.OSS; using QYZH.InteractiveMagazine.Infrastructure.RabbitMQ; using QYZH.InteractiveMagazine.IService; @@ -11,6 +14,7 @@ using QYZH.InteractiveMagazine.Models.Entity; using QYZH.InteractiveMagazine.Models.Enum; using QYZH.InteractiveMagazine.Repository; using System.Diagnostics; +using System.Net; using Yitter.IdGenerator; namespace QYZH.InteractiveMagazine.Service; @@ -20,6 +24,8 @@ public class JournalPageService(BaseRepository JournalRepository, IHttpClientFactory httpClientFactory, IConfiguration configuration, IRabbitMQService rabbitMqService, + ILogger logger, + BaseRepository JournalPageRepository, BaseRepository JournalPageTaskRepository, BaseRepository JournalPageTaskAnswerRepository) : BaseRepository, IJournalPageService { @@ -108,10 +114,87 @@ public class JournalPageService(BaseRepository JournalRepository, /// public async Task UpdatePageNoAsync(long JournalId) { - var msRes = await rabbitMqService.SendAsync(new RabbitMQSendParam { Exchange = "ex.journal", Queue = "mq.journal.dotcode.auto", RoutingKey = "rk.journal.dotcode.auto", Data = JournalId });//发生消息 + var journalEntity = await JournalRepository.Queryable().FirstAsync(w => w.Id == JournalId); + BusinessException.ThrowIf(journalEntity == null, "不存在此期刊"); + + //如果书籍状态不等于“已归档”,“已废弃”,“已铺码”的情况下,就更新状态为“已铺码” + BusinessException.ThrowIf((JournalStatusEnum)journalEntity.Status is JournalStatusEnum.Abandoned or JournalStatusEnum.Archive or JournalStatusEnum.Codeing, "当前【状态】不允许铺码"); + + var journalPageList = await JournalPageRepository.Queryable().Where(x => x.JournalId == JournalId).OrderBy(x => x.PageNum).ToListAsync(); + BusinessException.ThrowIf(journalPageList.Count == 0, "此期刊不存在任何书页"); + + var uploadPdfUrl = DomainHelper.OssFullUrl(journalEntity?.PdfUrl!); + BusinessException.ThrowIf(string.IsNullOrWhiteSpace(uploadPdfUrl), "此期刊上传的PDF路径错误,请检查期刊PDF文件是否上传成功"); + + logger.LogInformation("uploadPdfUrl:" + uploadPdfUrl); + //验证是否上传了PDF文件 + var response = await httpClientFactory.CreateClient().SendAsync(new HttpRequestMessage(HttpMethod.Head, uploadPdfUrl)); + BusinessException.ThrowIf(response.StatusCode != HttpStatusCode.OK, "获取期刊上传的PDF文件失败,请检查PDF文件是否上传成功"); + + journalEntity.Status = (int)JournalStatusEnum.Codeing; + + await JournalRepository.Updateable(journalEntity).UpdateColumns(x => new { x.Status, x.UpdatedAt }).ExecuteCommandAsync(); + + var data = new JournalPagePrintDto + { + JournalId = JournalId, + JournalPdfUrl = uploadPdfUrl, + PageNum = [.. journalPageList.Select(x => x.PageNum)] + }; + var msRes = await rabbitMqService.SendAsync(new RabbitMQSendParam { Exchange = "ex.journal", Queue = "mq.journal.dotcode.auto", RoutingKey = "rk.journal.dotcode.auto", Data = data });//发生消息 return msRes; } + /// + /// 回调接口-自动铺码, 书页铺码后回调接口,更新书页的点阵码 + /// + /// + /// + public async Task CallbackPageUpdatePageNo(JournalPagePrintDto request) + { + return await UseTranAsync(async () => + { + var journalEntity = await JournalRepository.Queryable().FirstAsync(w => w.Id == request.JournalId); + BusinessException.ThrowIf(journalEntity == null, "不存在此书"); + //如果书籍状态不等于“铺码中”则不允许回调接口更新点阵码 + BusinessException.ThrowIf(journalEntity.Status != (int)JournalStatusEnum.Codeing, "当前【状态】不允许修改铺码"); + + var bookPageList = await JournalPageRepository.Queryable().Where(x => x.JournalId == request.JournalId).OrderBy(x => x.PageNum).ToListAsync(); + + BusinessException.ThrowIf(bookPageList.Count == 0, "此书不存在任何书页"); + + journalEntity.Status = (int)request.Status!.Value; + journalEntity.UpdatedAt = DateTime.Now; + + //如果铺码成功了,并且之前已经有下载链接了,就删除原来的文件 + if (request.Status == JournalStatusEnum.CodeSuccess && !string.IsNullOrWhiteSpace(journalEntity.DownloadJournalPagePdfName)) + { + //删除oss上原来的文件 + ossService.DeleteObject(journalEntity.DownloadJournalPagePdfName.RemoveDomain()); + } + //如果铺码成功了,就更新下载链接,以及书页的点阵码 + if (request.Status == JournalStatusEnum.CodeSuccess) + { + journalEntity.DownloadJournalPagePdfName = request.DownloadJournalPagePdfName; + + BusinessException.ThrowIf(request.PageNo.Length != bookPageList.Count, $"点阵码条数与页码数量不匹配,点阵码条数:{request.PageNo.Length},页码数量:{bookPageList.Count}"); + + + for (var i = 0; i < bookPageList.Count; i++) + { + //让也页码和点阵码的顺序必须保持一致 + bookPageList[i].PageNo = request.PageNo[i]; + bookPageList[i].UpdatedAt = DateTime.Now; + } + + await JournalPageRepository.UpdateRangeAsync(bookPageList); + } + + await JournalRepository.Updateable(journalEntity).UpdateColumns(x => new { x.Status, x.DownloadJournalPagePdfName, x.UpdatedAt }).ExecuteCommandAsync(); + + return true; + }); + } public async Task DetailAsync(long id) { var output = await Queryable() diff --git a/QYZH.InteractiveMagazine.Service/PetService.cs b/QYZH.InteractiveMagazine.Service/PetService.cs index 07c3b41..71c1150 100644 --- a/QYZH.InteractiveMagazine.Service/PetService.cs +++ b/QYZH.InteractiveMagazine.Service/PetService.cs @@ -252,7 +252,7 @@ public class PetService( logger.LogWarning("喂养失败,宠物未激活,PetId: {PetId}, Status: {Status}", input.PetId, pet.Status); throw new BusinessException("宠物未激活,无法喂养", 400); } - FeedPetOutput result = new FeedPetOutput (); + FeedPetOutput result = new FeedPetOutput(); // 事务保证一致性 await UseTranAsync(async () => { @@ -590,6 +590,11 @@ public class PetService( if (template == null || template.IsDeleted) throw new BusinessException("宠物模板不存在", 404); + + if (template.Type == PetTemplateTypeEnum.Default) + throw new BusinessException("默认模板不允许删除", 400); + + // 校验是否有用户宠物实例关联 var hasUserPet = petRepository.Context.Queryable() .Any(p => p.TemplateId == id && !p.IsDeleted); @@ -659,9 +664,9 @@ public class PetService( var template = await petTemplateRepository.GetByIdAsync(id); if (template == null || template.IsDeleted) throw new BusinessException("宠物模板不存在", 404); - - template.Status = template.Status == (int)DefaultStatusEnum.Active - ? (int)DefaultStatusEnum.Inactive + + template.Status = template.Status == (int)DefaultStatusEnum.Active + ? (int)DefaultStatusEnum.Inactive : (int)DefaultStatusEnum.Active; template.UpdatedBy = "System"; template.UpdatedAt = DateTime.Now; diff --git a/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs b/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs index 76b03bc..2ba3b25 100644 --- a/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs +++ b/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs @@ -374,6 +374,18 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers return BaseResponse.Success(data); } + /// + /// 回调接口-自动铺码, 书页铺码后回调接口,更新书页的点阵码 + /// + /// + /// + [HttpPost, Route("page/callbackupdatepageno")] + [AllowAnonymous] + public async Task> CallbackPageUpdatePageNo([FromBody] JournalPagePrintDto journalPagePrintDto) + { + var data = await JournalPageService.CallbackPageUpdatePageNo(journalPagePrintDto); + return BaseResponse.Success(data); + } /// /// 下载书籍页码点阵码PDF文件名称 /// diff --git a/QYZH.InteractiveMagazine.WebApi/appsettings.json b/QYZH.InteractiveMagazine.WebApi/appsettings.json index d6d78f9..d7f928a 100644 --- a/QYZH.InteractiveMagazine.WebApi/appsettings.json +++ b/QYZH.InteractiveMagazine.WebApi/appsettings.json @@ -65,6 +65,6 @@ "DurationSeconds": 3600, //过期时间(秒) "Endpoint": "oss-cn-beijing.aliyuncs.com", "ProjectName": "InteractiveMagazine", - "Domain": "https://oss.test.qyzhjy.com/" + "Domain": "http://oss.test.qyzhjy.com/" } } diff --git a/QYZH.InteractiveMagazine.WorkService/Program.cs b/QYZH.InteractiveMagazine.WorkService/Program.cs index 7a7fe43..bafdc3b 100644 --- a/QYZH.InteractiveMagazine.WorkService/Program.cs +++ b/QYZH.InteractiveMagazine.WorkService/Program.cs @@ -2,6 +2,8 @@ using Hangfire; using Hangfire.Dashboard; using Hangfire.MemoryStorage; using QYZH.InteractiveMagazine.Infrastructure.RabbitMQ; +using QYZH.InteractiveMagazine.Infrastructure.Redis; +using QYZH.InteractiveMagazine.Infrastructure.SDK; using QYZH.InteractiveMagazine.Models.Settings; using QYZH.InteractiveMagazine.WorkService.Consumers; using QYZH.InteractiveMagazine.WorkService.Jobs; @@ -49,6 +51,9 @@ SugarIocServices.ConfigurationSugar(db => }; }); +// 显式注册 ISqlSugarClient,供后台服务中通过 DI 解析 +builder.Services.AddScoped(_ => DbScoped.SugarScope); + // 配置Hangfire(内存存储,后续可切换Redis) builder.Services.AddHangfire(config => config .UseMemoryStorage() @@ -58,6 +63,15 @@ builder.Services.AddHangfire(config => config })); builder.Services.AddHangfireServer(); +// 配置Redis +builder.Services.AddCSRedisCacheExtension(builder.Configuration.GetSection("RedisSettings")); + +// 配置HttpClient +builder.Services.AddHttpClient(); + +// 配置OSS/SDK服务 +builder.Services.AddSDKService(builder.Configuration); + // 配置RabbitMQ builder.Services.AddRabbitMQ(builder.Configuration); diff --git a/QYZH.InteractiveMagazine.WorkService/appsettings.json b/QYZH.InteractiveMagazine.WorkService/appsettings.json index 61de186..a50d7b8 100644 --- a/QYZH.InteractiveMagazine.WorkService/appsettings.json +++ b/QYZH.InteractiveMagazine.WorkService/appsettings.json @@ -2,6 +2,11 @@ "ConnectionStrings": { "DefaultConnection": "server=192.168.20.150;port=13306;database=InteractiveMagazine;user=user;password=n68792bu!y99r905;charset=utf8mb4;" }, + "RedisSettings": { + "ConnectionString": "192.168.20.150:16379,defaultDatabase=5", + "Sentinels": [], + "ExpireSecondRange": [ 3600, 7200 ] + }, "RabbitMq": { "HostName": "192.168.20.150", "Port": 5672, @@ -55,6 +60,14 @@ "DurationSeconds": 3600, //过期时间(秒) "Endpoint": "oss-cn-beijing.aliyuncs.com", "ProjectName": "InteractiveMagazine", - "Domain": "https://oss.test.qyzhjy.com/" + "Domain": "http://oss.test.qyzhjy.com/" + }, + "PrintConfig": { + "DPrint": 0, //打印场景,0:普通激光打印机,1:工业印刷,默认为0(可选) + "CallBackApiUrl": "http://localhost:8080/api/page/callbackupdatepageno", // 开发环境 打印成功回调API地址修改打印状态 + //"CallBackApiUrl": "http://192.168.20.150:8000/api/icr/page/callbackupdatepageno", // 测试环境 打印成功回调API地址修改打印状态 + //"CallBackApiUrl": "https://zyb.qyzhjy.com/zybback/api/icr/page/callbackupdatepageno", // 正式环境 打印成功回调API地址修改打印状态 + //这个ID执行的xml文件是:sublic_license_1761.172.8.16_1000.xml,如果想执行sublic_license_1761.211.21.48_10000.xml 换成 765837655859269 ---暂时没有导入页码 + "DotId": 683790963662917 } }