feat: 新增铺码回调接口与相关配置,优化模板校验逻辑
1. 调整OSS访问域名从HTTPS改为HTTP 2. 新增宠物默认模板枚举并限制删除默认模板 3. 添加书页铺码回调接口与WebAPI端点 4. 配置Redis、HttpClient与OSS SDK服务 5. 新增打印配置项与回调地址 6. 优化PetService代码格式与宠物模板启停逻辑 7. 完善UpdatePageNoAsync的校验与处理逻辑
This commit is contained in:
@ -21,6 +21,10 @@ public interface IJournalPageService: IBaseService<JournalPage>
|
|||||||
|
|
||||||
Task<JournalPageV2Output> DetailAsync(long id);
|
Task<JournalPageV2Output> DetailAsync(long id);
|
||||||
Task<bool> DeleteAsync(long id);
|
Task<bool> DeleteAsync(long id);
|
||||||
|
/// <summary>
|
||||||
//Task<List<JournalPageNoArticleOutput>> PageNoArticleAsync(long id);
|
/// 回调接口-自动铺码, 书页铺码后回调接口,更新书页的点阵码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bookPagePrintDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<bool> CallbackPageUpdatePageNo(JournalPagePrintDto journalPagePrintDto);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,11 @@ namespace QYZH.InteractiveMagazine.Models.Enum;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum PetTemplateTypeEnum
|
public enum PetTemplateTypeEnum
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 默认
|
||||||
|
/// </summary>
|
||||||
|
[Description("默认")]
|
||||||
|
Default = 0,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 普通
|
/// 普通
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
|
|
||||||
|
using Aliyun.Acs.Core.Logging;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using QYZH.InteractiveMagazine.Common.Extensions;
|
using QYZH.InteractiveMagazine.Common.Extensions;
|
||||||
|
using QYZH.InteractiveMagazine.Common.Helpers;
|
||||||
using QYZH.InteractiveMagazine.Infrastructure.OSS;
|
using QYZH.InteractiveMagazine.Infrastructure.OSS;
|
||||||
using QYZH.InteractiveMagazine.Infrastructure.RabbitMQ;
|
using QYZH.InteractiveMagazine.Infrastructure.RabbitMQ;
|
||||||
using QYZH.InteractiveMagazine.IService;
|
using QYZH.InteractiveMagazine.IService;
|
||||||
@ -11,6 +14,7 @@ using QYZH.InteractiveMagazine.Models.Entity;
|
|||||||
using QYZH.InteractiveMagazine.Models.Enum;
|
using QYZH.InteractiveMagazine.Models.Enum;
|
||||||
using QYZH.InteractiveMagazine.Repository;
|
using QYZH.InteractiveMagazine.Repository;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Net;
|
||||||
using Yitter.IdGenerator;
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
namespace QYZH.InteractiveMagazine.Service;
|
namespace QYZH.InteractiveMagazine.Service;
|
||||||
@ -20,6 +24,8 @@ public class JournalPageService(BaseRepository<Journal> JournalRepository,
|
|||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
IConfiguration configuration,
|
IConfiguration configuration,
|
||||||
IRabbitMQService rabbitMqService,
|
IRabbitMQService rabbitMqService,
|
||||||
|
ILogger<AiBasePromptService> logger,
|
||||||
|
BaseRepository<JournalPage> JournalPageRepository,
|
||||||
BaseRepository<JournalPageTask> JournalPageTaskRepository,
|
BaseRepository<JournalPageTask> JournalPageTaskRepository,
|
||||||
BaseRepository<JournalPageTaskAnswer> JournalPageTaskAnswerRepository) : BaseRepository<JournalPage>, IJournalPageService
|
BaseRepository<JournalPageTaskAnswer> JournalPageTaskAnswerRepository) : BaseRepository<JournalPage>, IJournalPageService
|
||||||
{
|
{
|
||||||
@ -108,10 +114,87 @@ public class JournalPageService(BaseRepository<Journal> JournalRepository,
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<bool> UpdatePageNoAsync(long JournalId)
|
public async Task<bool> 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;
|
return msRes;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 回调接口-自动铺码, 书页铺码后回调接口,更新书页的点阵码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> 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<JournalPageV2Output> DetailAsync(long id)
|
public async Task<JournalPageV2Output> DetailAsync(long id)
|
||||||
{
|
{
|
||||||
var output = await Queryable()
|
var output = await Queryable()
|
||||||
|
|||||||
@ -252,7 +252,7 @@ public class PetService(
|
|||||||
logger.LogWarning("喂养失败,宠物未激活,PetId: {PetId}, Status: {Status}", input.PetId, pet.Status);
|
logger.LogWarning("喂养失败,宠物未激活,PetId: {PetId}, Status: {Status}", input.PetId, pet.Status);
|
||||||
throw new BusinessException("宠物未激活,无法喂养", 400);
|
throw new BusinessException("宠物未激活,无法喂养", 400);
|
||||||
}
|
}
|
||||||
FeedPetOutput result = new FeedPetOutput ();
|
FeedPetOutput result = new FeedPetOutput();
|
||||||
// 事务保证一致性
|
// 事务保证一致性
|
||||||
await UseTranAsync(async () =>
|
await UseTranAsync(async () =>
|
||||||
{
|
{
|
||||||
@ -590,6 +590,11 @@ public class PetService(
|
|||||||
if (template == null || template.IsDeleted)
|
if (template == null || template.IsDeleted)
|
||||||
throw new BusinessException("宠物模板不存在", 404);
|
throw new BusinessException("宠物模板不存在", 404);
|
||||||
|
|
||||||
|
|
||||||
|
if (template.Type == PetTemplateTypeEnum.Default)
|
||||||
|
throw new BusinessException("默认模板不允许删除", 400);
|
||||||
|
|
||||||
|
|
||||||
// 校验是否有用户宠物实例关联
|
// 校验是否有用户宠物实例关联
|
||||||
var hasUserPet = petRepository.Context.Queryable<UserPet>()
|
var hasUserPet = petRepository.Context.Queryable<UserPet>()
|
||||||
.Any(p => p.TemplateId == id && !p.IsDeleted);
|
.Any(p => p.TemplateId == id && !p.IsDeleted);
|
||||||
|
|||||||
@ -374,6 +374,18 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
|
|||||||
return BaseResponse<bool>.Success(data);
|
return BaseResponse<bool>.Success(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回调接口-自动铺码, 书页铺码后回调接口,更新书页的点阵码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bookPagePrintDto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, Route("page/callbackupdatepageno")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<BaseResponse<bool>> CallbackPageUpdatePageNo([FromBody] JournalPagePrintDto journalPagePrintDto)
|
||||||
|
{
|
||||||
|
var data = await JournalPageService.CallbackPageUpdatePageNo(journalPagePrintDto);
|
||||||
|
return BaseResponse<bool>.Success(data);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下载书籍页码点阵码PDF文件名称
|
/// 下载书籍页码点阵码PDF文件名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -65,6 +65,6 @@
|
|||||||
"DurationSeconds": 3600, //过期时间(秒)
|
"DurationSeconds": 3600, //过期时间(秒)
|
||||||
"Endpoint": "oss-cn-beijing.aliyuncs.com",
|
"Endpoint": "oss-cn-beijing.aliyuncs.com",
|
||||||
"ProjectName": "InteractiveMagazine",
|
"ProjectName": "InteractiveMagazine",
|
||||||
"Domain": "https://oss.test.qyzhjy.com/"
|
"Domain": "http://oss.test.qyzhjy.com/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@ using Hangfire;
|
|||||||
using Hangfire.Dashboard;
|
using Hangfire.Dashboard;
|
||||||
using Hangfire.MemoryStorage;
|
using Hangfire.MemoryStorage;
|
||||||
using QYZH.InteractiveMagazine.Infrastructure.RabbitMQ;
|
using QYZH.InteractiveMagazine.Infrastructure.RabbitMQ;
|
||||||
|
using QYZH.InteractiveMagazine.Infrastructure.Redis;
|
||||||
|
using QYZH.InteractiveMagazine.Infrastructure.SDK;
|
||||||
using QYZH.InteractiveMagazine.Models.Settings;
|
using QYZH.InteractiveMagazine.Models.Settings;
|
||||||
using QYZH.InteractiveMagazine.WorkService.Consumers;
|
using QYZH.InteractiveMagazine.WorkService.Consumers;
|
||||||
using QYZH.InteractiveMagazine.WorkService.Jobs;
|
using QYZH.InteractiveMagazine.WorkService.Jobs;
|
||||||
@ -49,6 +51,9 @@ SugarIocServices.ConfigurationSugar(db =>
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 显式注册 ISqlSugarClient,供后台服务中通过 DI 解析
|
||||||
|
builder.Services.AddScoped<ISqlSugarClient>(_ => DbScoped.SugarScope);
|
||||||
|
|
||||||
// 配置Hangfire(内存存储,后续可切换Redis)
|
// 配置Hangfire(内存存储,后续可切换Redis)
|
||||||
builder.Services.AddHangfire(config => config
|
builder.Services.AddHangfire(config => config
|
||||||
.UseMemoryStorage()
|
.UseMemoryStorage()
|
||||||
@ -58,6 +63,15 @@ builder.Services.AddHangfire(config => config
|
|||||||
}));
|
}));
|
||||||
builder.Services.AddHangfireServer();
|
builder.Services.AddHangfireServer();
|
||||||
|
|
||||||
|
// 配置Redis
|
||||||
|
builder.Services.AddCSRedisCacheExtension(builder.Configuration.GetSection("RedisSettings"));
|
||||||
|
|
||||||
|
// 配置HttpClient
|
||||||
|
builder.Services.AddHttpClient();
|
||||||
|
|
||||||
|
// 配置OSS/SDK服务
|
||||||
|
builder.Services.AddSDKService(builder.Configuration);
|
||||||
|
|
||||||
// 配置RabbitMQ
|
// 配置RabbitMQ
|
||||||
builder.Services.AddRabbitMQ(builder.Configuration);
|
builder.Services.AddRabbitMQ(builder.Configuration);
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,11 @@
|
|||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": "server=192.168.20.150;port=13306;database=InteractiveMagazine;user=user;password=n68792bu!y99r905;charset=utf8mb4;"
|
"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": {
|
"RabbitMq": {
|
||||||
"HostName": "192.168.20.150",
|
"HostName": "192.168.20.150",
|
||||||
"Port": 5672,
|
"Port": 5672,
|
||||||
@ -55,6 +60,14 @@
|
|||||||
"DurationSeconds": 3600, //过期时间(秒)
|
"DurationSeconds": 3600, //过期时间(秒)
|
||||||
"Endpoint": "oss-cn-beijing.aliyuncs.com",
|
"Endpoint": "oss-cn-beijing.aliyuncs.com",
|
||||||
"ProjectName": "InteractiveMagazine",
|
"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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user