2026-06-06 23:34:12 +08:00

251 lines
9.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Furion.FriendlyException;
using Microsoft.Extensions.Logging;
using YD_Event.Application.Auth;
using YD_Event.Application.Merchant.Dtos;
using YD_Event.Core.Entities;
using YD_Event.Core.Enum;
namespace YD_Event.Application.Merchant;
/// <summary>
/// 商户管理
/// </summary>
public class MerchantService : BaseService<YD_Event.Core.Entities.Merchant>, ITransient
{
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Merchant> _repository;
private readonly ISqlSugarRepository<UserCoupon> _userCouponRepository;
private readonly ISqlSugarRepository<WeChatPayConfig> _weChatPayConfigRepository;
private readonly ISqlSugarRepository<EventInfo> _eventRepository;
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Order> _orderRepository;
private readonly AuthManager _authManager;
private readonly IIdGenerator _idGenerator;
private readonly Microsoft.Extensions.Logging.ILogger<MerchantService> _logger;
public MerchantService(ISqlSugarRepository<YD_Event.Core.Entities.Merchant> repository,
ISqlSugarRepository<UserCoupon> userCouponRepository,
ISqlSugarRepository<WeChatPayConfig> weChatPayConfigRepository,
ISqlSugarRepository<EventInfo> eventRepository,
ISqlSugarRepository<YD_Event.Core.Entities.Order> orderRepository,
AuthManager authManager,
IIdGenerator idGenerator,
Microsoft.Extensions.Logging.ILogger<MerchantService> logger) : base(repository)
{
_repository = repository;
_userCouponRepository = userCouponRepository;
_weChatPayConfigRepository = weChatPayConfigRepository;
_eventRepository = eventRepository;
_orderRepository = orderRepository;
_authManager = authManager;
_idGenerator = idGenerator;
_logger = logger;
}
/// <summary>
/// 商户分页查询
/// </summary>
[DisplayName("商户分页查询")]
[HttpGet("page")]
public async Task<PageResult<MerchantOutput>> Page([FromQuery] MerchantQueryInput input)
{
var pageResult = await _repository.AsQueryable()
.WhereIF(!string.IsNullOrWhiteSpace(input.MerchantName), x => x.MerchantName.Contains(input.MerchantName))
.WhereIF(!string.IsNullOrWhiteSpace(input.ContactPhone), x => x.ContactPhone.Contains(input.ContactPhone))
.WhereIF(input.AuditStatus.HasValue, x => x.AuditStatus == input.AuditStatus)
.WhereIF(input.StartTime.HasValue, x => x.CreatedTime >= input.StartTime)
.WhereIF(input.EndTime.HasValue, x => x.CreatedTime <= input.EndTime)
.OrderByDescending(x => x.CreatedTime)
.Select(x => new MerchantOutput
{
Id = x.Id,
MerchantName = x.MerchantName,
CreditCode = x.CreditCode,
BankName = x.BankName,
AccountNumber = x.AccountNumber,
BusinessLicenseUrl = x.BusinessLicenseUrl,
ContactPhone = x.ContactPhone,
Address = x.Address,
AuditStatus = x.AuditStatus,
AuditRemark = x.AuditRemark,
Status = x.Status,
CreatedTime = x.CreatedTime,
UpdatedTime = x.UpdatedTime
})
.ToPagedListAsync(input);
return pageResult;
}
/// <summary>
/// 添加商户
/// </summary>
[DisplayName("添加商户")]
[HttpPost("add")]
[UnitOfWork]
public async Task Add(AddMerchantInput input)
{
var entity = input.Adapt<YD_Event.Core.Entities.Merchant>();
entity.Id = _idGenerator.NextId();
await _repository.InsertAsync(entity);
if (input.WeChatPayConfig != null)
{
var weChatPayConfig = input.WeChatPayConfig.Adapt<WeChatPayConfig>();
weChatPayConfig.Id = _idGenerator.NextId();
weChatPayConfig.MerchantId = entity.Id;
await _weChatPayConfigRepository.InsertAsync(weChatPayConfig);
}
}
/// <summary>
/// 更新商户
/// </summary>
[DisplayName("更新商户")]
[HttpPut("edit")]
[UnitOfWork]
public async Task Update(UpdateMerchantInput input)
{
var entity = await _repository.GetByIdAsync(input.Id);
if (entity == null) throw Oops.Bah("商户不存在");
input.Adapt(entity);
await _repository.UpdateAsync(entity);
var existingWeChatPayConfig = await _weChatPayConfigRepository.GetFirstAsync(c => c.MerchantId == input.Id);
if (input.WeChatPayConfig != null)
{
if (existingWeChatPayConfig != null)
{
input.WeChatPayConfig.Adapt(existingWeChatPayConfig);
await _weChatPayConfigRepository.UpdateAsync(existingWeChatPayConfig);
}
else
{
var weChatPayConfig = input.WeChatPayConfig.Adapt<WeChatPayConfig>();
weChatPayConfig.Id = _idGenerator.NextId();
weChatPayConfig.MerchantId = input.Id;
await _weChatPayConfigRepository.InsertAsync(weChatPayConfig);
}
}
else
{
if (existingWeChatPayConfig != null)
{
await _weChatPayConfigRepository.SoftDeleteByIdAsync(existingWeChatPayConfig.Id);
}
}
}
/// <summary>
/// 删除商户
/// </summary>
[DisplayName("删除商户")]
[HttpPost("delete")]
[UnitOfWork]
public async Task Delete([FromBody] List<long> ids)
{
_logger.LogInformation("开始删除商户:商户ID列表={Ids}", string.Join(",", ids));
if (ids == null || !ids.Any())
{
_logger.LogWarning("删除商户失败:未选择商户");
return;
}
// 检查商户是否被赛事使用
var hasEvents = await _eventRepository.IsAnyAsync(x =>
x.MerchantId.HasValue && ids.Contains(x.MerchantId.Value) && !x.DeleteMark);
if (hasEvents)
{
_logger.LogWarning("删除商户失败:部分商户正在被赛事使用");
throw Oops.Bah("部分商户正在被赛事使用,无法删除。请先从赛事中移除这些商户。");
}
// 检查商户是否有订单记录
var hasOrders = await _orderRepository.IsAnyAsync(x =>
x.MerchantId.HasValue && ids.Contains(x.MerchantId.Value) && !x.DeleteMark);
if (hasOrders)
{
_logger.LogWarning("删除商户失败:部分商户已有订单记录");
throw Oops.Bah("部分商户已有订单记录,为保证数据完整性,无法删除。");
}
// 执行删除 - 软删
await _repository.SoftDeleteByIdsAsync(ids);
await _weChatPayConfigRepository.SoftDeleteAsync(x => ids.Contains(x.MerchantId));
_logger.LogInformation("删除商户成功:商户ID列表={Ids}", string.Join(",", ids));
}
/// <summary>
/// 获取商户详情
/// </summary>
[DisplayName("获取商户详情")]
[HttpGet("detail")]
public async Task<MerchantOutput> Detail([FromQuery] long id)
{
var entity = await _repository.GetByIdAsync(id);
if (entity == null) throw Oops.Bah("商户不存在");
var weChatPayConfig = await _weChatPayConfigRepository.GetFirstAsync(c => c.MerchantId == id);
return new MerchantOutput
{
Id = entity.Id,
MerchantName = entity.MerchantName,
CreditCode = entity.CreditCode,
BankName = entity.BankName,
AccountNumber = entity.AccountNumber,
BusinessLicenseUrl = entity.BusinessLicenseUrl,
ContactPhone = entity.ContactPhone,
Address = entity.Address,
AuditStatus = entity.AuditStatus,
AuditRemark = entity.AuditRemark,
Status = entity.Status,
CreatedTime = entity.CreatedTime,
UpdatedTime = entity.UpdatedTime,
WeChatPayConfig = weChatPayConfig != null ? weChatPayConfig.Adapt<WeChatPayConfigDto>() : null
};
}
/// <summary>
/// 发放优惠券
/// </summary>
[DisplayName("发放优惠券")]
[HttpPost("issueCoupon")]
[UnitOfWork]
public async Task IssueCoupon([FromBody] IssueCouponInput input)
{
if (input.MerchantIds == null || !input.MerchantIds.Any()) return;
if (input.Count <= 0) throw Oops.Bah("发放数量必须大于0");
var merchants = await _repository.GetListAsync(m => input.MerchantIds.Contains(m.Id));
if (!merchants.Any()) return;
var coupons = new List<UserCoupon>();
var now = DateTime.Now;
foreach (var merchant in merchants)
{
for (int i = 0; i < input.Count; i++)
{
coupons.Add(new UserCoupon
{
Id = _idGenerator.NextId(),
UserId = merchant.CreatedUserId, // Issue to the creator of the merchant
CouponId = input.CouponId,
Status = 0, // Unused
ClaimTime = now,
CreatedTime = now,
CreatedUserId = _authManager.UserId
});
}
}
await _userCouponRepository.InsertRangeAsync(coupons);
}
}