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

@ -4,6 +4,7 @@ using QYZH.InteractiveMagazine.Common.Helpers;
using QYZH.InteractiveMagazine.Infrastructure.Auth;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Models.Settings;
@ -38,7 +39,7 @@ public class WeChatAuthService(
logger.LogInformation("微信小程序登录");
if (string.IsNullOrWhiteSpace(input.Code))
throw new BusinessException("微信登录凭证 code 不能为空", 400);
throw new BusinessException("微信登录凭证 code 不能为空", ResultCode.BAD_REQUEST);
var weChatSettings = GetWeChatSettings();
@ -48,7 +49,7 @@ public class WeChatAuthService(
{
var errMsg = wxResponse?.ErrMsg ?? "未知错误";
logger.LogWarning("微信 code2session 接口调用失败errcode: {ErrCode}, errmsg: {ErrMsg}", wxResponse?.ErrCode, errMsg);
throw new BusinessException($"微信登录失败:{errMsg}", 400);
throw new BusinessException($"微信登录失败:{errMsg}", ResultCode.BAD_REQUEST);
}
logger.LogInformation("微信 code2session 成功OpenId: {OpenId}", wxResponse.OpenId);
@ -130,7 +131,7 @@ public class WeChatAuthService(
logger.LogInformation("微信快捷登录OpenId: {OpenId}", input.OpenId);
if (string.IsNullOrWhiteSpace(input.OpenId))
throw new BusinessException("OpenId 不能为空", 400);
throw new BusinessException("OpenId 不能为空", ResultCode.BAD_REQUEST);
var wxUser = await wxUserRepository.Context.Queryable<WxUser>()
.Where(w => w.OpenId == input.OpenId && !w.IsDeleted)
@ -139,7 +140,7 @@ public class WeChatAuthService(
if (wxUser == null)
{
logger.LogWarning("快捷登录失败OpenId: {OpenId} 下无 WxUser", input.OpenId);
throw new BusinessException("未找到该微信账号关联的用户,请先完成注册", 404);
throw new BusinessException("未找到该微信账号关联的用户,请先完成注册", ResultCode.NOT_FOUND);
}
var users = await wxUserRepository.Context.Queryable<Users>()
@ -165,17 +166,17 @@ public class WeChatAuthService(
.FirstAsync();
if (targetUser == null)
throw new BusinessException("目标用户不存在", 404);
throw new BusinessException("目标用户不存在", ResultCode.NOT_FOUND);
// 校验目标用户属于同一 WxUser
if (targetUser.WxUserId != wxUserId)
{
logger.LogWarning("切换用户失败WxUserId 不匹配,当前: {Current}, 目标: {Target}", wxUserId, targetUser.WxUserId);
throw new BusinessException("无法切换到该用户", 403);
throw new BusinessException("无法切换到该用户", ResultCode.FORBIDDEN);
}
if (targetUser.Status == (int)UserStatusEnum.Disabled)
throw new BusinessException("目标账号已被禁用", 403);
throw new BusinessException("目标账号已被禁用", ResultCode.FORBIDDEN);
// 更新 IsLastOnline清除所有设置目标为 true
await wxUserRepository.Context.Updateable<Users>()
@ -232,7 +233,7 @@ public class WeChatAuthService(
logger.LogInformation("新增用户WxUserId: {WxUserId}, Name: {Name}", wxUserId, input.Name);
if (string.IsNullOrWhiteSpace(input.Name))
throw new BusinessException("昵称不能为空", 400);
throw new BusinessException("昵称不能为空", ResultCode.BAD_REQUEST);
// 校验 WxUser 是否存在
var wxUser = await wxUserRepository.Context.Queryable<WxUser>()
@ -240,7 +241,7 @@ public class WeChatAuthService(
.FirstAsync();
if (wxUser == null)
throw new BusinessException("微信用户不存在", 404);
throw new BusinessException("微信用户不存在", ResultCode.NOT_FOUND);
// 创建新用户
var newUser = new Users
@ -280,14 +281,14 @@ public class WeChatAuthService(
logger.LogInformation("修改家长名字WxUserId: {WxUserId}, NewName: {Name}", wxUserId, input.Name);
if (string.IsNullOrWhiteSpace(input.Name))
throw new BusinessException("名字不能为空", 400);
throw new BusinessException("名字不能为空", ResultCode.BAD_REQUEST);
var wxUser = await wxUserRepository.Context.Queryable<WxUser>()
.Where(w => w.Id == wxUserId && !w.IsDeleted)
.FirstAsync();
if (wxUser == null)
throw new BusinessException("微信用户不存在", 404);
throw new BusinessException("微信用户不存在", ResultCode.NOT_FOUND);
await wxUserRepository.Context.Updateable<WxUser>()
.SetColumns(w => w.Name == input.Name.Trim())
@ -358,7 +359,7 @@ public class WeChatAuthService(
catch (Exception ex)
{
logger.LogError(ex, "调用微信 code2session 接口异常URL: {Url}", url);
throw new BusinessException("微信服务请求失败,请稍后重试", 500);
throw new BusinessException("微信服务请求失败,请稍后重试", ResultCode.GLOBAL_ERROR);
}
}
@ -378,7 +379,7 @@ public class WeChatAuthService(
{
var errMsg = response?.ErrMsg ?? "未知错误";
logger.LogError("获取微信 access_token 失败errcode: {ErrCode}, errmsg: {ErrMsg}", response?.ErrCode, errMsg);
throw new BusinessException("微信服务请求失败,请稍后重试", 500);
throw new BusinessException("微信服务请求失败,请稍后重试", ResultCode.GLOBAL_ERROR);
}
var expiresIn = response.ExpiresIn > 300 ? response.ExpiresIn - 300 : response.ExpiresIn;
@ -441,7 +442,7 @@ public class WeChatAuthService(
if (settings == null || string.IsNullOrWhiteSpace(settings.AppId) || string.IsNullOrWhiteSpace(settings.AppSecret))
{
logger.LogError("微信配置不完整,请检查 appsettings.json 中的 WeChatSettings 节点");
throw new BusinessException("微信配置不完整,请联系系统管理员", 500);
throw new BusinessException("微信配置不完整,请联系系统管理员", ResultCode.GLOBAL_ERROR);
}
return settings;
}
@ -458,7 +459,7 @@ public class WeChatAuthService(
};
if (string.IsNullOrWhiteSpace(jwtSettings.SecretKey))
throw new BusinessException("JWT 配置不完整", 500);
throw new BusinessException("JWT 配置不完整", ResultCode.GLOBAL_ERROR);
return jwtSettings;
}