From 378bf7fe510e2ffca1d9e60ee729bf6819ab8340 Mon Sep 17 00:00:00 2001 From: fuenmao <980740792@qq.com> Date: Fri, 11 Sep 2026 11:31:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=91=98=E5=B7=A5=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=E4=BF=A1=E6=81=AF=E5=AE=9E=E5=90=8D=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BF=A1=E6=81=AF=E6=9D=BF=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dto/OnboardingPublicSubmissionInput.cs | 23 ++++++++ .../OnboardingPublicSubmissionService.cs | 52 +++++++++++++++++-- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/SimpleAdmin.Application/Services/Onboarding/PublicSubmission/Dto/OnboardingPublicSubmissionInput.cs b/SimpleAdmin.Application/Services/Onboarding/PublicSubmission/Dto/OnboardingPublicSubmissionInput.cs index 2da8218..a0f9d0e 100644 --- a/SimpleAdmin.Application/Services/Onboarding/PublicSubmission/Dto/OnboardingPublicSubmissionInput.cs +++ b/SimpleAdmin.Application/Services/Onboarding/PublicSubmission/Dto/OnboardingPublicSubmissionInput.cs @@ -71,4 +71,27 @@ public class OnboardingSubmitInput /// [global::System.ComponentModel.DataAnnotations.Required] public string Token { get; set; } + + /// + /// 员工是否已在最终提交前逐项确认实名认证信息。 + /// + public bool IdentityInformationConfirmed { get; set; } + + /// + /// 员工最终确认的真实姓名。 + /// + [global::System.ComponentModel.DataAnnotations.Required] + public string ConfirmedEmployeeName { get; set; } + + /// + /// 员工最终确认的身份证号码。 + /// + [global::System.ComponentModel.DataAnnotations.Required] + public string ConfirmedIdCardNumber { get; set; } + + /// + /// 员工最终确认的手机号码。 + /// + [global::System.ComponentModel.DataAnnotations.Required] + public string ConfirmedPhone { get; set; } } diff --git a/SimpleAdmin.Application/Services/Onboarding/PublicSubmission/OnboardingPublicSubmissionService.cs b/SimpleAdmin.Application/Services/Onboarding/PublicSubmission/OnboardingPublicSubmissionService.cs index 36521df..845c950 100644 --- a/SimpleAdmin.Application/Services/Onboarding/PublicSubmission/OnboardingPublicSubmissionService.cs +++ b/SimpleAdmin.Application/Services/Onboarding/PublicSubmission/OnboardingPublicSubmissionService.cs @@ -127,6 +127,7 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ // 最终提交必须重新执行全量校验,不能只依赖员工手机端的页面校验。 OnboardingEmployeeInfoValidator.ValidateAndNormalize(info); + EnsureIdentityInformationConfirmed(input, info); await _db.Updateable(info).ExecuteCommandAsync(); await _identityValidationService.EnsureNoDuplicate( @@ -155,9 +156,11 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ if (hasUnconfirmedRequiredContract) throw Oops.Bah("请查看并确认全部必签合同"); + var submittedAt = DateTime.Now; + var identityConfirmationHash = BuildIdentityConfirmationHash(info); task.TaskStatus = OnboardingTaskStatus.Reviewing; task.SubmitCount++; - task.LastSubmittedAt = DateTime.Now; + task.LastSubmittedAt = submittedAt; task.RejectReason = null; await _db.Updateable(task).ExecuteCommandAsync(); @@ -167,9 +170,18 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ TaskId = task.Id, AuditRound = task.SubmitCount, AuditAction = OnboardingAuditAction.Submit, - AuditOpinion = "员工提交入职资料", - SnapshotJson = global::System.Text.Json.JsonSerializer.Serialize(new { info, materials }), - AuditedAt = DateTime.Now + AuditOpinion = "员工提交入职资料,并确认姓名、身份证号码和手机号码用于实名认证", + SnapshotJson = global::System.Text.Json.JsonSerializer.Serialize(new + { + info, + materials, + identityConfirmation = new + { + confirmedAt = submittedAt, + summaryHash = identityConfirmationHash + } + }), + AuditedAt = submittedAt }).ExecuteCommandAsync(); } @@ -214,6 +226,38 @@ public class OnboardingPublicSubmissionService : IOnboardingPublicSubmissionServ throw Oops.Bah("该材料已达到最大上传数量"); } + /// + /// 后端再次比较员工勾选确认时的三项实名信息,防止绕过页面或确认后数据发生变化。 + /// + private static void EnsureIdentityInformationConfirmed( + OnboardingSubmitInput input, + ObTaskEmployeeInfo info) + { + if (!input.IdentityInformationConfirmed) + throw Oops.Bah("请逐项确认姓名、身份证号码和手机号码无误"); + + var confirmedEmployeeName = input.ConfirmedEmployeeName?.Trim(); + var confirmedIdCardNumber = input.ConfirmedIdCardNumber?.Trim().ToUpperInvariant(); + var confirmedPhone = input.ConfirmedPhone?.Trim(); + + if (!string.Equals(confirmedEmployeeName, info.EmployeeName, StringComparison.Ordinal)) + throw Oops.Bah("姓名在确认后发生了变化,请返回基本信息重新核对并确认"); + if (!string.Equals(confirmedIdCardNumber, info.IdCardNumber, StringComparison.Ordinal)) + throw Oops.Bah("身份证号码在确认后发生了变化,请返回基本信息重新核对并确认"); + if (!string.Equals(confirmedPhone, info.Phone, StringComparison.Ordinal)) + throw Oops.Bah("手机号码在确认后发生了变化,请返回基本信息重新核对并确认"); + } + + /// + /// 审核快照只记录实名信息摘要,完整原始值仍以本轮员工信息快照为准。 + /// + private static string BuildIdentityConfirmationHash(ObTaskEmployeeInfo info) + { + var value = $"{info.EmployeeName}\n{info.IdCardNumber}\n{info.Phone}"; + var bytes = global::System.Text.Encoding.UTF8.GetBytes(value); + return Convert.ToHexString(global::System.Security.Cryptography.SHA256.HashData(bytes)); + } + private Task> GetMaterialRequirements(long taskId) { return _db.Queryable()