优化新增运动员逻辑

This commit is contained in:
马梓彭 2026-06-17 21:39:16 +08:00
parent 2705da9b72
commit b7b7709e0c
3 changed files with 114 additions and 58 deletions

View File

@ -177,59 +177,83 @@ public class AppUserService : BaseService<AppUserEntity>, ITransient
throw Oops.Bah("当前用户未关联单位,无法进行操作"); throw Oops.Bah("当前用户未关联单位,无法进行操作");
} }
// 手机号为空时,跳过基于手机号的重复检测(单位添加运动员时,联系电话非必填) // 根据认证类型决定查重策略:
// - 运动员 + 有认证类型 + 有证件号 → 用证件号查重
// - 其他情况 → 用手机号查重(原逻辑)
var mobileIsEmpty = string.IsNullOrWhiteSpace(input.Mobile); var mobileIsEmpty = string.IsNullOrWhiteSpace(input.Mobile);
bool useCertCheck = input.PersonType == PersonType.Athlete && input.AuthType > 0 && (
((input.AuthType == 1 || input.AuthType == 3) && !string.IsNullOrWhiteSpace(input.IdCardNumber))
|| (input.AuthType == 2 && !string.IsNullOrWhiteSpace(input.PassportNumber))
);
// ============== 新增:证件号查重验证 ============== // 查重基础查询(排除自身ID)
// 身份证/户口本认证时检查身份证号是否重复 ISugarQueryable<AppUserEntity> BuildBaseQuery()
if ((input.AuthType == 1 || input.AuthType == 3) && !string.IsNullOrWhiteSpace(input.IdCardNumber))
{ {
var q1 = _appUserRep.AsQueryable() var q = _appUserRep.AsQueryable()
.Where(x => x.IdCardNumber == input.IdCardNumber .Where(x => x.PersonType == input.PersonType && !x.DeleteMark);
&& x.PersonType == input.PersonType
&& !x.DeleteMark);
if (input.Id.HasValue) if (input.Id.HasValue)
{ {
q1 = q1.Where(x => x.Id != input.Id.Value); q = q.Where(x => x.Id != input.Id.Value);
}
var duplicateIdCard = await q1.FirstAsync();
if (duplicateIdCard != null)
{
throw Oops.Bah($"系统中已存在相同身份证号的{GetPersonTypeDisplay(input.PersonType)},请核对信息");
} }
return q;
} }
// 护照认证时检查护照号是否重复 // ========== 查重流程(证件号或手机号,流程一致) ==========
if (input.AuthType == 2 && !string.IsNullOrWhiteSpace(input.PassportNumber))
{
var q2 = _appUserRep.AsQueryable()
.Where(x => x.PassportNumber == input.PassportNumber
&& x.PersonType == input.PersonType
&& !x.DeleteMark);
if (input.Id.HasValue)
{
q2 = q2.Where(x => x.Id != input.Id.Value);
}
var duplicatePassport = await q2.FirstAsync();
if (duplicatePassport != null)
{
throw Oops.Bah($"系统中已存在相同护照号的{GetPersonTypeDisplay(input.PersonType)},请核对信息");
}
}
// 先检查是否存在相同手机号且相同类型的运动员在其他单位
AppUserEntity? existingInOtherUnit = null; AppUserEntity? existingInOtherUnit = null;
if (!mobileIsEmpty) AppUserEntity? existingWithoutUnit = null;
if (useCertCheck)
{ {
existingInOtherUnit = await _appUserRep.AsQueryable() var certQuery = BuildBaseQuery();
.Where(x => x.Mobile == input.Mobile
&& x.PersonType == input.PersonType // 按认证类型明确匹配不同证件字段
&& x.MerchantCertificationId != merchantCertificationId if (input.AuthType == 1)
&& x.MerchantCertificationId != null {
&& !x.DeleteMark) // 身份证认证 → 用 IdCardNumber 查重
.FirstAsync(); certQuery = certQuery.Where(x => x.IdCardNumber == input.IdCardNumber);
}
else if (input.AuthType == 2)
{
// 护照认证 → 用 PassportNumber 查重
certQuery = certQuery.Where(x => x.PassportNumber == input.PassportNumber);
}
else if (input.AuthType == 3)
{
// 户口本认证 → 用 IdCardNumber 查重
certQuery = certQuery.Where(x => x.IdCardNumber == input.IdCardNumber);
}
var certMatches = await certQuery.ToListAsync();
// 本单位同证件号 → 提示重复
var duplicateInSameUnit = certMatches.FirstOrDefault(x => x.MerchantCertificationId == merchantCertificationId);
if (duplicateInSameUnit != null)
{
throw Oops.Bah($"该{GetCertDisplay(input.AuthType)}在本单位已存在相同类型的成员,请核对信息");
}
// 其他单位有记录 → 单位更换
existingInOtherUnit = certMatches.FirstOrDefault(x => x.MerchantCertificationId != null && x.MerchantCertificationId != merchantCertificationId);
// 未加入单位的记录 → 复用
if (existingInOtherUnit == null)
{
existingWithoutUnit = certMatches.FirstOrDefault(x => x.MerchantCertificationId == null);
}
}
else
{
// 原逻辑:按手机号查重
if (!mobileIsEmpty)
{
existingInOtherUnit = await _appUserRep.AsQueryable()
.Where(x => x.Mobile == input.Mobile
&& x.PersonType == input.PersonType
&& x.MerchantCertificationId != merchantCertificationId
&& x.MerchantCertificationId != null
&& !x.DeleteMark)
.FirstAsync();
}
} }
AppUserEntity? entity = null; AppUserEntity? entity = null;
@ -244,26 +268,35 @@ public class AppUserService : BaseService<AppUserEntity>, ITransient
entity = existingInOtherUnit; entity = existingInOtherUnit;
originalMerchantId = entity.MerchantCertificationId; originalMerchantId = entity.MerchantCertificationId;
} }
else if (existingWithoutUnit != null)
{
// 找到已存在但未加入任何单位的记录,复用该记录(证件号查重时进入)
entity = existingWithoutUnit;
entity.UpdatedUserId = _authManager.UserId;
entity.UpdatedTime = DateTime.Now;
}
else else
{ {
// 检查是否存在相同手机号但还未加入任何单位的记录(小程序注册的用户) // 按原手机号继续查询(仅当未使用证件号查重时)
AppUserEntity? existingWithoutUnit = null; if (!useCertCheck && !mobileIsEmpty)
if (!mobileIsEmpty)
{ {
existingWithoutUnit = await _appUserRep.AsQueryable() var mobileMatch = await _appUserRep.AsQueryable()
.Where(x => x.Mobile == input.Mobile .Where(x => x.Mobile == input.Mobile
&& x.PersonType == input.PersonType && x.PersonType == input.PersonType
&& x.MerchantCertificationId == null && x.MerchantCertificationId == null
&& !x.DeleteMark) && !x.DeleteMark)
.FirstAsync(); .FirstAsync();
}
if (mobileMatch != null)
if (existingWithoutUnit != null) {
{ entity = mobileMatch;
// 找到已存在但未加入任何单位的记录,复用该记录 entity.UpdatedUserId = _authManager.UserId;
entity = existingWithoutUnit; entity.UpdatedTime = DateTime.Now;
entity.UpdatedUserId = _authManager.UserId; }
entity.UpdatedTime = DateTime.Now; else
{
isNewRecord = true;
}
} }
else else
{ {
@ -471,6 +504,22 @@ public class AppUserService : BaseService<AppUserEntity>, ITransient
}; };
} }
/// <summary>
/// 获取证件类型显示名称
/// </summary>
/// <param name="authType"></param>
/// <returns></returns>
private static string GetCertDisplay(int authType)
{
return authType switch
{
1 => "身份证号",
2 => "护照号码",
3 => "身份证号",
_ => "证件号"
};
}
#endregion #endregion
#region 领队/教练管理 (向下兼容) #region 领队/教练管理 (向下兼容)

