YD_Event.Admin/YD_Event.Application/Event/EventRuleSnapshotService.cs

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
}