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

@ -13,6 +13,14 @@ public class GlobalExceptionMiddleware : IMiddleware
{ {
private readonly ILogger<GlobalExceptionMiddleware> _logger; private readonly ILogger<GlobalExceptionMiddleware> _logger;
/// <summary>
/// JSON序列化选项camelCase与Controller保持一致
/// </summary>
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
/// <summary> /// <summary>
/// 构造函数 /// 构造函数
/// </summary> /// </summary>
@ -35,7 +43,7 @@ public class GlobalExceptionMiddleware : IMiddleware
} }
catch (BusinessException ex) catch (BusinessException ex)
{ {
_logger.LogWarning(ex, "业务异常:{Message}", ex.Message); _logger.LogWarning(ex, "业务异常:{Message},状态码:{ResultCode}", ex.Message, ex.ResultCode);
await HandleBusinessExceptionAsync(context, ex); await HandleBusinessExceptionAsync(context, ex);
} }
catch (Exception ex) catch (Exception ex)
@ -46,17 +54,17 @@ public class GlobalExceptionMiddleware : IMiddleware
} }
/// <summary> /// <summary>
/// 处理业务异常 /// 处理业务异常按业务状态码映射HTTP状态码
/// </summary> /// </summary>
/// <param name="context">HTTP上下文</param> /// <param name="context">HTTP上下文</param>
/// <param name="ex">业务异常</param> /// <param name="ex">业务异常</param>
private static async Task HandleBusinessExceptionAsync(HttpContext context, BusinessException ex) private static async Task HandleBusinessExceptionAsync(HttpContext context, BusinessException ex)
{ {
context.Response.ContentType = "application/json"; context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status400BadRequest; context.Response.StatusCode = GetHttpStatusCode(ex.ResultCode);
var response = BaseResponse<object>.Fail(ResultCode.FAIL,ex.Message); var response = BaseResponse<object>.Fail(ex.ResultCode, ex.Message);
var json = JsonSerializer.Serialize(response); var json = JsonSerializer.Serialize(response, JsonOptions);
await context.Response.WriteAsync(json); await context.Response.WriteAsync(json);
} }
@ -71,9 +79,32 @@ public class GlobalExceptionMiddleware : IMiddleware
context.Response.ContentType = "application/json"; context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status500InternalServerError; context.Response.StatusCode = StatusCodes.Status500InternalServerError;
var response = BaseResponse<object>.Fail("系统内部错误,请稍后重试"); var response = BaseResponse<object>.Fail(ResultCode.GLOBAL_ERROR, "系统内部错误,请稍后重试");
var json = JsonSerializer.Serialize(response); var json = JsonSerializer.Serialize(response, JsonOptions);
await context.Response.WriteAsync(json); await context.Response.WriteAsync(json);
} }
/// <summary>
/// 根据业务状态码获取对应的HTTP状态码
/// </summary>
/// <param name="resultCode">业务状态码</param>
/// <returns>HTTP状态码</returns>
private static int GetHttpStatusCode(ResultCode resultCode)
{
return resultCode switch
{
ResultCode.DENY => StatusCodes.Status401Unauthorized,
ResultCode.FORBIDDEN => StatusCodes.Status403Forbidden,
ResultCode.NOT_FOUND => StatusCodes.Status404NotFound,
ResultCode.BAD_REQUEST => StatusCodes.Status400BadRequest,
ResultCode.PARAM_ERROR => StatusCodes.Status400BadRequest,
ResultCode.CONFLICT => StatusCodes.Status409Conflict,
ResultCode.UNPROCESSABLE_ENTITY => StatusCodes.Status422UnprocessableEntity,
ResultCode.TOO_MANY_REQUESTS => StatusCodes.Status429TooManyRequests,
ResultCode.BAD_GATEWAY => StatusCodes.Status502BadGateway,
ResultCode.SERVICE_UNAVAILABLE => StatusCodes.Status503ServiceUnavailable,
_ => StatusCodes.Status400BadRequest
};
}
} }

View File

@ -24,7 +24,7 @@ public class ModelValidActionFilterAttribute : ActionFilterAttribute
errorDic.Add(key, errorStr); errorDic.Add(key, errorStr);
} }
} }
var result = new BaseResponse<Dictionary<string, string>>() { code = ResultCode.FAIL }; var result = new BaseResponse<Dictionary<string, string>>() { code = ResultCode.BAD_REQUEST };
result.message = string.Join("|", errorDic.Select(e => e.Value).Distinct()); result.message = string.Join("|", errorDic.Select(e => e.Value).Distinct());
result.result = errorDic; result.result = errorDic;

View File

@ -1,6 +1,7 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.Common.Extensions; using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.Models.Common; using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
namespace QYZH.InteractiveMagazine.Infrastructure.OSS; namespace QYZH.InteractiveMagazine.Infrastructure.OSS;
@ -87,7 +88,7 @@ public class OssImageHelper
catch (Exception ex) when (ex is not BusinessException) catch (Exception ex) when (ex is not BusinessException)
{ {
_logger.LogError(ex, "OSS 图片搬运异常Source: {Source}, Target: {Target}", sourcePath, targetPath); _logger.LogError(ex, "OSS 图片搬运异常Source: {Source}, Target: {Target}", sourcePath, targetPath);
throw new BusinessException("图片搬运失败,请重试", 500); throw new BusinessException("图片搬运失败,请重试", ResultCode.GLOBAL_ERROR);
} }
} }

View File

@ -7,6 +7,8 @@ using CSRedis;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using QYZH.InteractiveMagazine.Common.Extensions; using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using System.Text.Json; using System.Text.Json;
using System.Web; using System.Web;
@ -193,6 +195,53 @@ namespace QYZH.InteractiveMagazine.Infrastructure.OSS
} }
} }
/// <summary>
/// 判断对象是否存在
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool DoesObjectExist(string key)
{
try
{
if (key.IsNull()) return false;
key = key.RemoveDomain();
key = HttpUtility.UrlDecode(key);
return _ossClient.DoesObjectExist(_ossOption.BucketName, key);
}
catch (OssException ex)
{
_logger.LogError(ex.Message + ex.StackTrace);
return false;
}
}
/// <summary>
/// 获取对象内容流
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public Stream? GetObjectStream(string key)
{
try
{
if (key.IsNull()) return null;
key = key.RemoveDomain();
key = HttpUtility.UrlDecode(key);
var ossObject = _ossClient.GetObject(_ossOption.BucketName, key);
return ossObject.Content;
}
catch (OssException ex)
{
_logger.LogError(ex.Message + ex.StackTrace);
return null;
}
}
/// <summary> /// <summary>
/// 删除多个 /// 删除多个
/// </summary> /// </summary>

View File

@ -1,3 +1,5 @@
using QYZH.InteractiveMagazine.Models.Dto;
namespace QYZH.InteractiveMagazine.Models.Common; namespace QYZH.InteractiveMagazine.Models.Common;
/// <summary> /// <summary>
@ -10,6 +12,11 @@ public class BusinessException : Exception
/// </summary> /// </summary>
public int Code { get; set; } public int Code { get; set; }
/// <summary>
/// 业务状态码
/// </summary>
public ResultCode ResultCode { get; set; } = ResultCode.FAIL;
/// <summary> /// <summary>
/// 无参构造函数 /// 无参构造函数
/// </summary> /// </summary>
@ -33,6 +40,18 @@ public class BusinessException : Exception
public BusinessException(string message, int code) : base(message) public BusinessException(string message, int code) : base(message)
{ {
Code = code; Code = code;
ResultCode = System.Enum.IsDefined(typeof(ResultCode), code) ? (ResultCode)code : ResultCode.FAIL;
}
/// <summary>
/// 构造函数(按业务状态码)
/// </summary>
/// <param name="message">异常消息</param>
/// <param name="resultCode">业务状态码</param>
public BusinessException(string message, ResultCode resultCode) : base(message)
{
ResultCode = resultCode;
Code = (int)resultCode;
} }
/// <summary> /// <summary>
@ -62,4 +81,15 @@ public class BusinessException : Exception
throw new BusinessException(message); throw new BusinessException(message);
} }
} }
/// <summary>
/// 条件抛出业务异常(带业务状态码)
/// </summary>
/// <param name="isTrue">是否触发</param>
/// <param name="message">异常消息</param>
/// <param name="resultCode">业务状态码</param>
public static void ThrowIf(bool isTrue, string message, ResultCode resultCode)
{
if (isTrue) throw new BusinessException(message, resultCode);
}
} }

View File

@ -195,5 +195,23 @@ public enum ResultCode
FORBIDDEN = 403, FORBIDDEN = 403,
[Description("Bad Request")] [Description("Bad Request")]
BAD_REQUEST = 400 BAD_REQUEST = 400,
[Description("资源不存在")]
NOT_FOUND = 404,
[Description("冲突/重复提交")]
CONFLICT = 409,
[Description("业务规则校验失败")]
UNPROCESSABLE_ENTITY = 422,
[Description("请求过于频繁")]
TOO_MANY_REQUESTS = 429,
[Description("第三方服务异常")]
BAD_GATEWAY = 502,
[Description("服务不可用")]
SERVICE_UNAVAILABLE = 503
} }

View File

@ -0,0 +1,161 @@
using SqlSugar;
namespace QYZH.InteractiveMagazine.Models.Entity
{
/// <summary>
/// Snapshot record for a user answer.
/// </summary>
[SugarTable("JournalPageTaskUserAnswerSnapshot")]
public class JournalPageTaskUserAnswerSnapshot : SqlSugarBaseEntity
{
/// <summary>
/// Source JournalPageTaskUserAnswer record Id.
/// </summary>
public long JournalPageTaskUserAnswerId { get; set; }
/// <summary>
/// Journal Id.
/// </summary>
public long JournalId { get; set; }
/// <summary>
/// Journal page Id.
/// </summary>
public long JournalPageId { get; set; }
/// <summary>
/// Journal page task Id.
/// </summary>
public long JournalPageTaskId { get; set; }
/// <summary>
/// Journal page task group Id.
/// </summary>
public long JournalPageTaskGroupId { get; set; }
/// <summary>
/// User Id.
/// </summary>
public long UserId { get; set; }
/// <summary>
/// Answer result.
/// </summary>
public string? Result { get; set; }
/// <summary>
/// Points awarded.
/// </summary>
public float Points { get; set; }
/// <summary>
/// Growth points awarded.
/// </summary>
public float GrowthPoints { get; set; }
/// <summary>
/// Task score.
/// </summary>
public float Score { get; set; }
/// <summary>
/// Question answer image URL.
/// </summary>
public string? QuestionAnswerUrl { get; set; }
/// <summary>
/// Answer image URL.
/// </summary>
public string? AnswerUrl { get; set; }
/// <summary>
/// Page answer image URL.
/// </summary>
public string? PageAnswerUrl { get; set; }
/// <summary>
/// Optimistic concurrency revision.
/// </summary>
public int Revision { get; set; }
/// <summary>
/// Answer status.
/// </summary>
public int AnswerStatus { get; set; }
/// <summary>
/// Answer start time.
/// </summary>
public DateTime AnswerStartTime { get; set; }
/// <summary>
/// Answer end time.
/// </summary>
public DateTime AnswerEndTime { get; set; }
/// <summary>
/// Answer duration in seconds.
/// </summary>
public int AnswerSeconds { get; set; }
/// <summary>
/// Image recognition result.
/// </summary>
public int ImageRecognition { get; set; }
/// <summary>
/// Journal page number.
/// </summary>
public int JournalPageNum { get; set; }
/// <summary>
/// Modify count.
/// </summary>
public int Modify { get; set; }
/// <summary>
/// Last tag Id.
/// </summary>
public long LastTag { get; set; }
/// <summary>
/// Dot page number.
/// </summary>
public int DotPageNum { get; set; }
/// <summary>
/// Page result image URL.
/// </summary>
public string? PageResultUrl { get; set; }
/// <summary>
/// Question type.
/// </summary>
public string? Type { get; set; }
/// <summary>
/// Dot page number text.
/// </summary>
public string? DotPageNo { get; set; }
/// <summary>
/// Page answer dot image URL.
/// </summary>
public string? PageAnswerDotUrl { get; set; }
/// <summary>
/// Break count.
/// </summary>
public int BreakCount { get; set; }
/// <summary>
/// Break time records.
/// </summary>
public string? BreakTimes { get; set; }
/// <summary>
/// Assignment status.
/// </summary>
public string? AssignmentStatus { get; set; }
}
}

View File

