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; using QYZH.InteractiveMagazine.Models.Common; using QYZH.InteractiveMagazine.Models.Dto; using QYZH.InteractiveMagazine.Models.Dto.Journal; 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; public class JournalPageService(BaseRepository JournalRepository, OssService ossService, IHttpClientFactory httpClientFactory, IConfiguration configuration, IRabbitMQService rabbitMqService, ILogger logger, BaseRepository JournalPageRepository, BaseRepository JournalPageTaskRepository, BaseRepository JournalPageTaskAnswerRepository) : BaseRepository, IJournalPageService { public async Task InsertAsync(JournalAddV2Input input) { var Journal = await JournalRepository.Queryable().Where(w => w.Id == input.JournalId).FirstAsync(); BusinessException.ThrowIf(Journal.IsNull(), "未找到书本", ResultCode.NOT_FOUND); BusinessException.ThrowIf(Journal?.Status == (int)JournalStatusEnum.Archive, "书籍已归档不能修改", ResultCode.CONFLICT); var pages = new List(); //var dotMatrixpages = new List(); //var dotMatrixpage = new DotMatrixPage() //{ // Id = YitIdHelper.NextId(), // DotMatrixNoteJournalId = input.JournalId, // WidthMilliMeter = Journal.Width, // HightMilliMeter = Journal.Height, //}; var pageTemp = new JournalPage() { JournalId = input.JournalId, JournalCatalogId = input.JournalCatalogId, //DotMatrixPageId = dotMatrixpage.Id, Url = input.Url, PageNum = input.PageNum, }; //dotMatrixpages.Add(dotMatrixpage); pages.Add(pageTemp); await UseTranAsync(async () => { //using var uow = Context.Ado.BeginTran(); var pageData = await base.InsertRangeAsync(pages); BusinessException.ThrowIf(pageData.IsNull(), "创建页失败", ResultCode.GLOBAL_ERROR); //var result = await dotMatrixPageRepository.InsertRangeAsync(dotMatrixpages); //BusinessException.ThrowIf(result, "创建点阵页失败"); }); return pages.Count; // 返回主目录ID } public async Task UpdateAsync(PageLayoutInput input) { var page = await Queryable().Where(w => w.Id == input.Id).FirstAsync(); BusinessException.ThrowIf(page == null, "不存在此页", ResultCode.NOT_FOUND); var Journal = await JournalRepository.GetByIdAsync(page.JournalId); BusinessException.ThrowIf(Journal == null, "不存在此书", ResultCode.NOT_FOUND); BusinessException.ThrowIf(Journal?.Status == (int)JournalStatusEnum.Archive, "书籍已归档不能修改", ResultCode.CONFLICT); var transResult = await UseTranAsync(async () => { //await dotMatrixPageRepository.Updateable().SetColumns(s => s.Area == input.Layout) // .SetColumns(s => s.AreaPoints == dotMatrixPage.Area) // .SetColumns(s => s.WidthMilliMeter == dotMatrixPage.WidthMilliMeter) // .SetColumns(s => s.HightMilliMeter == dotMatrixPage.HightMilliMeter) // .SetColumns(s => s.WidthDotMatrix == dotMatrixPage.WidthDotMatrix) // .SetColumns(s => s.HightDotMatrix == dotMatrixPage.HightDotMatrix) // .Where(w => w.Id == page.DotMatrixPageId).ExecuteCommandAsync(); page.Layout = input.Layout; base.Update(page); input.TasksImages?.ForEach(it => { var key = $"journal/{Journal.Id}/{input.Id}/{it.TaskId}/qustion.{it.Url.ToExtension()}"; ossService.CopyObject(it.Url.RemoveDomain(), key); JournalPageTaskRepository.Updateable().SetColumns(s => s.TaskUrl, key).Where(w => w.Id == it.TaskId).ExecuteCommand(); }); return true; }); return transResult; } /// /// 修改书页的点阵码 /// /// /// public async Task UpdatePageNoAsync(long JournalId) { var journalEntity = await JournalRepository.Queryable().FirstAsync(w => w.Id == JournalId); BusinessException.ThrowIf(journalEntity == null, "不存在此期刊", ResultCode.NOT_FOUND); //如果书籍状态不等于“已归档”,“已废弃”,“已铺码”的情况下,就更新状态为“已铺码” BusinessException.ThrowIf((JournalStatusEnum)journalEntity.Status is JournalStatusEnum.Abandoned or JournalStatusEnum.Archive or JournalStatusEnum.Codeing, "当前【状态】不允许铺码", ResultCode.UNPROCESSABLE_ENTITY); var journalPageList = await JournalPageRepository.Queryable().Where(x => x.JournalId == JournalId).OrderBy(x => x.PageNum).ToListAsync(); BusinessException.ThrowIf(journalPageList.Count == 0, "此期刊不存在任何书页", ResultCode.NOT_FOUND); var uploadPdfKey = journalEntity?.PdfUrl?.RemoveDomain(); BusinessException.ThrowIf(string.IsNullOrWhiteSpace(uploadPdfKey), "此期刊上传的PDF路径错误,请检查期刊PDF文件是否上传成功", ResultCode.BAD_REQUEST); var uploadPdfUrl = DomainHelper.OssFullUrl(uploadPdfKey); BusinessException.ThrowIf(string.IsNullOrWhiteSpace(uploadPdfUrl), "此期刊上传的PDF路径错误,请检查期刊PDF文件是否上传成功", ResultCode.BAD_REQUEST); logger.LogInformation("uploadPdfUrl:" + uploadPdfUrl); //验证是否上传了PDF文件 var isPdfExists = ossService.DoesObjectExist(uploadPdfKey); BusinessException.ThrowIf(!isPdfExists, "获取期刊上传的PDF文件失败,请检查PDF文件是否上传成功", ResultCode.GLOBAL_ERROR); 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, "不存在此书", ResultCode.NOT_FOUND); //如果书籍状态不等于“铺码中”则不允许回调接口更新点阵码 BusinessException.ThrowIf(journalEntity.Status != (int)JournalStatusEnum.Codeing, "当前【状态】不允许修改铺码", ResultCode.UNPROCESSABLE_ENTITY); var bookPageList = await JournalPageRepository.Queryable().Where(x => x.JournalId == request.JournalId).OrderBy(x => x.PageNum).ToListAsync(); BusinessException.ThrowIf(bookPageList.Count == 0, "此书不存在任何书页", ResultCode.NOT_FOUND); 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}", ResultCode.BAD_REQUEST); 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() //.LeftJoin((a, b) => a.DotMatrixPageId == b.Id) .Where(a => a.Id == id) .Select(a => new JournalPageV2Output { JournalId = a.JournalId, JournalCatalogId = a.JournalCatalogId, JournalPageId = a.Id, Url = a.Url, Layout = a.Layout, PageNum = a.PageNum, }) .FirstAsync(); if (output != null) { var tasks = await JournalPageTaskRepository.Queryable() .Where(a => a.JournalPageId == output.JournalPageId) .ToListAsync(); if (tasks.Count > 0) { var taskIds = tasks.Select(t => t.Id).ToList(); var allAnswers = await JournalPageTaskAnswerRepository.Queryable() .Where(a => taskIds.Contains(a.JournalPageTaskId)) .ToListAsync(); output.Tasks = tasks.Select(t => new JournalPageTaskV2Output { Id = t.Id, GroupId = t.GroupId, No = t.No, Type = t.Type, Answers = allAnswers .Where(a => a.JournalPageTaskId == t.Id) .Select(a => new JournalTaskAnswerOutput { Id = a.Id, Answer = a.Answer, AnswerUrl = a.AnswerUrL }).ToList() }).ToList(); } } //if (output?.Areas != null) // output.Areas = await _JournalPageOtherRepository.Queryable().Where(w => w.JournalPageId == output.JournalPageId).Select().ToListAsync(); return output; } public async Task DeleteAsync(long id) { return await Deleteable().Where(d => d.Id == id).ExecuteCommandAsync() > 0; } //public async Task> PageNoArticleAsync(long JournalId) //{ // return await Queryable().Where(d => d.JournalId == JournalId) // .Where(w => w.JournalArticleId == null) // .ToListAsync(x => new JournalPageNoArticleOutput() // { // Id = x.Id, // PageUrl = x.Url, // PageNum = x.PageNum // }); //} private int MillimeterToDotMatrixUnit(float millimeterValue) { return (int)(millimeterValue * 8 / 0.3); } } public class JournalDotPage_Task { public int X { get; set; } public int Y { get; set; } public int W { get; set; } public int H { get; set; } } public class JournalDotPage_Answer { public int X { get; set; } public int Y { get; set; } public int W { get; set; } public int H { get; set; } } public class JournalDotPage_Area { public JournalDotPage_Task Task { get; set; } public List AnswerList { get; set; } public long TaskId { get; set; } }