From b7b7709e0c5b8abbc5d4fe31c15ea64058100dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Wed, 17 Jun 2026 21:39:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=B0=E5=A2=9E=E8=BF=90?= =?UTF-8?q?=E5=8A=A8=E5=91=98=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppUser/AppUserService.cs | 159 ++++++++++++------ YD_Event.Application/Client/MyController.cs | 6 +- YD_Event.Application/YD_Event.Application.xml | 7 + 3 files changed, 114 insertions(+), 58 deletions(-) diff --git a/YD_Event.Application/AppUser/AppUserService.cs b/YD_Event.Application/AppUser/AppUserService.cs index e40254f..d1e5bb9 100644 --- a/YD_Event.Application/AppUser/AppUserService.cs +++ b/YD_Event.Application/AppUser/AppUserService.cs @@ -177,59 +177,83 @@ public class AppUserService : BaseService, 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 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, 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, ITransient }; } + /// + /// 获取证件类型显示名称 + /// + /// + /// + private static string GetCertDisplay(int authType) + { + return authType switch + { + 1 => "身份证号", + 2 => "护照号码", + 3 => "身份证号", + _ => "证件号" + }; + } + #endregion #region 领队/教练管理 (向下兼容) diff --git a/YD_Event.Application/Client/MyController.cs b/YD_Event.Application/Client/MyController.cs index 5856587..f24316f 100644 --- a/YD_Event.Application/Client/MyController.cs +++ b/YD_Event.Application/Client/MyController.cs @@ -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("该身份证号已被其他用户使用"); } diff --git a/YD_Event.Application/YD_Event.Application.xml b/YD_Event.Application/YD_Event.Application.xml index 37313ea..38a9edb 100644 --- a/YD_Event.Application/YD_Event.Application.xml +++ b/YD_Event.Application/YD_Event.Application.xml @@ -102,6 +102,13 @@ + + + 获取证件类型显示名称 + + + + 删除成员(解除与单位的关联,而非删除用户)