diff --git a/QYZH.InteractiveMagazine.IService/IJournalService.cs b/QYZH.InteractiveMagazine.IService/IJournalService.cs index 1f16412..153e7db 100644 --- a/QYZH.InteractiveMagazine.IService/IJournalService.cs +++ b/QYZH.InteractiveMagazine.IService/IJournalService.cs @@ -49,6 +49,8 @@ public interface IJournalService : IBaseService Task StatusAsync(long id, JournalStatusEnum status); + Task PublishAsync(long id); + Task PrintCodeAsync(long id); Task ResultReportAsync(DotMatrixNoteJournalReportInput input); diff --git a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalDto.cs b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalDto.cs index 0b14eaf..31329c7 100644 --- a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalDto.cs +++ b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalDto.cs @@ -120,8 +120,33 @@ namespace QYZH.InteractiveMagazine.Models.Dto.Journal /// public string? DownloadJournalPagePdfName { get; set; } + /// + /// 发布开始时间 + /// + public DateTime? StartTime { get; set; } + + /// + /// 发布结束时间 + /// + public DateTime? EndTime { get; set; } + public string CreatedBy { get; set; } public DateTime CreatedAt { get; set; } } + + public class JournalPublishBookMessage + { + public long BookId { get; set; } + public DateTime StartTime { get; set; } + public DateTime EndTime { get; set; } + } + + public class JournalPublishBookPageMessage + { + public long BookId { get; set; } + public long PageId { get; set; } + public string? PageNo { get; set; } + public string? Layout { get; set; } + } } diff --git a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalEditDto.cs b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalEditDto.cs index a06f000..7a57d4c 100644 --- a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalEditDto.cs +++ b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalEditDto.cs @@ -69,6 +69,16 @@ namespace QYZH.InteractiveMagazine.Models.Dto.Journal /// public string? PdfPreviewUrl { get; set; } + /// + /// Desc:发布开始时间 + /// + public DateTime? StartTime { get; set; } + + /// + /// Desc:发布结束时间 + /// + public DateTime? EndTime { get; set; } + } public partial class JournalEditDto: JournalAddDto { diff --git a/QYZH.InteractiveMagazine.Models/Entity/Journal.cs b/QYZH.InteractiveMagazine.Models/Entity/Journal.cs index 2a97b97..4e1cb8b 100644 --- a/QYZH.InteractiveMagazine.Models/Entity/Journal.cs +++ b/QYZH.InteractiveMagazine.Models/Entity/Journal.cs @@ -106,6 +106,20 @@ namespace QYZH.InteractiveMagazine.Models.Entity /// public string DownloadJournalPagePdfName { get; set; } + /// + /// Desc:发布日期开始时间 + /// Default: + /// Nullable:True + /// + public DateTime? StartTime { get; set; } + + /// + /// Desc:发布日期结束时间 + /// Default: + /// Nullable:True + /// + public DateTime? EndTime { get; set; } + /// /// Desc:书籍描述/简介 diff --git a/QYZH.InteractiveMagazine.Service/JournalService.cs b/QYZH.InteractiveMagazine.Service/JournalService.cs index ce5e227..6194492 100644 --- a/QYZH.InteractiveMagazine.Service/JournalService.cs +++ b/QYZH.InteractiveMagazine.Service/JournalService.cs @@ -21,8 +21,17 @@ public class JournalService(BaseRepository JournalPageRepository, BaseRepository JournalPageTaskAnswerRepository, BaseRepository JournalCatalogRepository, BaseRepository dotFileRepository, - BaseRepository dotFileDetailRepository, OssService ossService, ILogger logger) : BaseRepository, IJournalService + BaseRepository dotFileDetailRepository, + OssService ossService, + IRabbitMQService rabbitMqService, + ILogger logger) : BaseRepository, IJournalService { + private const string JournalExchange = "ex.journal"; + private const string PublishBookQueue = "mq.journal.publish.book"; + private const string PublishBookRoutingKey = "rk.journal.publish.book"; + private const string PublishBookPageQueue = "mq.journal.publish.bookpage"; + private const string PublishBookPageRoutingKey = "rk.journal.publish.bookpage"; + /// /// 查询List /// @@ -82,6 +91,8 @@ public class JournalService(BaseRepository JournalPageRepository, Cover = input.Cover?.RemoveDomain(), BackCover = input.BackCover?.RemoveDomain(), PdfPreviewUrl = input.PdfPreviewUrl?.RemoveDomain(), + StartTime = input.StartTime, + EndTime = input.EndTime, CreatedBy = "System", UpdatedBy = "System", CreatedAt = DateTime.Now, @@ -167,6 +178,9 @@ public class JournalService(BaseRepository JournalPageRepository, Journal.Height = input.Height; Journal.Name = input.Name; Journal.Title = input.Title; + Journal.StartTime = input.StartTime; + Journal.EndTime = input.EndTime; + Journal.UpdatedAt = DateTime.Now; var res = await UseTranAsync(async () => { @@ -320,4 +334,59 @@ public class JournalService(BaseRepository JournalPageRepository, var res = await base.Updateable().SetColumns(s => s.Status, status).Where(w => w.Id == id).ExecuteCommandAsync() > 0; return res; } -} \ No newline at end of file + + public async Task PublishAsync(long id) + { + var book = await base.GetByIdAsync(id); + BusinessException.ThrowIf(book == null || book.IsDeleted, "杂志不存在", ResultCode.NOT_FOUND); + + var pages = await JournalPageRepository.Queryable() + .Where(x => x.JournalId == id && !x.IsDeleted) + .OrderBy(x => x.PageNum) + .OrderBy(x => x.Sort) + .ToListAsync(); + BusinessException.ThrowIf(pages.Count == 0, "书籍未添加任何书页,无法发布", ResultCode.UNPROCESSABLE_ENTITY); + + BusinessException.ThrowIf(!book.StartTime.HasValue, "发布开始时间不能为空", ResultCode.UNPROCESSABLE_ENTITY); + BusinessException.ThrowIf(!book.EndTime.HasValue, "发布结束时间不能为空", ResultCode.UNPROCESSABLE_ENTITY); + BusinessException.ThrowIf(book.EndTime < book.StartTime, "发布结束时间不能早于开始时间", ResultCode.UNPROCESSABLE_ENTITY); + + var bookMessageSent = await rabbitMqService.SendAsync(new RabbitMQSendParam + { + Exchange = JournalExchange, + Queue = PublishBookQueue, + RoutingKey = PublishBookRoutingKey, + Data = new JournalPublishBookMessage + { + BookId = id, + StartTime = book.StartTime.Value, + EndTime = book.EndTime.Value + } + }); + BusinessException.ThrowIf(!bookMessageSent, "发布书籍消息发送失败", ResultCode.GLOBAL_ERROR); + + foreach (var page in pages) + { + var pageMessageSent = await rabbitMqService.SendAsync(new RabbitMQSendParam + { + Exchange = JournalExchange, + Queue = PublishBookPageQueue, + RoutingKey = PublishBookPageRoutingKey, + Data = new JournalPublishBookPageMessage + { + BookId = id, + PageId = page.Id, + PageNo = page.PageNo, + Layout = page.Layout + } + }); + BusinessException.ThrowIf(!pageMessageSent, $"发布书页消息发送失败,PageId: {page.Id}", ResultCode.GLOBAL_ERROR); + } + + return await base.Updateable() + .SetColumns(s => s.Status, JournalStatusEnum.Published) + .SetColumns(s => s.UpdatedAt, DateTime.Now) + .Where(w => w.Id == id) + .ExecuteCommandAsync() > 0; + } +} diff --git a/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs b/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs index 8d2b452..89255f1 100644 --- a/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs +++ b/QYZH.InteractiveMagazine.WebApi/Controllers/JournalController.cs @@ -141,6 +141,17 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers return BaseResponse.Success(data); } + /// + /// 书籍发布 + /// + /// + [HttpPost, Route("journal/publish/{id:long}")] + public async Task> Publish(long id) + { + var data = await JournalService.PublishAsync(id); + return BaseResponse.Success(data); + } + /// /// 书籍铺码 /// @@ -200,17 +211,6 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers #region 书籍目录 - ///// - ///// 书籍目录详情 - ///// - ///// - //[HttpGet, Route("catalog/tree/{JournalId:long}")] - //public async Task>> CatalogDetailAsync(long JournalId) - //{ - // var data = await _JournalCatalogService.DetailAsync(JournalId); - // return BaseResponse>.Success(data); - //} - /// /// 书籍目录详情 /// @@ -312,18 +312,6 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers return BaseResponse.Success(data); } - ///// - ///// 书籍目录复制 - ///// - ///// - ///// - //[HttpPost, Route("catalog/copy")] - //[ProducesResponseType(typeof(BaseResponse), 200)] - //public async Task CatalogCopy(CopyInput input) - //{ - // var data = await _JournalCatalogServices.CopyAsync(input); - // return ApiResult(data, "书籍目录删除失败!"); - //} /// /// 书籍目录移动 @@ -411,30 +399,6 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers } - ///// - ///// 打印书页(全部) 暂时废弃这个方,直接使用 Adobe Reader X 软件打印就可以了 - ///// - ///// - //[HttpPost, Route("page/printJournalPage/{JournalId:long}")] - //public async Task> PrintJournalPage([Required(ErrorMessage = "书籍编号不允许为空")] long JournalId) - //{ - // var data = await JournalPageService.PrintJournalPageAsync(JournalId); - // return BaseResponse.Success(data); - //} - - - ///// - ///// 书页删除 - ///// - ///// - //[HttpPost, Route("page/delete/{id:long}")] - //[ProducesResponseType(typeof(BaseResponse), 200)] - //public async Task PageDelete(long id) - //{ - // var data = await _JournalPageServices.DeleteAsync(id); - // return ApiResult(data, "更新书页失败!"); - //} - /// /// 书页详情 /// @@ -446,17 +410,6 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers return BaseResponse.Success(data); } - ///// - ///// 不包含有文章的书页 - ///// - ///// - //[HttpGet, Route("page/no-article/{JournalId:long}")] - //[ProducesResponseType(typeof(BaseResponse>), 200)] - //public async Task PageNoArticleAsync(long JournalId) - //{ - // var data = await _JournalPageService.PageNoArticleAsync(JournalId); - // return BaseResponse>(data, "查询书页失败!"); - //} #endregion