411 lines
14 KiB
C#
411 lines
14 KiB
C#
|
|
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.Repository;
|
|||
|
|
using SqlSugar;
|
|||
|
|
|
|||
|
|
namespace QYZH.InteractiveMagazine.Service;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 勋章服务实现
|
|||
|
|
/// </summary>
|
|||
|
|
public class MedalService(BaseRepository<Medal> medalRepository, ILogger<MedalService> logger) : BaseRepository<Medal>, IMedalService
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 创建勋章
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<MedalOutput> CreateAsync(MedalInput input)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("正在创建勋章,勋章名称: {Name}", input.Name);
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(input.Name))
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("勋章名称不能为空", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(input.ConditionType))
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("条件类型不能为空", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(input.Type))
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("勋章类型不能为空", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (input.ConditionValue < 0)
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("条件阈值不能为负数", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var medal = new Medal
|
|||
|
|
{
|
|||
|
|
Name = input.Name.Trim(),
|
|||
|
|
Description = input.Description,
|
|||
|
|
ImageUrl = input.ImageUrl,
|
|||
|
|
ConditionType = input.ConditionType,
|
|||
|
|
ConditionValue = input.ConditionValue,
|
|||
|
|
SortOrder = input.SortOrder,
|
|||
|
|
Type = input.Type,
|
|||
|
|
JournalId = input.JournalId,
|
|||
|
|
CreatedBy = "System",
|
|||
|
|
UpdatedBy = "System",
|
|||
|
|
CreatedAt = DateTime.Now,
|
|||
|
|
UpdatedAt = DateTime.Now,
|
|||
|
|
IsDeleted = false
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var result = await medalRepository.InsertAsync(medal);
|
|||
|
|
if (!result)
|
|||
|
|
{
|
|||
|
|
logger.LogError("勋章创建失败,勋章名称: {Name}", input.Name);
|
|||
|
|
throw new BusinessException("创建勋章失败", 500);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.LogInformation("勋章创建成功,勋章名称: {Name}, ID: {Id}", input.Name, medal.Id);
|
|||
|
|
|
|||
|
|
return new MedalOutput
|
|||
|
|
{
|
|||
|
|
Id = medal.Id,
|
|||
|
|
Name = medal.Name,
|
|||
|
|
Description = medal.Description,
|
|||
|
|
ImageUrl = medal.ImageUrl,
|
|||
|
|
ConditionType = medal.ConditionType,
|
|||
|
|
ConditionValue = medal.ConditionValue,
|
|||
|
|
SortOrder = medal.SortOrder,
|
|||
|
|
Type = medal.Type,
|
|||
|
|
JournalId = medal.JournalId,
|
|||
|
|
CreatedBy = medal.CreatedBy,
|
|||
|
|
CreatedAt = medal.CreatedAt,
|
|||
|
|
UpdatedBy = medal.UpdatedBy,
|
|||
|
|
UpdatedAt = medal.UpdatedAt
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 更新勋章
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<MedalOutput> UpdateAsync(long id, MedalInput input)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("正在更新勋章,ID: {Id}", id);
|
|||
|
|
|
|||
|
|
var medal = await medalRepository.GetByIdAsync(id);
|
|||
|
|
if (medal == null)
|
|||
|
|
{
|
|||
|
|
logger.LogWarning("未找到要更新的勋章,ID: {Id}", id);
|
|||
|
|
throw new BusinessException("勋章不存在", 404);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(input.Name))
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("勋章名称不能为空", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(input.ConditionType))
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("条件类型不能为空", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(input.Type))
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("勋章类型不能为空", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (input.ConditionValue < 0)
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("条件阈值不能为负数", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
medal.Name = input.Name.Trim();
|
|||
|
|
medal.Description = input.Description;
|
|||
|
|
medal.ImageUrl = input.ImageUrl;
|
|||
|
|
medal.ConditionType = input.ConditionType;
|
|||
|
|
medal.ConditionValue = input.ConditionValue;
|
|||
|
|
medal.SortOrder = input.SortOrder;
|
|||
|
|
medal.Type = input.Type;
|
|||
|
|
medal.JournalId = input.JournalId;
|
|||
|
|
medal.UpdatedBy = "System";
|
|||
|
|
medal.UpdatedAt = DateTime.Now;
|
|||
|
|
|
|||
|
|
var result = await medalRepository.UpdateAsync(medal);
|
|||
|
|
if (!result)
|
|||
|
|
{
|
|||
|
|
logger.LogError("勋章更新失败,ID: {Id}", id);
|
|||
|
|
throw new BusinessException("更新勋章失败", 500);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.LogInformation("勋章更新成功,ID: {Id}", id);
|
|||
|
|
|
|||
|
|
return new MedalOutput
|
|||
|
|
{
|
|||
|
|
Id = medal.Id,
|
|||
|
|
Name = medal.Name,
|
|||
|
|
Description = medal.Description,
|
|||
|
|
ImageUrl = medal.ImageUrl,
|
|||
|
|
ConditionType = medal.ConditionType,
|
|||
|
|
ConditionValue = medal.ConditionValue,
|
|||
|
|
SortOrder = medal.SortOrder,
|
|||
|
|
Type = medal.Type,
|
|||
|
|
JournalId = medal.JournalId,
|
|||
|
|
CreatedBy = medal.CreatedBy,
|
|||
|
|
CreatedAt = medal.CreatedAt,
|
|||
|
|
UpdatedBy = medal.UpdatedBy,
|
|||
|
|
UpdatedAt = medal.UpdatedAt
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 删除勋章(软删除)
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task DeleteAsync(long id)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("正在删除勋章,ID: {Id}", id);
|
|||
|
|
|
|||
|
|
var medal = await medalRepository.GetByIdAsync(id);
|
|||
|
|
if (medal == null)
|
|||
|
|
{
|
|||
|
|
logger.LogWarning("未找到要删除的勋章,ID: {Id}", id);
|
|||
|
|
throw new BusinessException("勋章不存在", 404);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var result = await medalRepository.DeleteByIdAsync(id);
|
|||
|
|
if (!result)
|
|||
|
|
{
|
|||
|
|
logger.LogError("勋章删除失败,ID: {Id}", id);
|
|||
|
|
throw new BusinessException("删除勋章失败", 500);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.LogInformation("勋章删除成功,ID: {Id}", id);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据ID获取勋章
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<MedalOutput> GetByIdAsync(long id)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("正在获取勋章信息,ID: {Id}", id);
|
|||
|
|
|
|||
|
|
var medal = await medalRepository.GetByIdAsync(id);
|
|||
|
|
if (medal == null)
|
|||
|
|
{
|
|||
|
|
logger.LogWarning("未找到勋章,ID: {Id}", id);
|
|||
|
|
throw new BusinessException("勋章不存在", 404);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return new MedalOutput
|
|||
|
|
{
|
|||
|
|
Id = medal.Id,
|
|||
|
|
Name = medal.Name,
|
|||
|
|
Description = medal.Description,
|
|||
|
|
ImageUrl = medal.ImageUrl,
|
|||
|
|
ConditionType = medal.ConditionType,
|
|||
|
|
ConditionValue = medal.ConditionValue,
|
|||
|
|
SortOrder = medal.SortOrder,
|
|||
|
|
Type = medal.Type,
|
|||
|
|
JournalId = medal.JournalId,
|
|||
|
|
CreatedBy = medal.CreatedBy,
|
|||
|
|
CreatedAt = medal.CreatedAt,
|
|||
|
|
UpdatedBy = medal.UpdatedBy,
|
|||
|
|
UpdatedAt = medal.UpdatedAt
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 分页查询勋章列表
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<PageListModel<MedalOutput>> GetListAsync(MedalQueryInput input)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("正在查询勋章列表,页码: {PageIndex}, 每页条数: {PageSize}", 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 medalRepository.Queryable()
|
|||
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), m => m.Name.Contains(input.Name))
|
|||
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Type), m => m.Type == input.Type)
|
|||
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.ConditionType), m => m.ConditionType == input.ConditionType)
|
|||
|
|
.OrderBy(m => m.SortOrder, SqlSugar.OrderByType.Asc)
|
|||
|
|
.OrderByDescending(m => m.CreatedAt)
|
|||
|
|
.Select(m => new MedalOutput
|
|||
|
|
{
|
|||
|
|
Id = m.Id,
|
|||
|
|
Name = m.Name,
|
|||
|
|
Description = m.Description,
|
|||
|
|
ImageUrl = m.ImageUrl,
|
|||
|
|
ConditionType = m.ConditionType,
|
|||
|
|
ConditionValue = m.ConditionValue,
|
|||
|
|
SortOrder = m.SortOrder,
|
|||
|
|
Type = m.Type,
|
|||
|
|
JournalId = m.JournalId,
|
|||
|
|
CreatedBy = m.CreatedBy,
|
|||
|
|
CreatedAt = m.CreatedAt,
|
|||
|
|
UpdatedBy = m.UpdatedBy,
|
|||
|
|
UpdatedAt = m.UpdatedAt
|
|||
|
|
}, true)
|
|||
|
|
.ToPageListAsync(input.PageIndex, input.PageSize, totalNumber);
|
|||
|
|
|
|||
|
|
return new PageListModel<MedalOutput>(pageResult, input.PageIndex, input.PageSize, totalNumber);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 更新勋章启用/禁用状态
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task UpdateStatusAsync(long id, int status)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("正在更新勋章状态,ID: {Id}, Status: {Status}", id, status);
|
|||
|
|
|
|||
|
|
if (status != 0 && status != 1)
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("状态值无效,只能为0(禁用)或1(启用)", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var medal = await medalRepository.GetByIdAsync(id);
|
|||
|
|
if (medal == null)
|
|||
|
|
{
|
|||
|
|
logger.LogWarning("未找到要更新状态的勋章,ID: {Id}", id);
|
|||
|
|
throw new BusinessException("勋章不存在", 404);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
medal.Status = status;
|
|||
|
|
medal.UpdatedBy = "System";
|
|||
|
|
medal.UpdatedAt = DateTime.Now;
|
|||
|
|
|
|||
|
|
var result = await medalRepository.UpdateAsync(medal);
|
|||
|
|
if (!result)
|
|||
|
|
{
|
|||
|
|
logger.LogError("勋章状态更新失败,ID: {Id}", id);
|
|||
|
|
throw new BusinessException("更新勋章状态失败", 500);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.LogInformation("勋章状态更新成功,ID: {Id}, Status: {Status}", id, status);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取所有启用勋章列表(含当前用户拥有状态)
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<List<WxMedalListOutput>> GetAllMedalsAsync(long userId)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("正在获取所有勋章列表,用户ID: {UserId}", userId);
|
|||
|
|
|
|||
|
|
var medals = await medalRepository.Queryable()
|
|||
|
|
.Where(m => m.Status == 1)
|
|||
|
|
.OrderBy(m => m.SortOrder, SqlSugar.OrderByType.Asc)
|
|||
|
|
.OrderByDescending(m => m.CreatedAt)
|
|||
|
|
.ToListAsync();
|
|||
|
|
|
|||
|
|
var userMedals = await Context.Queryable<UserMedal>()
|
|||
|
|
.Where(um => um.UserId == userId && um.Status == "Awarded")
|
|||
|
|
.ToListAsync();
|
|||
|
|
|
|||
|
|
var userMedalDict = userMedals.ToDictionary(um => um.MedalId, um => um.AwardedAt);
|
|||
|
|
|
|||
|
|
return medals.Select(m => new WxMedalListOutput
|
|||
|
|
{
|
|||
|
|
Id = m.Id,
|
|||
|
|
Name = m.Name,
|
|||
|
|
Description = m.Description,
|
|||
|
|
ImageUrl = m.ImageUrl,
|
|||
|
|
ConditionType = m.ConditionType,
|
|||
|
|
ConditionValue = m.ConditionValue,
|
|||
|
|
SortOrder = m.SortOrder,
|
|||
|
|
Type = m.Type,
|
|||
|
|
IsOwned = userMedalDict.ContainsKey((int)m.Id),
|
|||
|
|
AwardedAt = userMedalDict.TryGetValue((int)m.Id, out var awardedAt) ? awardedAt : null
|
|||
|
|
}).ToList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取用户已拥有的勋章列表
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task<List<WxUserMedalOutput>> GetUserMedalsAsync(long userId)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("正在获取用户勋章列表,用户ID: {UserId}", userId);
|
|||
|
|
|
|||
|
|
var result = await Context.Queryable<UserMedal>()
|
|||
|
|
.InnerJoin<Medal>((um, m) => um.MedalId == m.Id)
|
|||
|
|
.Where((um, m) => um.UserId == userId && um.Status == "Awarded")
|
|||
|
|
.OrderByDescending((um, m) => um.AwardedAt)
|
|||
|
|
.Select((um, m) => new WxUserMedalOutput
|
|||
|
|
{
|
|||
|
|
MedalId = m.Id,
|
|||
|
|
Name = m.Name,
|
|||
|
|
Description = m.Description,
|
|||
|
|
ImageUrl = m.ImageUrl,
|
|||
|
|
Type = m.Type,
|
|||
|
|
AwardedAt = um.AwardedAt,
|
|||
|
|
Status = um.Status
|
|||
|
|
})
|
|||
|
|
.ToListAsync();
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 激活/获得勋章
|
|||
|
|
/// </summary>
|
|||
|
|
public async Task ActivateMedalAsync(long userId, WxMedalActivateInput input)
|
|||
|
|
{
|
|||
|
|
logger.LogInformation("用户正在激活勋章,用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId);
|
|||
|
|
|
|||
|
|
if (input.MedalId <= 0)
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("勋章ID无效", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var medal = await medalRepository.GetByIdAsync(input.MedalId);
|
|||
|
|
if (medal == null)
|
|||
|
|
{
|
|||
|
|
logger.LogWarning("未找到要激活的勋章,勋章ID: {MedalId}", input.MedalId);
|
|||
|
|
throw new BusinessException("勋章不存在", 404);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (medal.Status != 1)
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("该勋章当前不可获得", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var existingUserMedal = await Context.Queryable<UserMedal>()
|
|||
|
|
.Where(um => um.UserId == userId && um.MedalId == (int)input.MedalId && um.Status == "Awarded")
|
|||
|
|
.FirstAsync();
|
|||
|
|
|
|||
|
|
if (existingUserMedal != null)
|
|||
|
|
{
|
|||
|
|
throw new BusinessException("您已拥有该勋章", 400);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var userMedal = new UserMedal
|
|||
|
|
{
|
|||
|
|
UserId = userId,
|
|||
|
|
MedalId = (int)input.MedalId,
|
|||
|
|
AwardedAt = DateTime.Now,
|
|||
|
|
Type = medal.Type,
|
|||
|
|
Status = "Awarded",
|
|||
|
|
CreatedBy = "System",
|
|||
|
|
UpdatedBy = "System",
|
|||
|
|
CreatedAt = DateTime.Now,
|
|||
|
|
UpdatedAt = DateTime.Now,
|
|||
|
|
IsDeleted = false
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
var insertResult = await Context.Insertable(userMedal).ExecuteCommandAsync();
|
|||
|
|
if (insertResult <= 0)
|
|||
|
|
{
|
|||
|
|
logger.LogError("勋章激活失败,用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId);
|
|||
|
|
throw new BusinessException("激活勋章失败", 500);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logger.LogInformation("勋章激活成功,用户ID: {UserId}, 勋章ID: {MedalId}", userId, input.MedalId);
|
|||
|
|
}
|
|||
|
|
}
|