View File

@ -176,7 +176,7 @@ public class MyController : IDynamicApiController
// 身份证号查重 // 身份证号查重
var duplicateIdCard = await _appUserRepository.AsQueryable() var duplicateIdCard = await _appUserRepository.AsQueryable()
.Where(u => u.IdCardNumber == input.IdCardNumber && u.Id != userId && !u.DeleteMark) .Where(u => u.IdCardNumber == input.IdCardNumber && u.Id != userId && !u.DeleteMark && u.PersonType == PersonType.Athlete)
.FirstAsync(); .FirstAsync();
if (duplicateIdCard != null) throw Oops.Bah("该身份证号已被其他用户使用"); if (duplicateIdCard != null) throw Oops.Bah("该身份证号已被其他用户使用");
} }
@ -189,7 +189,7 @@ public class MyController : IDynamicApiController
// 护照号查重 // 护照号查重
var duplicatePassport = await _appUserRepository.AsQueryable() var duplicatePassport = await _appUserRepository.AsQueryable()
.Where(u => u.PassportNumber == input.PassportNumber && u.Id != userId && !u.DeleteMark) .Where(u => u.PassportNumber == input.PassportNumber && u.Id != userId && !u.DeleteMark && u.PersonType == PersonType.Athlete)
.FirstAsync(); .FirstAsync();
if (duplicatePassport != null) throw Oops.Bah("该护照号码已被其他用户使用"); if (duplicatePassport != null) throw Oops.Bah("该护照号码已被其他用户使用");
} }
@ -200,7 +200,7 @@ public class MyController : IDynamicApiController
// 身份证号查重 // 身份证号查重
var duplicateIdCard = await _appUserRepository.AsQueryable() var duplicateIdCard = await _appUserRepository.AsQueryable()
.Where(u => u.IdCardNumber == input.IdCardNumber && u.Id != userId && !u.DeleteMark) .Where(u => u.IdCardNumber == input.IdCardNumber && u.Id != userId && !u.DeleteMark && u.PersonType == PersonType.Athlete)
.FirstAsync(); .FirstAsync();
if (duplicateIdCard != null) throw Oops.Bah("该身份证号已被其他用户使用"); if (duplicateIdCard != null) throw Oops.Bah("该身份证号已被其他用户使用");
} }

View File

@ -102,6 +102,13 @@
<param name="personType"></param> <param name="personType"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:YD_Event.Application.AppUser.AppUserService.GetCertDisplay(System.Int32)">
<summary>
获取证件类型显示名称
</summary>
<param name="authType"></param>
<returns></returns>
</member>
<member name="M:YD_Event.Application.AppUser.AppUserService.DeleteMember(System.Int64)"> <member name="M:YD_Event.Application.AppUser.AppUserService.DeleteMember(System.Int64)">
<summary> <summary>
删除成员(解除与单位的关联,而非删除用户) 删除成员(解除与单位的关联,而非删除用户)