refactor,feat: 批量代码重构与新增业务模块
1. 重命名枚举项与实体字段,修正类型引用 2. 新增IsNull扩展方法与多项字符串处理扩展 3. 新增大量业务DTO、服务接口与枚举定义 4. 重构RabbitMQ服务实现,替换旧版消息队列组件 5. 优化签到服务的宠物喂养事务逻辑 6. 移除冗余的项目引用与旧版消息队列代码 7. 新增Excel导出、导入模板相关工具方法
This commit is contained in:
313
QYZH.InteractiveMagazine.Service/JournalService.cs
Normal file
313
QYZH.InteractiveMagazine.Service/JournalService.cs
Normal file
@ -0,0 +1,313 @@
|
||||
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<JournalPage> JournalPageRepository,
|
||||
BaseRepository<JournalPageTask> JournalPageTaskRepository,
|
||||
BaseRepository<DotFile> dotFileRepository,
|
||||
BaseRepository<DotFileDetail> dotFileDetailRepository, OssService ossService, ILogger<JournalService> logger) : BaseRepository<Journal>, IJournalService
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询List
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<JournalDto>> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
/// <param name="search"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageListModel<JournalDto>> GetPageListAsync(PageQueryModel<JournalQueryDto> search)
|
||||
{
|
||||
RefAsync<int> totalNumber = 0;
|
||||
|
||||
var dataList = await Queryable()
|
||||
//.InnerJoin<IcrJournalOrganization>((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<JournalDto>(dataList, search.PageIndex, search.PageSize, totalNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<BaseResponse<bool>> 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;
|
||||
Journal.Title = input.Title;
|
||||
|
||||
var res = await UseTranAsync(async () =>
|
||||
{
|
||||
var result = await Context.Updateable(Journal).IgnoreColumns(c => c.Status).ExecuteCommandAsync();
|
||||
return result > 0;
|
||||
});
|
||||
|
||||
|
||||
|
||||
return BaseResponse<bool>.Success(res);
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<JournalTaskOutput>> 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<JournalDto> DetailAsync(long id)
|
||||
{
|
||||
var Journal = await base.Queryable().Where(w => w.Id == id).Select<JournalDto>().FirstAsync();
|
||||
return Journal;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteAsync(List<long> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id">书id</param>
|
||||
/// <param name="index">起始页码</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> 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<DotMatrixOutput> 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<bool> 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<bool> StatusAsync(long id, JournalStatusEnum status)
|
||||
{
|
||||
var book = await base.GetByIdAsync(id);
|
||||
var tasks = await Context.Queryable<JournalPageTask>().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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user