YD_Event.Admin/YD_Event.Application/Refund/RefundConfigService.cs

176 lines
5.7 KiB
C#
Raw Normal View History

2026-03-02 09:54:52 +08:00
using YD_Event.Application.Refund.Dtos;
using YD_Event.Core.Entities;
namespace YD_Event.Application.Refund;
/// <summary>
/// 退款配置服务
/// </summary>
public class RefundConfigService : BaseService<RefundConfig>, ITransient
{
private readonly ISqlSugarRepository<RefundConfig> _repository;
private readonly IIdGenerator _idGenerator;
private readonly IEasyCachingProvider _easyCachingProvider;
private const string CacheKey = "RefundConfig:List";
public RefundConfigService(ISqlSugarRepository<RefundConfig> repository,
IIdGenerator idGenerator,
IEasyCachingProvider easyCachingProvider) : base(repository)
{
_repository = repository;
_idGenerator = idGenerator;
_easyCachingProvider = easyCachingProvider;
}
/// <summary>
/// 获取所有退款配置
/// </summary>
/// <returns></returns>
[DisplayName("获取所有退款配置")]
[HttpGet("list")]
public async Task<List<RefundConfigDto>> GetList()
{
// 优先从缓存获取
var cacheValue = await _easyCachingProvider.GetAsync<List<RefundConfigDto>>(CacheKey);
if (cacheValue.HasValue)
{
return cacheValue.Value;
}
var list = await _repository.GetListAsync();
var dtos = list.OrderBy(x => x.DayStart).Adapt<List<RefundConfigDto>>();
// 写入缓存,过期时间 1 小时
await _easyCachingProvider.SetAsync(CacheKey, dtos, TimeSpan.FromHours(1));
return dtos;
}
/// <summary>
/// 分页查询退款配置
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("分页查询退款配置")]
[HttpGet("page")]
public async Task<PageResult<RefundConfigDto>> 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);
}
/// <summary>
/// 添加退款配置
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[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<RefundConfig>();
entity.Id = _idGenerator.NextId();
await _repository.InsertAsync(entity);
// 清除缓存
await _easyCachingProvider.RemoveAsync(CacheKey);
}
/// <summary>
/// 更新退款配置
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[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);
}
/// <summary>
/// 删除退款配置
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
[DisplayName("删除退款配置")]
[HttpPost("delete")]
public async Task Delete([FromBody] List<long> ids)
{
await _repository.DeleteAsync(x => ids.Contains(x.Id));
// 清除缓存
await _easyCachingProvider.RemoveAsync(CacheKey);
}
/// <summary>
/// 计算退款金额
/// </summary>
/// <param name="totalAmount">总金额</param>
/// <param name="eventStartTime">赛事开始时间</param>
/// <returns>应退金额</returns>
[NonAction]
public async Task<decimal> 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;
}
}