@ -25,31 +25,31 @@ public class AdminAuthService(BaseRepository<AdminUser> adminUserRepository, ICo
if (string.IsNullOrWhiteSpace(input.UserName)) if (string.IsNullOrWhiteSpace(input.UserName))
{ {
throw new BusinessException("用户名不能为空", 400); throw new BusinessException("用户名不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.Password)) if (string.IsNullOrWhiteSpace(input.Password))
{ {
throw new BusinessException("密码不能为空", 400); throw new BusinessException("密码不能为空", ResultCode.BAD_REQUEST);
} }
var adminUser = await adminUserRepository.GetFirstAsync(a => a.UserName == input.UserName); var adminUser = await adminUserRepository.GetFirstAsync(a => a.UserName == input.UserName);
if (adminUser == null) if (adminUser == null)
{ {
logger.LogWarning("管理员登录失败,用户名不存在: {UserName}", input.UserName); logger.LogWarning("管理员登录失败,用户名不存在: {UserName}", input.UserName);
throw new BusinessException("用户名或密码错误", 401); throw new BusinessException("用户名或密码错误", ResultCode.DENY);
} }
if (!BCrypt.Net.BCrypt.Verify(input.Password, adminUser.PasswordHash)) if (!BCrypt.Net.BCrypt.Verify(input.Password, adminUser.PasswordHash))
{ {
logger.LogWarning("管理员登录失败,密码错误: {UserName}", input.UserName); logger.LogWarning("管理员登录失败,密码错误: {UserName}", input.UserName);
throw new BusinessException("用户名或密码错误", 401); throw new BusinessException("用户名或密码错误", ResultCode.DENY);
} }
if (adminUser.Status != 1) if (adminUser.Status != 1)
{ {
logger.LogWarning("管理员登录失败,账号已禁用: {UserName}", input.UserName); logger.LogWarning("管理员登录失败,账号已禁用: {UserName}", input.UserName);
throw new BusinessException("账号已被禁用,请联系系统管理员", 403); throw new BusinessException("账号已被禁用,请联系系统管理员", ResultCode.FORBIDDEN);
} }
var jwtSettings = GetJwtSettings(); var jwtSettings = GetJwtSettings();
@ -86,7 +86,7 @@ public class AdminAuthService(BaseRepository<AdminUser> adminUserRepository, ICo
if (adminUser == null) if (adminUser == null)
{ {
logger.LogWarning("未找到管理员ID: {UserId}", userId); logger.LogWarning("未找到管理员ID: {UserId}", userId);
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
} }
return new AdminUserInfoOutput return new AdminUserInfoOutput
@ -104,25 +104,25 @@ public class AdminAuthService(BaseRepository<AdminUser> adminUserRepository, ICo
if (string.IsNullOrWhiteSpace(oldPassword)) if (string.IsNullOrWhiteSpace(oldPassword))
{ {
throw new BusinessException("原密码不能为空", 400); throw new BusinessException("原密码不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(newPassword)) if (string.IsNullOrWhiteSpace(newPassword))
{ {
throw new BusinessException("新密码不能为空", 400); throw new BusinessException("新密码不能为空", ResultCode.BAD_REQUEST);
} }
var adminUser = await adminUserRepository.GetByIdAsync(userId); var adminUser = await adminUserRepository.GetByIdAsync(userId);
if (adminUser == null) if (adminUser == null)
{ {
logger.LogWarning("未找到管理员ID: {UserId}", userId); logger.LogWarning("未找到管理员ID: {UserId}", userId);
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
} }
if (!BCrypt.Net.BCrypt.Verify(oldPassword, adminUser.PasswordHash)) if (!BCrypt.Net.BCrypt.Verify(oldPassword, adminUser.PasswordHash))
{ {
logger.LogWarning("管理员修改密码失败原密码错误ID: {UserId}", userId); logger.LogWarning("管理员修改密码失败原密码错误ID: {UserId}", userId);
throw new BusinessException("原密码错误", 400); throw new BusinessException("原密码错误", ResultCode.DENY);
} }
adminUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(newPassword); adminUser.PasswordHash = BCrypt.Net.BCrypt.HashPassword(newPassword);
@ -130,7 +130,7 @@ public class AdminAuthService(BaseRepository<AdminUser> adminUserRepository, ICo
var result = await adminUserRepository.UpdateAsync(adminUser); var result = await adminUserRepository.UpdateAsync(adminUser);
if (!result) if (!result)
{ {
throw new BusinessException("修改密码失败", 500); throw new BusinessException("修改密码失败", ResultCode.GLOBAL_ERROR);
} }
await RedisHelper.DelAsync($"{TokenKeyPrefix}:{userId}"); await RedisHelper.DelAsync($"{TokenKeyPrefix}:{userId}");
@ -151,7 +151,7 @@ public class AdminAuthService(BaseRepository<AdminUser> adminUserRepository, ICo
if (string.IsNullOrWhiteSpace(jwtSettings.SecretKey)) if (string.IsNullOrWhiteSpace(jwtSettings.SecretKey))
{ {
throw new BusinessException("JWT 配置不完整", 500); throw new BusinessException("JWT 配置不完整", ResultCode.GLOBAL_ERROR);
} }
return jwtSettings; return jwtSettings;

View File

@ -27,12 +27,12 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (string.IsNullOrWhiteSpace(input.UserName)) if (string.IsNullOrWhiteSpace(input.UserName))
{ {
throw new BusinessException("用户名不能为空", 400); throw new BusinessException("用户名不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.Password)) if (string.IsNullOrWhiteSpace(input.Password))
{ {
throw new BusinessException("密码不能为空", 400); throw new BusinessException("密码不能为空", ResultCode.BAD_REQUEST);
} }
// 检查用户名是否已存在 // 检查用户名是否已存在
@ -40,7 +40,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (existingUser != null) if (existingUser != null)
{ {
logger.LogWarning("创建管理员失败,用户名已存在: {UserName}", input.UserName); logger.LogWarning("创建管理员失败,用户名已存在: {UserName}", input.UserName);
throw new BusinessException("用户名已存在", 400); throw new BusinessException("用户名已存在", ResultCode.CONFLICT);
} }
var adminUser = new AdminUser var adminUser = new AdminUser
@ -60,7 +60,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (!result) if (!result)
{ {
logger.LogError("管理员创建失败,用户名: {UserName}", input.UserName); logger.LogError("管理员创建失败,用户名: {UserName}", input.UserName);
throw new BusinessException("创建管理员失败", 500); throw new BusinessException("创建管理员失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("管理员创建成功,用户名: {UserName}, ID: {Id}", input.UserName, adminUser.Id); logger.LogInformation("管理员创建成功,用户名: {UserName}, ID: {Id}", input.UserName, adminUser.Id);
@ -79,7 +79,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (adminUser == null) if (adminUser == null)
{ {
logger.LogWarning("未找到要更新的管理员ID: {Id}", id); logger.LogWarning("未找到要更新的管理员ID: {Id}", id);
throw new BusinessException("管理员不存在", 404); throw new BusinessException("管理员不存在", ResultCode.NOT_FOUND);
} }
// 如果用户名有变更,检查是否与其他用户重复 // 如果用户名有变更,检查是否与其他用户重复
@ -89,7 +89,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (existingUser != null && existingUser.Id != id) if (existingUser != null && existingUser.Id != id)
{ {
logger.LogWarning("更新管理员失败,用户名已存在: {UserName}", input.UserName); logger.LogWarning("更新管理员失败,用户名已存在: {UserName}", input.UserName);
throw new BusinessException("用户名已存在", 400); throw new BusinessException("用户名已存在", ResultCode.CONFLICT);
} }
adminUser.UserName = input.UserName.Trim(); adminUser.UserName = input.UserName.Trim();
@ -111,7 +111,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (!result) if (!result)
{ {
logger.LogError("管理员更新失败ID: {Id}", id); logger.LogError("管理员更新失败ID: {Id}", id);
throw new BusinessException("更新管理员失败", 500); throw new BusinessException("更新管理员失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("管理员更新成功ID: {Id}", id); logger.LogInformation("管理员更新成功ID: {Id}", id);
@ -130,14 +130,14 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (adminUser == null) if (adminUser == null)
{ {
logger.LogWarning("未找到要删除的管理员ID: {Id}", id); logger.LogWarning("未找到要删除的管理员ID: {Id}", id);
throw new BusinessException("管理员不存在", 404); throw new BusinessException("管理员不存在", ResultCode.NOT_FOUND);
} }
var result = await adminUserRepository.DeleteByIdAsync(id); var result = await adminUserRepository.DeleteByIdAsync(id);
if (!result) if (!result)
{ {
logger.LogError("管理员删除失败ID: {Id}", id); logger.LogError("管理员删除失败ID: {Id}", id);
throw new BusinessException("删除管理员失败", 500); throw new BusinessException("删除管理员失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("管理员删除成功ID: {Id}", id); logger.LogInformation("管理员删除成功ID: {Id}", id);
@ -154,7 +154,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (adminUser == null) if (adminUser == null)
{ {
logger.LogWarning("未找到管理员ID: {Id}", id); logger.LogWarning("未找到管理员ID: {Id}", id);
throw new BusinessException("管理员不存在", 404); throw new BusinessException("管理员不存在", ResultCode.NOT_FOUND);
} }
return new AdminUserOutput return new AdminUserOutput
{ {
@ -178,12 +178,12 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (input.PageIndex <= 0) if (input.PageIndex <= 0)
{ {
throw new BusinessException("页码必须大于0", 400); throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
} }
if (input.PageSize <= 0 || input.PageSize > 100) if (input.PageSize <= 0 || input.PageSize > 100)
{ {
throw new BusinessException("每页条数必须在1-100之间", 400); throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
} }
RefAsync<int> totalNumber = 0; RefAsync<int> totalNumber = 0;
var pageResult = await adminUserRepository.Queryable() var pageResult = await adminUserRepository.Queryable()
@ -215,7 +215,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (adminUser == null) if (adminUser == null)
{ {
logger.LogWarning("未找到要更新状态的管理员ID: {Id}", id); logger.LogWarning("未找到要更新状态的管理员ID: {Id}", id);
throw new BusinessException("管理员不存在", 404); throw new BusinessException("管理员不存在", ResultCode.NOT_FOUND);
} }
adminUser.Status = adminUser.Status==(int)DefaultStatusEnum.Active?(int)DefaultStatusEnum.Inactive:(int)DefaultStatusEnum.Active; adminUser.Status = adminUser.Status==(int)DefaultStatusEnum.Active?(int)DefaultStatusEnum.Inactive:(int)DefaultStatusEnum.Active;
@ -226,7 +226,7 @@ public class AdminUserService(BaseRepository<AdminUser> adminUserRepository, ILo
if (!result) if (!result)
{ {
logger.LogError("管理员状态更新失败ID: {Id}", id); logger.LogError("管理员状态更新失败ID: {Id}", id);
throw new BusinessException("更新管理员状态失败", 500); throw new BusinessException("更新管理员状态失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("管理员状态更新成功ID: {Id}", id); logger.LogInformation("管理员状态更新成功ID: {Id}", id);

View File

@ -25,24 +25,24 @@ public class AiBasePromptService(
if (string.IsNullOrWhiteSpace(input.PromptKey)) if (string.IsNullOrWhiteSpace(input.PromptKey))
{ {
throw new BusinessException("配置标识不能为空", 400); throw new BusinessException("配置标识不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.PromptName)) if (string.IsNullOrWhiteSpace(input.PromptName))
{ {
throw new BusinessException("配置名称不能为空", 400); throw new BusinessException("配置名称不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.PromptTemplate)) if (string.IsNullOrWhiteSpace(input.PromptTemplate))
{ {
throw new BusinessException("Prompt模板内容不能为空", 400); throw new BusinessException("Prompt模板内容不能为空", ResultCode.BAD_REQUEST);
} }
// 检查PromptKey是否已存在 // 检查PromptKey是否已存在
var exists = await promptRepository.IsAnyAsync(p => p.PromptKey == input.PromptKey.Trim()); var exists = await promptRepository.IsAnyAsync(p => p.PromptKey == input.PromptKey.Trim());
if (exists) if (exists)
{ {
throw new BusinessException($"配置标识 '{input.PromptKey.Trim()}' 已存在", 400); throw new BusinessException($"配置标识 '{input.PromptKey.Trim()}' 已存在", ResultCode.BAD_REQUEST);
} }
var entity = new AiBasePrompt var entity = new AiBasePrompt
@ -64,7 +64,7 @@ public class AiBasePromptService(
if (!result) if (!result)
{ {
logger.LogError("Prompt配置创建失败PromptKey: {PromptKey}", input.PromptKey); logger.LogError("Prompt配置创建失败PromptKey: {PromptKey}", input.PromptKey);
throw new BusinessException("创建Prompt配置失败", 500); throw new BusinessException("创建Prompt配置失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("Prompt配置创建成功PromptKey: {PromptKey}, ID: {Id}", input.PromptKey, entity.Id); logger.LogInformation("Prompt配置创建成功PromptKey: {PromptKey}, ID: {Id}", input.PromptKey, entity.Id);
@ -97,29 +97,29 @@ public class AiBasePromptService(
if (entity == null) if (entity == null)
{ {
logger.LogWarning("未找到要更新的Prompt配置ID: {Id}", id); logger.LogWarning("未找到要更新的Prompt配置ID: {Id}", id);
throw new BusinessException("Prompt配置不存在", 404); throw new BusinessException("Prompt配置不存在", ResultCode.NOT_FOUND);
} }
if (string.IsNullOrWhiteSpace(input.PromptKey)) if (string.IsNullOrWhiteSpace(input.PromptKey))
{ {
throw new BusinessException("配置标识不能为空", 400); throw new BusinessException("配置标识不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.PromptName)) if (string.IsNullOrWhiteSpace(input.PromptName))
{ {
throw new BusinessException("配置名称不能为空", 400); throw new BusinessException("配置名称不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.PromptTemplate)) if (string.IsNullOrWhiteSpace(input.PromptTemplate))
{ {
throw new BusinessException("Prompt模板内容不能为空", 400); throw new BusinessException("Prompt模板内容不能为空", ResultCode.BAD_REQUEST);
} }
// 检查PromptKey是否被其他记录占用 // 检查PromptKey是否被其他记录占用
var exists = await promptRepository.IsAnyAsync(p => p.PromptKey == input.PromptKey.Trim() && p.Id != id); var exists = await promptRepository.IsAnyAsync(p => p.PromptKey == input.PromptKey.Trim() && p.Id != id);
if (exists) if (exists)
{ {
throw new BusinessException($"配置标识 '{input.PromptKey.Trim()}' 已被其他配置使用", 400); throw new BusinessException($"配置标识 '{input.PromptKey.Trim()}' 已被其他配置使用", ResultCode.BAD_REQUEST);
} }
entity.PromptKey = input.PromptKey.Trim(); entity.PromptKey = input.PromptKey.Trim();
@ -135,7 +135,7 @@ public class AiBasePromptService(
if (!result) if (!result)
{ {
logger.LogError("Prompt配置更新失败ID: {Id}", id); logger.LogError("Prompt配置更新失败ID: {Id}", id);
throw new BusinessException("更新Prompt配置失败", 500); throw new BusinessException("更新Prompt配置失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("Prompt配置更新成功ID: {Id}", id); logger.LogInformation("Prompt配置更新成功ID: {Id}", id);
@ -168,14 +168,14 @@ public class AiBasePromptService(
if (entity == null) if (entity == null)
{ {
logger.LogWarning("未找到要删除的Prompt配置ID: {Id}", id); logger.LogWarning("未找到要删除的Prompt配置ID: {Id}", id);
throw new BusinessException("Prompt配置不存在", 404); throw new BusinessException("Prompt配置不存在", ResultCode.NOT_FOUND);
} }
var result = await promptRepository.DeleteByIdAsync(id); var result = await promptRepository.DeleteByIdAsync(id);
if (!result) if (!result)
{ {
logger.LogError("Prompt配置删除失败ID: {Id}", id); logger.LogError("Prompt配置删除失败ID: {Id}", id);
throw new BusinessException("删除Prompt配置失败", 500); throw new BusinessException("删除Prompt配置失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("Prompt配置删除成功ID: {Id}", id); logger.LogInformation("Prompt配置删除成功ID: {Id}", id);
@ -192,7 +192,7 @@ public class AiBasePromptService(
if (entity == null) if (entity == null)
{ {
logger.LogWarning("未找到Prompt配置ID: {Id}", id); logger.LogWarning("未找到Prompt配置ID: {Id}", id);
throw new BusinessException("Prompt配置不存在", 404); throw new BusinessException("Prompt配置不存在", ResultCode.NOT_FOUND);
} }
return new AiBasePromptOutput return new AiBasePromptOutput
@ -221,12 +221,12 @@ public class AiBasePromptService(
if (input.PageIndex <= 0) if (input.PageIndex <= 0)
{ {
throw new BusinessException("页码必须大于0", 400); throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
} }
if (input.PageSize <= 0 || input.PageSize > 100) if (input.PageSize <= 0 || input.PageSize > 100)
{ {
throw new BusinessException("每页条数必须在1-100之间", 400); throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
} }
RefAsync<int> totalNumber = 0; RefAsync<int> totalNumber = 0;
@ -296,7 +296,7 @@ public class AiBasePromptService(
if (entity == null) if (entity == null)
{ {
logger.LogWarning("未找到要切换状态的Prompt配置ID: {Id}", id); logger.LogWarning("未找到要切换状态的Prompt配置ID: {Id}", id);
throw new BusinessException("Prompt配置不存在", 404); throw new BusinessException("Prompt配置不存在", ResultCode.NOT_FOUND);
} }
entity.Status = entity.Status == 1 ? 0 : 1; entity.Status = entity.Status == 1 ? 0 : 1;
@ -307,7 +307,7 @@ public class AiBasePromptService(
if (!result) if (!result)
{ {
logger.LogError("Prompt配置状态切换失败ID: {Id}", id); logger.LogError("Prompt配置状态切换失败ID: {Id}", id);
throw new BusinessException("切换Prompt状态失败", 500); throw new BusinessException("切换Prompt状态失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("Prompt配置状态切换成功ID: {Id}, Status: {Status}", id, entity.Status); logger.LogInformation("Prompt配置状态切换成功ID: {Id}, Status: {Status}", id, entity.Status);

View File

@ -83,7 +83,7 @@ public class AiChatService(
{ {
if (string.IsNullOrWhiteSpace(input.Message)) if (string.IsNullOrWhiteSpace(input.Message))
{ {
throw new BusinessException("消息内容不能为空", 400); throw new BusinessException("消息内容不能为空", ResultCode.BAD_REQUEST);
} }
var apiKey = configuration["AiChat:ApiKey"]; var apiKey = configuration["AiChat:ApiKey"];
@ -95,7 +95,7 @@ public class AiChatService(
if (string.IsNullOrWhiteSpace(apiKey) || string.IsNullOrWhiteSpace(baseUrl) || string.IsNullOrWhiteSpace(model)) if (string.IsNullOrWhiteSpace(apiKey) || string.IsNullOrWhiteSpace(baseUrl) || string.IsNullOrWhiteSpace(model))
{ {
throw new BusinessException("AI聊天服务配置不完整请检查 AiChat 配置节", 500); throw new BusinessException("AI聊天服务配置不完整请检查 AiChat 配置节", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("开始调用AI聊天服务流式消息长度{Length}", input.Message.Length); logger.LogInformation("开始调用AI聊天服务流式消息长度{Length}", input.Message.Length);
@ -132,7 +132,7 @@ public class AiChatService(
{ {
var errorContent = await response.Content.ReadAsStringAsync(cancellationToken); var errorContent = await response.Content.ReadAsStringAsync(cancellationToken);
logger.LogError("AI聊天服务调用失败状态码{StatusCode},响应:{Response}", response.StatusCode, errorContent); logger.LogError("AI聊天服务调用失败状态码{StatusCode},响应:{Response}", response.StatusCode, errorContent);
throw new BusinessException($"AI服务调用失败{response.StatusCode}", 500); throw new BusinessException($"AI服务调用失败{response.StatusCode}", ResultCode.GLOBAL_ERROR);
} }
// 流式读取响应体 // 流式读取响应体

View File

@ -27,17 +27,17 @@ public class CheckInConfigService(
if (input.DayNumber <= 0) if (input.DayNumber <= 0)
{ {
throw new BusinessException("连续签到天数必须大于0", 400); throw new BusinessException("连续签到天数必须大于0", ResultCode.BAD_REQUEST);
} }
if (input.RewardPoints < 0) if (input.RewardPoints < 0)
{ {
throw new BusinessException("奖励积分不能为负数", 400); throw new BusinessException("奖励积分不能为负数", ResultCode.BAD_REQUEST);
} }
if (input.BonusPoints < 0) if (input.BonusPoints < 0)
{ {
throw new BusinessException("额外奖励积分不能为负数", 400); throw new BusinessException("额外奖励积分不能为负数", ResultCode.BAD_REQUEST);
} }
// 检查同类型下是否已存在相同天数配置 // 检查同类型下是否已存在相同天数配置
@ -47,7 +47,7 @@ public class CheckInConfigService(
if (exists) if (exists)
{ {
throw new BusinessException($"该类型下已存在连续{input.DayNumber}天的配置", 400); throw new BusinessException($"该类型下已存在连续{input.DayNumber}天的配置", ResultCode.BAD_REQUEST);
} }
var config = new CheckInConfig var config = new CheckInConfig
@ -67,7 +67,7 @@ public class CheckInConfigService(
var result = await checkInConfigRepository.InsertAsync(config); var result = await checkInConfigRepository.InsertAsync(config);
if (!result) if (!result)
{ {
throw new BusinessException("创建签到配置失败", 500); throw new BusinessException("创建签到配置失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("签到配置创建成功ID: {Id}", config.Id); logger.LogInformation("签到配置创建成功ID: {Id}", config.Id);
@ -85,22 +85,22 @@ public class CheckInConfigService(
if (config == null) if (config == null)
{ {
logger.LogWarning("未找到要更新的签到配置ID: {Id}", id); logger.LogWarning("未找到要更新的签到配置ID: {Id}", id);
throw new BusinessException("签到配置不存在", 404); throw new BusinessException("签到配置不存在", ResultCode.NOT_FOUND);
} }
if (input.DayNumber <= 0) if (input.DayNumber <= 0)
{ {
throw new BusinessException("连续签到天数必须大于0", 400); throw new BusinessException("连续签到天数必须大于0", ResultCode.BAD_REQUEST);
} }
if (input.RewardPoints < 0) if (input.RewardPoints < 0)
{ {
throw new BusinessException("奖励积分不能为负数", 400); throw new BusinessException("奖励积分不能为负数", ResultCode.BAD_REQUEST);
} }
if (input.BonusPoints < 0) if (input.BonusPoints < 0)
{ {
throw new BusinessException("额外奖励积分不能为负数", 400); throw new BusinessException("额外奖励积分不能为负数", ResultCode.BAD_REQUEST);
} }
// 检查同类型下是否已存在相同天数配置(排除自身) // 检查同类型下是否已存在相同天数配置(排除自身)
@ -110,7 +110,7 @@ public class CheckInConfigService(
if (exists) if (exists)
{ {
throw new BusinessException($"该类型下已存在连续{input.DayNumber}天的配置", 400); throw new BusinessException($"该类型下已存在连续{input.DayNumber}天的配置", ResultCode.BAD_REQUEST);
} }
config.DayNumber = input.DayNumber; config.DayNumber = input.DayNumber;
@ -123,7 +123,7 @@ public class CheckInConfigService(
var updateResult = await checkInConfigRepository.UpdateAsync(config); var updateResult = await checkInConfigRepository.UpdateAsync(config);
if (!updateResult) if (!updateResult)
{ {
throw new BusinessException("更新签到配置失败", 500); throw new BusinessException("更新签到配置失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("签到配置更新成功ID: {Id}", id); logger.LogInformation("签到配置更新成功ID: {Id}", id);
@ -141,7 +141,7 @@ public class CheckInConfigService(
if (config == null) if (config == null)
{ {
logger.LogWarning("未找到要删除的签到配置ID: {Id}", id); logger.LogWarning("未找到要删除的签到配置ID: {Id}", id);
throw new BusinessException("签到配置不存在", 404); throw new BusinessException("签到配置不存在", ResultCode.NOT_FOUND);
} }
var result = await checkInConfigRepository.Context.Updateable<CheckInConfig>() var result = await checkInConfigRepository.Context.Updateable<CheckInConfig>()
@ -156,7 +156,7 @@ public class CheckInConfigService(
if (result <= 0) if (result <= 0)
{ {
throw new BusinessException("删除签到配置失败", 500); throw new BusinessException("删除签到配置失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("签到配置删除成功ID: {Id}", id); logger.LogInformation("签到配置删除成功ID: {Id}", id);
@ -170,7 +170,7 @@ public class CheckInConfigService(
var config = await checkInConfigRepository.GetByIdAsync(id); var config = await checkInConfigRepository.GetByIdAsync(id);
if (config == null) if (config == null)
{ {
throw new BusinessException("签到配置不存在", 404); throw new BusinessException("签到配置不存在", ResultCode.NOT_FOUND);
} }
return MapToOutput(config); return MapToOutput(config);
@ -185,12 +185,12 @@ public class CheckInConfigService(
if (input.PageIndex <= 0) if (input.PageIndex <= 0)
{ {
throw new BusinessException("页码必须大于0", 400); throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
} }
if (input.PageSize <= 0 || input.PageSize > 100) if (input.PageSize <= 0 || input.PageSize > 100)
{ {
throw new BusinessException("每页条数必须在1-100之间", 400); throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
} }
RefAsync<int> totalNumber = 0; RefAsync<int> totalNumber = 0;
@ -217,7 +217,7 @@ public class CheckInConfigService(
if (config == null) if (config == null)
{ {
logger.LogWarning("未找到要更新状态的签到配置ID: {Id}", id); logger.LogWarning("未找到要更新状态的签到配置ID: {Id}", id);
throw new BusinessException("签到配置不存在", 404); throw new BusinessException("签到配置不存在", ResultCode.NOT_FOUND);
} }
config.Status = config.Status == (int)DefaultStatusEnum.Active config.Status = config.Status == (int)DefaultStatusEnum.Active
@ -230,7 +230,7 @@ public class CheckInConfigService(
if (!result) if (!result)
{ {
logger.LogError("签到配置状态更新失败ID: {Id}", id); logger.LogError("签到配置状态更新失败ID: {Id}", id);
throw new BusinessException("更新签到配置状态失败", 500); throw new BusinessException("更新签到配置状态失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("签到配置状态更新成功ID: {Id}, Status: {Status}", id, config.Status); logger.LogInformation("签到配置状态更新成功ID: {Id}, Status: {Status}", id, config.Status);

View File

@ -2,6 +2,7 @@ using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.Common.Extensions; using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.IService; using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common; using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.CheckIn; using QYZH.InteractiveMagazine.Models.Dto.CheckIn;
using QYZH.InteractiveMagazine.Models.Dto.Compensation; using QYZH.InteractiveMagazine.Models.Dto.Compensation;
using QYZH.InteractiveMagazine.Models.Dto.Pet; using QYZH.InteractiveMagazine.Models.Dto.Pet;
@ -44,7 +45,7 @@ public class CheckInService(
if (alreadyCheckedIn) if (alreadyCheckedIn)
{ {
throw new BusinessException("今日已签到,请明天再来", 400); throw new BusinessException("今日已签到,请明天再来", ResultCode.BAD_REQUEST);
} }
// 2. 计算连续签到天数 // 2. 计算连续签到天数
@ -60,7 +61,7 @@ public class CheckInService(
if (user == null) if (user == null)
{ {
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
} }
// 5. 查询用户宠物(如果有) // 5. 查询用户宠物(如果有)
@ -226,7 +227,7 @@ public class CheckInService(
targetDate = targetDate.Date; targetDate = targetDate.Date;
if (targetDate >= DateTime.Now.Date) if (targetDate >= DateTime.Now.Date)
throw new BusinessException("只能补签过去的日期", 400); throw new BusinessException("只能补签过去的日期", ResultCode.BAD_REQUEST);
// 检查目标日期是否已有签到记录 // 检查目标日期是否已有签到记录
var alreadyCheckedIn = await checkInRecordRepository.Context.Queryable<CheckInRecord>() var alreadyCheckedIn = await checkInRecordRepository.Context.Queryable<CheckInRecord>()
@ -235,7 +236,7 @@ public class CheckInService(
.AnyAsync(); .AnyAsync();
if (alreadyCheckedIn) if (alreadyCheckedIn)
throw new BusinessException($"{targetDate:yyyy-MM-dd} 已签到,无需补签", 400); throw new BusinessException($"{targetDate:yyyy-MM-dd} 已签到,无需补签", ResultCode.BAD_REQUEST);
// 检查用户背包中是否有补签卡 // 检查用户背包中是否有补签卡
var makeUpCard = await checkInRecordRepository.Context.Queryable<UserBag>() var makeUpCard = await checkInRecordRepository.Context.Queryable<UserBag>()
@ -248,7 +249,7 @@ public class CheckInService(
.FirstAsync(); .FirstAsync();
if (makeUpCard == null) if (makeUpCard == null)
throw new BusinessException("补签卡不足,无法补签", 400); throw new BusinessException("补签卡不足,无法补签", ResultCode.BAD_REQUEST);
// 查询用户信息 // 查询用户信息
var user = await checkInRecordRepository.Context.Queryable<Users>() var user = await checkInRecordRepository.Context.Queryable<Users>()
@ -256,7 +257,7 @@ public class CheckInService(
.FirstAsync(); .FirstAsync();
if (user == null) if (user == null)
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
// 查询宠物 // 查询宠物
var pet = await checkInRecordRepository.Context.Queryable<UserPet>() var pet = await checkInRecordRepository.Context.Queryable<UserPet>()

View File

@ -24,8 +24,8 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
{ {
logger.LogInformation("正在查询社区消息列表,页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize); logger.LogInformation("正在查询社区消息列表,页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize);
if (input.PageIndex <= 0) throw new BusinessException("页码必须大于0", 400); if (input.PageIndex <= 0) throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
if (input.PageSize <= 0 || input.PageSize > 100) throw new BusinessException("每页条数必须在1-100之间", 400); if (input.PageSize <= 0 || input.PageSize > 100) throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
RefAsync<int> totalNumber = 0; RefAsync<int> totalNumber = 0;
var pageResult = await messageRepository.Queryable() var pageResult = await messageRepository.Queryable()
@ -75,7 +75,7 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (message == null) if (message == null)
{ {
logger.LogWarning("未找到社区消息ID: {Id}", id); logger.LogWarning("未找到社区消息ID: {Id}", id);
throw new BusinessException("消息不存在", 404); throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
} }
return new AdminMessageDetailOutput return new AdminMessageDetailOutput
@ -112,14 +112,14 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (message == null) if (message == null)
{ {
logger.LogWarning("未找到要删除的社区消息ID: {Id}", id); logger.LogWarning("未找到要删除的社区消息ID: {Id}", id);
throw new BusinessException("消息不存在", 404); throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
} }
var result = await messageRepository.DeleteByIdAsync(id); var result = await messageRepository.DeleteByIdAsync(id);
if (!result) if (!result)
{ {
logger.LogError("社区消息删除失败ID: {Id}", id); logger.LogError("社区消息删除失败ID: {Id}", id);
throw new BusinessException("删除消息失败", 500); throw new BusinessException("删除消息失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("社区消息删除成功ID: {Id}", id); logger.LogInformation("社区消息删除成功ID: {Id}", id);
@ -134,14 +134,14 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (status != 1 && status != 2) if (status != 1 && status != 2)
{ {
throw new BusinessException("状态值无效只能为1(解冻/通过)或2(冻结)", 400); throw new BusinessException("状态值无效只能为1(解冻/通过)或2(冻结)", ResultCode.BAD_REQUEST);
} }
var message = await messageRepository.GetByIdAsync(id); var message = await messageRepository.GetByIdAsync(id);
if (message == null) if (message == null)
{ {
logger.LogWarning("未找到社区消息ID: {Id}", id); logger.LogWarning("未找到社区消息ID: {Id}", id);
throw new BusinessException("消息不存在", 404); throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
} }
message.Status = status; message.Status = status;
@ -152,7 +152,7 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (!result) if (!result)
{ {
logger.LogError("社区消息冻结状态更新失败ID: {Id}", id); logger.LogError("社区消息冻结状态更新失败ID: {Id}", id);
throw new BusinessException("更新冻结状态失败", 500); throw new BusinessException("更新冻结状态失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("社区消息冻结状态更新成功ID: {Id}, Status: {Status}", id, status); logger.LogInformation("社区消息冻结状态更新成功ID: {Id}, Status: {Status}", id, status);
@ -167,14 +167,14 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (isFeatured != 0 && isFeatured != 1) if (isFeatured != 0 && isFeatured != 1)
{ {
throw new BusinessException("精选值无效只能为0(取消)或1(精选)", 400); throw new BusinessException("精选值无效只能为0(取消)或1(精选)", ResultCode.BAD_REQUEST);
} }
var message = await messageRepository.GetByIdAsync(id); var message = await messageRepository.GetByIdAsync(id);
if (message == null) if (message == null)
{ {
logger.LogWarning("未找到社区消息ID: {Id}", id); logger.LogWarning("未找到社区消息ID: {Id}", id);
throw new BusinessException("消息不存在", 404); throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
} }
message.IsFeatured = isFeatured; message.IsFeatured = isFeatured;
@ -185,7 +185,7 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (!result) if (!result)
{ {
logger.LogError("社区消息精选设置失败ID: {Id}", id); logger.LogError("社区消息精选设置失败ID: {Id}", id);
throw new BusinessException("设置精选失败", 500); throw new BusinessException("设置精选失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("社区消息精选设置成功ID: {Id}, IsFeatured: {IsFeatured}", id, isFeatured); logger.LogInformation("社区消息精选设置成功ID: {Id}, IsFeatured: {IsFeatured}", id, isFeatured);
@ -202,7 +202,7 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (message == null) if (message == null)
{ {
logger.LogWarning("未找到社区消息ID: {Id}", id); logger.LogWarning("未找到社区消息ID: {Id}", id);
throw new BusinessException("消息不存在", 404); throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
} }
message.SortOrder = sortOrder; message.SortOrder = sortOrder;
@ -213,7 +213,7 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (!result) if (!result)
{ {
logger.LogError("社区消息排序权重设置失败ID: {Id}", id); logger.LogError("社区消息排序权重设置失败ID: {Id}", id);
throw new BusinessException("设置排序权重失败", 500); throw new BusinessException("设置排序权重失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("社区消息排序权重设置成功ID: {Id}, SortOrder: {SortOrder}", id, sortOrder); logger.LogInformation("社区消息排序权重设置成功ID: {Id}, SortOrder: {SortOrder}", id, sortOrder);
@ -228,7 +228,7 @@ public class CommunityMessageService(BaseRepository<CommunityMessage> messageRep
if (ids == null || ids.Count == 0) if (ids == null || ids.Count == 0)
{ {
throw new BusinessException("消息ID列表不能为空", 400); throw new BusinessException("消息ID列表不能为空", ResultCode.BAD_REQUEST);
} }
var result = await Context.Updateable<CommunityMessage>() var result = await Context.Updateable<CommunityMessage>()

View File

@ -73,10 +73,10 @@ public class CompensationManageService(
var task = await compensationTaskRepository.GetByIdAsync(taskId); var task = await compensationTaskRepository.GetByIdAsync(taskId);
if (task == null) if (task == null)
throw new BusinessException("补偿任务不存在", 404); throw new BusinessException("补偿任务不存在", ResultCode.NOT_FOUND);
if (task.Status != (int)CompensationTaskStatusEnum.Failed && task.Status != (int)CompensationTaskStatusEnum.Cancelled) if (task.Status != (int)CompensationTaskStatusEnum.Failed && task.Status != (int)CompensationTaskStatusEnum.Cancelled)
throw new BusinessException($"只有失败或已取消的任务才能重试,当前状态: {task.Status}", 400); throw new BusinessException($"只有失败或已取消的任务才能重试,当前状态: {task.Status}", ResultCode.BAD_REQUEST);
// 重置任务状态为 Pending清零重试次数设置立即执行 // 重置任务状态为 Pending清零重试次数设置立即执行
await compensationTaskRepository.Context.Updateable<CompensationTask>() await compensationTaskRepository.Context.Updateable<CompensationTask>()
@ -116,10 +116,10 @@ public class CompensationManageService(
var task = await compensationTaskRepository.GetByIdAsync(taskId); var task = await compensationTaskRepository.GetByIdAsync(taskId);
if (task == null) if (task == null)
throw new BusinessException("补偿任务不存在", 404); throw new BusinessException("补偿任务不存在", ResultCode.NOT_FOUND);
if (task.Status == (int)CompensationTaskStatusEnum.Success) if (task.Status == (int)CompensationTaskStatusEnum.Success)
throw new BusinessException("该任务已经是成功状态,无需标记", 400); throw new BusinessException("该任务已经是成功状态,无需标记", ResultCode.BAD_REQUEST);
// 标记为 Success // 标记为 Success
await compensationTaskRepository.Context.Updateable<CompensationTask>() await compensationTaskRepository.Context.Updateable<CompensationTask>()
@ -184,7 +184,7 @@ public class CompensationManageService(
.FirstAsync(); .FirstAsync();
if (result == null) if (result == null)
throw new BusinessException("补偿任务不存在", 404); throw new BusinessException("补偿任务不存在", ResultCode.NOT_FOUND);
return result; return result;
} }

View File

@ -5,6 +5,7 @@ using QYZH.InteractiveMagazine.Infrastructure.OSS;
using QYZH.InteractiveMagazine.IService; using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Base; using QYZH.InteractiveMagazine.Models.Base;
using QYZH.InteractiveMagazine.Models.Common; using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Journal; using QYZH.InteractiveMagazine.Models.Dto.Journal;
using QYZH.InteractiveMagazine.Models.Entity; using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum; using QYZH.InteractiveMagazine.Models.Enum;
@ -35,10 +36,10 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
public async Task<long> ImportAsync(JournalImportDto input) public async Task<long> ImportAsync(JournalImportDto input)
{ {
var Journals = await Queryable<Journal>().Where(w => w.Id == input.JournalId).FirstAsync(); 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); 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() var JournalCatalog = new JournalCatalog()
@ -106,7 +107,7 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
public async Task<List<JournalCatalogTreeListDto>> GetJournalCatalogListAsync(long JournalId) public async Task<List<JournalCatalogTreeListDto>> GetJournalCatalogListAsync(long JournalId)
{ {
var Journal = await Queryable<Journal>().Where(w => w.Id == JournalId).FirstAsync(); 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() var pageNumList = await _JournalPageRepository.Queryable()
.InnerJoin<JournalCatalog>((a, b) => a.JournalCatalogId == b.Id) .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) public async Task<List<IcrJournalCatalogTreeDto>> GetJournalCataloTreeAsync(long JournalId)
{ {
var Journal = await Queryable<Journal>().Where(w => w.Id == JournalId).FirstAsync(); 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() 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) public async Task<bool> ImportCatalogAsync(long JournalId, List<JournalCatalogTreeListDto> dtos)
{ {
dtos = dtos.Where(c => !string.IsNullOrWhiteSpace(c.Name)).ToList(); 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(); 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 pageNums = dtos.Select(c => c.PageNum).ToList();
var pageNumNotExists = await _JournalPageRepository.Queryable().AnyAsync(w => w.JournalId == JournalId && !pageNums.Contains(w.PageNum)); 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 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) if (input.Type == 1)
{ {
var Journal = await Queryable<Journal>().Where(w => w.Id == input.JournalId).FirstAsync(); 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() //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; 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)); 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)); //var x = await _JournalPageRepository.DeleteAsync(w => ids.Contains(w.JournalCatalogId));
@ -406,14 +407,14 @@ public class JournalCatalogService : BaseRepository<JournalCatalog>, IJournalCat
{ {
// 1. 获取源节点并校验 // 1. 获取源节点并校验
var sourceNode = await base.Queryable().Where(x => x.Id == input.SourceId).FirstAsync(); 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. 校验目标父节点(如果指定) // 2. 校验目标父节点(如果指定)
if (input.TargetParentId > 0) if (input.TargetParentId > 0)
{ {
var targetParentExists = await base.Queryable().Where(x => x.Id == input.TargetParentId).AnyAsync(); 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 () => await base.UseTranAsync(async () =>

View File

@ -9,6 +9,7 @@ using QYZH.InteractiveMagazine.Infrastructure.OSS;
using QYZH.InteractiveMagazine.Infrastructure.RabbitMQ; using QYZH.InteractiveMagazine.Infrastructure.RabbitMQ;
using QYZH.InteractiveMagazine.IService; using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common; using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Journal; using QYZH.InteractiveMagazine.Models.Dto.Journal;
using QYZH.InteractiveMagazine.Models.Entity; using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum; using QYZH.InteractiveMagazine.Models.Enum;
@ -34,9 +35,9 @@ public class JournalPageService(BaseRepository<Journal> JournalRepository,
{ {
var Journal = await JournalRepository.Queryable().Where(w => w.Id == input.JournalId).FirstAsync(); var Journal = await JournalRepository.Queryable().Where(w => w.Id == input.JournalId).FirstAsync();
BusinessException.ThrowIf(Journal.IsNull(), "未找到书本"); BusinessException.ThrowIf(Journal.IsNull(), "未找到书本", ResultCode.NOT_FOUND);
BusinessException.ThrowIf(Journal?.Status == (int)JournalStatusEnum.Archive, "书籍已归档不能修改"); BusinessException.ThrowIf(Journal?.Status == (int)JournalStatusEnum.Archive, "书籍已归档不能修改", ResultCode.CONFLICT);
var pages = new List<JournalPage>(); var pages = new List<JournalPage>();
//var dotMatrixpages = new List<DotMatrixPage>(); //var dotMatrixpages = new List<DotMatrixPage>();
@ -65,7 +66,7 @@ public class JournalPageService(BaseRepository<Journal> JournalRepository,
{ {
//using var uow = Context.Ado.BeginTran(); //using var uow = Context.Ado.BeginTran();
var pageData = await base.InsertRangeAsync(pages); var pageData = await base.InsertRangeAsync(pages);
BusinessException.ThrowIf(pageData.IsNull(), "创建页失败"); BusinessException.ThrowIf(pageData.IsNull(), "创建页失败", ResultCode.GLOBAL_ERROR);
//var result = await dotMatrixPageRepository.InsertRangeAsync(dotMatrixpages); //var result = await dotMatrixPageRepository.InsertRangeAsync(dotMatrixpages);
//BusinessException.ThrowIf(result, "创建点阵页失败"); //BusinessException.ThrowIf(result, "创建点阵页失败");
@ -77,12 +78,12 @@ public class JournalPageService(BaseRepository<Journal> JournalRepository,
public async Task<bool> UpdateAsync(PageLayoutInput input) public async Task<bool> UpdateAsync(PageLayoutInput input)
{ {
var page = await Queryable().Where(w => w.Id == input.Id).FirstAsync(); var page = await Queryable().Where(w => w.Id == input.Id).FirstAsync();
BusinessException.ThrowIf(page == null, "不存在此页"); BusinessException.ThrowIf(page == null, "不存在此页", ResultCode.NOT_FOUND);
var Journal = await JournalRepository.GetByIdAsync(page.JournalId); var Journal = await JournalRepository.GetByIdAsync(page.JournalId);
BusinessException.ThrowIf(Journal == null, "不存在此书"); BusinessException.ThrowIf(Journal == null, "不存在此书", ResultCode.NOT_FOUND);
BusinessException.ThrowIf(Journal?.Status == (int)JournalStatusEnum.Archive, "书籍已归档不能修改"); BusinessException.ThrowIf(Journal?.Status == (int)JournalStatusEnum.Archive, "书籍已归档不能修改", ResultCode.CONFLICT);
var transResult = await UseTranAsync(async () => var transResult = await UseTranAsync(async () =>
{ {
//await dotMatrixPageRepository.Updateable().SetColumns(s => s.Area == input.Layout) //await dotMatrixPageRepository.Updateable().SetColumns(s => s.Area == input.Layout)
@ -115,21 +116,24 @@ public class JournalPageService(BaseRepository<Journal> JournalRepository,
public async Task<bool> UpdatePageNoAsync(long JournalId) public async Task<bool> UpdatePageNoAsync(long JournalId)
{ {
var journalEntity = await JournalRepository.Queryable().FirstAsync(w => w.Id == JournalId); var journalEntity = await JournalRepository.Queryable().FirstAsync(w => w.Id == JournalId);
BusinessException.ThrowIf(journalEntity == null, "不存在此期刊"); BusinessException.ThrowIf(journalEntity == null, "不存在此期刊", ResultCode.NOT_FOUND);
//如果书籍状态不等于“已归档”,“已废弃”,“已铺码”的情况下,就更新状态为“已铺码” //如果书籍状态不等于“已归档”,“已废弃”,“已铺码”的情况下,就更新状态为“已铺码”
BusinessException.ThrowIf((JournalStatusEnum)journalEntity.Status is JournalStatusEnum.Abandoned or JournalStatusEnum.Archive or JournalStatusEnum.Codeing, "当前【状态】不允许铺码"); BusinessException.ThrowIf((JournalStatusEnum)journalEntity.Status is JournalStatusEnum.Abandoned or JournalStatusEnum.Archive or JournalStatusEnum.Codeing, "当前【状态】不允许铺码", ResultCode.UNPROCESSABLE_ENTITY);
var journalPageList = await JournalPageRepository.Queryable().Where(x => x.JournalId == JournalId).OrderBy(x => x.PageNum).ToListAsync(); var journalPageList = await JournalPageRepository.Queryable().Where(x => x.JournalId == JournalId).OrderBy(x => x.PageNum).ToListAsync();
BusinessException.ThrowIf(journalPageList.Count == 0, "此期刊不存在任何书页"); BusinessException.ThrowIf(journalPageList.Count == 0, "此期刊不存在任何书页", ResultCode.NOT_FOUND);
var uploadPdfUrl = DomainHelper.OssFullUrl(journalEntity?.PdfUrl!); var uploadPdfKey = journalEntity?.PdfUrl?.RemoveDomain();
BusinessException.ThrowIf(string.IsNullOrWhiteSpace(uploadPdfUrl), "此期刊上传的PDF路径错误请检查期刊PDF文件是否上传成功"); BusinessException.ThrowIf(string.IsNullOrWhiteSpace(uploadPdfKey), "此期刊上传的PDF路径错误请检查期刊PDF文件是否上传成功", ResultCode.BAD_REQUEST);
var uploadPdfUrl = DomainHelper.OssFullUrl(uploadPdfKey);
BusinessException.ThrowIf(string.IsNullOrWhiteSpace(uploadPdfUrl), "此期刊上传的PDF路径错误请检查期刊PDF文件是否上传成功", ResultCode.BAD_REQUEST);
logger.LogInformation("uploadPdfUrl:" + uploadPdfUrl); logger.LogInformation("uploadPdfUrl:" + uploadPdfUrl);
//验证是否上传了PDF文件 //验证是否上传了PDF文件
var response = await httpClientFactory.CreateClient().SendAsync(new HttpRequestMessage(HttpMethod.Head, uploadPdfUrl)); var isPdfExists = ossService.DoesObjectExist(uploadPdfKey);
BusinessException.ThrowIf(response.StatusCode != HttpStatusCode.OK, "获取期刊上传的PDF文件失败请检查PDF文件是否上传成功"); BusinessException.ThrowIf(!isPdfExists, "获取期刊上传的PDF文件失败请检查PDF文件是否上传成功", ResultCode.GLOBAL_ERROR);
journalEntity.Status = (int)JournalStatusEnum.Codeing; journalEntity.Status = (int)JournalStatusEnum.Codeing;
@ -154,14 +158,14 @@ public class JournalPageService(BaseRepository<Journal> JournalRepository,
return await UseTranAsync(async () => return await UseTranAsync(async () =>
{ {
var journalEntity = await JournalRepository.Queryable().FirstAsync(w => w.Id == request.JournalId); var journalEntity = await JournalRepository.Queryable().FirstAsync(w => w.Id == request.JournalId);
BusinessException.ThrowIf(journalEntity == null, "不存在此书"); BusinessException.ThrowIf(journalEntity == null, "不存在此书", ResultCode.NOT_FOUND);
//如果书籍状态不等于“铺码中”则不允许回调接口更新点阵码 //如果书籍状态不等于“铺码中”则不允许回调接口更新点阵码
BusinessException.ThrowIf(journalEntity.Status != (int)JournalStatusEnum.Codeing, "当前【状态】不允许修改铺码"); BusinessException.ThrowIf(journalEntity.Status != (int)JournalStatusEnum.Codeing, "当前【状态】不允许修改铺码", ResultCode.UNPROCESSABLE_ENTITY);
var bookPageList = await JournalPageRepository.Queryable().Where(x => x.JournalId == request.JournalId).OrderBy(x => x.PageNum).ToListAsync(); var bookPageList = await JournalPageRepository.Queryable().Where(x => x.JournalId == request.JournalId).OrderBy(x => x.PageNum).ToListAsync();
BusinessException.ThrowIf(bookPageList.Count == 0, "此书不存在任何书页"); BusinessException.ThrowIf(bookPageList.Count == 0, "此书不存在任何书页", ResultCode.NOT_FOUND);
journalEntity.Status = (int)request.Status!.Value; journalEntity.Status = (int)request.Status!.Value;
journalEntity.UpdatedAt = DateTime.Now; journalEntity.UpdatedAt = DateTime.Now;
@ -177,7 +181,7 @@ public class JournalPageService(BaseRepository<Journal> JournalRepository,
{ {
journalEntity.DownloadJournalPagePdfName = request.DownloadJournalPagePdfName; journalEntity.DownloadJournalPagePdfName = request.DownloadJournalPagePdfName;
BusinessException.ThrowIf(request.PageNo.Length != bookPageList.Count, $"点阵码条数与页码数量不匹配,点阵码条数:{request.PageNo.Length},页码数量:{bookPageList.Count}"); BusinessException.ThrowIf(request.PageNo.Length != bookPageList.Count, $"点阵码条数与页码数量不匹配,点阵码条数:{request.PageNo.Length},页码数量:{bookPageList.Count}", ResultCode.BAD_REQUEST);
for (var i = 0; i < bookPageList.Count; i++) for (var i = 0; i < bookPageList.Count; i++)

View File

@ -3,6 +3,7 @@ using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.Infrastructure.OSS; using QYZH.InteractiveMagazine.Infrastructure.OSS;
using QYZH.InteractiveMagazine.IService; using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common; using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Journal; using QYZH.InteractiveMagazine.Models.Dto.Journal;
using QYZH.InteractiveMagazine.Models.Entity; using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum; using QYZH.InteractiveMagazine.Models.Enum;
@ -18,7 +19,7 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
public async Task<long?> InsertAsync(JournalPageTaskAddInput input) public async Task<long?> InsertAsync(JournalPageTaskAddInput input)
{ {
var JournalStatus = await journalRepository.Queryable().Where(w => w.Id == input.JournalId).Select(s => s.Status).FirstAsync(); var JournalStatus = await journalRepository.Queryable().Where(w => w.Id == input.JournalId).Select(s => s.Status).FirstAsync();
BusinessException.ThrowIf(JournalStatus == (int)JournalStatusEnum.Archive, "书籍已归档不能添加题目"); BusinessException.ThrowIf(JournalStatus == (int)JournalStatusEnum.Archive, "书籍已归档不能添加题目", ResultCode.CONFLICT);
var map = input.Adapt<JournalPageTask>(); var map = input.Adapt<JournalPageTask>();
map.Id = YitIdHelper.NextId(); map.Id = YitIdHelper.NextId();
@ -28,7 +29,7 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
{ {
var startNo = $"{no[0]}-{no[1]}-{no[2]}-1"; var startNo = $"{no[0]}-{no[1]}-{no[2]}-1";
var groupTask = await Queryable().Where(w => w.No == startNo && w.JournalId == input.JournalId).FirstAsync(); var groupTask = await Queryable().Where(w => w.No == startNo && w.JournalId == input.JournalId).FirstAsync();
BusinessException.ThrowIf(groupTask.IsNull(), "未找到关联跨页的第一部分"); BusinessException.ThrowIf(groupTask.IsNull(), "未找到关联跨页的第一部分", ResultCode.NOT_FOUND);
map.GroupId = groupTask.GroupId; map.GroupId = groupTask.GroupId;
map.Type = groupTask.Type; map.Type = groupTask.Type;
} }
@ -42,13 +43,13 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
public async Task<bool> UpdateAsync(JournalPageTaskUpdateInput input) public async Task<bool> UpdateAsync(JournalPageTaskUpdateInput input)
{ {
var JournalStatus = await journalRepository.Queryable().Where(w => w.Id == input.JournalId).Select(s => s.Status).FirstAsync(); var JournalStatus = await journalRepository.Queryable().Where(w => w.Id == input.JournalId).Select(s => s.Status).FirstAsync();
BusinessException.ThrowIf(JournalStatus == (int)JournalStatusEnum.Archive, "书籍已归档不能修改题目"); BusinessException.ThrowIf(JournalStatus == (int)JournalStatusEnum.Archive, "书籍已归档不能修改题目", ResultCode.CONFLICT);
var task = await base.Queryable().Where(w => w.Id == input.Id).FirstAsync(); var task = await base.Queryable().Where(w => w.Id == input.Id).FirstAsync();
BusinessException.ThrowIf(task.IsNull(), "未找到关联的题号"); BusinessException.ThrowIf(task.IsNull(), "未找到关联的题号", ResultCode.NOT_FOUND);
var sameTask = await base.Queryable().Where(w => w.No == input.No && w.JournalId == input.JournalId && w.Id != input.Id).FirstAsync(); var sameTask = await base.Queryable().Where(w => w.No == input.No && w.JournalId == input.JournalId && w.Id != input.Id).FirstAsync();
BusinessException.ThrowIf(sameTask.IsNotEmpty(), "已经存在相同题号题目"); BusinessException.ThrowIf(sameTask.IsNotEmpty(), "已经存在相同题号题目", ResultCode.CONFLICT);
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}"; var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}";
@ -74,7 +75,7 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
{ {
var startNo = $"{no[0]}-{no[1]}-{no[2]}-1"; var startNo = $"{no[0]}-{no[1]}-{no[2]}-1";
var groupTask = await Queryable().Where(w => w.No == startNo && w.JournalId == input.JournalId).FirstAsync(); var groupTask = await Queryable().Where(w => w.No == startNo && w.JournalId == input.JournalId).FirstAsync();
BusinessException.ThrowIf(groupTask.IsNull(), "未找到关联跨页的第一部分"); BusinessException.ThrowIf(groupTask.IsNull(), "未找到关联跨页的第一部分", ResultCode.NOT_FOUND);
task.GroupId = groupTask.GroupId; task.GroupId = groupTask.GroupId;
task.Type = groupTask.Type; task.Type = groupTask.Type;
} }
@ -124,7 +125,7 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
public async Task<bool> DeleteAsync(long id) public async Task<bool> DeleteAsync(long id)
{ {
var task = await base.Queryable().Where(w => w.Id == id).FirstAsync(); var task = await base.Queryable().Where(w => w.Id == id).FirstAsync();
BusinessException.ThrowIf(task.IsNull(), "问题不存在"); BusinessException.ThrowIf(task.IsNull(), "问题不存在", ResultCode.NOT_FOUND);
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{id}"; var key = $"journal/{task.JournalId}/{task.JournalPageId}/{id}";
@ -139,7 +140,7 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
public async Task<bool> ComplementAsync(JournalPageTaskComplementInput input) public async Task<bool> ComplementAsync(JournalPageTaskComplementInput input)
{ {
var task = await base.Queryable().Where(w => w.Id == input.Id).FirstAsync(); var task = await base.Queryable().Where(w => w.Id == input.Id).FirstAsync();
BusinessException.ThrowIf(task.IsNull(), "问题不存在"); BusinessException.ThrowIf(task.IsNull(), "问题不存在", ResultCode.NOT_FOUND);
if (input.AudioUrl.NotNull()) if (input.AudioUrl.NotNull())
{ {
@ -159,7 +160,7 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
public async Task<long> AddAnswerAsync(JournalTaskAnswerAddInput input) public async Task<long> AddAnswerAsync(JournalTaskAnswerAddInput input)
{ {
var task = await base.Queryable().Where(w => w.Id == input.JournalPageTaskId).FirstAsync(); var task = await base.Queryable().Where(w => w.Id == input.JournalPageTaskId).FirstAsync();
BusinessException.ThrowIf(task.IsNull(), "问题不存在"); BusinessException.ThrowIf(task.IsNull(), "问题不存在", ResultCode.NOT_FOUND);
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}"; var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}";
input.Answer = Deal(null, input.Answer, key, "answer"); input.Answer = Deal(null, input.Answer, key, "answer");
@ -181,7 +182,7 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
public async Task<bool> UpdateAnswerAsync(JournalTaskAnswerUpdateInput input) public async Task<bool> UpdateAnswerAsync(JournalTaskAnswerUpdateInput input)
{ {
var answer = await answerRepository.Queryable().Where(a => a.Id == input.Id).FirstAsync(); var answer = await answerRepository.Queryable().Where(a => a.Id == input.Id).FirstAsync();
BusinessException.ThrowIf(answer.IsNull(), "答案不存在"); BusinessException.ThrowIf(answer.IsNull(), "答案不存在", ResultCode.NOT_FOUND);
var task = await base.Queryable().Where(w => w.Id == answer.JournalPageTaskId).FirstAsync(); var task = await base.Queryable().Where(w => w.Id == answer.JournalPageTaskId).FirstAsync();
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}"; var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}";
@ -199,7 +200,7 @@ public class JournalPageTaskService(BaseRepository<Journal> journalRepository, O
public async Task<bool> DeleteAnswerAsync(long id) public async Task<bool> DeleteAnswerAsync(long id)
{ {
var answer = await answerRepository.Queryable().Where(a => a.Id == id).FirstAsync(); var answer = await answerRepository.Queryable().Where(a => a.Id == id).FirstAsync();
BusinessException.ThrowIf(answer.IsNull(), "答案不存在"); BusinessException.ThrowIf(answer.IsNull(), "答案不存在", ResultCode.NOT_FOUND);
var task = await base.Queryable().Where(w => w.Id == answer.JournalPageTaskId).FirstAsync(); var task = await base.Queryable().Where(w => w.Id == answer.JournalPageTaskId).FirstAsync();
var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}"; var key = $"journal/{task.JournalId}/{task.JournalPageId}/{task.GroupId}";

View File

@ -68,7 +68,7 @@ public class JournalService(BaseRepository<JournalPage> JournalPageRepository,
/// <returns>新杂志ID</returns> /// <returns>新杂志ID</returns>
public async Task<BaseResponse<long>> AddAsync(JournalAddDto input) public async Task<BaseResponse<long>> AddAsync(JournalAddDto input)
{ {
BusinessException.ThrowIf(string.IsNullOrWhiteSpace(input.Name), "书籍名称不能为空"); BusinessException.ThrowIf(string.IsNullOrWhiteSpace(input.Name), "书籍名称不能为空", ResultCode.BAD_REQUEST);
var journal = new Journal var journal = new Journal
{ {
@ -114,7 +114,7 @@ public class JournalService(BaseRepository<JournalPage> JournalPageRepository,
var res = await base.InsertAsync(journal); var res = await base.InsertAsync(journal);
if (!res) if (!res)
{ {
new BusinessException("创建失败"); new BusinessException("创建失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("杂志创建成功ID: {Id}, 名称: {Name}", journal.Id, input.Name); logger.LogInformation("杂志创建成功ID: {Id}, 名称: {Name}", journal.Id, input.Name);
return BaseResponse<long>.Success(journal.Id); return BaseResponse<long>.Success(journal.Id);
@ -129,8 +129,8 @@ public class JournalService(BaseRepository<JournalPage> JournalPageRepository,
{ {
var Journal = await base.GetByIdAsync(input.Id); var Journal = await base.GetByIdAsync(input.Id);
BusinessException.ThrowIf(Journal.IsNull(), "不存在的Id"); BusinessException.ThrowIf(Journal.IsNull(), "不存在的Id", ResultCode.NOT_FOUND);
BusinessException.ThrowIf(Journal.Status == (int)JournalStatusEnum.Archive, "已归档不可编辑"); BusinessException.ThrowIf(Journal.Status == (int)JournalStatusEnum.Archive, "已归档不可编辑", ResultCode.CONFLICT);
if (string.IsNullOrWhiteSpace(input.Cover)) if (string.IsNullOrWhiteSpace(input.Cover))
{ {
Journal.Cover = null; Journal.Cover = null;
@ -204,8 +204,8 @@ public class JournalService(BaseRepository<JournalPage> JournalPageRepository,
public async Task<bool> DeleteAsync(List<long> ids) 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)), "ID不存在", ResultCode.NOT_FOUND);
BusinessException.ThrowIf(base.Queryable().Any(w => ids.Contains(w.Id) && w.Status == (int)JournalStatusEnum.Archive), "已归档不可删除"); BusinessException.ThrowIf(base.Queryable().Any(w => ids.Contains(w.Id) && w.Status == (int)JournalStatusEnum.Archive), "已归档不可删除", ResultCode.CONFLICT);
var result = await UseTranAsync(async () => var result = await UseTranAsync(async () =>
{ {
await base.DeleteAsync(d => ids.Contains(d.Id)); await base.DeleteAsync(d => ids.Contains(d.Id));
@ -282,11 +282,11 @@ public class JournalService(BaseRepository<JournalPage> JournalPageRepository,
public async Task<DotMatrixOutput> PrintCodeAsync(long id) public async Task<DotMatrixOutput> PrintCodeAsync(long id)
{ {
var Journal = await base.Queryable().Where(w => w.Id == id).FirstAsync(); var Journal = await base.Queryable().Where(w => w.Id == id).FirstAsync();
BusinessException.ThrowIf(Journal.IsNull(), "不存在书"); BusinessException.ThrowIf(Journal.IsNull(), "不存在书", ResultCode.NOT_FOUND);
BusinessException.ThrowIf(Journal.Status == (int)JournalStatusEnum.Codeing, "正在生成中..."); BusinessException.ThrowIf(Journal.Status == (int)JournalStatusEnum.Codeing, "正在生成中...", ResultCode.CONFLICT);
var pages = await JournalPageRepository.Queryable().Where(w => w.JournalId == id).ToListAsync(); var pages = await JournalPageRepository.Queryable().Where(w => w.JournalId == id).ToListAsync();
BusinessException.ThrowIf(pages.IsNull(), "不存在页"); BusinessException.ThrowIf(pages.IsNull(), "不存在页", ResultCode.NOT_FOUND);
var output = new DotMatrixOutput() var output = new DotMatrixOutput()
{ {
@ -315,8 +315,8 @@ public class JournalService(BaseRepository<JournalPage> JournalPageRepository,
{ {
var book = await base.GetByIdAsync(id); var book = await base.GetByIdAsync(id);
var tasks = await Context.Queryable<JournalPageTask>().Where(w => w.JournalId == id).ToListAsync(); var tasks = await Context.Queryable<JournalPageTask>().Where(w => w.JournalId == id).ToListAsync();
BusinessException.ThrowIf(tasks.Count == 0 && status == JournalStatusEnum.Archive, "未添加任何题目,无法归档"); BusinessException.ThrowIf(tasks.Count == 0 && status == JournalStatusEnum.Archive, "未添加任何题目,无法归档", ResultCode.UNPROCESSABLE_ENTITY);
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())}未保存,无法归档"); 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())}未保存,无法归档", ResultCode.UNPROCESSABLE_ENTITY);
var res = await base.Updateable().SetColumns(s => s.Status, status).Where(w => w.Id == id).ExecuteCommandAsync() > 0; var res = await base.Updateable().SetColumns(s => s.Status, status).Where(w => w.Id == id).ExecuteCommandAsync() > 0;
return res; return res;
} }

View File

@ -27,12 +27,12 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (string.IsNullOrWhiteSpace(input.Name)) if (string.IsNullOrWhiteSpace(input.Name))
{ {
throw new BusinessException("勋章名称不能为空", 400); throw new BusinessException("勋章名称不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.Type)) if (string.IsNullOrWhiteSpace(input.Type))
{ {
throw new BusinessException("勋章类型不能为空", 400); throw new BusinessException("勋章类型不能为空", ResultCode.BAD_REQUEST);
} }
var medal = new Medal var medal = new Medal
@ -58,7 +58,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
var result = await medalRepository.InsertAsync(medal); var result = await medalRepository.InsertAsync(medal);
if (!result) if (!result)
{ {
throw new BusinessException("创建勋章失败", 500); throw new BusinessException("创建勋章失败", ResultCode.GLOBAL_ERROR);
} }
if (input.Rules != null && input.Rules.Count > 0) if (input.Rules != null && input.Rules.Count > 0)
@ -74,7 +74,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex, "勋章创建事务失败,勋章名称: {Name}", input.Name); logger.LogError(ex, "勋章创建事务失败,勋章名称: {Name}", input.Name);
throw new BusinessException("创建勋章失败", 500); throw new BusinessException("创建勋章失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("勋章创建成功,勋章名称: {Name}, ID: {Id}", input.Name, medal.Id); logger.LogInformation("勋章创建成功,勋章名称: {Name}, ID: {Id}", input.Name, medal.Id);
@ -94,17 +94,17 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (medal == null) if (medal == null)
{ {
logger.LogWarning("未找到要更新的勋章ID: {Id}", id); logger.LogWarning("未找到要更新的勋章ID: {Id}", id);
throw new BusinessException("勋章不存在", 404); throw new BusinessException("勋章不存在", ResultCode.NOT_FOUND);
} }
if (string.IsNullOrWhiteSpace(input.Name)) if (string.IsNullOrWhiteSpace(input.Name))
{ {
throw new BusinessException("勋章名称不能为空", 400); throw new BusinessException("勋章名称不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.Type)) if (string.IsNullOrWhiteSpace(input.Type))
{ {
throw new BusinessException("勋章类型不能为空", 400); throw new BusinessException("勋章类型不能为空", ResultCode.BAD_REQUEST);
} }
medal.Name = input.Name.Trim(); medal.Name = input.Name.Trim();
@ -123,7 +123,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
var result = await medalRepository.UpdateAsync(medal); var result = await medalRepository.UpdateAsync(medal);
if (!result) if (!result)
{ {
throw new BusinessException("更新勋章失败", 500); throw new BusinessException("更新勋章失败", ResultCode.GLOBAL_ERROR);
} }
// 删除旧规则,重新插入新规则 // 删除旧规则,重新插入新规则
@ -145,7 +145,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex, "勋章更新事务失败ID: {Id}", id); logger.LogError(ex, "勋章更新事务失败ID: {Id}", id);
throw new BusinessException("更新勋章失败", 500); throw new BusinessException("更新勋章失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("勋章更新成功ID: {Id}", id); logger.LogInformation("勋章更新成功ID: {Id}", id);
@ -165,7 +165,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (medal == null) if (medal == null)
{ {
logger.LogWarning("未找到要删除的勋章ID: {Id}", id); logger.LogWarning("未找到要删除的勋章ID: {Id}", id);
throw new BusinessException("勋章不存在", 404); throw new BusinessException("勋章不存在", ResultCode.NOT_FOUND);
} }
try try
@ -175,7 +175,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
var result = await medalRepository.DeleteByIdAsync(id); var result = await medalRepository.DeleteByIdAsync(id);
if (!result) if (!result)
{ {
throw new BusinessException("删除勋章失败", 500); throw new BusinessException("删除勋章失败", ResultCode.GLOBAL_ERROR);
} }
// 同时软删除关联规则 // 同时软删除关联规则
@ -192,7 +192,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
catch (Exception ex) catch (Exception ex)
{ {
logger.LogError(ex, "勋章删除事务失败ID: {Id}", id); logger.LogError(ex, "勋章删除事务失败ID: {Id}", id);
throw new BusinessException("删除勋章失败", 500); throw new BusinessException("删除勋章失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("勋章删除成功ID: {Id}", id); logger.LogInformation("勋章删除成功ID: {Id}", id);
@ -209,7 +209,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (medal == null) if (medal == null)
{ {
logger.LogWarning("未找到勋章ID: {Id}", id); logger.LogWarning("未找到勋章ID: {Id}", id);
throw new BusinessException("勋章不存在", 404); throw new BusinessException("勋章不存在", ResultCode.NOT_FOUND);
} }
var rules = await GetRulesByMedalIdAsync(medal.Id); var rules = await GetRulesByMedalIdAsync(medal.Id);
@ -225,12 +225,12 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (input.PageIndex <= 0) if (input.PageIndex <= 0)
{ {
throw new BusinessException("页码必须大于0", 400); throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
} }
if (input.PageSize <= 0 || input.PageSize > 100) if (input.PageSize <= 0 || input.PageSize > 100)
{ {
throw new BusinessException("每页条数必须在1-100之间", 400); throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
} }
RefAsync<int> totalNumber = 0; RefAsync<int> totalNumber = 0;
@ -266,7 +266,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (medal == null) if (medal == null)
{ {
logger.LogWarning("未找到要更新状态的勋章ID: {Id}", id); logger.LogWarning("未找到要更新状态的勋章ID: {Id}", id);
throw new BusinessException("勋章不存在", 404); throw new BusinessException("勋章不存在", ResultCode.NOT_FOUND);
} }
medal.Status = medal.Status == 0 ? 1 : 0; medal.Status = medal.Status == 0 ? 1 : 0;
@ -277,7 +277,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (!result) if (!result)
{ {
logger.LogError("勋章状态更新失败ID: {Id}", id); logger.LogError("勋章状态更新失败ID: {Id}", id);
throw new BusinessException("更新勋章状态失败", 500); throw new BusinessException("更新勋章状态失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("勋章状态更新成功ID: {Id}, Status: {Status}", id, medal.Status); logger.LogInformation("勋章状态更新成功ID: {Id}, Status: {Status}", id, medal.Status);
return result; return result;
@ -364,19 +364,19 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (input.MedalId <= 0) if (input.MedalId <= 0)
{ {
throw new BusinessException("勋章ID无效", 400); throw new BusinessException("勋章ID无效", ResultCode.BAD_REQUEST);
} }
var medal = await medalRepository.GetByIdAsync(input.MedalId); var medal = await medalRepository.GetByIdAsync(input.MedalId);
if (medal == null) if (medal == null)
{ {
logger.LogWarning("未找到要激活的勋章勋章ID: {MedalId}", input.MedalId); logger.LogWarning("未找到要激活的勋章勋章ID: {MedalId}", input.MedalId);
throw new BusinessException("勋章不存在", 404); throw new BusinessException("勋章不存在", ResultCode.NOT_FOUND);
} }
if (medal.Status != 1) if (medal.Status != 1)
{ {
throw new BusinessException("该勋章当前不可获得", 400); throw new BusinessException("该勋章当前不可获得", ResultCode.BAD_REQUEST);
} }
// 规则校验 // 规则校验
@ -384,7 +384,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (!passed) if (!passed)
{ {
logger.LogWarning("勋章规则校验未通过用户ID: {UserId}, 勋章ID: {MedalId}, 原因: {Reason}", userId, input.MedalId, failReason); logger.LogWarning("勋章规则校验未通过用户ID: {UserId}, 勋章ID: {MedalId}, 原因: {Reason}", userId, input.MedalId, failReason);
throw new BusinessException(failReason!, 400); throw new BusinessException(failReason!, ResultCode.BAD_REQUEST);
} }
var existingUserMedal = await Context.Queryable<UserMedal>() var existingUserMedal = await Context.Queryable<UserMedal>()
@ -393,7 +393,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (existingUserMedal != null) if (existingUserMedal != null)
{ {
throw new BusinessException("您已拥有该勋章", 400); throw new BusinessException("您已拥有该勋章", ResultCode.BAD_REQUEST);
} }
var userMedal = new UserMedal var userMedal = new UserMedal
@ -414,7 +414,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (insertResult <= 0) if (insertResult <= 0)
{ {
logger.LogError("勋章激活失败用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId); logger.LogError("勋章激活失败用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId);
throw new BusinessException("激活勋章失败", 500); throw new BusinessException("激活勋章失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("勋章激活成功用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId); logger.LogInformation("勋章激活成功用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId);
@ -486,7 +486,7 @@ public class MedalService(BaseRepository<Medal> medalRepository, IOptions<MedalR
if (count <= 0) if (count <= 0)
{ {
logger.LogError("勋章规则插入失败MedalId: {MedalId}", medalId); logger.LogError("勋章规则插入失败MedalId: {MedalId}", medalId);
throw new BusinessException("创建勋章规则失败", 500); throw new BusinessException("创建勋章规则失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("勋章规则创建成功MedalId: {MedalId}, 规则数: {Count}", medalId, rules.Count); logger.LogInformation("勋章规则创建成功MedalId: {MedalId}, 规则数: {Count}", medalId, rules.Count);

View File

@ -105,7 +105,7 @@ public class OperationLogService(
if (log == null) if (log == null)
{ {
throw new BusinessException("操作日志记录不存在"); throw new BusinessException("操作日志记录不存在", ResultCode.NOT_FOUND);
} }
var result = new OperationLogDetailOutput var result = new OperationLogDetailOutput

View File

@ -223,12 +223,12 @@ public class PetService(
if (input.PetId <= 0) if (input.PetId <= 0)
{ {
throw new BusinessException("宠物Id不能为空", 400); throw new BusinessException("宠物Id不能为空", ResultCode.BAD_REQUEST);
} }
if (input.GrowthPoints <= 0) if (input.GrowthPoints <= 0)
{ {
throw new BusinessException("成长值必须大于0", 400); throw new BusinessException("成长值必须大于0", ResultCode.BAD_REQUEST);
} }
// 查询宠物 // 查询宠物
@ -236,21 +236,21 @@ public class PetService(
if (pet == null || pet.IsDeleted) if (pet == null || pet.IsDeleted)
{ {
logger.LogWarning("喂养失败宠物不存在PetId: {PetId}", input.PetId); logger.LogWarning("喂养失败宠物不存在PetId: {PetId}", input.PetId);
throw new BusinessException("宠物不存在", 404); throw new BusinessException("宠物不存在", ResultCode.NOT_FOUND);
} }
// 校验宠物归属 // 校验宠物归属
if (pet.UserId != userId) if (pet.UserId != userId)
{ {
logger.LogWarning("喂养失败无权操作该宠物UserId: {UserId}, PetUserId: {PetUserId}", userId, pet.UserId); logger.LogWarning("喂养失败无权操作该宠物UserId: {UserId}, PetUserId: {PetUserId}", userId, pet.UserId);
throw new BusinessException("无权操作该宠物", 403); throw new BusinessException("无权操作该宠物", ResultCode.FORBIDDEN);
} }
// 校验宠物状态 // 校验宠物状态
if (pet.Status != (int)UserPetStatusEnum.Active) if (pet.Status != (int)UserPetStatusEnum.Active)
{ {
logger.LogWarning("喂养失败宠物未激活PetId: {PetId}, Status: {Status}", input.PetId, pet.Status); logger.LogWarning("喂养失败宠物未激活PetId: {PetId}, Status: {Status}", input.PetId, pet.Status);
throw new BusinessException("宠物未激活,无法喂养", 400); throw new BusinessException("宠物未激活,无法喂养", ResultCode.BAD_REQUEST);
} }
FeedPetOutput result = new FeedPetOutput(); FeedPetOutput result = new FeedPetOutput();
// 事务保证一致性 // 事务保证一致性
@ -273,13 +273,13 @@ public class PetService(
// 查询宠物 // 查询宠物
var pet = await petRepository.GetByIdAsync(input.PetId); var pet = await petRepository.GetByIdAsync(input.PetId);
if (pet == null || pet.IsDeleted) if (pet == null || pet.IsDeleted)
throw new BusinessException("宠物不存在", 404); throw new BusinessException("宠物不存在", ResultCode.NOT_FOUND);
if (pet.UserId != userId) if (pet.UserId != userId)
throw new BusinessException("无权操作该宠物", 403); throw new BusinessException("无权操作该宠物", ResultCode.FORBIDDEN);
if (pet.Status != (int)UserPetStatusEnum.Active) if (pet.Status != (int)UserPetStatusEnum.Active)
throw new BusinessException("宠物未激活,无法喂养", 400); throw new BusinessException("宠物未激活,无法喂养", ResultCode.BAD_REQUEST);
var growthBefore = pet.GrowthPoints; var growthBefore = pet.GrowthPoints;
var growthAfter = growthBefore + input.GrowthPoints; var growthAfter = growthBefore + input.GrowthPoints;
@ -297,7 +297,7 @@ public class PetService(
if (updateResult <= 0) if (updateResult <= 0)
{ {
throw new BusinessException("更新宠物成长值失败", 500); throw new BusinessException("更新宠物成长值失败", ResultCode.GLOBAL_ERROR);
} }
// 进化检查查找下一阶段进化形态PreviousEvolutionId 类型为 long? // 进化检查查找下一阶段进化形态PreviousEvolutionId 类型为 long?
@ -348,7 +348,7 @@ public class PetService(
var insertResult = await feedingRecordRepository.InsertAsync(record); var insertResult = await feedingRecordRepository.InsertAsync(record);
if (!insertResult) if (!insertResult)
{ {
throw new BusinessException("写入喂养记录失败", 500); throw new BusinessException("写入喂养记录失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("喂养宠物成功PetId: {PetId}, 成长值: {Before} -> {After}, 进化: {HasEvolved}", logger.LogInformation("喂养宠物成功PetId: {PetId}, 成长值: {Before} -> {After}, 进化: {HasEvolved}",
@ -402,10 +402,10 @@ public class PetService(
public async Task<PetTemplateOutput> CreateTemplateAsync(PetTemplateInput input) public async Task<PetTemplateOutput> CreateTemplateAsync(PetTemplateInput input)
{ {
if (string.IsNullOrWhiteSpace(input.Name)) if (string.IsNullOrWhiteSpace(input.Name))
throw new BusinessException("模板名称不能为空", 400); throw new BusinessException("模板名称不能为空", ResultCode.BAD_REQUEST);
if (input.Evolutions == null || input.Evolutions.Count == 0) if (input.Evolutions == null || input.Evolutions.Count == 0)
throw new BusinessException("至少需要一个进化阶段", 400); throw new BusinessException("至少需要一个进化阶段", ResultCode.BAD_REQUEST);
PetTemplate template = null!; PetTemplate template = null!;
@ -430,7 +430,7 @@ public class PetService(
var inserted = await petTemplateRepository.InsertAsync(template); var inserted = await petTemplateRepository.InsertAsync(template);
if (!inserted) if (!inserted)
throw new BusinessException("创建宠物模板失败", 500); throw new BusinessException("创建宠物模板失败", ResultCode.GLOBAL_ERROR);
// 2. 按 StageLevel 排序,依次创建进化阶段 // 2. 按 StageLevel 排序,依次创建进化阶段
var sortedEvolutions = input.Evolutions.OrderBy(e => e.StageLevel).ToList(); var sortedEvolutions = input.Evolutions.OrderBy(e => e.StageLevel).ToList();
@ -458,7 +458,7 @@ public class PetService(
var evoInserted = await petEvolutionRepository.InsertAsync(evolution); var evoInserted = await petEvolutionRepository.InsertAsync(evolution);
if (!evoInserted) if (!evoInserted)
throw new BusinessException($"创建进化阶段 [{evoInput.StageName}] 失败", 500); throw new BusinessException($"创建进化阶段 [{evoInput.StageName}] 失败", ResultCode.GLOBAL_ERROR);
// 记录初始阶段(第一个) // 记录初始阶段(第一个)
if (previousEvolution == null) if (previousEvolution == null)
@ -560,10 +560,10 @@ public class PetService(
{ {
var template = await petTemplateRepository.GetByIdAsync(id); var template = await petTemplateRepository.GetByIdAsync(id);
if (template == null || template.IsDeleted) if (template == null || template.IsDeleted)
throw new BusinessException("宠物模板不存在", 404); throw new BusinessException("宠物模板不存在", ResultCode.NOT_FOUND);
if (string.IsNullOrWhiteSpace(input.Name)) if (string.IsNullOrWhiteSpace(input.Name))
throw new BusinessException("模板名称不能为空", 400); throw new BusinessException("模板名称不能为空", ResultCode.BAD_REQUEST);
template.Name = input.Name.Trim(); template.Name = input.Name.Trim();
template.Description = input.Description; template.Description = input.Description;
@ -575,7 +575,7 @@ public class PetService(
var result = await petTemplateRepository.UpdateAsync(template); var result = await petTemplateRepository.UpdateAsync(template);
if (!result) if (!result)
throw new BusinessException("更新宠物模板失败", 500); throw new BusinessException("更新宠物模板失败", ResultCode.GLOBAL_ERROR);
logger.LogInformation("更新宠物模板成功Id: {Id}", id); logger.LogInformation("更新宠物模板成功Id: {Id}", id);
return BuildTemplateOutput(template); return BuildTemplateOutput(template);
@ -588,18 +588,18 @@ public class PetService(
{ {
var template = await petTemplateRepository.GetByIdAsync(id); var template = await petTemplateRepository.GetByIdAsync(id);
if (template == null || template.IsDeleted) if (template == null || template.IsDeleted)
throw new BusinessException("宠物模板不存在", 404); throw new BusinessException("宠物模板不存在", ResultCode.NOT_FOUND);
if (template.Type == PetTemplateTypeEnum.Default) if (template.Type == PetTemplateTypeEnum.Default)
throw new BusinessException("默认模板不允许删除", 400); throw new BusinessException("默认模板不允许删除", ResultCode.BAD_REQUEST);
// 校验是否有用户宠物实例关联 // 校验是否有用户宠物实例关联
var hasUserPet = petRepository.Context.Queryable<UserPet>() var hasUserPet = petRepository.Context.Queryable<UserPet>()
.Any(p => p.TemplateId == id && !p.IsDeleted); .Any(p => p.TemplateId == id && !p.IsDeleted);
if (hasUserPet) if (hasUserPet)
throw new BusinessException("该模板下存在用户宠物实例,无法删除", 400); throw new BusinessException("该模板下存在用户宠物实例,无法删除", ResultCode.BAD_REQUEST);
template.IsDeleted = true; template.IsDeleted = true;
template.UpdatedBy = "System"; template.UpdatedBy = "System";
@ -616,7 +616,7 @@ public class PetService(
{ {
var template = await petTemplateRepository.GetByIdAsync(id); var template = await petTemplateRepository.GetByIdAsync(id);
if (template == null || template.IsDeleted) if (template == null || template.IsDeleted)
throw new BusinessException("宠物模板不存在", 404); throw new BusinessException("宠物模板不存在", ResultCode.NOT_FOUND);
return BuildTemplateOutput(template); return BuildTemplateOutput(template);
} }
@ -663,7 +663,7 @@ public class PetService(
{ {
var template = await petTemplateRepository.GetByIdAsync(id); var template = await petTemplateRepository.GetByIdAsync(id);
if (template == null || template.IsDeleted) if (template == null || template.IsDeleted)
throw new BusinessException("宠物模板不存在", 404); throw new BusinessException("宠物模板不存在", ResultCode.NOT_FOUND);
template.Status = template.Status == (int)DefaultStatusEnum.Active template.Status = template.Status == (int)DefaultStatusEnum.Active
? (int)DefaultStatusEnum.Inactive ? (int)DefaultStatusEnum.Inactive
@ -703,16 +703,16 @@ public class PetService(
public async Task<PetEvolutionOutput> CreateEvolutionAsync(PetEvolutionInput input) public async Task<PetEvolutionOutput> CreateEvolutionAsync(PetEvolutionInput input)
{ {
if (input.TemplateId <= 0) if (input.TemplateId <= 0)
throw new BusinessException("模板Id不能为空", 400); throw new BusinessException("模板Id不能为空", ResultCode.BAD_REQUEST);
if (string.IsNullOrWhiteSpace(input.StageName)) if (string.IsNullOrWhiteSpace(input.StageName))
throw new BusinessException("阶段名称不能为空", 400); throw new BusinessException("阶段名称不能为空", ResultCode.BAD_REQUEST);
// 校验模板是否存在 // 校验模板是否存在
var templateExists = petTemplateRepository.Context.Queryable<PetTemplate>() var templateExists = petTemplateRepository.Context.Queryable<PetTemplate>()
.Any(t => t.Id == input.TemplateId && !t.IsDeleted); .Any(t => t.Id == input.TemplateId && !t.IsDeleted);
if (!templateExists) if (!templateExists)
throw new BusinessException("宠物模板不存在", 404); throw new BusinessException("宠物模板不存在", ResultCode.NOT_FOUND);
var evolution = new PetEvolution var evolution = new PetEvolution
{ {
@ -732,7 +732,7 @@ public class PetService(
var result = await petEvolutionRepository.InsertAsync(evolution); var result = await petEvolutionRepository.InsertAsync(evolution);
if (!result) if (!result)
throw new BusinessException("创建进化阶段失败", 500); throw new BusinessException("创建进化阶段失败", ResultCode.GLOBAL_ERROR);
logger.LogInformation("创建进化阶段成功Id: {Id}, StageName: {StageName}", evolution.Id, evolution.StageName); logger.LogInformation("创建进化阶段成功Id: {Id}, StageName: {StageName}", evolution.Id, evolution.StageName);
return BuildEvolutionOutput(evolution); return BuildEvolutionOutput(evolution);
@ -745,10 +745,10 @@ public class PetService(
{ {
var evolution = await petEvolutionRepository.GetByIdAsync(id); var evolution = await petEvolutionRepository.GetByIdAsync(id);
if (evolution == null || evolution.IsDeleted) if (evolution == null || evolution.IsDeleted)
throw new BusinessException("进化阶段不存在", 404); throw new BusinessException("进化阶段不存在", ResultCode.NOT_FOUND);
if (string.IsNullOrWhiteSpace(input.StageName)) if (string.IsNullOrWhiteSpace(input.StageName))
throw new BusinessException("阶段名称不能为空", 400); throw new BusinessException("阶段名称不能为空", ResultCode.BAD_REQUEST);
evolution.TemplateId = input.TemplateId; evolution.TemplateId = input.TemplateId;
evolution.StageName = input.StageName.Trim(); evolution.StageName = input.StageName.Trim();
@ -761,7 +761,7 @@ public class PetService(
var result = await petEvolutionRepository.UpdateAsync(evolution); var result = await petEvolutionRepository.UpdateAsync(evolution);
if (!result) if (!result)
throw new BusinessException("更新进化阶段失败", 500); throw new BusinessException("更新进化阶段失败", ResultCode.GLOBAL_ERROR);
logger.LogInformation("更新进化阶段成功Id: {Id}", id); logger.LogInformation("更新进化阶段成功Id: {Id}", id);
return BuildEvolutionOutput(evolution); return BuildEvolutionOutput(evolution);
@ -774,13 +774,13 @@ public class PetService(
{ {
var evolution = await petEvolutionRepository.GetByIdAsync(id); var evolution = await petEvolutionRepository.GetByIdAsync(id);
if (evolution == null || evolution.IsDeleted) if (evolution == null || evolution.IsDeleted)
throw new BusinessException("进化阶段不存在", 404); throw new BusinessException("进化阶段不存在", ResultCode.NOT_FOUND);
// 校验是否有用户宠物处于该形态 // 校验是否有用户宠物处于该形态
var hasUserPet = petRepository.Context.Queryable<UserPet>() var hasUserPet = petRepository.Context.Queryable<UserPet>()
.Any(p => p.CurrentEvolutionId == id && !p.IsDeleted); .Any(p => p.CurrentEvolutionId == id && !p.IsDeleted);
if (hasUserPet) if (hasUserPet)
throw new BusinessException("有用户宠物正处于该形态,无法删除", 400); throw new BusinessException("有用户宠物正处于该形态,无法删除", ResultCode.BAD_REQUEST);
evolution.IsDeleted = true; evolution.IsDeleted = true;
evolution.UpdatedBy = "System"; evolution.UpdatedBy = "System";
@ -797,7 +797,7 @@ public class PetService(
{ {
var evolution = await petEvolutionRepository.GetByIdAsync(id); var evolution = await petEvolutionRepository.GetByIdAsync(id);
if (evolution == null || evolution.IsDeleted) if (evolution == null || evolution.IsDeleted)
throw new BusinessException("进化阶段不存在", 404); throw new BusinessException("进化阶段不存在", ResultCode.NOT_FOUND);
return BuildEvolutionOutput(evolution); return BuildEvolutionOutput(evolution);
} }
@ -861,16 +861,16 @@ public class PetService(
public async Task<PetSkinOutput> CreateSkinAsync(PetSkinInput input) public async Task<PetSkinOutput> CreateSkinAsync(PetSkinInput input)
{ {
if (input.TemplateId <= 0) if (input.TemplateId <= 0)
throw new BusinessException("模板Id不能为空", 400); throw new BusinessException("模板Id不能为空", ResultCode.BAD_REQUEST);
if (string.IsNullOrWhiteSpace(input.Name)) if (string.IsNullOrWhiteSpace(input.Name))
throw new BusinessException("皮肤名称不能为空", 400); throw new BusinessException("皮肤名称不能为空", ResultCode.BAD_REQUEST);
// 校验模板是否存在 // 校验模板是否存在
var templateExists = petTemplateRepository.Context.Queryable<PetTemplate>() var templateExists = petTemplateRepository.Context.Queryable<PetTemplate>()
.Any(t => t.Id == input.TemplateId && !t.IsDeleted); .Any(t => t.Id == input.TemplateId && !t.IsDeleted);
if (!templateExists) if (!templateExists)
throw new BusinessException("宠物模板不存在", 404); throw new BusinessException("宠物模板不存在", ResultCode.NOT_FOUND);
var skin = new PetSkin var skin = new PetSkin
{ {
@ -890,7 +890,7 @@ public class PetService(
var result = await petSkinRepository.InsertAsync(skin); var result = await petSkinRepository.InsertAsync(skin);
if (!result) if (!result)
throw new BusinessException("创建皮肤失败", 500); throw new BusinessException("创建皮肤失败", ResultCode.GLOBAL_ERROR);
// 搬运封面图到正式目录 // 搬运封面图到正式目录
if (OssImageHelper.IsTempImage(skin.CoverImageUrl)) if (OssImageHelper.IsTempImage(skin.CoverImageUrl))
@ -911,10 +911,10 @@ public class PetService(
{ {
var skin = await petSkinRepository.GetByIdAsync(id); var skin = await petSkinRepository.GetByIdAsync(id);
if (skin == null || skin.IsDeleted) if (skin == null || skin.IsDeleted)
throw new BusinessException("皮肤不存在", 404); throw new BusinessException("皮肤不存在", ResultCode.NOT_FOUND);
if (string.IsNullOrWhiteSpace(input.Name)) if (string.IsNullOrWhiteSpace(input.Name))
throw new BusinessException("皮肤名称不能为空", 400); throw new BusinessException("皮肤名称不能为空", ResultCode.BAD_REQUEST);
skin.TemplateId = input.TemplateId; skin.TemplateId = input.TemplateId;
skin.Name = input.Name.Trim(); skin.Name = input.Name.Trim();
@ -937,7 +937,7 @@ public class PetService(
var result = await petSkinRepository.UpdateAsync(skin); var result = await petSkinRepository.UpdateAsync(skin);
if (!result) if (!result)
throw new BusinessException("更新皮肤失败", 500); throw new BusinessException("更新皮肤失败", ResultCode.GLOBAL_ERROR);
logger.LogInformation("更新皮肤成功Id: {Id}", id); logger.LogInformation("更新皮肤成功Id: {Id}", id);
@ -957,13 +957,13 @@ public class PetService(
{ {
var skin = await petSkinRepository.GetByIdAsync(id); var skin = await petSkinRepository.GetByIdAsync(id);
if (skin == null || skin.IsDeleted) if (skin == null || skin.IsDeleted)
throw new BusinessException("皮肤不存在", 404); throw new BusinessException("皮肤不存在", ResultCode.NOT_FOUND);
// 校验是否有用户宠物正在使用该皮肤 // 校验是否有用户宠物正在使用该皮肤
var inUse = petRepository.Context.Queryable<UserPet>() var inUse = petRepository.Context.Queryable<UserPet>()
.Any(p => p.CurrentSkinId == id && !p.IsDeleted); .Any(p => p.CurrentSkinId == id && !p.IsDeleted);
if (inUse) if (inUse)
throw new BusinessException("有用户宠物正在使用该皮肤,无法删除", 400); throw new BusinessException("有用户宠物正在使用该皮肤,无法删除", ResultCode.BAD_REQUEST);
skin.IsDeleted = true; skin.IsDeleted = true;
skin.UpdatedBy = "System"; skin.UpdatedBy = "System";
@ -980,7 +980,7 @@ public class PetService(
{ {
var skin = await petSkinRepository.GetByIdAsync(id); var skin = await petSkinRepository.GetByIdAsync(id);
if (skin == null || skin.IsDeleted) if (skin == null || skin.IsDeleted)
throw new BusinessException("皮肤不存在", 404); throw new BusinessException("皮肤不存在", ResultCode.NOT_FOUND);
var images = await petSkinImageRepository.Queryable() var images = await petSkinImageRepository.Queryable()
.Where(i => i.SkinId == id && !i.IsDeleted) .Where(i => i.SkinId == id && !i.IsDeleted)
@ -1072,19 +1072,19 @@ public class PetService(
public async Task<PetSkinImageOutput> CreateSkinImageAsync(PetSkinImageInput input) public async Task<PetSkinImageOutput> CreateSkinImageAsync(PetSkinImageInput input)
{ {
if (input.SkinId <= 0) if (input.SkinId <= 0)
throw new BusinessException("皮肤Id不能为空", 400); throw new BusinessException("皮肤Id不能为空", ResultCode.BAD_REQUEST);
if (input.EvolutionStageId <= 0) if (input.EvolutionStageId <= 0)
throw new BusinessException("进化阶段Id不能为空", 400); throw new BusinessException("进化阶段Id不能为空", ResultCode.BAD_REQUEST);
if (string.IsNullOrWhiteSpace(input.ImageUrl)) if (string.IsNullOrWhiteSpace(input.ImageUrl))
throw new BusinessException("图片地址不能为空", 400); throw new BusinessException("图片地址不能为空", ResultCode.BAD_REQUEST);
// 校验皮肤是否存在 // 校验皮肤是否存在
var skinExists = petSkinRepository.Context.Queryable<PetSkin>() var skinExists = petSkinRepository.Context.Queryable<PetSkin>()
.Any(s => s.Id == input.SkinId && !s.IsDeleted); .Any(s => s.Id == input.SkinId && !s.IsDeleted);
if (!skinExists) if (!skinExists)
throw new BusinessException("皮肤不存在", 404); throw new BusinessException("皮肤不存在", ResultCode.NOT_FOUND);
var image = new PetSkinImage var image = new PetSkinImage
{ {
@ -1102,7 +1102,7 @@ public class PetService(
var result = await petSkinImageRepository.InsertAsync(image); var result = await petSkinImageRepository.InsertAsync(image);
if (!result) if (!result)
throw new BusinessException("创建皮肤图片失败", 500); throw new BusinessException("创建皮肤图片失败", ResultCode.GLOBAL_ERROR);
// 搬运图片到正式目录 // 搬运图片到正式目录
if (OssImageHelper.IsTempImage(image.ImageUrl)) if (OssImageHelper.IsTempImage(image.ImageUrl))
@ -1123,10 +1123,10 @@ public class PetService(
{ {
var image = await petSkinImageRepository.GetByIdAsync(id); var image = await petSkinImageRepository.GetByIdAsync(id);
if (image == null || image.IsDeleted) if (image == null || image.IsDeleted)
throw new BusinessException("皮肤图片不存在", 404); throw new BusinessException("皮肤图片不存在", ResultCode.NOT_FOUND);
if (string.IsNullOrWhiteSpace(input.ImageUrl)) if (string.IsNullOrWhiteSpace(input.ImageUrl))
throw new BusinessException("图片地址不能为空", 400); throw new BusinessException("图片地址不能为空", ResultCode.BAD_REQUEST);
image.SkinId = input.SkinId; image.SkinId = input.SkinId;
image.EvolutionStageId = input.EvolutionStageId; image.EvolutionStageId = input.EvolutionStageId;
@ -1147,7 +1147,7 @@ public class PetService(
var result = await petSkinImageRepository.UpdateAsync(image); var result = await petSkinImageRepository.UpdateAsync(image);
if (!result) if (!result)
throw new BusinessException("更新皮肤图片失败", 500); throw new BusinessException("更新皮肤图片失败", ResultCode.GLOBAL_ERROR);
logger.LogInformation("更新皮肤图片成功Id: {Id}", id); logger.LogInformation("更新皮肤图片成功Id: {Id}", id);
return BuildSkinImageOutput(image); return BuildSkinImageOutput(image);
@ -1160,7 +1160,7 @@ public class PetService(
{ {
var image = await petSkinImageRepository.GetByIdAsync(id); var image = await petSkinImageRepository.GetByIdAsync(id);
if (image == null || image.IsDeleted) if (image == null || image.IsDeleted)
throw new BusinessException("皮肤图片不存在", 404); throw new BusinessException("皮肤图片不存在", ResultCode.NOT_FOUND);
image.IsDeleted = true; image.IsDeleted = true;
image.UpdatedBy = "System"; image.UpdatedBy = "System";
@ -1208,7 +1208,7 @@ public class PetService(
public async Task<List<PetEvolutionOutput>> GetEvolutionsByTemplateIdAsync(long templateId) public async Task<List<PetEvolutionOutput>> GetEvolutionsByTemplateIdAsync(long templateId)
{ {
if (templateId <= 0) if (templateId <= 0)
throw new BusinessException("模板Id不能为空", 400); throw new BusinessException("模板Id不能为空", ResultCode.BAD_REQUEST);
var list = await petEvolutionRepository.Queryable() var list = await petEvolutionRepository.Queryable()
.Where(e => e.TemplateId == templateId && !e.IsDeleted) .Where(e => e.TemplateId == templateId && !e.IsDeleted)
@ -1224,7 +1224,7 @@ public class PetService(
public async Task<List<PetSkinOutput>> GetSkinsByTemplateIdAsync(long templateId) public async Task<List<PetSkinOutput>> GetSkinsByTemplateIdAsync(long templateId)
{ {
if (templateId <= 0) if (templateId <= 0)
throw new BusinessException("模板Id不能为空", 400); throw new BusinessException("模板Id不能为空", ResultCode.BAD_REQUEST);
var list = await petSkinRepository.Queryable() var list = await petSkinRepository.Queryable()
.Where(s => s.TemplateId == templateId && !s.IsDeleted) .Where(s => s.TemplateId == templateId && !s.IsDeleted)
@ -1276,12 +1276,12 @@ public class PetService(
public async Task<List<SkinEvolutionStageOutput>> GetSkinImagesGroupedBySkinIdAsync(long skinId) public async Task<List<SkinEvolutionStageOutput>> GetSkinImagesGroupedBySkinIdAsync(long skinId)
{ {
if (skinId <= 0) if (skinId <= 0)
throw new BusinessException("皮肤Id不能为空", 400); throw new BusinessException("皮肤Id不能为空", ResultCode.BAD_REQUEST);
// 1. 获取皮肤信息 // 1. 获取皮肤信息
var skin = await petSkinRepository.GetByIdAsync(skinId); var skin = await petSkinRepository.GetByIdAsync(skinId);
if (skin == null || skin.IsDeleted) if (skin == null || skin.IsDeleted)
throw new BusinessException("皮肤不存在", 404); throw new BusinessException("皮肤不存在", ResultCode.NOT_FOUND);
// 2. 获取该模板的所有进化阶段(按阶段等级排序) // 2. 获取该模板的所有进化阶段(按阶段等级排序)
var evolutions = await petEvolutionRepository.Queryable() var evolutions = await petEvolutionRepository.Queryable()

View File

@ -28,7 +28,7 @@ public class PointsService(
input.UserId, input.Amount, input.ChangeType); input.UserId, input.Amount, input.ChangeType);
if (input.Amount <= 0) if (input.Amount <= 0)
throw new BusinessException("增加积分数量必须大于0", 400); throw new BusinessException("增加积分数量必须大于0", ResultCode.BAD_REQUEST);
AddPointsOutput result = null!; AddPointsOutput result = null!;
@ -49,7 +49,7 @@ public class PointsService(
input.UserId, input.Amount, input.ChangeType); input.UserId, input.Amount, input.ChangeType);
if (input.Amount <= 0) if (input.Amount <= 0)
throw new BusinessException("扣除积分数量必须大于0", 400); throw new BusinessException("扣除积分数量必须大于0", ResultCode.BAD_REQUEST);
DeductPointsOutput result = null!; DeductPointsOutput result = null!;
@ -71,7 +71,7 @@ public class PointsService(
public async Task<AddPointsOutput> AddPointsInTranAsync(AddPointsInput input) public async Task<AddPointsOutput> AddPointsInTranAsync(AddPointsInput input)
{ {
if (input.Amount <= 0) if (input.Amount <= 0)
throw new BusinessException("增加积分数量必须大于0", 400); throw new BusinessException("增加积分数量必须大于0", ResultCode.BAD_REQUEST);
// 查询用户当前积分 // 查询用户当前积分
var user = await Context.Queryable<Users>() var user = await Context.Queryable<Users>()
@ -79,7 +79,7 @@ public class PointsService(
.FirstAsync(); .FirstAsync();
if (user == null) if (user == null)
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
var previousBalance = user.Points; var previousBalance = user.Points;
var newBalance = previousBalance + input.Amount; var newBalance = previousBalance + input.Amount;
@ -129,7 +129,7 @@ public class PointsService(
public async Task<DeductPointsOutput> DeductPointsInTranAsync(DeductPointsInput input) public async Task<DeductPointsOutput> DeductPointsInTranAsync(DeductPointsInput input)
{ {
if (input.Amount <= 0) if (input.Amount <= 0)
throw new BusinessException("扣除积分数量必须大于0", 400); throw new BusinessException("扣除积分数量必须大于0", ResultCode.BAD_REQUEST);
// 查询用户当前积分 // 查询用户当前积分
var user = await Context.Queryable<Users>() var user = await Context.Queryable<Users>()
@ -137,13 +137,13 @@ public class PointsService(
.FirstAsync(); .FirstAsync();
if (user == null) if (user == null)
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
var previousBalance = user.Points; var previousBalance = user.Points;
// 余额不足校验 // 余额不足校验
if (previousBalance < input.Amount) if (previousBalance < input.Amount)
throw new BusinessException($"积分不足,需要 {input.Amount} 积分,当前余额 {previousBalance}", 400); throw new BusinessException($"积分不足,需要 {input.Amount} 积分,当前余额 {previousBalance}", ResultCode.BAD_REQUEST);
var newBalance = previousBalance - input.Amount; var newBalance = previousBalance - input.Amount;
@ -214,7 +214,7 @@ public class PointsService(
.FirstAsync(); .FirstAsync();
if (user == null) if (user == null)
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
// 查询累计收入Income 类型) // 查询累计收入Income 类型)
var totalIncome = await Context.Queryable<PointsRecord>() var totalIncome = await Context.Queryable<PointsRecord>()
@ -241,10 +241,10 @@ public class PointsService(
public async Task<PageListModel<PointsRecordOutput>> GetPointsRecordsAsync(PointsRecordQueryInput input) public async Task<PageListModel<PointsRecordOutput>> GetPointsRecordsAsync(PointsRecordQueryInput input)
{ {
if (input.PageIndex <= 0) if (input.PageIndex <= 0)
throw new BusinessException("页码必须大于0", 400); throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
if (input.PageSize <= 0 || input.PageSize > 100) if (input.PageSize <= 0 || input.PageSize > 100)
throw new BusinessException("每页条数必须在1-100之间", 400); throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
var query = Context.Queryable<PointsRecord>() var query = Context.Queryable<PointsRecord>()
.Where(r => r.UserId == input.UserId && !r.IsDeleted) .Where(r => r.UserId == input.UserId && !r.IsDeleted)

View File

@ -29,17 +29,17 @@ public class ProductService(
if (string.IsNullOrWhiteSpace(input.Name)) if (string.IsNullOrWhiteSpace(input.Name))
{ {
throw new BusinessException("商品名称不能为空", 400); throw new BusinessException("商品名称不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.Type)) if (string.IsNullOrWhiteSpace(input.Type))
{ {
throw new BusinessException("商品类型不能为空", 400); throw new BusinessException("商品类型不能为空", ResultCode.BAD_REQUEST);
} }
if (input.Price < 0) if (input.Price < 0)
{ {
throw new BusinessException("商品价格不能为负数", 400); throw new BusinessException("商品价格不能为负数", ResultCode.BAD_REQUEST);
} }
var product = new Product var product = new Product
@ -66,7 +66,7 @@ public class ProductService(
if (!result) if (!result)
{ {
logger.LogError("商品创建失败,商品名称: {Name}", input.Name); logger.LogError("商品创建失败,商品名称: {Name}", input.Name);
throw new BusinessException("创建商品失败", 500); throw new BusinessException("创建商品失败", ResultCode.GLOBAL_ERROR);
} }
// 将 temp 目录下的图片搬运到正式目录 // 将 temp 目录下的图片搬运到正式目录
@ -113,22 +113,22 @@ public class ProductService(
if (product == null) if (product == null)
{ {
logger.LogWarning("未找到要更新的商品ID: {Id}", id); logger.LogWarning("未找到要更新的商品ID: {Id}", id);
throw new BusinessException("商品不存在", 404); throw new BusinessException("商品不存在", ResultCode.NOT_FOUND);
} }
if (string.IsNullOrWhiteSpace(input.Name)) if (string.IsNullOrWhiteSpace(input.Name))
{ {
throw new BusinessException("商品名称不能为空", 400); throw new BusinessException("商品名称不能为空", ResultCode.BAD_REQUEST);
} }
if (string.IsNullOrWhiteSpace(input.Type)) if (string.IsNullOrWhiteSpace(input.Type))
{ {
throw new BusinessException("商品类型不能为空", 400); throw new BusinessException("商品类型不能为空", ResultCode.BAD_REQUEST);
} }
if (input.Price < 0) if (input.Price < 0)
{ {
throw new BusinessException("商品价格不能为负数", 400); throw new BusinessException("商品价格不能为负数", ResultCode.BAD_REQUEST);
} }
// 将 temp 目录下的新图片搬运到正式目录 // 将 temp 目录下的新图片搬运到正式目录
@ -158,7 +158,7 @@ public class ProductService(
if (!result) if (!result)
{ {
logger.LogError("商品更新失败ID: {Id}", id); logger.LogError("商品更新失败ID: {Id}", id);
throw new BusinessException("更新商品失败", 500); throw new BusinessException("更新商品失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("商品更新成功ID: {Id}", id); logger.LogInformation("商品更新成功ID: {Id}", id);
@ -195,14 +195,14 @@ public class ProductService(
if (product == null) if (product == null)
{ {
logger.LogWarning("未找到要删除的商品ID: {Id}", id); logger.LogWarning("未找到要删除的商品ID: {Id}", id);
throw new BusinessException("商品不存在", 404); throw new BusinessException("商品不存在", ResultCode.NOT_FOUND);
} }
var result = await productRepository.DeleteByIdAsync(id); var result = await productRepository.DeleteByIdAsync(id);
if (!result) if (!result)
{ {
logger.LogError("商品删除失败ID: {Id}", id); logger.LogError("商品删除失败ID: {Id}", id);
throw new BusinessException("删除商品失败", 500); throw new BusinessException("删除商品失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("商品删除成功ID: {Id}", id); logger.LogInformation("商品删除成功ID: {Id}", id);
@ -219,7 +219,7 @@ public class ProductService(
if (product == null) if (product == null)
{ {
logger.LogWarning("未找到商品ID: {Id}", id); logger.LogWarning("未找到商品ID: {Id}", id);
throw new BusinessException("商品不存在", 404); throw new BusinessException("商品不存在", ResultCode.NOT_FOUND);
} }
return new ProductOutput return new ProductOutput
@ -252,12 +252,12 @@ public class ProductService(
if (input.PageIndex <= 0) if (input.PageIndex <= 0)
{ {
throw new BusinessException("页码必须大于0", 400); throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
} }
if (input.PageSize <= 0 || input.PageSize > 100) if (input.PageSize <= 0 || input.PageSize > 100)
{ {
throw new BusinessException("每页条数必须在1-100之间", 400); throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
} }
RefAsync<int> totalNumber = 0; RefAsync<int> totalNumber = 0;
@ -303,7 +303,7 @@ public class ProductService(
if (product == null) if (product == null)
{ {
logger.LogWarning("未找到要更新状态的商品ID: {Id}", id); logger.LogWarning("未找到要更新状态的商品ID: {Id}", id);
throw new BusinessException("商品不存在", 404); throw new BusinessException("商品不存在", ResultCode.NOT_FOUND);
} }
product.Status = product.Status == (int)ProductStatusEnum.OnSale product.Status = product.Status == (int)ProductStatusEnum.OnSale
@ -316,7 +316,7 @@ public class ProductService(
if (!result) if (!result)
{ {
logger.LogError("商品状态更新失败ID: {Id}", id); logger.LogError("商品状态更新失败ID: {Id}", id);
throw new BusinessException("更新商品状态失败", 500); throw new BusinessException("更新商品状态失败", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("商品上下架状态更新成功ID: {Id}, SaleStatus: {SaleStatus}", id, product.Status); logger.LogInformation("商品上下架状态更新成功ID: {Id}, SaleStatus: {SaleStatus}", id, product.Status);

View File

@ -1,6 +1,7 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.IService; using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common; using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Points; using QYZH.InteractiveMagazine.Models.Dto.Points;
using QYZH.InteractiveMagazine.Models.Dto.UserAnswerTaskService; using QYZH.InteractiveMagazine.Models.Dto.UserAnswerTaskService;
using QYZH.InteractiveMagazine.Models.Entity; using QYZH.InteractiveMagazine.Models.Entity;
@ -939,7 +940,7 @@ public class UserAnswerTaskService(
if (relatedTasks == null || relatedTasks.Count == 0) if (relatedTasks == null || relatedTasks.Count == 0)
{ {
throw new BusinessException("任务不存在", 404); throw new BusinessException("任务不存在", ResultCode.NOT_FOUND);
} }
// ============================================ // ============================================
@ -972,7 +973,7 @@ public class UserAnswerTaskService(
if (userAnswers == null || userAnswers.Count == 0) if (userAnswers == null || userAnswers.Count == 0)
{ {
throw new BusinessException("请先完成答题再领取积分", 400); throw new BusinessException("请先完成答题再领取积分", ResultCode.BAD_REQUEST);
} }
// ============================================ // ============================================
@ -988,7 +989,7 @@ public class UserAnswerTaskService(
var completedAnswer = userAnswers.FirstOrDefault(a => a.JournalPageTaskId == task.Id && a.Status == (int)UserAnswerStatusEnum.Complete); var completedAnswer = userAnswers.FirstOrDefault(a => a.JournalPageTaskId == task.Id && a.Status == (int)UserAnswerStatusEnum.Complete);
if (completedAnswer == null) if (completedAnswer == null)
{ {
throw new BusinessException("跨页题目需要完成所有任务才能领取积分", 400); throw new BusinessException("跨页题目需要完成所有任务才能领取积分", ResultCode.BAD_REQUEST);
} }
} }
} }
@ -997,7 +998,7 @@ public class UserAnswerTaskService(
// 普通题目:只需要 Status=1 即可 // 普通题目:只需要 Status=1 即可
if (userAnswers.FirstOrDefault()?.Status != (int)UserAnswerStatusEnum.Complete) if (userAnswers.FirstOrDefault()?.Status != (int)UserAnswerStatusEnum.Complete)
{ {
throw new BusinessException("请先完成答题再领取积分", 400); throw new BusinessException("请先完成答题再领取积分", ResultCode.BAD_REQUEST);
} }
} }
@ -1020,7 +1021,7 @@ public class UserAnswerTaskService(
if (totalPoints <= 0) if (totalPoints <= 0)
{ {
throw new BusinessException("该任务无积分可领取", 400); throw new BusinessException("该任务无积分可领取", ResultCode.BAD_REQUEST);
} }
// ============================================ // ============================================
@ -1054,7 +1055,7 @@ public class UserAnswerTaskService(
if (existingRecord != null) if (existingRecord != null)
{ {
throw new BusinessException("积分已领取,请勿重复领取", 400); throw new BusinessException("积分已领取,请勿重复领取", ResultCode.BAD_REQUEST);
} }
// ============================================ // ============================================
@ -1110,7 +1111,7 @@ public class UserAnswerTaskService(
if (input == null || input.GroupIds == null || input.GroupIds.Count == 0) if (input == null || input.GroupIds == null || input.GroupIds.Count == 0)
{ {
throw new BusinessException("任务分组Id列表不能为空", 400); throw new BusinessException("任务分组Id列表不能为空", ResultCode.BAD_REQUEST);
} }
var groupIds = input.GroupIds.Distinct().ToList(); var groupIds = input.GroupIds.Distinct().ToList();

View File

@ -31,14 +31,14 @@ public class UserJournalService(
// 校验参数 // 校验参数
if (input.JournalId <= 0|| input.Id <= 0) if (input.JournalId <= 0|| input.Id <= 0)
{ {
throw new BusinessException("参数错误,未获取到期刊", 400); throw new BusinessException("参数错误,未获取到期刊", ResultCode.BAD_REQUEST);
} }
// 校验用户是否存在 // 校验用户是否存在
var user = await usersRepository.GetByIdAsync(userId); var user = await usersRepository.GetByIdAsync(userId);
if (user == null || user.IsDeleted) if (user == null || user.IsDeleted)
{ {
logger.LogWarning("绑定期刊失败用户不存在UserId: {UserId}", userId); logger.LogWarning("绑定期刊失败用户不存在UserId: {UserId}", userId);
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
} }
// 校验期刊是否存在 // 校验期刊是否存在
@ -46,14 +46,14 @@ public class UserJournalService(
if (journal == null || journal.IsDeleted) if (journal == null || journal.IsDeleted)
{ {
logger.LogWarning("绑定期刊失败期刊不存在JournalId: {JournalId}", input.JournalId); logger.LogWarning("绑定期刊失败期刊不存在JournalId: {JournalId}", input.JournalId);
throw new BusinessException("期刊不存在", 404); throw new BusinessException("期刊不存在", ResultCode.NOT_FOUND);
} }
// 校验期刊状态 // 校验期刊状态
if (journal.Status != (int)JournalStatusEnum.Published) if (journal.Status != (int)JournalStatusEnum.Published)
{ {
logger.LogWarning("绑定期刊失败期刊未发布JournalId: {JournalId}, Status: {Status}", input.JournalId, journal.Status); logger.LogWarning("绑定期刊失败期刊未发布JournalId: {JournalId}, Status: {Status}", input.JournalId, journal.Status);
throw new BusinessException("该期刊暂未发布,无法绑定", 400); throw new BusinessException("该期刊暂未发布,无法绑定", ResultCode.UNPROCESSABLE_ENTITY);
} }
// 防重复绑定:同一用户 + 期刊 + 实例 + 类型 // 防重复绑定:同一用户 + 期刊 + 实例 + 类型
@ -63,7 +63,7 @@ public class UserJournalService(
if (isExist) if (isExist)
{ {
logger.LogWarning("重复绑定期刊UserId: {UserId}, JournalId: {JournalId}, Type: {Type}", userId, input.JournalId, input.Type); logger.LogWarning("重复绑定期刊UserId: {UserId}, JournalId: {JournalId}, Type: {Type}", userId, input.JournalId, input.Type);
throw new BusinessException("该期刊已被绑定", 400); throw new BusinessException("该期刊已被绑定", ResultCode.BAD_REQUEST);
} }
// 检查是否为首次绑定期刊(用于激活宠物) // 检查是否为首次绑定期刊(用于激活宠物)
@ -89,7 +89,7 @@ public class UserJournalService(
if (!result) if (!result)
{ {
logger.LogError("绑定期刊失败写入数据库失败UserId: {UserId}, JournalId: {JournalId}", userId, input.JournalId); logger.LogError("绑定期刊失败写入数据库失败UserId: {UserId}, JournalId: {JournalId}", userId, input.JournalId);
throw new BusinessException("绑定期刊失败,请稍后重试", 500); throw new BusinessException("绑定期刊失败,请稍后重试", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("用户绑定期刊成功UserId: {UserId}, JournalId: {JournalId}, Id: {Id}", userId, input.JournalId, userJournal.Id); logger.LogInformation("用户绑定期刊成功UserId: {UserId}, JournalId: {JournalId}, Id: {Id}", userId, input.JournalId, userJournal.Id);
@ -129,12 +129,12 @@ public class UserJournalService(
if (input.PageIndex <= 0) if (input.PageIndex <= 0)
{ {
throw new BusinessException("页码必须大于0", 400); throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
} }
if (input.PageSize <= 0 || input.PageSize > 100) if (input.PageSize <= 0 || input.PageSize > 100)
{ {
throw new BusinessException("每页条数必须在1-100之间", 400); throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
} }
RefAsync<int> totalNumber = 0; RefAsync<int> totalNumber = 0;
@ -167,21 +167,21 @@ public class UserJournalService(
if (userJournal == null || userJournal.IsDeleted) if (userJournal == null || userJournal.IsDeleted)
{ {
logger.LogWarning("取消绑定失败记录不存在Id: {Id}", id); logger.LogWarning("取消绑定失败记录不存在Id: {Id}", id);
throw new BusinessException("绑定记录不存在", 404); throw new BusinessException("绑定记录不存在", ResultCode.NOT_FOUND);
} }
// 校验归属权:只能取消自己的绑定 // 校验归属权:只能取消自己的绑定
if (userJournal.UserId != userId) if (userJournal.UserId != userId)
{ {
logger.LogWarning("取消绑定失败无权操作UserId: {UserId}, RecordUserId: {RecordUserId}", userId, userJournal.UserId); logger.LogWarning("取消绑定失败无权操作UserId: {UserId}, RecordUserId: {RecordUserId}", userId, userJournal.UserId);
throw new BusinessException("无权取消该绑定", 403); throw new BusinessException("无权取消该绑定", ResultCode.FORBIDDEN);
} }
var result = await userJournalRepository.DeleteByIdAsync(id); var result = await userJournalRepository.DeleteByIdAsync(id);
if (!result) if (!result)
{ {
logger.LogError("取消绑定失败Id: {Id}", id); logger.LogError("取消绑定失败Id: {Id}", id);
throw new BusinessException("取消绑定失败,请稍后重试", 500); throw new BusinessException("取消绑定失败,请稍后重试", ResultCode.GLOBAL_ERROR);
} }
logger.LogInformation("取消期刊绑定成功UserId: {UserId}, Id: {Id}", userId, id); logger.LogInformation("取消期刊绑定成功UserId: {UserId}, Id: {Id}", userId, id);

View File

@ -197,7 +197,7 @@ public class UsersService(
// 校验用户是否存在 // 校验用户是否存在
var user = await Queryable().Where(u => u.Id == userId && !u.IsDeleted).FirstAsync(); var user = await Queryable().Where(u => u.Id == userId && !u.IsDeleted).FirstAsync();
if (user == null) if (user == null)
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
// 调用积分服务增加积分 // 调用积分服务增加积分
var result = await pointsService.AddPointsAsync(new AddPointsInput var result = await pointsService.AddPointsAsync(new AddPointsInput
@ -247,7 +247,7 @@ public class UsersService(
// 校验用户是否存在 // 校验用户是否存在
var user = await Queryable().Where(u => u.Id == userId && !u.IsDeleted).FirstAsync(); var user = await Queryable().Where(u => u.Id == userId && !u.IsDeleted).FirstAsync();
if (user == null) if (user == null)
throw new BusinessException("用户不存在", 404); throw new BusinessException("用户不存在", ResultCode.NOT_FOUND);
// 调用积分服务扣除积分 // 调用积分服务扣除积分
var result = await pointsService.DeductPointsAsync(new DeductPointsInput var result = await pointsService.DeductPointsAsync(new DeductPointsInput

View File

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

View File

@ -116,13 +116,13 @@ public class WeChatCommunityService(
if (input.MessageId <= 0) if (input.MessageId <= 0)
{ {
throw new BusinessException("消息ID无效", 400); throw new BusinessException("消息ID无效", ResultCode.BAD_REQUEST);
} }
var message = await messageRepository.GetByIdAsync(input.MessageId); var message = await messageRepository.GetByIdAsync(input.MessageId);
if (message == null) if (message == null)
{ {
throw new BusinessException("消息不存在", 404); throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
} }
// 检查是否已点赞 // 检查是否已点赞
@ -132,7 +132,7 @@ public class WeChatCommunityService(
if (existingLike != null) if (existingLike != null)
{ {
throw new BusinessException("您已点赞过该消息", 400); throw new BusinessException("您已点赞过该消息", ResultCode.BAD_REQUEST);
} }
// 插入点赞记录 // 插入点赞记录
@ -151,7 +151,7 @@ public class WeChatCommunityService(
var insertResult = await Context.Insertable(like).ExecuteCommandAsync(); var insertResult = await Context.Insertable(like).ExecuteCommandAsync();
if (insertResult <= 0) if (insertResult <= 0)
{ {
throw new BusinessException("点赞失败", 500); throw new BusinessException("点赞失败", ResultCode.GLOBAL_ERROR);
} }
// 更新点赞数 // 更新点赞数
@ -183,13 +183,13 @@ public class WeChatCommunityService(
if (messageId <= 0) if (messageId <= 0)
{ {
throw new BusinessException("消息ID无效", 400); throw new BusinessException("消息ID无效", ResultCode.BAD_REQUEST);
} }
var message = await messageRepository.GetByIdAsync(messageId); var message = await messageRepository.GetByIdAsync(messageId);
if (message == null) if (message == null)
{ {
throw new BusinessException("消息不存在", 404); throw new BusinessException("消息不存在", ResultCode.NOT_FOUND);
} }
var existingLike = await Context.Queryable<CommunityMessageLike>() var existingLike = await Context.Queryable<CommunityMessageLike>()
@ -198,7 +198,7 @@ public class WeChatCommunityService(
if (existingLike == null) if (existingLike == null)
{ {
throw new BusinessException("您尚未点赞过该消息", 400); throw new BusinessException("您尚未点赞过该消息", ResultCode.BAD_REQUEST);
} }
// 软删除点赞记录 // 软删除点赞记录

View File

@ -1,6 +1,7 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.IService; using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common; using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Dto.Bag; using QYZH.InteractiveMagazine.Models.Dto.Bag;
using QYZH.InteractiveMagazine.Models.Dto.Mall; using QYZH.InteractiveMagazine.Models.Dto.Mall;
using QYZH.InteractiveMagazine.Models.Dto.Points; using QYZH.InteractiveMagazine.Models.Dto.Points;
@ -187,10 +188,10 @@ public class WxMallService(
userId, input.ProductId, input.Quantity); userId, input.ProductId, input.Quantity);
if (input.ProductId <= 0) if (input.ProductId <= 0)
throw new BusinessException("商品Id无效", 400); throw new BusinessException("商品Id无效", ResultCode.BAD_REQUEST);
if (input.Quantity <= 0) if (input.Quantity <= 0)
throw new BusinessException("兑换数量必须大于0", 400); throw new BusinessException("兑换数量必须大于0", ResultCode.BAD_REQUEST);
// 查询商品 // 查询商品
var product = await exchangeRecordRepository.Context.Queryable<Product>() var product = await exchangeRecordRepository.Context.Queryable<Product>()
@ -198,7 +199,7 @@ public class WxMallService(
.FirstAsync(); .FirstAsync();
if (product == null) if (product == null)
throw new BusinessException("商品不存在或已下架", 404); throw new BusinessException("商品不存在或已下架", ResultCode.NOT_FOUND);
var totalCost = product.Price * input.Quantity; var totalCost = product.Price * input.Quantity;
@ -404,24 +405,24 @@ public class WxMallService(
logger.LogInformation("使用背包物品UserId: {UserId}, BagItemId: {BagItemId}", userId, input.BagItemId); logger.LogInformation("使用背包物品UserId: {UserId}, BagItemId: {BagItemId}", userId, input.BagItemId);
if (input.BagItemId <= 0) if (input.BagItemId <= 0)
throw new BusinessException("背包物品Id无效", 400); throw new BusinessException("背包物品Id无效", ResultCode.BAD_REQUEST);
var bagItem = await exchangeRecordRepository.Context.Queryable<UserBag>() var bagItem = await exchangeRecordRepository.Context.Queryable<UserBag>()
.Where(b => b.Id == input.BagItemId && b.UserId == userId && b.Status == (int)UserBagStatusEnum.Available) .Where(b => b.Id == input.BagItemId && b.UserId == userId && b.Status == (int)UserBagStatusEnum.Available)
.FirstAsync(); .FirstAsync();
if (bagItem == null) if (bagItem == null)
throw new BusinessException("背包物品不存在", 404); throw new BusinessException("背包物品不存在", ResultCode.NOT_FOUND);
if (bagItem.Quantity <= 0) if (bagItem.Quantity <= 0)
throw new BusinessException("物品数量不足", 400); throw new BusinessException("物品数量不足", ResultCode.BAD_REQUEST);
switch (bagItem.ItemType) switch (bagItem.ItemType)
{ {
case "MakeUpCard": case "MakeUpCard":
return await UseMakeUpCardAsync(userId, bagItem, input); return await UseMakeUpCardAsync(userId, bagItem, input);
default: default:
throw new BusinessException($"不支持使用该类型物品: {bagItem.ItemType}", 400); throw new BusinessException($"不支持使用该类型物品: {bagItem.ItemType}", ResultCode.BAD_REQUEST);
} }
} }
@ -431,15 +432,15 @@ public class WxMallService(
private async Task<UseItemOutput> UseMakeUpCardAsync(long userId, UserBag bagItem, UseItemInput input) private async Task<UseItemOutput> UseMakeUpCardAsync(long userId, UserBag bagItem, UseItemInput input)
{ {
if (string.IsNullOrEmpty(input.TargetDate)) if (string.IsNullOrEmpty(input.TargetDate))
throw new BusinessException("请指定补签日期", 400); throw new BusinessException("请指定补签日期", ResultCode.BAD_REQUEST);
if (!DateTime.TryParse(input.TargetDate, out var targetDate)) if (!DateTime.TryParse(input.TargetDate, out var targetDate))
throw new BusinessException("日期格式无效", 400); throw new BusinessException("日期格式无效", ResultCode.BAD_REQUEST);
targetDate = targetDate.Date; targetDate = targetDate.Date;
if (targetDate >= DateTime.Now.Date) if (targetDate >= DateTime.Now.Date)
throw new BusinessException("只能补签过去的日期", 400); throw new BusinessException("只能补签过去的日期", ResultCode.BAD_REQUEST);
// 调用签到服务执行补签(内部会检查并扣减补签卡) // 调用签到服务执行补签(内部会检查并扣减补签卡)
var checkInResult = await checkInService.MakeUpCheckInAsync(userId, targetDate); var checkInResult = await checkInService.MakeUpCheckInAsync(userId, targetDate);
@ -467,7 +468,7 @@ public class WxMallService(
.FirstAsync(); .FirstAsync();
if (pet == null) if (pet == null)
throw new BusinessException("您还没有宠物", 404); throw new BusinessException("您还没有宠物", ResultCode.NOT_FOUND);
if (input.SkinId == 0) if (input.SkinId == 0)
{ {
@ -488,7 +489,7 @@ public class WxMallService(
.FirstAsync(); .FirstAsync();
if (skin == null) if (skin == null)
throw new BusinessException("皮肤不存在", 404); throw new BusinessException("皮肤不存在", ResultCode.NOT_FOUND);
// 校验背包中是否拥有该皮肤(通过 MetaData 中的 SkinId 判断) // 校验背包中是否拥有该皮肤(通过 MetaData 中的 SkinId 判断)
var hasSkin = await exchangeRecordRepository.Context.Queryable<UserBag>() var hasSkin = await exchangeRecordRepository.Context.Queryable<UserBag>()
@ -499,7 +500,7 @@ public class WxMallService(
var owned = hasSkin.Any(b => GetSkinIdFromMetaData(b.MetaData) == input.SkinId); var owned = hasSkin.Any(b => GetSkinIdFromMetaData(b.MetaData) == input.SkinId);
if (!owned) if (!owned)
throw new BusinessException("您尚未拥有该皮肤,请先兑换", 400); throw new BusinessException("您尚未拥有该皮肤,请先兑换", ResultCode.BAD_REQUEST);
// 换肤 // 换肤
await exchangeRecordRepository.Context.Updateable<UserPet>() await exchangeRecordRepository.Context.Updateable<UserPet>()

View File

@ -62,7 +62,10 @@ public abstract class BaseController : ControllerBase
/// <returns>统一响应对象</returns> /// <returns>统一响应对象</returns>
protected BaseResponse<object> Fail(string message, int code = 500) protected BaseResponse<object> Fail(string message, int code = 500)
{ {
return BaseResponse<object>.Fail(ResultCode.GLOBAL_ERROR, message); var resultCode = Enum.IsDefined(typeof(ResultCode), code)
? (ResultCode)code
: ResultCode.GLOBAL_ERROR;
return BaseResponse<object>.Fail(resultCode, message);
} }
protected IActionResult ApiResult(bool success, string msg) protected IActionResult ApiResult(bool success, string msg)
@ -91,7 +94,7 @@ public abstract class BaseController : ControllerBase
//var webHostEnvironment = App.WebHostEnvironment; //var webHostEnvironment = App.WebHostEnvironment;
if (!Path.Exists(path)) if (!Path.Exists(path))
{ {
throw new BusinessException(fileName + "文件不存在"); throw new BusinessException(fileName + "文件不存在", ResultCode.NOT_FOUND);
} }
var stream = System.IO.File.OpenRead(path); //创建文件流 var stream = System.IO.File.OpenRead(path); //创建文件流

View File

@ -395,15 +395,15 @@ namespace QYZH.InteractiveMagazine.WebApi.Controllers
{ {
var entity = await JournalService.GetFirstAsync(x => x.Id == JournalId); var entity = await JournalService.GetFirstAsync(x => x.Id == JournalId);
if (entity == null) if (entity == null)
throw new BusinessException("书籍不存在"); throw new BusinessException("书籍不存在", ResultCode.NOT_FOUND);
var downloadUrl = entity.DownloadJournalPagePdfName; var downloadUrl = entity.DownloadJournalPagePdfName;
if (string.IsNullOrWhiteSpace(downloadUrl)) if (string.IsNullOrWhiteSpace(downloadUrl))
throw new BusinessException("下载点阵码PDF文件为空,请先铺码"); throw new BusinessException("下载点阵码PDF文件为空,请先铺码", ResultCode.BAD_REQUEST);
var stream = await httpClientFactory.CreateClient().GetStreamAsync(downloadUrl); //创建文件流 var stream = await httpClientFactory.CreateClient().GetStreamAsync(downloadUrl); //创建文件流
if (stream == null) if (stream == null)
throw new BusinessException("下载点阵码PDF文件失败"); throw new BusinessException("下载点阵码PDF文件失败", ResultCode.GLOBAL_ERROR);
Response.Headers.Append("Access-Control-Expose-Headers", "Content-Disposition"); Response.Headers.Append("Access-Control-Expose-Headers", "Content-Disposition");

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using QYZH.InteractiveMagazine.Common.Extensions;
using QYZH.InteractiveMagazine.Infrastructure.OSS; using QYZH.InteractiveMagazine.Infrastructure.OSS;
using QYZH.InteractiveMagazine.Models.Dto.Journal; using QYZH.InteractiveMagazine.Models.Dto.Journal;
using QYZH.InteractiveMagazine.Models.Entity; using QYZH.InteractiveMagazine.Models.Entity;
@ -65,7 +66,19 @@ public class AutoDotCodeConsumer(IConfiguration configuration,
var uploadFilePath = uploadPdfDic + uploadFileName; var uploadFilePath = uploadPdfDic + uploadFileName;
// 获取上传成功的书籍页码pdf文件 // 获取上传成功的书籍页码pdf文件
var pdfSteam = await httpClientFactory.CreateClient().GetStreamAsync(journalPagePrintDtoMessage.JournalPdfUrl, cancellationToken); var journalPdfKey = journalPagePrintDtoMessage.JournalPdfUrl?.RemoveDomain();
if (string.IsNullOrWhiteSpace(journalPdfKey))
{
logger.LogError("书籍上传的PDF文件地址为空JournalId: {JournalId}", journalPagePrintDtoMessage.JournalId);
return;
}
await using var pdfSteam = ossService.GetObjectStream(journalPdfKey);
if (pdfSteam == null)
{
logger.LogError("获取书籍上传的PDF文件失败OSS Key: {OssKey}", journalPdfKey);
return;
}
await using (var fs = new FileStream(uploadFilePath, FileMode.CreateNew, FileAccess.Write)) await using (var fs = new FileStream(uploadFilePath, FileMode.CreateNew, FileAccess.Write))
{ {

View File

@ -1,18 +1,21 @@
using Newtonsoft.Json;
using QYZH.InteractiveMagazine.Infrastructure.OSS;
using SqlSugar;
using System.Text; using System.Text;
using System.Threading.Channels;
using Yitter.IdGenerator;
namespace QYZH.InteractiveMagazine.WorkService.Consumers; namespace QYZH.InteractiveMagazine.WorkService.Consumers;
/// <summary> /// <summary>
/// 期刊任务接收消费者(示例) /// 期刊任务接收消费者(示例)
/// </summary> /// </summary>
public class JournalTaskReceiveConsumer : IQueueConsumer public class JournalTaskReceiveConsumer(ILogger<JournalTaskReceiveConsumer> logger, IConfiguration configuration,
IServiceScopeFactory scopeFactory,
IWebHostEnvironment webHostEnvironment,
IHttpClientFactory httpClientFactory,
OssService ossService) : IQueueConsumer
{ {
private readonly ILogger<JournalTaskReceiveConsumer> _logger;
public JournalTaskReceiveConsumer(ILogger<JournalTaskReceiveConsumer> logger)
{
_logger = logger;
}
public string Exchange => "ex.journal"; public string Exchange => "ex.journal";
@ -20,20 +23,63 @@ public class JournalTaskReceiveConsumer : IQueueConsumer
public string RoutingKey => "rk.journal.task.receive"; public string RoutingKey => "rk.journal.task.receive";
public async Task HandleAsync(byte[] message, CancellationToken cancellationToken = default) public async Task HandleAsync(byte[] body, CancellationToken cancellationToken = default)
{ {
var body = Encoding.UTF8.GetString(message); var message = Encoding.UTF8.GetString(body);
_logger.LogInformation("收到期刊任务消息: {Message}", body); logger.LogInformation("收到期刊任务消息: {Message}", message);
using var scope = scopeFactory.CreateScope();
var client = scope.ServiceProvider.GetRequiredService<ISqlSugarClient>();
// TODO: 在此编写具体的消息处理逻辑 // TODO: 在此编写具体的消息处理逻辑
try
{
var data = System.Text.Json.JsonSerializer.Deserialize<QuestionData>(message);
client.Ado.CommitTran();
}
catch (Exception ex)
{
client.Ado.RollbackTran();
logger.LogError(ex.Message + ex.StackTrace);
}
await Task.CompletedTask; await Task.CompletedTask;
} }
public Task OnErrorAsync(byte[] message, Exception exception) public Task OnErrorAsync(byte[] body, Exception exception)
{ {
var body = Encoding.UTF8.GetString(message); var message = Encoding.UTF8.GetString(body);
_logger.LogError(exception, "处理期刊任务消息失败: {Message}", body); logger.LogError(exception, "处理期刊任务消息失败: {Message}", message);
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
public class QuestionData
{
public long UserId { get; set; }
public long JournalId { get; set; }
public long PageId { get; set; }
public string PageAnswerUrl { get; set; }
public Question[] Questions { get; set; }
public DateTime CreatedTime { get; set; }
}
public class Question
{
public long Id { get; set; }
public string Url { get; set; }
public string[] AnswerUrl { get; set; }
public DateTime AnswerStartTime { get; set; }
public DateTime AnswerEndTime { get; set; }
public int AnswerTime { get; set; }
public int BreakCount { get; set; }
public List<BreakTime> BreakTimes { get; set; }
}
public class BreakTime
{
public DateTime Time { get; set; }
public long WaitTime { get; set; }
}

View File

@ -1,33 +0,0 @@
-- ========================================
-- 宠物模块数据结构优化迁移脚本
-- 执行前请备份相关表数据
-- ========================================
-- 1. 修改 Pet 表CurrentEvolutionId int → bigint
ALTER TABLE Pet MODIFY COLUMN CurrentEvolutionId BIGINT NOT NULL DEFAULT 0;
-- 2. 修改 PetEvolution 表PreviousEvolutionId int → bigint, 删除 ImageUrl
ALTER TABLE PetEvolution MODIFY COLUMN PreviousEvolutionId BIGINT NULL;
ALTER TABLE PetEvolution DROP COLUMN ImageUrl;
-- 3. 修改 PetSkin 表:删除 ImageUrl 和 ProductId
ALTER TABLE PetSkin DROP COLUMN ImageUrl;
ALTER TABLE PetSkin DROP COLUMN ProductId;
-- 4. 新建 PetSkinImage 表(每个皮肤在每个进化阶段下有一组有序图片)
CREATE TABLE IF NOT EXISTS PetSkinImage (
Id BIGINT NOT NULL PRIMARY KEY COMMENT '主键雪花ID',
SkinId BIGINT NOT NULL COMMENT '皮肤Id关联PetSkin.Id0表示默认皮肤',
EvolutionStageId BIGINT NOT NULL COMMENT '进化阶段Id关联PetEvolution.Id',
ImageUrl VARCHAR(500) NOT NULL COMMENT '图片地址',
SortOrder INT NOT NULL DEFAULT 0 COMMENT '图片顺序(动画帧序号)',
Type VARCHAR(50) NOT NULL DEFAULT 'Normal' COMMENT '图片类型: Normal, Special',
Status INT NOT NULL DEFAULT 0 COMMENT '基础状态',
IsDeleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '软删除',
CreatedBy VARCHAR(100) NULL COMMENT '创建人',
CreatedAt DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
UpdatedBy VARCHAR(100) NULL COMMENT '更新人',
UpdatedAt DATETIME NULL COMMENT '更新时间',
INDEX idx_skin_evolution (SkinId, EvolutionStageId),
INDEX idx_sort (SkinId, EvolutionStageId, SortOrder)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='宠物皮肤图片表';