258 lines
9.1 KiB
C#
258 lines
9.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using System.Text.Encodings.Web;
|
|
using System.Threading.Tasks;
|
|
using YD_Event.Application.Event.Dtos;
|
|
using YD_Event.Core.Entities;
|
|
using SqlSugar;
|
|
|
|
namespace YD_Event.Application.Event;
|
|
|
|
/// <summary>
|
|
/// 赛事规则快照服务 - 管理积分规则和退款规则的快照
|
|
/// </summary>
|
|
public class EventRuleSnapshotService : ITransient
|
|
{
|
|
private readonly ISqlSugarRepository<EventInfo> _eventInfoRepository;
|
|
private readonly ISqlSugarRepository<PointsRule> _pointsRuleRepository;
|
|
private readonly ISqlSugarRepository<PointsRuleDetail> _pointsRuleDetailRepository;
|
|
private readonly ISqlSugarRepository<RefundConfig> _refundConfigRepository;
|
|
|
|
// JSON 序列化选项,支持中文正常显示
|
|
private static readonly System.Text.Json.JsonSerializerOptions _jsonOptions = new System.Text.Json.JsonSerializerOptions
|
|
{
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
|
WriteIndented = false
|
|
};
|
|
|
|
public EventRuleSnapshotService(
|
|
ISqlSugarRepository<EventInfo> eventInfoRepository,
|
|
ISqlSugarRepository<PointsRule> pointsRuleRepository,
|
|
ISqlSugarRepository<PointsRuleDetail> pointsRuleDetailRepository,
|
|
ISqlSugarRepository<RefundConfig> refundConfigRepository)
|
|
{
|
|
_eventInfoRepository = eventInfoRepository;
|
|
_pointsRuleRepository = pointsRuleRepository;
|
|
_pointsRuleDetailRepository = pointsRuleDetailRepository;
|
|
_refundConfigRepository = refundConfigRepository;
|
|
}
|
|
|
|
#region 积分规则快照
|
|
|
|
/// <summary>
|
|
/// 保存积分规则快照到赛事
|
|
/// </summary>
|
|
/// <param name="eventId">赛事 ID</param>
|
|
/// <param name="pointsRuleId">积分规则 ID</param>
|
|
/// <returns></returns>
|
|
[DisplayName("保存积分规则快照")]
|
|
public async Task SavePointsRuleSnapshot(long eventId, long? pointsRuleId)
|
|
{
|
|
var eventInfo = await _eventInfoRepository.GetByIdAsync(eventId);
|
|
if (eventInfo == null)
|
|
throw new InvalidOperationException("赛事不存在");
|
|
|
|
if (!pointsRuleId.HasValue || pointsRuleId.Value <= 0)
|
|
{
|
|
eventInfo.PointsRuleSnapshot = null;
|
|
await _eventInfoRepository.UpdateAsync(eventInfo);
|
|
return;
|
|
}
|
|
|
|
var pointsRule = await _pointsRuleRepository.GetByIdAsync(pointsRuleId.Value);
|
|
if (pointsRule == null)
|
|
throw new InvalidOperationException("积分规则不存在");
|
|
|
|
var details = await _pointsRuleDetailRepository.GetListAsync(x =>
|
|
x.PointsRuleId == pointsRuleId.Value && !x.DeleteMark);
|
|
|
|
var snapshot = new PointsRuleSnapshotDto
|
|
{
|
|
PointsRuleId = pointsRule.Id,
|
|
RuleName = pointsRule.RuleName,
|
|
ParticipationPoints = pointsRule.ParticipationPoints,
|
|
Remark = pointsRule.Remark,
|
|
Details = details.Select(d => new PointsRuleDetailSnapshotDto
|
|
{
|
|
StartRank = d.StartRank,
|
|
EndRank = d.EndRank,
|
|
Points = d.Points
|
|
}).ToList()
|
|
};
|
|
|
|
eventInfo.PointsRuleSnapshot = System.Text.Json.JsonSerializer.Serialize(snapshot, _jsonOptions);
|
|
await _eventInfoRepository.UpdateAsync(eventInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取赛事积分规则快照
|
|
/// </summary>
|
|
/// <param name="eventId">赛事 ID</param>
|
|
/// <returns>积分规则快照,如果不存在则返回 null</returns>
|
|
[DisplayName("获取积分规则快照")]
|
|
public async Task<PointsRuleSnapshotDto?> GetPointsRuleSnapshot(long eventId)
|
|
{
|
|
var eventInfo = await _eventInfoRepository.GetByIdAsync(eventId);
|
|
if (eventInfo == null)
|
|
throw new InvalidOperationException("赛事不存在");
|
|
|
|
if (string.IsNullOrWhiteSpace(eventInfo.PointsRuleSnapshot))
|
|
return null;
|
|
|
|
try
|
|
{
|
|
return System.Text.Json.JsonSerializer.Deserialize<PointsRuleSnapshotDto>(eventInfo.PointsRuleSnapshot, _jsonOptions);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 退款规则快照
|
|
|
|
/// <summary>
|
|
/// 保存退款规则快照到赛事
|
|
/// </summary>
|
|
/// <param name="eventId">赛事 ID</param>
|
|
/// <returns></returns>
|
|
[DisplayName("保存退款规则快照")]
|
|
public async Task SaveRefundRuleSnapshot(long eventId)
|
|
{
|
|
var eventInfo = await _eventInfoRepository.GetByIdAsync(eventId);
|
|
if (eventInfo == null)
|
|
throw new InvalidOperationException("赛事不存在");
|
|
|
|
var refundConfigs = await _refundConfigRepository.GetListAsync(x =>
|
|
x.Status == Core.Enum.AvailabilityStatus.Enable && !x.DeleteMark);
|
|
|
|
if (!refundConfigs.Any())
|
|
{
|
|
eventInfo.RefundRuleSnapshot = null;
|
|
await _eventInfoRepository.UpdateAsync(eventInfo);
|
|
return;
|
|
}
|
|
|
|
var snapshots = refundConfigs.OrderBy(c => c.DayStart).Select(c => new RefundRuleSnapshotDto
|
|
{
|
|
RefundConfigId = c.Id,
|
|
DayStart = c.DayStart,
|
|
DayEnd = c.DayEnd,
|
|
DeductPercentage = c.DeductPercentage,
|
|
Remark = c.Remark
|
|
}).ToList();
|
|
|
|
eventInfo.RefundRuleSnapshot = System.Text.Json.JsonSerializer.Serialize(snapshots, _jsonOptions);
|
|
await _eventInfoRepository.UpdateAsync(eventInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取赛事退款规则快照
|
|
/// </summary>
|
|
/// <param name="eventId">赛事 ID</param>
|
|
/// <returns>退款规则快照列表,如果不存在则返回空列表</returns>
|
|
[DisplayName("获取退款规则快照")]
|
|
public async Task<List<RefundRuleSnapshotDto>> GetRefundRuleSnapshot(long eventId)
|
|
{
|
|
var eventInfo = await _eventInfoRepository.GetByIdAsync(eventId);
|
|
if (eventInfo == null)
|
|
throw new InvalidOperationException("赛事不存在");
|
|
|
|
if (string.IsNullOrWhiteSpace(eventInfo.RefundRuleSnapshot))
|
|
return new List<RefundRuleSnapshotDto>();
|
|
|
|
try
|
|
{
|
|
var snapshots = System.Text.Json.JsonSerializer.Deserialize<List<RefundRuleSnapshotDto>>(eventInfo.RefundRuleSnapshot, _jsonOptions);
|
|
return snapshots ?? new List<RefundRuleSnapshotDto>();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return new List<RefundRuleSnapshotDto>();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 快捷方法
|
|
|
|
/// <summary>
|
|
/// 同时保存积分规则和退款规则快照
|
|
/// </summary>
|
|
/// <param name="eventId">赛事 ID</param>
|
|
/// <param name="pointsRuleId">积分规则 ID</param>
|
|
/// <returns></returns>
|
|
[DisplayName("保存所有规则快照")]
|
|
public async Task SaveAllRuleSnapshots(long eventId, long? pointsRuleId)
|
|
{
|
|
await SavePointsRuleSnapshot(eventId, pointsRuleId);
|
|
await SaveRefundRuleSnapshot(eventId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据赛事实体保存快照(用于创建/编辑时)
|
|
/// </summary>
|
|
/// <param name="eventInfo">赛事实体</param>
|
|
/// <returns></returns>
|
|
[DisplayName("根据赛事实体保存快照")]
|
|
public async Task SaveAllRuleSnapshots(EventInfo eventInfo)
|
|
{
|
|
if (eventInfo.PointsRuleId.HasValue && eventInfo.PointsRuleId.Value > 0)
|
|
{
|
|
var pointsRule = await _pointsRuleRepository.GetByIdAsync(eventInfo.PointsRuleId.Value);
|
|
if (pointsRule != null)
|
|
{
|
|
var details = await _pointsRuleDetailRepository.GetListAsync(x =>
|
|
x.PointsRuleId == eventInfo.PointsRuleId.Value && !x.DeleteMark);
|
|
|
|
var snapshot = new PointsRuleSnapshotDto
|
|
{
|
|
PointsRuleId = pointsRule.Id,
|
|
RuleName = pointsRule.RuleName,
|
|
ParticipationPoints = pointsRule.ParticipationPoints,
|
|
Remark = pointsRule.Remark,
|
|
Details = details.Select(d => new PointsRuleDetailSnapshotDto
|
|
{
|
|
StartRank = d.StartRank,
|
|
EndRank = d.EndRank,
|
|
Points = d.Points
|
|
}).ToList()
|
|
};
|
|
|
|
eventInfo.PointsRuleSnapshot = System.Text.Json.JsonSerializer.Serialize(snapshot, _jsonOptions);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eventInfo.PointsRuleSnapshot = null;
|
|
}
|
|
|
|
var refundConfigs = await _refundConfigRepository.GetListAsync(x =>
|
|
x.Status == Core.Enum.AvailabilityStatus.Enable && !x.DeleteMark);
|
|
|
|
if (refundConfigs.Any())
|
|
{
|
|
var snapshots = refundConfigs.OrderBy(c => c.DayStart).Select(c => new RefundRuleSnapshotDto
|
|
{
|
|
RefundConfigId = c.Id,
|
|
DayStart = c.DayStart,
|
|
DayEnd = c.DayEnd,
|
|
DeductPercentage = c.DeductPercentage,
|
|
Remark = c.Remark
|
|
}).ToList();
|
|
|
|
eventInfo.RefundRuleSnapshot = System.Text.Json.JsonSerializer.Serialize(snapshots, _jsonOptions);
|
|
}
|
|
else
|
|
{
|
|
eventInfo.RefundRuleSnapshot = null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|