项目,积分bug
This commit is contained in:
parent
fcfb534f46
commit
b73ad0a94e
@ -10,15 +10,21 @@ public class CouponService : BaseService<YD_Event.Core.Entities.Coupon>, ITransi
|
||||
{
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Coupon> _repository;
|
||||
private readonly ISqlSugarRepository<EventInfo> _eventRepository;
|
||||
private readonly ISqlSugarRepository<CouponRedemptionCode> _redemptionCodeRepository;
|
||||
private readonly ISqlSugarRepository<UserCoupon> _userCouponRepository;
|
||||
private readonly IIdGenerator _idGenerator;
|
||||
|
||||
public CouponService(
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.Coupon> repository,
|
||||
ISqlSugarRepository<EventInfo> eventRepository,
|
||||
ISqlSugarRepository<CouponRedemptionCode> redemptionCodeRepository,
|
||||
ISqlSugarRepository<UserCoupon> userCouponRepository,
|
||||
IIdGenerator idGenerator) : base(repository)
|
||||
{
|
||||
_repository = repository;
|
||||
_eventRepository = eventRepository;
|
||||
_redemptionCodeRepository = redemptionCodeRepository;
|
||||
_userCouponRepository = userCouponRepository;
|
||||
_idGenerator = idGenerator;
|
||||
}
|
||||
|
||||
@ -77,7 +83,6 @@ public class CouponService : BaseService<YD_Event.Core.Entities.Coupon>, ITransi
|
||||
Value = item.Value,
|
||||
StartTime = item.StartTime,
|
||||
EndTime = item.EndTime,
|
||||
RedemptionCode = item.RedemptionCode,
|
||||
TotalQuantity = item.TotalQuantity,
|
||||
ClaimedQuantity = item.ClaimedQuantity,
|
||||
UsedQuantity = item.UsedQuantity,
|
||||
@ -123,16 +128,10 @@ public class CouponService : BaseService<YD_Event.Core.Entities.Coupon>, ITransi
|
||||
{
|
||||
var entity = await _repository.GetByIdAsync(input.Id);
|
||||
if (entity == null) throw Oops.Bah("优惠券不存在");
|
||||
|
||||
// 保存当前的兑换码,防止被意外清空
|
||||
var currentRedemptionCode = entity.RedemptionCode;
|
||||
|
||||
// 使用Mapster进行属性映射,但保留兑换码
|
||||
// 使用Mapster进行属性映射
|
||||
input.Adapt(entity);
|
||||
|
||||
// 恢复兑换码
|
||||
entity.RedemptionCode = currentRedemptionCode;
|
||||
|
||||
// 处理赛事ID集合
|
||||
if (input.EventIds != null && input.EventIds.Any())
|
||||
{
|
||||
@ -157,57 +156,206 @@ public class CouponService : BaseService<YD_Event.Core.Entities.Coupon>, ITransi
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成兑换码
|
||||
/// 生成单个兑换码(兼容旧接口)
|
||||
/// </summary>
|
||||
[DisplayName("生成兑换码")]
|
||||
[UnitOfWork]
|
||||
[Obsolete("请使用 GenerateRedemptionCodes 方法")]
|
||||
public async Task<string> GenerateCode(long id)
|
||||
{
|
||||
// 使用事务和乐观锁来确保并发安全
|
||||
var entity = await _repository.AsQueryable()
|
||||
.Where(x => x.Id == id)
|
||||
.FirstAsync();
|
||||
|
||||
if (entity == null) throw Oops.Bah("优惠券不存在");
|
||||
var result = await GenerateRedemptionCodes(new GenerateRedemptionCodesInput { CouponId = id, Count = 1 });
|
||||
return result.FirstOrDefault()?.Code ?? string.Empty;
|
||||
}
|
||||
|
||||
// 如果已经有码,直接返回
|
||||
if (!string.IsNullOrWhiteSpace(entity.RedemptionCode))
|
||||
{
|
||||
return entity.RedemptionCode;
|
||||
}
|
||||
/// <summary>
|
||||
/// 批量生成兑换码
|
||||
/// </summary>
|
||||
[DisplayName("批量生成兑换码")]
|
||||
[UnitOfWork]
|
||||
public async Task<List<RedemptionCodeOutput>> GenerateRedemptionCodes(GenerateRedemptionCodesInput input)
|
||||
{
|
||||
// 验证优惠券是否存在
|
||||
var coupon = await _repository.GetByIdAsync(input.CouponId);
|
||||
if (coupon == null) throw Oops.Bah("优惠券不存在");
|
||||
|
||||
// 生成新的兑换码,并确保唯一性
|
||||
string newCode;
|
||||
int retryCount = 0;
|
||||
const int maxRetry = 5;
|
||||
|
||||
do
|
||||
var generatedCodes = new List<CouponRedemptionCode>();
|
||||
const int maxRetryPerCode = 5;
|
||||
|
||||
for (int i = 0; i < input.Count; i++)
|
||||
{
|
||||
// 生成8位大写字母数字组合的兑换码
|
||||
newCode = Guid.NewGuid().ToString("N").Substring(0, 8).ToUpper();
|
||||
retryCount++;
|
||||
|
||||
// 检查是否已存在
|
||||
var exists = await _repository.AsQueryable()
|
||||
.Where(x => x.RedemptionCode == newCode)
|
||||
.AnyAsync();
|
||||
|
||||
if (!exists)
|
||||
string newCode;
|
||||
int retryCount = 0;
|
||||
bool codeIsUnique = false;
|
||||
|
||||
do
|
||||
{
|
||||
break;
|
||||
// 生成12位大写字母数字组合的兑换码
|
||||
newCode = GenerateRandomCode(12);
|
||||
retryCount++;
|
||||
|
||||
// 检查是否已存在
|
||||
var exists = await _redemptionCodeRepository.AsQueryable()
|
||||
.Where(x => x.Code == newCode)
|
||||
.AnyAsync();
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
codeIsUnique = true;
|
||||
}
|
||||
} while (!codeIsUnique && retryCount < maxRetryPerCode);
|
||||
|
||||
if (!codeIsUnique)
|
||||
{
|
||||
throw Oops.Bah($"生成第 {i + 1} 个兑换码时失败,请重试");
|
||||
}
|
||||
} while (retryCount < maxRetry);
|
||||
|
||||
if (retryCount >= maxRetry)
|
||||
{
|
||||
throw Oops.Bah("生成兑换码失败,请重试");
|
||||
|
||||
var redemptionCode = new CouponRedemptionCode
|
||||
{
|
||||
Id = _idGenerator.NextId(),
|
||||
CouponId = input.CouponId,
|
||||
Code = newCode,
|
||||
Status = 0,
|
||||
DeleteMark = false
|
||||
};
|
||||
|
||||
generatedCodes.Add(redemptionCode);
|
||||
}
|
||||
|
||||
// 更新兑换码
|
||||
entity.RedemptionCode = newCode;
|
||||
await _repository.UpdateAsync(entity);
|
||||
// 批量插入
|
||||
await _redemptionCodeRepository.InsertRangeAsync(generatedCodes);
|
||||
|
||||
return entity.RedemptionCode;
|
||||
// 返回结果
|
||||
return generatedCodes.Select(x => new RedemptionCodeOutput
|
||||
{
|
||||
Id = x.Id,
|
||||
CouponId = x.CouponId,
|
||||
Code = x.Code,
|
||||
Status = x.Status,
|
||||
CreatedTime = x.CreatedTime
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码分页查询
|
||||
/// </summary>
|
||||
[DisplayName("兑换码分页查询")]
|
||||
public async Task<PageResult<RedemptionCodeOutput>> GetRedemptionCodePage(RedemptionCodeQueryInput input)
|
||||
{
|
||||
var query = _redemptionCodeRepository.AsQueryable()
|
||||
.WhereIF(input.CouponId.HasValue, x => x.CouponId == input.CouponId.Value)
|
||||
.WhereIF(input.Status.HasValue, x => x.Status == input.Status.Value)
|
||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Code), x => x.Code.Contains(input.Code))
|
||||
.OrderByDescending(x => x.CreatedTime);
|
||||
|
||||
var pagedList = await query.ToPagedListAsync(input);
|
||||
|
||||
return new PageResult<RedemptionCodeOutput>
|
||||
{
|
||||
PageNo = pagedList.PageNo,
|
||||
PageSize = pagedList.PageSize,
|
||||
Total = pagedList.Total,
|
||||
Rows = pagedList.Rows.Select(x => new RedemptionCodeOutput
|
||||
{
|
||||
Id = x.Id,
|
||||
CouponId = x.CouponId,
|
||||
Code = x.Code,
|
||||
Status = x.Status,
|
||||
UsedTime = x.UsedTime,
|
||||
UserCouponId = x.UserCouponId,
|
||||
CreatedTime = x.CreatedTime
|
||||
}).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用兑换码
|
||||
/// </summary>
|
||||
[DisplayName("使用兑换码")]
|
||||
[UnitOfWork]
|
||||
public async Task<long> UseRedemptionCode(UseRedemptionCodeInput input)
|
||||
{
|
||||
// 查找兑换码
|
||||
var redemptionCode = await _redemptionCodeRepository.AsQueryable()
|
||||
.Where(x => x.Code == input.Code)
|
||||
.FirstAsync();
|
||||
|
||||
if (redemptionCode == null)
|
||||
{
|
||||
throw Oops.Bah("兑换码不存在");
|
||||
}
|
||||
|
||||
// 检查是否已使用
|
||||
if (redemptionCode.Status == 1)
|
||||
{
|
||||
throw Oops.Bah("该兑换码已被使用");
|
||||
}
|
||||
|
||||
// 检查优惠券是否有效
|
||||
var coupon = await _repository.GetByIdAsync(redemptionCode.CouponId);
|
||||
if (coupon == null)
|
||||
{
|
||||
throw Oops.Bah("关联优惠券不存在");
|
||||
}
|
||||
|
||||
if (coupon.Status != AvailabilityStatus.Enable)
|
||||
{
|
||||
throw Oops.Bah("优惠券已停用");
|
||||
}
|
||||
|
||||
// 检查优惠券有效期
|
||||
var now = DateTime.Now;
|
||||
if (coupon.StartTime.HasValue && now < coupon.StartTime.Value)
|
||||
{
|
||||
throw Oops.Bah("优惠券尚未到使用时间");
|
||||
}
|
||||
if (coupon.EndTime.HasValue && now > coupon.EndTime.Value)
|
||||
{
|
||||
throw Oops.Bah("优惠券已过期");
|
||||
}
|
||||
|
||||
// 检查库存
|
||||
if (coupon.TotalQuantity > 0 && coupon.ClaimedQuantity >= coupon.TotalQuantity)
|
||||
{
|
||||
throw Oops.Bah("优惠券已领完");
|
||||
}
|
||||
|
||||
// 创建用户优惠券记录
|
||||
var userCoupon = new UserCoupon
|
||||
{
|
||||
Id = _idGenerator.NextId(),
|
||||
UserId = input.UserId ?? 0,
|
||||
CouponId = coupon.Id,
|
||||
ClaimTime = now,
|
||||
Status = 0,
|
||||
RedemptionCodeId = redemptionCode.Id,
|
||||
RedemptionCode = redemptionCode.Code,
|
||||
DeleteMark = false
|
||||
};
|
||||
|
||||
await _userCouponRepository.InsertAsync(userCoupon);
|
||||
|
||||
// 更新兑换码状态
|
||||
redemptionCode.Status = 1;
|
||||
redemptionCode.UsedTime = now;
|
||||
redemptionCode.UserCouponId = userCoupon.Id;
|
||||
await _redemptionCodeRepository.UpdateAsync(redemptionCode);
|
||||
|
||||
// 更新优惠券领取数量
|
||||
coupon.ClaimedQuantity++;
|
||||
await _repository.UpdateAsync(coupon);
|
||||
|
||||
return userCoupon.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成随机兑换码
|
||||
/// </summary>
|
||||
private string GenerateRandomCode(int length)
|
||||
{
|
||||
const string chars = "ABCDEFGHJKMNPQRSTUVWXYZ23456789";
|
||||
var random = new Random();
|
||||
return new string(Enumerable.Repeat(chars, length)
|
||||
.Select(s => s[random.Next(s.Length)]).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -109,11 +109,6 @@ public class CouponPageOutput
|
||||
/// </summary>
|
||||
public List<long> EventIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码
|
||||
/// </summary>
|
||||
public string RedemptionCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总数量
|
||||
/// </summary>
|
||||
@ -161,3 +156,101 @@ public class EventSelectOutput
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成兑换码输入
|
||||
/// </summary>
|
||||
public class GenerateRedemptionCodesInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 优惠券ID
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "优惠券ID不能为空")]
|
||||
public long CouponId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 生成数量
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "生成数量不能为空")]
|
||||
[Range(1, 1000, ErrorMessage = "生成数量必须在1-1000之间")]
|
||||
public int Count { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码输出
|
||||
/// </summary>
|
||||
public class RedemptionCodeOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 优惠券ID
|
||||
/// </summary>
|
||||
public long CouponId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用状态(0-未使用 1-已使用)
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用时间
|
||||
/// </summary>
|
||||
public DateTime? UsedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的用户优惠券ID
|
||||
/// </summary>
|
||||
public long? UserCouponId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreatedTime { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用兑换码输入
|
||||
/// </summary>
|
||||
public class UseRedemptionCodeInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 兑换码
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "兑换码不能为空")]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
public long? UserId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码查询输入
|
||||
/// </summary>
|
||||
public class RedemptionCodeQueryInput : Pagination
|
||||
{
|
||||
/// <summary>
|
||||
/// 优惠券ID
|
||||
/// </summary>
|
||||
public long? CouponId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用状态(0-未使用 1-已使用)
|
||||
/// </summary>
|
||||
public int? Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码(模糊查询)
|
||||
/// </summary>
|
||||
public string? Code { get; set; }
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using YD_Event.Application.Event.Dtos;
|
||||
using YD_Event.Application.Common;
|
||||
using YD_Event.Core.Entities;
|
||||
using YD_Event.Core.Enum;
|
||||
using Easy.Core;
|
||||
|
||||
@ -62,6 +62,7 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
private readonly ProjectService _projectService;
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Coupon> _couponRepository;
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.UserCoupon> _userCouponRepository;
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.CouponRedemptionCode> _redemptionCodeRepository;
|
||||
private readonly ISqlSugarRepository<EventRegistrationPayment> _paymentRepository;
|
||||
private readonly ILogger<UserEventRegistrationService> _logger;
|
||||
private readonly OrderNoGeneratorService _orderNoGeneratorService;
|
||||
@ -95,6 +96,7 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
ProjectService projectService,
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.Coupon> couponRepository,
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.UserCoupon> userCouponRepository,
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.CouponRedemptionCode> redemptionCodeRepository,
|
||||
ISqlSugarRepository<EventRegistrationPayment> paymentRepository,
|
||||
ILogger<UserEventRegistrationService> logger,
|
||||
OrderNoGeneratorService orderNoGeneratorService)
|
||||
@ -127,6 +129,7 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
_projectService = projectService;
|
||||
_couponRepository = couponRepository;
|
||||
_userCouponRepository = userCouponRepository;
|
||||
_redemptionCodeRepository = redemptionCodeRepository;
|
||||
_paymentRepository = paymentRepository;
|
||||
_logger = logger;
|
||||
_orderNoGeneratorService = orderNoGeneratorService;
|
||||
@ -1171,9 +1174,21 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
InvalidReason = ""
|
||||
};
|
||||
|
||||
// 查找优惠券(通过兑换码)
|
||||
// 查找兑换码
|
||||
var redemptionCode = await _redemptionCodeRepository.GetFirstAsync(rc =>
|
||||
rc.Code == input.CouponCode &&
|
||||
rc.Status == 0 && // 0-未使用
|
||||
!rc.DeleteMark);
|
||||
|
||||
if (redemptionCode == null)
|
||||
{
|
||||
result.InvalidReason = "兑换码不存在或已使用";
|
||||
return result;
|
||||
}
|
||||
|
||||
// 查找优惠券
|
||||
var coupon = await _couponRepository.GetFirstAsync(c =>
|
||||
c.RedemptionCode == input.CouponCode &&
|
||||
c.Id == redemptionCode.CouponId &&
|
||||
c.Status == AvailabilityStatus.Enable &&
|
||||
!c.DeleteMark);
|
||||
|
||||
@ -1234,12 +1249,20 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
CouponId = coupon.Id,
|
||||
ClaimTime = DateTime.Now,
|
||||
Status = 0, // 未使用
|
||||
RedemptionCodeId = redemptionCode.Id,
|
||||
RedemptionCode = redemptionCode.Code,
|
||||
CreatedUserId = userId,
|
||||
CreatedTime = DateTime.Now,
|
||||
DeleteMark = false
|
||||
};
|
||||
await _userCouponRepository.InsertAsync(userCoupon);
|
||||
|
||||
// 更新兑换码状态和关联
|
||||
redemptionCode.Status = 1; // 已使用
|
||||
redemptionCode.UsedTime = DateTime.Now;
|
||||
redemptionCode.UserCouponId = userCoupon.Id;
|
||||
await _redemptionCodeRepository.UpdateAsync(redemptionCode);
|
||||
|
||||
// 更新优惠券已领取数量
|
||||
coupon.ClaimedQuantity += 1;
|
||||
await _couponRepository.UpdateAsync(coupon);
|
||||
|
||||
@ -41,6 +41,8 @@ public class AddMerchantInput
|
||||
/// <summary>
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "联系电话不能为空")]
|
||||
[RegularExpression(@"^1[3-9]\d{9}$", ErrorMessage = "请输入正确的手机号格式")]
|
||||
public string? ContactPhone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -50,6 +50,8 @@ public class PointsRuleService : BaseService<PointsRule>, ITransient
|
||||
[UnitOfWork]
|
||||
public async Task Add(AddPointsRuleInput input)
|
||||
{
|
||||
ValidateRankDetails(input.Details);
|
||||
|
||||
var entity = input.Adapt<PointsRule>();
|
||||
entity.Id = _idGenerator.NextId();
|
||||
|
||||
@ -78,6 +80,8 @@ public class PointsRuleService : BaseService<PointsRule>, ITransient
|
||||
var entity = await _repository.GetByIdAsync(input.Id);
|
||||
if (entity == null) throw Oops.Bah("规则不存在");
|
||||
|
||||
ValidateRankDetails(input.Details);
|
||||
|
||||
input.Adapt(entity);
|
||||
await _repository.UpdateAsync(entity);
|
||||
|
||||
@ -96,6 +100,32 @@ public class PointsRuleService : BaseService<PointsRule>, ITransient
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证名次积分详情是否有重叠
|
||||
/// </summary>
|
||||
private void ValidateRankDetails(List<PointsRuleDetailInput>? details)
|
||||
{
|
||||
if (details == null || details.Count <= 1)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < details.Count; i++)
|
||||
{
|
||||
var item1 = details[i];
|
||||
|
||||
for (int j = i + 1; j < details.Count; j++)
|
||||
{
|
||||
var item2 = details[j];
|
||||
|
||||
// 检查是否重叠:两个区间 [s1, e1] 和 [s2, e2] 不重叠的条件是 e1 < s2 或 e2 < s1
|
||||
bool isOverlap = !(item1.EndRank < item2.StartRank || item2.EndRank < item1.StartRank);
|
||||
if (isOverlap)
|
||||
{
|
||||
throw Oops.Bah($"名次范围 {item1.StartRank}-{item1.EndRank} 与 {item2.StartRank}-{item2.EndRank} 存在重叠,请调整!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除积分规则
|
||||
/// </summary>
|
||||
|
||||
@ -3631,7 +3631,27 @@
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Coupon.CouponService.GenerateCode(System.Int64)">
|
||||
<summary>
|
||||
生成兑换码
|
||||
生成单个兑换码(兼容旧接口)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Coupon.CouponService.GenerateRedemptionCodes(YD_Event.Application.Coupon.Dtos.GenerateRedemptionCodesInput)">
|
||||
<summary>
|
||||
批量生成兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Coupon.CouponService.GetRedemptionCodePage(YD_Event.Application.Coupon.Dtos.RedemptionCodeQueryInput)">
|
||||
<summary>
|
||||
兑换码分页查询
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Coupon.CouponService.UseRedemptionCode(YD_Event.Application.Coupon.Dtos.UseRedemptionCodeInput)">
|
||||
<summary>
|
||||
使用兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Coupon.CouponService.GenerateRandomCode(System.Int32)">
|
||||
<summary>
|
||||
生成随机兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Coupon.CouponService.GetEventList">
|
||||
@ -3734,11 +3754,6 @@
|
||||
适用赛事ID集合 (编辑回显用)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.CouponPageOutput.RedemptionCode">
|
||||
<summary>
|
||||
兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.CouponPageOutput.TotalQuantity">
|
||||
<summary>
|
||||
总数量
|
||||
@ -3784,6 +3799,96 @@
|
||||
赛事名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Coupon.Dtos.GenerateRedemptionCodesInput">
|
||||
<summary>
|
||||
生成兑换码输入
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.GenerateRedemptionCodesInput.CouponId">
|
||||
<summary>
|
||||
优惠券ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.GenerateRedemptionCodesInput.Count">
|
||||
<summary>
|
||||
生成数量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Coupon.Dtos.RedemptionCodeOutput">
|
||||
<summary>
|
||||
兑换码输出
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeOutput.Id">
|
||||
<summary>
|
||||
ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeOutput.CouponId">
|
||||
<summary>
|
||||
优惠券ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeOutput.Code">
|
||||
<summary>
|
||||
兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeOutput.Status">
|
||||
<summary>
|
||||
使用状态(0-未使用 1-已使用)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeOutput.UsedTime">
|
||||
<summary>
|
||||
使用时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeOutput.UserCouponId">
|
||||
<summary>
|
||||
关联的用户优惠券ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeOutput.CreatedTime">
|
||||
<summary>
|
||||
创建时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Coupon.Dtos.UseRedemptionCodeInput">
|
||||
<summary>
|
||||
使用兑换码输入
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.UseRedemptionCodeInput.Code">
|
||||
<summary>
|
||||
兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.UseRedemptionCodeInput.UserId">
|
||||
<summary>
|
||||
用户ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Coupon.Dtos.RedemptionCodeQueryInput">
|
||||
<summary>
|
||||
兑换码查询输入
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeQueryInput.CouponId">
|
||||
<summary>
|
||||
优惠券ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeQueryInput.Status">
|
||||
<summary>
|
||||
使用状态(0-未使用 1-已使用)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Coupon.Dtos.RedemptionCodeQueryInput.Code">
|
||||
<summary>
|
||||
兑换码(模糊查询)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Event.Dtos.ArrangementProjectListOutput">
|
||||
<summary>
|
||||
编排项目列表输出
|
||||
@ -6724,11 +6829,7 @@
|
||||
教练/领队列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Event.EventScoreService.ImportScore(System.Int64,Microsoft.AspNetCore.Http.IFormFile)">
|
||||
<summary>
|
||||
导入成绩
|
||||
</summary>
|
||||
</member>
|
||||
<!-- Badly formed XML comment ignored for member "M:YD_Event.Application.Event.EventScoreService.ImportScore(System.Int64,Microsoft.AspNetCore.Http.IFormFile)" -->
|
||||
<member name="M:YD_Event.Application.Event.EventScoreService.IssueCertificate(YD_Event.Application.Event.Dtos.IssueCertificateInput)">
|
||||
<summary>
|
||||
发放证书
|
||||
@ -9113,6 +9214,11 @@
|
||||
更新积分规则
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Points.PointsRuleService.ValidateRankDetails(System.Collections.Generic.List{YD_Event.Application.Points.Dtos.PointsRuleDetailInput})">
|
||||
<summary>
|
||||
验证名次积分详情是否有重叠
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Points.PointsRuleService.Delete(System.Collections.Generic.List{System.Int64})">
|
||||
<summary>
|
||||
删除积分规则
|
||||
|
||||
@ -47,12 +47,6 @@ public class Coupon : Entity<long>, ISoftDelete, ICreatedUserId, ICreatedTime, I
|
||||
[SugarColumn(ColumnDescription = "可用赛事ID集合", Length = 500, IsNullable = true)]
|
||||
public string EventIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "兑换码", Length = 32, IsNullable = true)]
|
||||
public string RedemptionCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 总数量(库存)
|
||||
/// </summary>
|
||||
|
||||
63
YD_Event.Core/Entities/CouponRedemptionCode.cs
Normal file
63
YD_Event.Core/Entities/CouponRedemptionCode.cs
Normal file
@ -0,0 +1,63 @@
|
||||
namespace YD_Event.Core.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 优惠券兑换码记录表
|
||||
/// </summary>
|
||||
[SugarTable("CouponRedemptionCode")]
|
||||
public class CouponRedemptionCode : Entity<long>, ISoftDelete, ICreatedUserId, ICreatedTime, IUpdatedUserId, IUpdatedTime
|
||||
{
|
||||
/// <summary>
|
||||
/// 优惠券ID
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "优惠券ID")]
|
||||
public long CouponId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "兑换码", Length = 32)]
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用状态(0-未使用 1-已使用)
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "使用状态", DefaultValue = "0")]
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "使用时间", IsNullable = true)]
|
||||
public DateTime? UsedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的用户优惠券ID
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "关联的用户优惠券ID", IsNullable = true)]
|
||||
public long? UserCouponId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 删除标志
|
||||
/// </summary>
|
||||
public bool DeleteMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建人Id
|
||||
/// </summary>
|
||||
public long CreatedUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新人Id
|
||||
/// </summary>
|
||||
public long? UpdatedUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime? UpdatedTime { get; set; }
|
||||
}
|
||||
@ -44,6 +44,18 @@ public class UserCoupon : Entity<long>, ISoftDelete, ICreatedUserId, ICreatedTim
|
||||
[SugarColumn(ColumnDescription = "关联订单ID", IsNullable = true)]
|
||||
public long? OrderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码ID
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "兑换码ID", IsNullable = true)]
|
||||
public long? RedemptionCodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 兑换码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "兑换码", Length = 32, IsNullable = true)]
|
||||
public string? RedemptionCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 删除标志
|
||||
/// </summary>
|
||||
|
||||
@ -279,9 +279,9 @@
|
||||
"Id": 1012,
|
||||
"Name": "查看详情",
|
||||
"Type": 2,
|
||||
"Code": "project:view",
|
||||
"Code": "project:detail",
|
||||
"ParentId": 1008,
|
||||
"RouteName": "btn_project_view",
|
||||
"RouteName": "btn_project_detail",
|
||||
"Path": "",
|
||||
"Component": "",
|
||||
"Redirect": "",
|
||||
@ -1639,6 +1639,27 @@
|
||||
"CreatedUserId": 1000,
|
||||
"CreatedTime": "2023-06-01T00:00:00"
|
||||
},
|
||||
{
|
||||
"Id": 1068,
|
||||
"Name": "查看详情",
|
||||
"Type": 2,
|
||||
"Code": "integral:config:detail",
|
||||
"ParentId": 1064,
|
||||
"RouteName": "btn_integral_config_detail",
|
||||
"Path": "",
|
||||
"Component": "",
|
||||
"Icon": "",
|
||||
"IsIframe": "0",
|
||||
"IsVisible": "0",
|
||||
"IsKeepAlive": "1",
|
||||
"IsFixed": "0",
|
||||
"Status": 0,
|
||||
"Sort": 4,
|
||||
"Remark": "",
|
||||
"DeleteMark": false,
|
||||
"CreatedUserId": 1000,
|
||||
"CreatedTime": "2023-06-01T00:00:00"
|
||||
},
|
||||
{
|
||||
"Id": 2000,
|
||||
"Name": "赛事管理",
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
using EasyCaching.Core;
|
||||
using EasyCaching.Core;
|
||||
|
||||
namespace SqlSugar;
|
||||
|
||||
/// <summary>
|
||||
/// SqlSugar ORM框架所需缓存配置
|
||||
/// 解决对象池已释放的问题:每次获取缓存实例时都从服务容器获取
|
||||
/// </summary>
|
||||
public class SqlSugarCache : ICacheService
|
||||
{
|
||||
private static readonly IEasyCachingProvider Cache = App.GetRequiredService<IEasyCachingProvider>();
|
||||
/// <summary>
|
||||
/// 获取当前的缓存提供程序实例
|
||||
/// </summary>
|
||||
private static IEasyCachingProvider Cache => App.GetRequiredService<IEasyCachingProvider>();
|
||||
|
||||
public void Add<V>(string key, V value)
|
||||
{
|
||||
|
||||
@ -353,6 +353,37 @@
|
||||
执行导出
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Domain.OrderNoGeneratorService">
|
||||
<summary>
|
||||
订单号生成器服务
|
||||
提供分布式唯一订单号生成,确保高并发下的唯一性
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Domain.OrderNoGeneratorService.GenerateOrderNoAsync">
|
||||
<summary>
|
||||
生成唯一订单号
|
||||
格式:yyyyMMddHHmmss + 4位序列号
|
||||
保证高并发下的唯一性
|
||||
</summary>
|
||||
<returns>唯一订单号</returns>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Domain.OrderNoGeneratorService.GenerateRefundOrderNoAsync">
|
||||
<summary>
|
||||
生成退款订单号
|
||||
格式:REF + yyyyMMddHHmmss + 4位序列号
|
||||
</summary>
|
||||
<returns>退款订单号</returns>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Domain.OrderNoGeneratorService.GenerateOrderNoInternal">
|
||||
<summary>
|
||||
内部生成订单号(带线程安全的序列号)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Domain.OrderNoGeneratorService.GetTimestamp(System.DateTime)">
|
||||
<summary>
|
||||
获取时间戳(用于比较)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Domain.Pricing.EventPricingService">
|
||||
<summary>
|
||||
赛事定价计算服务
|
||||
@ -938,11 +969,6 @@
|
||||
可用赛事ID集合(逗号分隔)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.Coupon.RedemptionCode">
|
||||
<summary>
|
||||
兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.Coupon.TotalQuantity">
|
||||
<summary>
|
||||
总数量(库存)
|
||||
@ -993,6 +1019,61 @@
|
||||
更新时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Entities.CouponRedemptionCode">
|
||||
<summary>
|
||||
优惠券兑换码记录表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.CouponId">
|
||||
<summary>
|
||||
优惠券ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.Code">
|
||||
<summary>
|
||||
兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.Status">
|
||||
<summary>
|
||||
使用状态(0-未使用 1-已使用)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.UsedTime">
|
||||
<summary>
|
||||
使用时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.UserCouponId">
|
||||
<summary>
|
||||
关联的用户优惠券ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.DeleteMark">
|
||||
<summary>
|
||||
删除标志
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.CreatedUserId">
|
||||
<summary>
|
||||
创建人Id
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.CreatedTime">
|
||||
<summary>
|
||||
创建时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.UpdatedUserId">
|
||||
<summary>
|
||||
更新人Id
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.CouponRedemptionCode.UpdatedTime">
|
||||
<summary>
|
||||
更新时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Entities.EventCertificate">
|
||||
<summary>
|
||||
赛事证书表
|
||||
@ -4051,6 +4132,16 @@
|
||||
关联订单ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.UserCoupon.RedemptionCodeId">
|
||||
<summary>
|
||||
兑换码ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.UserCoupon.RedemptionCode">
|
||||
<summary>
|
||||
兑换码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.UserCoupon.DeleteMark">
|
||||
<summary>
|
||||
删除标志
|
||||
@ -5895,6 +5986,12 @@
|
||||
<member name="T:SqlSugar.SqlSugarCache">
|
||||
<summary>
|
||||
SqlSugar ORM框架所需缓存配置
|
||||
解决对象池已释放的问题:每次获取缓存实例时都从服务容器获取
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:SqlSugar.SqlSugarCache.Cache">
|
||||
<summary>
|
||||
获取当前的缓存提供程序实例
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SqlSugar.SqlSugarExtensions.AddSqlSugar(Microsoft.Extensions.DependencyInjection.IServiceCollection,YD_Event.Core.Options.ConnectionConfigExt,System.Action{SqlSugar.ISqlSugarClient})">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user