using YD_Event.Application.Refund.Dtos; using YD_Event.Core.Entities; namespace YD_Event.Application.Refund; /// /// 退款配置服务 /// public class RefundConfigService : BaseService, ITransient { private readonly ISqlSugarRepository _repository; private readonly IIdGenerator _idGenerator; private readonly IEasyCachingProvider _easyCachingProvider; private const string CacheKey = "RefundConfig:List"; public RefundConfigService(ISqlSugarRepository repository, IIdGenerator idGenerator, IEasyCachingProvider easyCachingProvider) : base(repository) { _repository = repository; _idGenerator = idGenerator; _easyCachingProvider = easyCachingProvider; } /// /// 获取所有退款配置 /// /// [DisplayName("获取所有退款配置")] [HttpGet("list")] public async Task> GetList() { // 优先从缓存获取 var cacheValue = await _easyCachingProvider.GetAsync>(CacheKey); if (cacheValue.HasValue) { return cacheValue.Value; } var list = await _repository.GetListAsync(); var dtos = list.OrderBy(x => x.DayStart).Adapt>(); // 写入缓存,过期时间 1 小时 await _easyCachingProvider.SetAsync(CacheKey, dtos, TimeSpan.FromHours(1)); return dtos; } /// /// 分页查询退款配置 /// /// /// [DisplayName("分页查询退款配置")] [HttpGet("page")] public async Task> Page([FromQuery] RefundConfigQueryInput input) { return await _repository.AsQueryable() .WhereIF(input.Status.HasValue, x => x.Status == input.Status) .OrderBy(x => x.DayStart) .Select(x => new RefundConfigDto { Id = x.Id, DayStart = x.DayStart, DayEnd = x.DayEnd, DeductPercentage = x.DeductPercentage, Remark = x.Remark, Status = x.Status }) .ToPagedListAsync(input); } /// /// 添加退款配置 /// /// /// [DisplayName("添加退款配置")] [HttpPost("add")] public async Task Add(RefundConfigInput input) { // 简单重叠校验 var isExist = await _repository.IsAnyAsync(x => (input.DayStart >= x.DayStart && input.DayStart < x.DayEnd) || (input.DayEnd > x.DayStart && input.DayEnd <= x.DayEnd) || (input.DayStart <= x.DayStart && input.DayEnd >= x.DayEnd)); if (isExist) throw Oops.Bah("退款规则时间段存在重叠"); var entity = input.Adapt(); entity.Id = _idGenerator.NextId(); await _repository.InsertAsync(entity); // 清除缓存 await _easyCachingProvider.RemoveAsync(CacheKey); } /// /// 更新退款配置 /// /// /// [DisplayName("更新退款配置")] [HttpPut("update")] public async Task Update(RefundConfigInput input) { if (!input.Id.HasValue) throw Oops.Bah("Id不能为空"); // 校验重叠 (排除自身) var isExist = await _repository.IsAnyAsync(x => x.Id != input.Id && ((input.DayStart >= x.DayStart && input.DayStart < x.DayEnd) || (input.DayEnd > x.DayStart && input.DayEnd <= x.DayEnd) || (input.DayStart <= x.DayStart && input.DayEnd >= x.DayEnd))); if (isExist) throw Oops.Bah("退款规则时间段存在重叠"); var entity = await _repository.GetByIdAsync(input.Id.Value); if (entity == null) throw Oops.Bah("配置不存在"); input.Adapt(entity); await _repository.UpdateAsync(entity); // 清除缓存 await _easyCachingProvider.RemoveAsync(CacheKey); } /// /// 删除退款配置 /// /// /// [DisplayName("删除退款配置")] [HttpPost("delete")] public async Task Delete([FromBody] List ids) { await _repository.DeleteAsync(x => ids.Contains(x.Id)); // 清除缓存 await _easyCachingProvider.RemoveAsync(CacheKey); } /// /// 计算退款金额 /// /// 总金额 /// 赛事开始时间 /// 应退金额 [NonAction] public async Task CalculateRefundAmount(decimal totalAmount, DateTime eventStartTime) { // 优先使用 GetList (带缓存) var configs = await GetList(); configs = configs.Where(x => x.Status == Core.Enum.AvailabilityStatus.Enable).ToList(); if (!configs.Any()) return totalAmount; var daysRemaining = (eventStartTime - DateTime.Now).TotalDays; if (daysRemaining < 0) daysRemaining = 0; // 查找匹配的规则 var matchConfig = configs.FirstOrDefault(c => daysRemaining >= c.DayStart && (c.DayEnd == int.MaxValue ? true : daysRemaining < c.DayEnd) ); if (matchConfig != null) { var deductAmount = totalAmount * (matchConfig.DeductPercentage / 100m); return totalAmount - deductAmount; } return totalAmount; } }