2026-06-10 17:53:38 +08:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.IService;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.Models.Common;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.Models.Dto;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.Models.Dto.CheckIn;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.Models.Entity;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.Models.Enum;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.Repository;
|
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
|
|
|
|
|
|
|
namespace QYZH.InteractiveMagazine.Service;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 签到配置服务实现
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class CheckInConfigService(
|
|
|
|
|
|
BaseRepository<CheckInConfig> checkInConfigRepository,
|
|
|
|
|
|
ILogger<CheckInConfigService> logger)
|
|
|
|
|
|
: BaseRepository<CheckInConfig>, ICheckInConfigService
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建签到配置
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<CheckInConfigOutput> CreateAsync(CheckInConfigInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.LogInformation("正在创建签到配置,DayNumber: {DayNumber}, Type: {Type}", input.DayNumber, input.Type);
|
|
|
|
|
|
|
|
|
|
|
|
if (input.DayNumber <= 0)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("连续签到天数必须大于0", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (input.RewardPoints < 0)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("奖励积分不能为负数", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (input.BonusPoints < 0)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("额外奖励积分不能为负数", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查同类型下是否已存在相同天数配置
|
|
|
|
|
|
var exists = await checkInConfigRepository.Context.Queryable<CheckInConfig>()
|
|
|
|
|
|
.Where(c => c.Type == input.Type && c.DayNumber == input.DayNumber && !c.IsDeleted)
|
|
|
|
|
|
.AnyAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (exists)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException($"该类型下已存在连续{input.DayNumber}天的配置", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var config = new CheckInConfig
|
|
|
|
|
|
{
|
|
|
|
|
|
DayNumber = input.DayNumber,
|
|
|
|
|
|
RewardPoints = input.RewardPoints,
|
|
|
|
|
|
BonusPoints = input.BonusPoints,
|
|
|
|
|
|
Type = input.Type,
|
|
|
|
|
|
Status = (int)DefaultStatusEnum.Active,
|
|
|
|
|
|
CreatedBy = "System",
|
|
|
|
|
|
UpdatedBy = "System",
|
|
|
|
|
|
CreatedAt = DateTime.Now,
|
|
|
|
|
|
UpdatedAt = DateTime.Now,
|
|
|
|
|
|
IsDeleted = false
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var result = await checkInConfigRepository.InsertAsync(config);
|
|
|
|
|
|
if (!result)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("创建签到配置失败", ResultCode.GLOBAL_ERROR);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
logger.LogInformation("签到配置创建成功,ID: {Id}", config.Id);
|
|
|
|
|
|
return MapToOutput(config);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 更新签到配置
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<CheckInConfigOutput> UpdateAsync(long id, CheckInConfigInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.LogInformation("正在更新签到配置,ID: {Id}", id);
|
|
|
|
|
|
|
|
|
|
|
|
var config = await checkInConfigRepository.GetByIdAsync(id);
|
|
|
|
|
|
if (config == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.LogWarning("未找到要更新的签到配置,ID: {Id}", id);
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("签到配置不存在", ResultCode.NOT_FOUND);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (input.DayNumber <= 0)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("连续签到天数必须大于0", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (input.RewardPoints < 0)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("奖励积分不能为负数", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (input.BonusPoints < 0)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("额外奖励积分不能为负数", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查同类型下是否已存在相同天数配置(排除自身)
|
|
|
|
|
|
var exists = await checkInConfigRepository.Context.Queryable<CheckInConfig>()
|
|
|
|
|
|
.Where(c => c.Type == input.Type && c.DayNumber == input.DayNumber && c.Id != id && !c.IsDeleted)
|
|
|
|
|
|
.AnyAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (exists)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException($"该类型下已存在连续{input.DayNumber}天的配置", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
config.DayNumber = input.DayNumber;
|
|
|
|
|
|
config.RewardPoints = input.RewardPoints;
|
|
|
|
|
|
config.BonusPoints = input.BonusPoints;
|
|
|
|
|
|
config.Type = input.Type;
|
|
|
|
|
|
config.UpdatedBy = "System";
|
|
|
|
|
|
config.UpdatedAt = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
var updateResult = await checkInConfigRepository.UpdateAsync(config);
|
|
|
|
|
|
if (!updateResult)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("更新签到配置失败", ResultCode.GLOBAL_ERROR);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
logger.LogInformation("签到配置更新成功,ID: {Id}", id);
|
|
|
|
|
|
return MapToOutput(config);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 删除签到配置(软删除)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task DeleteAsync(long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.LogInformation("正在删除签到配置,ID: {Id}", id);
|
|
|
|
|
|
|
|
|
|
|
|
var config = await checkInConfigRepository.GetByIdAsync(id);
|
|
|
|
|
|
if (config == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.LogWarning("未找到要删除的签到配置,ID: {Id}", id);
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("签到配置不存在", ResultCode.NOT_FOUND);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var result = await checkInConfigRepository.Context.Updateable<CheckInConfig>()
|
|
|
|
|
|
.SetColumns(c => new CheckInConfig
|
|
|
|
|
|
{
|
|
|
|
|
|
IsDeleted = true,
|
|
|
|
|
|
UpdatedBy = "System",
|
|
|
|
|
|
UpdatedAt = DateTime.Now
|
|
|
|
|
|
})
|
|
|
|
|
|
.Where(c => c.Id == id)
|
|
|
|
|
|
.ExecuteCommandAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (result <= 0)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("删除签到配置失败", ResultCode.GLOBAL_ERROR);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
logger.LogInformation("签到配置删除成功,ID: {Id}", id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据ID获取签到配置
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<CheckInConfigOutput> GetByIdAsync(long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var config = await checkInConfigRepository.GetByIdAsync(id);
|
|
|
|
|
|
if (config == null)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("签到配置不存在", ResultCode.NOT_FOUND);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return MapToOutput(config);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 分页查询签到配置列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<PageListModel<CheckInConfigOutput>> GetListAsync(CheckInConfigQueryInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.LogInformation("正在查询签到配置列表,页码: {PageIndex}, 每页条数: {PageSize}", input.PageIndex, input.PageSize);
|
|
|
|
|
|
|
|
|
|
|
|
if (input.PageIndex <= 0)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("页码必须大于0", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (input.PageSize <= 0 || input.PageSize > 100)
|
|
|
|
|
|
{
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("每页条数必须在1-100之间", ResultCode.BAD_REQUEST);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RefAsync<int> totalNumber = 0;
|
|
|
|
|
|
var configs = await checkInConfigRepository.Queryable()
|
|
|
|
|
|
.Where(c => !c.IsDeleted)
|
|
|
|
|
|
.WhereIF(input.Type.HasValue, c => c.Type == input.Type.Value)
|
|
|
|
|
|
.OrderBy(c => c.Type)
|
|
|
|
|
|
.OrderBy(c => c.DayNumber)
|
|
|
|
|
|
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
|
|
|
|
|
|
|
|
|
|
|
|
var pageResult = configs.Select(MapToOutput).ToList();
|
|
|
|
|
|
|
|
|
|
|
|
var result = new PageListModel<CheckInConfigOutput>(new List<CheckInConfigOutput>(), input.PageIndex, input.PageSize, totalNumber);
|
|
|
|
|
|
result.Result = pageResult;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 更新签到配置启用/禁用状态
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<bool> UpdateStatusAsync(long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var config = await checkInConfigRepository.GetByIdAsync(id);
|
|
|
|
|
|
if (config == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.LogWarning("未找到要更新状态的签到配置,ID: {Id}", id);
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("签到配置不存在", ResultCode.NOT_FOUND);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
config.Status = config.Status == (int)DefaultStatusEnum.Active
|
|
|
|
|
|
? (int)DefaultStatusEnum.Inactive
|
|
|
|
|
|
: (int)DefaultStatusEnum.Active;
|
|
|
|
|
|
config.UpdatedBy = "System";
|
|
|
|
|
|
config.UpdatedAt = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
var result = await checkInConfigRepository.UpdateAsync(config);
|
|
|
|
|
|
if (!result)
|
|
|
|
|
|
{
|
|
|
|
|
|
logger.LogError("签到配置状态更新失败,ID: {Id}", id);
|
2026-06-29 16:34:26 +08:00
|
|
|
|
throw new BusinessException("更新签到配置状态失败", ResultCode.GLOBAL_ERROR);
|
2026-06-10 17:53:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
logger.LogInformation("签到配置状态更新成功,ID: {Id}, Status: {Status}", id, config.Status);
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 实体映射为输出DTO
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static CheckInConfigOutput MapToOutput(CheckInConfig config)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new CheckInConfigOutput
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = config.Id,
|
|
|
|
|
|
DayNumber = config.DayNumber,
|
|
|
|
|
|
RewardPoints = config.RewardPoints,
|
|
|
|
|
|
BonusPoints = config.BonusPoints,
|
|
|
|
|
|
Type = config.Type,
|
|
|
|
|
|
Status = config.Status,
|
|
|
|
|
|
CreatedBy = config.CreatedBy,
|
|
|
|
|
|
CreatedAt = config.CreatedAt,
|
|
|
|
|
|
UpdatedBy = config.UpdatedBy,
|
|
|
|
|
|
UpdatedAt = config.UpdatedAt
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|