Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.Service/MedalService.cs
glz f9b79417a0 feat: add medal module and optimize community entities
1. 新增勋章管理全流程功能,包含实体、DTO、服务层、控制器
2. 重构DotFile实体继承基础实体类
3. 删除UserJournal的无用JournalInstanceId字段
4. 重构CommunityMessage实体字段并新增点赞数、精选标记字段
5. 新增社区点赞、评论、模板言论实体并替换旧有实体文件
6. 更新gitignore忽略PROJECT_STRUCTURE.md文件
2026-06-05 15:16:49 +08:00

411 lines
14 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.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);
}
}