From a9e0b8325a8a9734ab21b1a9163851b985859889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Sat, 4 Apr 2026 22:09:43 +0800 Subject: [PATCH] bug --- YD_Event.Application/Auth/AuthService.cs | 2 +- YD_Event.Application/Client/Dtos/MyDtos.cs | 10 ++++ YD_Event.Application/Client/MyController.cs | 33 ++++++++++-- .../Client/OAuthController.cs | 2 +- YD_Event.Application/Coupon/CouponService.cs | 53 ++++++++++++++++--- .../User/Dtos/AddSysUserInput.cs | 10 +++- YD_Event.Application/User/SysUserService.cs | 2 +- 7 files changed, 97 insertions(+), 15 deletions(-) diff --git a/YD_Event.Application/Auth/AuthService.cs b/YD_Event.Application/Auth/AuthService.cs index 9cb6dfb..281a47d 100644 --- a/YD_Event.Application/Auth/AuthService.cs +++ b/YD_Event.Application/Auth/AuthService.cs @@ -72,7 +72,7 @@ public class AuthService : IDynamicApiController [AuthClaimsConst.AccountKey] = user.Account, [AuthClaimsConst.UuidKey] = uniqueId, [AuthClaimsConst.AuthPlatformTypeKey] = AuthPlatformType.Manager - },100000); + }); // 获取刷新 token var refreshToken = JWTEncryption.GenerateRefreshToken(token); // 设置响应报文头 diff --git a/YD_Event.Application/Client/Dtos/MyDtos.cs b/YD_Event.Application/Client/Dtos/MyDtos.cs index bbf6ef6..0601940 100644 --- a/YD_Event.Application/Client/Dtos/MyDtos.cs +++ b/YD_Event.Application/Client/Dtos/MyDtos.cs @@ -50,6 +50,16 @@ public class MyProfileDto /// 所在单位 /// public string? MerchantName { get; set; } + + /// + /// 性别:0-未知,1-男,2-女 + /// + public int? Gender { get; set; } + + /// + /// 出生日期 + /// + public DateTime? BirthDate { get; set; } } /// diff --git a/YD_Event.Application/Client/MyController.cs b/YD_Event.Application/Client/MyController.cs index 0a9a4a1..e88fa8f 100644 --- a/YD_Event.Application/Client/MyController.cs +++ b/YD_Event.Application/Client/MyController.cs @@ -123,7 +123,9 @@ public class MyController : IDynamicApiController Points = pointsBalance, CertificateCount = certCount, AuthStatus = authStatus, - MerchantName = merchantName + MerchantName = merchantName, + Gender = (int?)user.Gender, + BirthDate = user.BirthDate }; } @@ -344,24 +346,45 @@ public class MyController : IDynamicApiController { var userId = GetCurrentUserId(); - // 联表查询 EventInfo 和 Project 获取赛事名称和项目名称 + // 先查询原始数据,然后在内存中转换证书名称 var query = _certificateRepository.AsQueryable() .LeftJoin((c, e) => c.EventId == e.Id) .LeftJoin((c, e, p) => c.ProjectId == p.Id) .Where((c, e, p) => c.CreatedUserId == userId && c.CertificateStatus == 2 && !c.DeleteMark) - .Select((c, e, p) => new MyCertificateDto + .Select((c, e, p) => new { Id = c.Id, EventName = e.EventName, ProjectName = p.Name, GroupName = c.GroupName, - CertificateName = GetCertificateName(c.CertificateType), + CertificateType = c.CertificateType, CertificateUrl = c.CertificateUrl, IssuedTime = c.IssuedTime }) .OrderByDescending(c => c.IssuedTime); - return await query.ToPagedListAsync(input); + var pagedResult = await query.ToPagedListAsync(input); + + // 在内存中转换证书名称 + var result = new PageResult + { + PageNo = pagedResult.PageNo, + PageSize = pagedResult.PageSize, + Total = pagedResult.Total, + Pages = pagedResult.Pages, + Rows = pagedResult.Rows.Select(x => new MyCertificateDto + { + Id = x.Id, + EventName = x.EventName, + ProjectName = x.ProjectName, + GroupName = x.GroupName, + CertificateName = GetCertificateName(x.CertificateType), + CertificateUrl = x.CertificateUrl, + IssuedTime = x.IssuedTime + }).ToList() + }; + + return result; } private string GetCertificateName(int certificateType) diff --git a/YD_Event.Application/Client/OAuthController.cs b/YD_Event.Application/Client/OAuthController.cs index b96b73e..3af35a4 100644 --- a/YD_Event.Application/Client/OAuthController.cs +++ b/YD_Event.Application/Client/OAuthController.cs @@ -198,7 +198,7 @@ public class OAuthController : IDynamicApiController [AuthClaimsConst.AccountKey] = appUser.Mobile, [AuthClaimsConst.UuidKey] = uniqueId, [AuthClaimsConst.AuthPlatformTypeKey] = AuthPlatformType.WeChatApplet - },100000); + }); string refreshToken = JWTEncryption.GenerateRefreshToken(accessToken); diff --git a/YD_Event.Application/Coupon/CouponService.cs b/YD_Event.Application/Coupon/CouponService.cs index d6526a3..09d2bb1 100644 --- a/YD_Event.Application/Coupon/CouponService.cs +++ b/YD_Event.Application/Coupon/CouponService.cs @@ -124,8 +124,15 @@ public class CouponService : BaseService, ITransi var entity = await _repository.GetByIdAsync(input.Id); if (entity == null) throw Oops.Bah("优惠券不存在"); + // 保存当前的兑换码,防止被意外清空 + var currentRedemptionCode = entity.RedemptionCode; + + // 使用Mapster进行属性映射,但保留兑换码 input.Adapt(entity); + // 恢复兑换码 + entity.RedemptionCode = currentRedemptionCode; + // 处理赛事ID集合 if (input.EventIds != null && input.EventIds.Any()) { @@ -153,19 +160,53 @@ public class CouponService : BaseService, ITransi /// 生成兑换码 /// [DisplayName("生成兑换码")] + [UnitOfWork] public async Task GenerateCode(long id) { - var entity = await _repository.GetByIdAsync(id); + // 使用事务和乐观锁来确保并发安全 + var entity = await _repository.AsQueryable() + .Where(x => x.Id == id) + .FirstAsync(); + if (entity == null) throw Oops.Bah("优惠券不存在"); - // 如果已经有码,直接返回;如果没有,生成新的 - if (string.IsNullOrWhiteSpace(entity.RedemptionCode)) + // 如果已经有码,直接返回 + if (!string.IsNullOrWhiteSpace(entity.RedemptionCode)) { - // 简单生成一个随机码,实际业务可能需要更复杂的规则 - entity.RedemptionCode = Guid.NewGuid().ToString("N").Substring(0, 8).ToUpper(); - await _repository.UpdateAsync(entity); + return entity.RedemptionCode; } + // 生成新的兑换码,并确保唯一性 + string newCode; + int retryCount = 0; + const int maxRetry = 5; + + do + { + // 生成8位大写字母数字组合的兑换码 + newCode = Guid.NewGuid().ToString("N").Substring(0, 8).ToUpper(); + retryCount++; + + // 检查是否已存在 + var exists = await _repository.AsQueryable() + .Where(x => x.RedemptionCode == newCode) + .AnyAsync(); + + if (!exists) + { + break; + } + } while (retryCount < maxRetry); + + if (retryCount >= maxRetry) + { + throw Oops.Bah("生成兑换码失败,请重试"); + } + + // 更新兑换码 + entity.RedemptionCode = newCode; + await _repository.UpdateAsync(entity); + return entity.RedemptionCode; } diff --git a/YD_Event.Application/User/Dtos/AddSysUserInput.cs b/YD_Event.Application/User/Dtos/AddSysUserInput.cs index 22364b8..71db879 100644 --- a/YD_Event.Application/User/Dtos/AddSysUserInput.cs +++ b/YD_Event.Application/User/Dtos/AddSysUserInput.cs @@ -1,4 +1,4 @@ -namespace YD_Event.Application.User.Dtos; +namespace YD_Event.Application.User.Dtos; /// /// 添加系统用户输入 @@ -19,6 +19,14 @@ public class AddSysUserInput [MaxLength(32, ErrorMessage = "账号限制32个字符内")] public string Account { get; set; } + /// + /// 密码 + /// + [Required(ErrorMessage = "密码为必填项")] + [MinLength(6, ErrorMessage = "密码长度至少6位")] + [MaxLength(32, ErrorMessage = "密码长度最多32位")] + public string Password { get; set; } + /// /// 关联角色ID集合 /// diff --git a/YD_Event.Application/User/SysUserService.cs b/YD_Event.Application/User/SysUserService.cs index 7e36154..0d3f677 100644 --- a/YD_Event.Application/User/SysUserService.cs +++ b/YD_Event.Application/User/SysUserService.cs @@ -110,7 +110,7 @@ public class SysUserService : BaseService, ITransient var user = dto.Adapt(); user.Id = _idGenerator.NextId(); string encode = _idGenerator.Encode(user.Id); - user.Password = MD5Encryption.Encrypt(encode + "123456"); // 默认密码 + user.Password = MD5Encryption.Encrypt(encode + dto.Password); user.CreatedTime = DateTime.Now; // 确保设置创建时间 // 处理角色关联