refactor: 统一业务异常处理,标准化结果码和错误响应

1.  新增并完善ResultCode枚举,补充标准HTTP状态码对应的业务状态码
2.  重构BusinessException,新增基于ResultCode的构造函数和ThrowIf扩展方法
3.  替换所有硬编码的HTTP状态码为统一的ResultCode枚举
4.  优化全局异常中间件,根据业务状态码映射对应HTTP状态码并规范化JSON响应
5.  修复OssImageHelper和AutoDotCodeConsumer中的OSS文件处理逻辑
6.  新增用户答题快照实体类
7.  清理废弃的宠物模块迁移脚本
This commit is contained in:
glz
2026-06-29 16:34:26 +08:00
parent 4579fefef9
commit bdaa6a0dc8
35 changed files with 693 additions and 364 deletions

View File

@ -5,6 +5,7 @@ using QYZH.InteractiveMagazine.Infrastructure.OSS;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Base;
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;
@ -35,10 +36,10 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
public async Task<long> ImportAsync(JournalImportDto input)
{
var Journals = await Queryable<Journal>().Where(w => w.Id == input.JournalId).FirstAsync();
BusinessException.ThrowIf(Journals.IsNull(), "未找到书本");
BusinessException.ThrowIf(Journals.IsNull(), "未找到书本", ResultCode.NOT_FOUND);
var pageNum = await _JournalPageRepository.Queryable().Where(w => w.JournalId == input.JournalId).MaxAsync(m => m.PageNum);
BusinessException.ThrowIf(pageNum != 0, "已经存在书页");
BusinessException.ThrowIf(pageNum != 0, "已经存在书页", ResultCode.CONFLICT);
var JournalCatalog = new JournalCatalog()
@ -106,7 +107,7 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
public async Task<List<JournalCatalogTreeListDto>> GetJournalCatalogListAsync(long JournalId)
{
var Journal = await Queryable<Journal>().Where(w => w.Id == JournalId).FirstAsync();
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本");
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本", ResultCode.NOT_FOUND);
var pageNumList = await _JournalPageRepository.Queryable()
.InnerJoin<JournalCatalog>((a, b) => a.JournalCatalogId == b.Id)
@ -136,7 +137,7 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
public async Task<List<IcrJournalCatalogTreeDto>> GetJournalCataloTreeAsync(long JournalId)
{
var Journal = await Queryable<Journal>().Where(w => w.Id == JournalId).FirstAsync();
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本");
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本", ResultCode.NOT_FOUND);
// 先查询所有目录
var allCatalogs = await base.Queryable()
@ -276,13 +277,13 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
public async Task<bool> ImportCatalogAsync(long JournalId, List<JournalCatalogTreeListDto> dtos)
{
dtos = dtos.Where(c => !string.IsNullOrWhiteSpace(c.Name)).ToList();
BusinessException.ThrowIf(dtos.Select(c => c.PageNum).Distinct().Count() != dtos.Count(), "存在重复的页码");
BusinessException.ThrowIf(dtos.Select(c => c.PageNum).Distinct().Count() != dtos.Count(), "存在重复的页码", ResultCode.CONFLICT);
var Journal = await Queryable<Journal>().Where(w => w.Id == JournalId).FirstAsync();
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本");
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本", ResultCode.NOT_FOUND);
var pageNums = dtos.Select(c => c.PageNum).ToList();
var pageNumNotExists = await _JournalPageRepository.Queryable().AnyAsync(w => w.JournalId == JournalId && !pageNums.Contains(w.PageNum));
BusinessException.ThrowIf(pageNumNotExists, "不存在的书页");
BusinessException.ThrowIf(pageNumNotExists, "不存在的书页", ResultCode.NOT_FOUND);
var firstCatelogGroup = dtos.Select(c => c.ParentName).Distinct().Select(c => new JournalCatalog
{
@ -352,7 +353,7 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
if (input.Type == 1)
{
var Journal = await Queryable<Journal>().Where(w => w.Id == input.JournalId).FirstAsync();
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本");
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本", ResultCode.NOT_FOUND);
//var dotMatrixPage = new DotMatrixPage()
//{
@ -390,10 +391,10 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
{
// 删除目录
var cata = await base.Deleteable().Where(d => ids.Contains(d.Id)).ExecuteCommandAsync() > 0;
BusinessException.ThrowIf(!cata, $"删除目录失败");
BusinessException.ThrowIf(!cata, $"删除目录失败", ResultCode.GLOBAL_ERROR);
// 删除所有页/问题
var pages = await _JournalPageRepository.DeleteAsync(w => ids.Contains(w.JournalCatalogId));
BusinessException.ThrowIf(pages.IsNull(), $"删除数据失败");
BusinessException.ThrowIf(pages.IsNull(), $"删除数据失败", ResultCode.GLOBAL_ERROR);
//var x = await _JournalPageRepository.DeleteAsync(w => ids.Contains(w.JournalCatalogId));
@ -406,14 +407,14 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
{
// 1. 获取源节点并校验
var sourceNode = await base.Queryable().Where(x => x.Id == input.SourceId).FirstAsync();
BusinessException.ThrowIf(sourceNode.IsNull(), $"要移动的节点{input.SourceId}不存在");
BusinessException.ThrowIf(sourceNode.IsNull(), $"要移动的节点{input.SourceId}不存在", ResultCode.NOT_FOUND);
// 2. 校验目标父节点(如果指定)
if (input.TargetParentId > 0)
{
var targetParentExists = await base.Queryable().Where(x => x.Id == input.TargetParentId).AnyAsync();
BusinessException.ThrowIf(!targetParentExists, $"目标父节点{input.TargetParentId}不存在");
BusinessException.ThrowIf(!targetParentExists, $"目标父节点{input.TargetParentId}不存在", ResultCode.NOT_FOUND);
}
await base.UseTranAsync(async () =>