优化新增运动员逻辑

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("当前用户未关联单位,无法进行操作");
}
// 手机号为空时,跳过基于手机号的重复检测(单位添加运动员时,联系电话非必填)
// 根据认证类型决定查重策略:
// - 运动员 + 有认证类型 + 有证件号 → 用证件号查重
// - 其他情况 → 用手机号查重(原逻辑)
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))
);
// ============== 新增:证件号查重验证 ==============
// 身份证/户口本认证时检查身份证号是否重复
if ((input.AuthType == 1 || input.AuthType == 3) && !string.IsNullOrWhiteSpace(input.IdCardNumber))
// 查重基础查询(排除自身ID)
ISugarQueryable<AppUserEntity> BuildBaseQuery()
{
var q1 = _appUserRep.AsQueryable()
.Where(x => x.IdCardNumber == input.IdCardNumber
&& x.PersonType == input.PersonType
&& !x.DeleteMark);
var q = _appUserRep.AsQueryable()
.Where(x => x.PersonType == input.PersonType && !x.DeleteMark);
if (input.Id.HasValue)
{
q1 = q1.Where(x => x.Id != input.Id.Value);
}
var duplicateIdCard = await q1.FirstAsync();
if (duplicateIdCard != null)
{
throw Oops.Bah($"系统中已存在相同身份证号的{GetPersonTypeDisplay(input.PersonType)},请核对信息");
q = q.Where(x => x.Id != input.Id.Value);
}
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;
if (!mobileIsEmpty)
AppUserEntity? existingWithoutUnit = null;
if (useCertCheck)
{
existingInOtherUnit = await _appUserRep.AsQueryable()
.Where(x => x.Mobile == input.Mobile
&& x.PersonType == input.PersonType
&& x.MerchantCertificationId != merchantCertificationId
&& x.MerchantCertificationId != null
&& !x.DeleteMark)
.FirstAsync();
var certQuery = BuildBaseQuery();
// 按认证类型明确匹配不同证件字段
if (input.AuthType == 1)
{
// 身份证认证 → 用 IdCardNumber 查重
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;
@ -244,26 +268,35 @@ public class AppUserService : BaseService<AppUserEntity>, ITransient
entity = existingInOtherUnit;
originalMerchantId = entity.MerchantCertificationId;
}
else if (existingWithoutUnit != null)
{
// 找到已存在但未加入任何单位的记录,复用该记录(证件号查重时进入)
entity = existingWithoutUnit;
entity.UpdatedUserId = _authManager.UserId;
entity.UpdatedTime = DateTime.Now;
}
else
{
// 检查是否存在相同手机号但还未加入任何单位的记录(小程序注册的用户)
AppUserEntity? existingWithoutUnit = null;
if (!mobileIsEmpty)
// 按原手机号继续查询(仅当未使用证件号查重时)
if (!useCertCheck && !mobileIsEmpty)
{
existingWithoutUnit = await _appUserRep.AsQueryable()
var mobileMatch = await _appUserRep.AsQueryable()
.Where(x => x.Mobile == input.Mobile
&& x.PersonType == input.PersonType
&& x.MerchantCertificationId == null
&& !x.DeleteMark)
.FirstAsync();
}
if (existingWithoutUnit != null)
{
// 找到已存在但未加入任何单位的记录,复用该记录
entity = existingWithoutUnit;
entity.UpdatedUserId = _authManager.UserId;
entity.UpdatedTime = DateTime.Now;
if (mobileMatch != null)
{
entity = mobileMatch;
entity.UpdatedUserId = _authManager.UserId;
entity.UpdatedTime = DateTime.Now;
}
else
{
isNewRecord = true;
}
}
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
#region 领队/教练管理 (向下兼容)

View File

@ -176,7 +176,7 @@ public class MyController : IDynamicApiController
// 身份证号查重
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();
if (duplicateIdCard != null) throw Oops.Bah("该身份证号已被其他用户使用");
}
@ -189,7 +189,7 @@ public class MyController : IDynamicApiController
// 护照号查重
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();
if (duplicatePassport != null) throw Oops.Bah("该护照号码已被其他用户使用");
}
@ -200,7 +200,7 @@ public class MyController : IDynamicApiController
// 身份证号查重
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();
if (duplicateIdCard != null) throw Oops.Bah("该身份证号已被其他用户使用");
}

View File

@ -102,6 +102,13 @@
<param name="personType"></param>
<returns></returns>
</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)">
<summary>
删除成员(解除与单位的关联,而非删除用户)