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);
}
}
}