Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.Service/UserJournalService.cs
glz 0126c6b097 refactor: 完善枚举系统与状态类型转换,新增枚举管理接口
1. 为所有枚举添加Description特性用于中文描述
2. 移除实体类中冗余的状态字段注释与定义
3. 将所有枚举状态参数改为int类型转换,统一数据交互格式
4. 新增系统管理枚举查询接口与实现,支持获取所有枚举元数据
5. 调整宠物服务模板状态更新接口参数类型
2026-06-08 17:54:36 +08:00

190 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.Extensions.Logging;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Dto;
using QYZH.InteractiveMagazine.Models.Entity;
using QYZH.InteractiveMagazine.Models.Enum;
using QYZH.InteractiveMagazine.Repository;
using SqlSugar;
namespace QYZH.InteractiveMagazine.Service;
/// <summary>
/// 用户期刊关联服务实现
/// </summary>
public class UserJournalService(
BaseRepository<UserJournal> userJournalRepository,
BaseRepository<Users> usersRepository,
BaseRepository<Journal> journalRepository,
ILogger<UserJournalService> logger,
IPetService petService)
: BaseRepository<UserJournal>, IUserJournalService
{
/// <summary>
/// 用户绑定期刊(扫码绑定)
/// </summary>
public async Task<BindJournalOutput> BindJournalAsync(long userId, BindJournalInput input)
{
logger.LogInformation("用户绑定期刊UserId: {UserId}, JournalId: {JournalId}, Id: {Id}, Type: {Type}",
userId, input.JournalId, input.Id, input.Type);
// 校验参数
if (input.JournalId <= 0|| input.Id <= 0)
{
throw new BusinessException("参数错误,未获取到期刊", 400);
}
// 校验用户是否存在
var user = await usersRepository.GetByIdAsync(userId);
if (user == null || user.IsDeleted)
{
logger.LogWarning("绑定期刊失败用户不存在UserId: {UserId}", userId);
throw new BusinessException("用户不存在", 404);
}
// 校验期刊是否存在
var journal = await journalRepository.GetByIdAsync(input.JournalId);
if (journal == null || journal.IsDeleted)
{
logger.LogWarning("绑定期刊失败期刊不存在JournalId: {JournalId}", input.JournalId);
throw new BusinessException("期刊不存在", 404);
}
// 校验期刊状态
if (journal.Status != (int)JournalStatusEnum.Published)
{
logger.LogWarning("绑定期刊失败期刊未发布JournalId: {JournalId}, Status: {Status}", input.JournalId, journal.Status);
throw new BusinessException("该期刊暂未发布,无法绑定", 400);
}
// 防重复绑定:同一用户 + 期刊 + 实例 + 类型
var isExist = userJournalRepository.Any(uj =>
uj.Id == input.Id);
if (isExist)
{
logger.LogWarning("重复绑定期刊UserId: {UserId}, JournalId: {JournalId}, Type: {Type}", userId, input.JournalId, input.Type);
throw new BusinessException("该期刊已被绑定", 400);
}
// 检查是否为首次绑定期刊(用于激活宠物)
var isFirstBind = !userJournalRepository.Context.Queryable<UserJournal>()
.Any(uj => uj.UserId == userId);
// 创建绑定记录
var userJournal = new UserJournal
{
UserId = userId,
JournalId = input.JournalId,
Id = input.Id,
Type = Enum.Parse<UserJournalTypeEnum>(input.Type, true),
Status = (int)UserJournalStatusEnum.Active,
IsDeleted = false,
CreatedBy = userId.ToString(),
CreatedAt = DateTime.Now,
UpdatedBy = userId.ToString(),
UpdatedAt = DateTime.Now
};
var result = await userJournalRepository.InsertAsync(userJournal);
if (!result)
{
logger.LogError("绑定期刊失败写入数据库失败UserId: {UserId}, JournalId: {JournalId}", userId, input.JournalId);
throw new BusinessException("绑定期刊失败,请稍后重试", 500);
}
logger.LogInformation("用户绑定期刊成功UserId: {UserId}, JournalId: {JournalId}, Id: {Id}", userId, input.JournalId, userJournal.Id);
// 首次绑定期刊时激活宠物
if (isFirstBind)
{
try
{
await petService.ActivatePetAsync(userId);
}
catch (Exception ex)
{
logger.LogError(ex, "首次绑定期刊激活宠物失败UserId: {UserId}", userId);
// 宠物激活失败不阻断绑定流程
}
}
return new BindJournalOutput
{
Id = userJournal.Id,
UserId = userJournal.UserId,
JournalId = userJournal.JournalId,
Type = userJournal.Type.ToString(),
Status = userJournal.Status.ToString(),
CreatedAt = userJournal.CreatedAt
};
}
/// <summary>
/// 获取用户的期刊绑定列表
/// </summary>
public async Task<PageListModel<BindJournalOutput>> GetUserJournalsAsync(long userId, UserJournalQueryInput input)
{
logger.LogInformation("查询用户期刊绑定列表UserId: {UserId}, PageIndex: {PageIndex}, PageSize: {PageSize}",
userId, input.PageIndex, input.PageSize);
if (input.PageIndex <= 0)
{
throw new BusinessException("页码必须大于0", 400);
}
if (input.PageSize <= 0 || input.PageSize > 100)
{
throw new BusinessException("每页条数必须在1-100之间", 400);
}
RefAsync<int> totalNumber = 0;
var pageResult = await userJournalRepository.Queryable()
.Where(uj => uj.UserId == userId)
.WhereIF(!string.IsNullOrWhiteSpace(input.Type), uj => uj.Type.ToString() == input.Type)
.OrderByDescending(uj => uj.CreatedAt)
.Select(uj => new BindJournalOutput
{
Id = uj.Id,
UserId = uj.UserId,
JournalId = uj.JournalId,
Type = uj.Type.ToString(),
Status = uj.Status.ToString(),
CreatedAt = uj.CreatedAt
}, true)
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
return new PageListModel<BindJournalOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
}
/// <summary>
/// 取消期刊绑定
/// </summary>
public async Task UnbindJournalAsync(long userId, long id)
{
logger.LogInformation("取消期刊绑定UserId: {UserId}, Id: {Id}", userId, id);
var userJournal = await userJournalRepository.GetByIdAsync(id);
if (userJournal == null || userJournal.IsDeleted)
{
logger.LogWarning("取消绑定失败记录不存在Id: {Id}", id);
throw new BusinessException("绑定记录不存在", 404);
}
// 校验归属权:只能取消自己的绑定
if (userJournal.UserId != userId)
{
logger.LogWarning("取消绑定失败无权操作UserId: {UserId}, RecordUserId: {RecordUserId}", userId, userJournal.UserId);
throw new BusinessException("无权取消该绑定", 403);
}
var result = await userJournalRepository.DeleteByIdAsync(id);
if (!result)
{
logger.LogError("取消绑定失败Id: {Id}", id);
throw new BusinessException("取消绑定失败,请稍后重试", 500);
}
logger.LogInformation("取消期刊绑定成功UserId: {UserId}, Id: {Id}", userId, id);
}
}