using Mapster; using Microsoft.Extensions.Logging; using QYZH.InteractiveMagazine.Common.Extensions; 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.DotMatrix; using QYZH.InteractiveMagazine.Models.Dto.Journal; using QYZH.InteractiveMagazine.Models.Entity; using QYZH.InteractiveMagazine.Models.Enum; using QYZH.InteractiveMagazine.Repository; using SqlSugar; using Yitter.IdGenerator; namespace QYZH.InteractiveMagazine.Service; public class JournalService(BaseRepository JournalPageRepository, BaseRepository JournalPageTaskRepository, BaseRepository dotFileRepository, BaseRepository dotFileDetailRepository, OssService ossService, ILogger logger) : BaseRepository, IJournalService { /// /// 查询List /// /// /// public async Task> GetListAsync(JournalQueryDto dto) { var query = await Queryable() .WhereIF(!string.IsNullOrWhiteSpace(dto.Name), a => a.Name.Contains(dto.Name)) .WhereIF(dto.Status.HasValue, a => a.Status == (int)dto.Status) .Select(a => new JournalDto(), true) .ToListAsync(); return query; } /// /// 分页查询 /// /// /// public async Task> GetPageListAsync(PageQueryModel search) { RefAsync totalNumber = 0; var dataList = await Queryable() //.InnerJoin((a, b) => a.Id == b.JournalId) .WhereIF(!string.IsNullOrWhiteSpace(search.Params.Name), a => a.Name.Contains(search.Params.Name)) .WhereIF(search.Params.Status.HasValue, a => a.Status == (int)search.Params.Status) .WhereIF(!string.IsNullOrWhiteSpace(search.Params.Name), a => a.Name.Contains(search.Params.Name)) .OrderByDescending(a => a.CreatedAt) .Select(a => new JournalDto(), true) .ToPageListAsync(search.PageIndex, search.PageSize, totalNumber); return new PageListModel(dataList, search.PageIndex, search.PageSize, totalNumber); } /// /// 编辑 /// /// /// public async Task> EditAsync(JournalEditDto input) { var Journal = await base.GetByIdAsync(input.Id); BusinessException.ThrowIf(Journal.IsNull(), "不存在的Id"); BusinessException.ThrowIf(Journal.Status == (int)JournalStatusEnum.Archive, "已归档不可编辑"); if (string.IsNullOrWhiteSpace(input.Cover)) { Journal.Cover = null; } else if (input.Cover.RemoveDomain() != Journal.Cover) { var key = $"Journal/{Journal.Id}/cover.{input.Cover.ToExtension()}"; ossService.CopyObject(input.Cover.RemoveDomain(), key); Journal.Cover = key; } if (string.IsNullOrWhiteSpace(input.BackCover)) { Journal.BackCover = null; } else if (input.BackCover.RemoveDomain() != Journal.BackCover) { var backCoverkey = $"Journal/{Journal.Id}/backCover.{input.BackCover.ToExtension()}"; ossService.CopyObject(input.BackCover.RemoveDomain(), backCoverkey); Journal.BackCover = backCoverkey; } if (string.IsNullOrWhiteSpace(input.PdfUrl)) { Journal.PdfUrl = null; } else if (input.PdfUrl.RemoveDomain() != Journal.PdfUrl) { var pdfUrlkey = $"Journal/{Journal.Id}/Journal.{input.PdfUrl.ToExtension()}"; ossService.CopyObject(input.PdfUrl.RemoveDomain(), pdfUrlkey); Journal.PdfUrl = pdfUrlkey; } Journal.Width = input.Width; Journal.Height = input.Height; Journal.Name = input.Name; var res = await UseTranAsync(async () => { var result = await Context.Updateable(Journal).IgnoreColumns(c => c.Status).ExecuteCommandAsync(); return result > 0; }); return BaseResponse.Success(res); } public async Task> Tasks(long id) { var data = await JournalPageTaskRepository.Queryable().Where(w => w.JournalId == id) .Select(x => new JournalTaskOutput() { TaskId = x.Id, TaskNo = x.No, TaskSubType = x.Type }).ToListAsync(); return data.OrderBy(x => { var parts = x.TaskNo.Split('-').Select(int.Parse).ToArray(); return (parts[0], parts[1], parts[2], parts[3]); // 元组 }).ToList(); } public async Task DetailAsync(long id) { var Journal = await base.Queryable().Where(w => w.Id == id).Select().FirstAsync(); return Journal; } public async Task DeleteAsync(List ids) { BusinessException.ThrowIf(!base.Queryable().Any(w => ids.Contains(w.Id)), "ID不存在"); BusinessException.ThrowIf(base.Queryable().Any(w => ids.Contains(w.Id) && w.Status == (int)JournalStatusEnum.Archive), "已归档不可删除"); var result = await UseTranAsync(async () => { await base.DeleteAsync(d => ids.Contains(d.Id)); await JournalPageRepository.DeleteAsync(d => ids.Contains(d.JournalId)); await JournalPageTaskRepository.DeleteAsync(d => ids.Contains(d.JournalId)); return true; }); //删除OSS上的Journal/{JournalId}文件夹 if (result) { foreach (var JournalId in ids) { var prefix = $"Journal/{JournalId}/"; var keys = ossService.ListObjects(prefix); if (keys?.Count > 0) { ossService.DeleteObjects(keys); } } } return result; } /// /// /// /// 书id /// 起始页码 /// public async Task StartPageAsync(long id, int index) { var oldIndex = await JournalPageRepository.Queryable().Where(w => w.JournalId == id && w.PageNum == 1).Select(x => x.Sort).FirstAsync(); // 如果位置没有变化,直接返回 if (index == oldIndex) return true; if (index > oldIndex) { // 向后移动的情况 var x = index - oldIndex; await JournalPageRepository.Updateable().SetColumns(s => s.PageNum, 0).Where(w => w.Sort < index).Where(w => w.JournalId == id).ExecuteCommandAsync(); await JournalPageRepository.Updateable().SetColumns(s => s.PageNum == s.PageNum - x).Where(w => w.Sort >= index).Where(w => w.JournalId == id).ExecuteCommandAsync(); } else { // 向前移动的情况 //var x = oldIndex - input.Index; await JournalPageRepository.Updateable().SetColumns(s => s.PageNum, 0).Where(w => w.Sort < index).Where(w => w.JournalId == id).ExecuteCommandAsync(); // 将目标页面设置为第一页 await JournalPageRepository.Updateable().SetColumns(s => s.PageNum == s.Sort - (index - 1)).Where(w => w.Sort >= index).Where(w => w.JournalId == id).ExecuteCommandAsync(); } // await JournalPageRepository.Updateable().SetColumns(s => s.PageNum == s.Sort).Where(w => w.JournalId == input.Id).ExecuteCommandAsync(); return true; } public async Task PrintCodeAsync(long id) { var Journal = await base.Queryable().Where(w => w.Id == id).FirstAsync(); BusinessException.ThrowIf(Journal.IsNull(), "不存在书"); BusinessException.ThrowIf(Journal.Status == (int)JournalStatusEnum.Codeing, "正在生成中..."); var pages = await JournalPageRepository.Queryable().Where(w => w.JournalId == id).ToListAsync(); BusinessException.ThrowIf(pages.IsNull(), "不存在页"); var output = new DotMatrixOutput() { Method = "Journal", Name = Journal.Name, NoteId = id, PdfUrl = Journal.PdfUrl }; //铺码业务后续调整 //var exist = pages.All(c => c.PageNo.IsNull()); //if (!exist) //{ // var dotIds = pages.Select(s => s.DotId).Distinct(); // var dots = await dotFileRepository.Queryable().Where(w => dotIds.Contains(w.Id)).ToListAsync(); // output.DotMatrixs = dots.Select(s => new DotMatrixMqOutput() { DotId = s.Id, FileAddress = s.FileAddress }).ToList(); // foreach (var page in pages) // { // var find = output.DotMatrixs.Find(f => f.DotId == page.DotId); // find!.Pages.Add(new DotMatrixPageDto() // { // PageNo = page.PageNo, // PageNum = 1 // }); // } // var ok = await producingService.SendAsync(new RabbitMQSendParam() { Exchange = "icr.direct", RoutingKey = "mq.dotmatrix", Data = output }); // BusinessException.ThrowIf(!ok, "消息发送失败,生成失败"); // await base.Updateable().SetColumns(s => s.Status, JournalStatusEnum.Codeing).Where(w => w.Id == id).ExecuteCommandAsync(); //} //else //{ // //var first = await dotFileDetailRepository.Queryable().Where(w => w.IsUse == false).GroupBy(g => g.DotId).Having(h => h.Count() >= pages.Count).FirstAsync(a => new { DotId = a.Key, Count = a.Count() }); // var first = await dotFileDetailRepository.Queryable().Where(w => w.IsUse == false).GroupBy(g => g.DotId).Having(h => SqlFunc.AggregateCount(h.Id) >= pages.Count).Select(a => new { DotId = a.DotId, Count = SqlFunc.AggregateCount(a.Id) }).FirstAsync(); // BusinessException.ThrowIf(first.IsNull(), "点阵页码不足,生成失败"); // var dotFile = await dotFileRepository.Queryable().Where(w => w.Id == first.DotId).FirstAsync(); // if (dotFile != null) // dotFile.Details = dotFileDetailRepository.Queryable().Where(w => !w.IsUse && w.DotId == dotFile.Id).Take(pages.Count()).ToList(); // var dotMatrix = new DotMatrixMqOutput() // { // DotId = dotFile.Id, // FileAddress = dotFile.FileAddress, // }; // output.DotMatrixs.Add(dotMatrix); // foreach (var item in dotFile.Details) // { // var index = dotFile.Details.IndexOf(item); // pages[index].PageNo = item.PageName; // pages[index].DotId = dotFile.Id; // dotMatrix.Pages.Add(new DotMatrixPageDto() // { // PageNo = item.PageName, // PageNum = 1 // }); // } // await UseTranAsync(async () => // { // // 更新使用数量 // //await dotFileRepository.Updateable().SetColumns(s => s.TotalUse, dotFile.TotalUse + pages.Count).Where(w => w.Id == dotFile.Id).ExecuteCommandAsync(); // // 更新使用 // await dotFileDetailRepository.Updateable().SetColumns(s => s.IsUse, true).Where(w => dotFile.Details.Select(s => s.Id).Contains(w.Id)).ExecuteCommandAsync(); // // 更新页码 // await dotMatrixPageRepository.UpdateRangeAsync(pages); // await Updateable().SetColumns(s => s.Status, JournalStatusEnum.CodeSuccess).Where(w => w.Id == id).ExecuteCommandAsync(); // //发送消息 // //var ok = await producingService.SendAsync(new RabbitMQSendParam() { Exchange = "icr.direct", RoutingKey = "mq.dotmatrix", Data = output }); // //BusinessException.ThrowIf(!ok, "消息发送失败,生成失败"); // }); //} return output; } public async Task ResultReportAsync(DotMatrixNoteJournalReportInput input) { if (input.FileUrl.IsNull() && input.FileKey.IsNull()) { return await Updateable().SetColumns(s => s.Status, input.Success ? JournalStatusEnum.CodeSuccess : JournalStatusEnum.CodeFail) .SetColumns(s => s.PdfPreviewUrl, input.FileKey) .Where(w => w.Id == input.Id) .ExecuteCommandAsync() > 0; } return await Updateable().SetColumns(s => s.Status, JournalStatusEnum.CodeFail).Where(w => w.Id == input.Id).ExecuteCommandAsync() > 0; } public async Task StatusAsync(long id, JournalStatusEnum status) { var book = await base.GetByIdAsync(id); var tasks = await Context.Queryable().Where(w => w.JournalId == id).ToListAsync(); BusinessException.ThrowIf(tasks.Count == 0 && status == JournalStatusEnum.Archive, "未添加任何题目,无法归档"); BusinessException.ThrowIf(tasks.Any(a => string.IsNullOrWhiteSpace(a.TaskUrl)) && status == JournalStatusEnum.Archive, $"{string.Join(',', tasks.Where(a => string.IsNullOrWhiteSpace(a.TaskUrl)).Select(a => a.No).ToList())}未保存,无法归档"); var res = await base.Updateable().SetColumns(s => s.Status, status).Where(w => w.Id == id).ExecuteCommandAsync() > 0; return res; } }