using SqlSugar; using YD_Event.Application.Points.Dtos; using YD_Event.Core.Entities; using YD_Event.Core.Enum; namespace YD_Event.Application.Points; /// /// 积分记录管理 /// public class PointsRecordService : BaseService, ITransient { private readonly ISqlSugarRepository _repository; private readonly ISqlSugarRepository _appUserRepository; private readonly ISqlSugarRepository _merchantRepository; public PointsRecordService( ISqlSugarRepository repository, ISqlSugarRepository appUserRepository, ISqlSugarRepository merchantRepository) : base(repository) { _repository = repository; _appUserRepository = appUserRepository; _merchantRepository = merchantRepository; } /// /// 积分记录分页查询 /// [DisplayName("积分记录分页查询")] [HttpGet("list")] public async Task> List([FromQuery] PointsRecordQueryInput input) { if (input.UserType == 0) // 普通用户 { var query = _appUserRepository.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.Name.Contains(input.Keyword) || u.Mobile.Contains(input.Keyword)); // 关联查询积分 // 注意:这里需要根据时间范围筛选积分记录,还是筛选最后有积分变动的用户? // 需求:时间范围筛选。通常指筛选在该时间范围内有积分变动的记录,或者只统计该时间范围内的积分。 // 但“积分额度”通常指总积分。 // 如果时间范围筛选是指“只看某段时间的积分情况”,那么积分额度应该是该段时间内的总和。 // 如果是指“筛选某段时间有活动的用户”,积分额度可能是总积分。 // 考虑到“积分额度排序”,通常是总积分。 // 让我们假设:时间范围筛选是指筛选在该时间范围内有积分变动的用户,积分额度为当前总积分。 // 或者:积分额度 = 该时间范围内的积分总和。 // 根据管理后台惯例,如果有时间筛选,通常列表显示的是该时间段的数据统计。 // 让我们采用:积分额度 = 该时间范围内的积分总和(如果没有时间筛选,就是所有时间)。 // 使用子查询或 LeftJoin 计算积分 var result = await query .Select(u => new PointsRecordListOutput { UserId = u.Id, UserType = 0, Name = u.Name, Phone = u.Mobile, IdentityInfo = u.IdCardImageUrl, // 身份证图片 TotalPoints = SqlFunc.Subqueryable() .Where(p => p.UserId == u.Id && !p.DeleteMark) .WhereIF(input.StartTime.HasValue, p => p.CreatedTime >= input.StartTime) .WhereIF(input.EndTime.HasValue, p => p.CreatedTime <= input.EndTime) .Sum(p => p.Points), // 实时计算 LastUpdateTime = SqlFunc.Subqueryable() .Where(p => p.UserId == u.Id && !p.DeleteMark) .WhereIF(input.StartTime.HasValue, p => p.CreatedTime >= input.StartTime) .WhereIF(input.EndTime.HasValue, p => p.CreatedTime <= input.EndTime) .Max(p => p.CreatedTime) }) .MergeTable() // 将上面的 Select 结果作为临时表,以便进行后续的 Where 和 OrderBy .WhereIF(input.StartTime.HasValue || input.EndTime.HasValue, x => x.LastUpdateTime != null) // 如果有时间筛选,只显示有记录的用户 .OrderByIF(!string.IsNullOrWhiteSpace(input.SortPoints), x => x.TotalPoints, input.SortPoints == "asc" ? OrderByType.Asc : OrderByType.Desc) .OrderByDescending(x => x.LastUpdateTime) // 默认按更新时间倒序 .ToPagedListAsync(input); return result; } else // 单位用户 { var query = _merchantRepository.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), m => m.MerchantName.Contains(input.Keyword) || m.ContactPhone.Contains(input.Keyword)); var result = await query .Select(m => new PointsRecordListOutput { UserId = m.Id, // 商户ID UserType = 1, Name = m.MerchantName, Phone = m.ContactPhone, IdentityInfo = m.CreditCode, // 统一社会信用代码 TotalPoints = SqlFunc.Subqueryable() .Where(p => p.MerchantId == m.Id && !p.DeleteMark) .WhereIF(input.StartTime.HasValue, p => p.CreatedTime >= input.StartTime) .WhereIF(input.EndTime.HasValue, p => p.CreatedTime <= input.EndTime) .Sum(p => p.Points), LastUpdateTime = SqlFunc.Subqueryable() .Where(p => p.MerchantId == m.Id && !p.DeleteMark) .WhereIF(input.StartTime.HasValue, p => p.CreatedTime >= input.StartTime) .WhereIF(input.EndTime.HasValue, p => p.CreatedTime <= input.EndTime) .Max(p => p.CreatedTime) }) .MergeTable() .WhereIF(input.StartTime.HasValue || input.EndTime.HasValue, x => x.LastUpdateTime != null) .OrderByIF(!string.IsNullOrWhiteSpace(input.SortPoints), x => x.TotalPoints, input.SortPoints == "asc" ? OrderByType.Asc : OrderByType.Desc) .OrderByDescending(x => x.LastUpdateTime) .ToPagedListAsync(input); return result; } } /// /// 积分明细查询 /// [DisplayName("积分明细查询")] [HttpGet("detail/{userId}")] public async Task> Detail([FromQuery] PointsDetailQueryInput input) { var query = _repository.AsQueryable() .LeftJoin((p, e) => p.EventId == e.Id) .LeftJoin((p, e, pr) => p.ProjectId == pr.Id) .LeftJoin((p, e, pr, pg) => p.ProjectGroupId == pg.Id) .Where((p, e, pr, pg) => !p.DeleteMark) .WhereIF(input.Type.HasValue, (p, e, pr, pg) => p.Type == input.Type) .OrderByDescending((p, e, pr, pg) => p.CreatedTime); if (input.UserType == 0) // 普通用户 { query = query.Where((p, e, pr, pg) => p.UserId == input.UserId); return await query .Select((p, e, pr, pg) => new PointsDetailOutput { CreatedTime = p.CreatedTime, Type = p.Type, Action = e.EventName, Item = pr.Name, Group = pg.GroupName, Points = p.Points, Remark = p.Remark }).ToPagedListAsync(input); } else // 单位用户 { // 单位用户:查询 MerchantId = userId 的记录 query = query.Where((p, e, pr, pg) => p.MerchantId == input.UserId); return await query .LeftJoin((p, e, pr, pg, u) => p.UserId == u.Id) .Select((p, e, pr, pg, u) => new PointsDetailOutput { CreatedTime = p.CreatedTime, Type = p.Type, Action = e.EventName, Item = pr.Name, Group = pg.GroupName, Points = p.Points, Remark = p.Remark, ParticipantName = u.Name, // 参赛人姓名 ParticipantId = u.Id // 参赛人ID }).ToPagedListAsync(input); } } }