From c682cd59ded8e71957a802dd4f8dcf58e0113c0f Mon Sep 17 00:00:00 2001 From: sunpengfei <i@angelzzz.com> Date: 星期四, 11 九月 2025 15:33:30 +0800 Subject: [PATCH] feat:开发 --- FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs | 447 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 438 insertions(+), 9 deletions(-) diff --git a/FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs b/FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs index a6aebe5..28b6bcf 100644 --- a/FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs +++ b/FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs @@ -1,11 +1,17 @@ 锘縰sing FlexJobApi.Core; +using FlexJobApi.Core.Models.ElectronSignServer.Common; +using FlexJobApi.Core.Models.ElectronSignServer.Contracts; +using FlexJobApi.Core.Models.ElectronSignServer.PersonalUserReals; +using FlexJobApi.Core.Models.ElectronSignServer.Users; using Furion; using Furion.DatabaseAccessor; using Furion.DataValidation; +using Furion.DistributedIDGenerator; using Furion.FriendlyException; using Furion.HttpRemote; using Mapster; using MediatR; +using Microsoft.AspNetCore.Components.Forms; using Microsoft.EntityFrameworkCore; using MiniExcelLibs; using NetTopologySuite.Index.HPRtree; @@ -16,6 +22,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace FlexJobApi.UserServer.Application { @@ -23,12 +30,39 @@ /// 鐏靛伐鍛戒护澶勭悊鍣� /// </summary> public class EnterpriseEmployeesCommandHandler( - IRepository<EnterpriseEmployee> rep + SmsUtils smsUtils, + WxmpUtils wxmpUtils, + IMediator mediator, + IRepository<EnterpriseEmployee> rep, + IRepository<User> repUser, + IRepository<Enterprise> repEnterprise, + IRepository<EnterpriseEmployeeContract> repEnterpriseEmployeeContract, + IRepository<ElectronSignSetting> repElectronSignSetting, + IRepository<ContractTemplate> repContractTemplate, + IRepository<EnterpriseCost> repEnterpriseCost, + IRepository<TaskInfoUser> repTaskInfoUser, + IRepository<CodeUrl> repCodeUrl ) : IRequestHandler<ImportEnterpriseEmployeesCommand, ImportEnterpriseEmployeesCommandResult>, - IRequestHandler<EditEnterpriseEmployeeCommand, Guid> + IRequestHandler<EditEnterpriseEmployeeCommand, Guid>, + IRequestHandler<InviteElectronSignCommand, int>, + IRequestHandler<PersonalUserElectronSignCommand, PersonalUserElectronSignCommandResult>, + IRequestHandler<EnterpriseUserElectronSignCommand, EnterpriseUserElectronSignCommandResult>, + IRequestHandler<StopElectronSignCommand, int>, + IRequestHandler<SendInviteElectronSignSmsCommand, int> { + private readonly SmsUtils smsUtils = smsUtils; + private readonly WxmpUtils wxmpUtils = wxmpUtils; + private readonly IMediator mediator = mediator; private readonly IRepository<EnterpriseEmployee> rep = rep; + private readonly IRepository<User> repUser = repUser; + private readonly IRepository<Enterprise> repEnterprise = repEnterprise; + private readonly IRepository<EnterpriseEmployeeContract> repEnterpriseEmployeeContract = repEnterpriseEmployeeContract; + private readonly IRepository<ElectronSignSetting> repElectronSignSetting = repElectronSignSetting; + private readonly IRepository<ContractTemplate> repContractTemplate = repContractTemplate; + private readonly IRepository<EnterpriseCost> repEnterpriseCost = repEnterpriseCost; + private readonly IRepository<TaskInfoUser> repTaskInfoUser = repTaskInfoUser; + private readonly IRepository<CodeUrl> repCodeUrl = repCodeUrl; /// <summary> /// 瀵煎叆鐏靛伐淇℃伅 @@ -44,6 +78,10 @@ var identities = models.DistinctSelect(it => it.Identity); var enterpriseEmployees = await rep.AsQueryable() .Where(it => it.EnterpriseId == logier.EnterpriseId && identities.Contains(it.Identity)) + .ToListAsync(); + var userIds = enterpriseEmployees.DistinctSelect(it => it.UserId.HasValue, it => it.UserId!.Value); + var users = await repUser.AsQueryable() + .Where(it => userIds.Contains(it.Id)) .ToListAsync(); var successList = new List<ImportEnterpriseEmployeesCommandModel>(); foreach (var model in models) @@ -100,11 +138,27 @@ } else { + var canUpdate = true; if (enterpriseEmployee.UserId.HasValue) { - errors.Add("宸叉姤鍚嶆棤娉曚慨鏀逛俊鎭�"); + var user = users.FirstOrDefault(it => it.Id == enterpriseEmployee.UserId.Value)!; + if (user.IsReal == true) + { + canUpdate = false; + errors.Add("宸插疄鍚嶆棤娉曚慨鏀逛俊鎭�"); + } + else + { + user.Name = model.Name; + user.ContactPhoneNumber = model.ContactPhoneNumber; + user.Identity = model.Identity; + user.Gender = model.Gender; + user.Birthday = model.Birthday; + user.Age = model.Age; + await repUser.UpdateAsync(user); + } } - else + if (canUpdate) { enterpriseEmployee.Name = model.Name; enterpriseEmployee.ContactPhoneNumber = model.ContactPhoneNumber; @@ -116,7 +170,7 @@ } } } - if (errors.IsNotNull()) + else { var error = model.Adapt<ImportEnterpriseEmployeesCommandResultError>(); error.ErrorMessage = errors.SplitJoin("锛�"); @@ -135,21 +189,396 @@ /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <returns></returns> - public Task<Guid> Handle(EditEnterpriseEmployeeCommand request, CancellationToken cancellationToken) + public async Task<Guid> Handle(EditEnterpriseEmployeeCommand request, CancellationToken cancellationToken) { var logier = JwtUtils.GetCurrentLogier(); - return request.SaveData<EnterpriseEmployee, EditEnterpriseEmployeeCommand>( + var entity = await request.SaveData<EnterpriseEmployee, EditEnterpriseEmployeeCommand>( q => q.Where(it => it.EnterpriseId == logier.EnterpriseId), - it => it.EnterpriseId == logier.EnterpriseId && it.Id != request.Id && it.Identity == request.Identity, + it => + it.EnterpriseId == logier.EnterpriseId + && it.Id != request.Id + && it.Name == request.Name + && it.Identity == request.Identity + && it.ContactPhoneNumber == request.ContactPhoneNumber, (entity) => { if (request.Id.HasValue && entity.UserId.HasValue) { - throw Oops.Oh(EnumErrorCodeType.s510, "宸叉姤鍚嶆棤娉曚慨鏀逛俊鎭�"); + var user = repUser.AsQueryable().FirstOrDefault(it => it.Id == entity.UserId.Value); + if (user!.IsReal == true) + { + throw Oops.Oh(EnumErrorCodeType.s510, "宸插疄鍚嶆棤娉曚慨鏀逛俊鎭�"); + } + else + { + user.Name = request.Name; + user.ContactPhoneNumber = request.ContactPhoneNumber; + user.Identity = request.Identity; + user.Birthday = request.Identity.GetBirthday(); + user.Gender = request.Gender; + user.Age = request.Age; + repUser.Update(user); + } } request.Adapt(entity); }, cancellationToken); + return entity.Id; } + + /// <summary> + /// 閭�璇风伒宸ョ绾� + /// </summary> + /// <param name="request"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + public async Task<int> Handle(InviteElectronSignCommand request, CancellationToken cancellationToken) + { + var logier = JwtUtils.GetCurrentLogier(); + + await mediator.Send(new CheckContractTemplateCommand + { + Id = request.ContractTemplateId + }, cancellationToken); + + var entities = await rep.AsQueryable() + .Where(it => it.EnterpriseId == logier.EnterpriseId && request.Ids.Contains(it.Id)) + .ToListAsync(); + foreach (var id in request.Ids) + { + var entity = entities.FirstOrDefault(it => it.Id == id); + if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "鐏靛伐"); + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Wait) throw Oops.Oh(EnumErrorCodeType.s400, $"宸查個璇穥entity.Name}"); + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Pass) throw Oops.Oh(EnumErrorCodeType.s400, $"宸茬绾entity.Name}"); + entity.ContractTemplateId = request.ContractTemplateId; + entity.UserSignContractStatus = EnumTaskUserSignContractStatus.Wait; + entity.UserSignContractTime = null; + entity.EnterpriseSignContractStatus = null; + entity.EnterpriseSignContractTime = null; + entity.ContractCode = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}"; + entity.ContractUrl = null; + var contract = new EnterpriseEmployeeContract + { + EnterpriseEmployeeId = entity.Id, + ContractTemplateId = entity.ContractTemplateId, + ContractCode = entity.ContractCode, + UserSignContractStatus = entity.UserSignContractStatus, + }; + await repEnterpriseEmployeeContract.InsertAsync(contract); + await rep.UpdateAsync(entity); + } + return entities.Count; + } + + /// <summary> + /// 鍙戦�侀個璇风绾︾煭淇� + /// </summary> + /// <param name="request"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + public async Task<int> Handle(SendInviteElectronSignSmsCommand request, CancellationToken cancellationToken) + { + var logier = JwtUtils.GetCurrentLogier(); + + await mediator.Send(new CheckContractTemplateCommand + { + Id = request.ContractTemplateId + }, cancellationToken); + + var entities = await rep.AsQueryable() + .Include(it => it.Enterprise) + .Include(it => it.ContractTemplate) + .Where(it => + it.EnterpriseId == logier.EnterpriseId + && request.Ids.Contains(it.Id)) + .ToListAsync(); + + foreach (var id in request.Ids) + { + var entity = entities.FirstOrDefault(it => it.Id == id); + if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "鐏靛伐"); + if (entity.UserSignContractStatus == null + || entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Refuse + || entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Stop) + { + entity.ContractTemplateId = request.ContractTemplateId; + entity.UserSignContractStatus = EnumTaskUserSignContractStatus.Wait; + entity.UserSignContractTime = null; + entity.EnterpriseSignContractStatus = null; + entity.EnterpriseSignContractTime = null; + entity.ContractCode = $"{DateTime.Now:yyyyMMddHHmmss}{new Random(IDGen.NextID().GetHashCode()).Next(1000, 9999)}"; + entity.ContractUrl = null; + var contract = new EnterpriseEmployeeContract + { + EnterpriseEmployeeId = entity.Id, + ContractTemplateId = entity.ContractTemplateId, + ContractCode = entity.ContractCode, + UserSignContractStatus = entity.UserSignContractStatus, + }; + await repEnterpriseEmployeeContract.InsertAsync(contract); + await rep.UpdateAsync(entity); + } + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Wait) + { + var codeUrl = new SaveCodeUrlCommand + { + Scene = EnumCodeUrlScene.InviteElectronSign, + ParamValue1 = entity.Id.ToString(), + ExpiredTime = DateTime.Now.AddMonths(1) + }; + var code = await mediator.Send(codeUrl); + await smsUtils.Send(new SendSmsModel + { + PhoneNumber = entity.ContactPhoneNumber, + TemplateCode = EnumSmsTemplateCode.InviteElectronSign, + }, + new + { + name = entity.Enterprise.EnterpriseName, + code = code + }); + } + } + + return entities.Count; + } + + /// <summary> + /// 涓汉鐢ㄦ埛绛剧害 + /// </summary> + /// <param name="request"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + public async Task<PersonalUserElectronSignCommandResult> Handle(PersonalUserElectronSignCommand request, CancellationToken cancellationToken) + { + if (request.Id == null) + { + if (request.SmsCode.IsNotNull()) + { + var codeUrl = await mediator.Send(new GetCodeUrlQuery + { + Code = request.SmsCode, + Scene = EnumCodeUrlScene.InviteElectronSign + }); + request.Id = codeUrl.ParamValue1.ToGuid()!; + } + else + { + throw Oops.Oh(EnumErrorCodeType.s400, "璇峰~鍐欑伒宸d鎴栫煭淇$紪鍙�"); + } + } + var entity = await rep.AsQueryable() + .Include(it => it.Enterprise) + .Include(it => it.ContractTemplate).ThenInclude(it => it.Values) + .Where(it => it.Id == request.Id) + .FirstOrDefaultAsync(); + if (entity == null) throw Oops.Oh(EnumErrorCodeType.s510, "鏈姤鍚嶈浼佷笟"); + if (entity.UserSignContractStatus == null) throw Oops.Oh(EnumErrorCodeType.s510, "浼佷笟鏈彂璧风绾�"); + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Pass) throw Oops.Oh(EnumErrorCodeType.s510, "宸茬绾�"); + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Refuse) throw Oops.Oh(EnumErrorCodeType.s510, "宸叉嫆绛�"); + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Stop) throw Oops.Oh(EnumErrorCodeType.s510, "宸茬粓姝�"); + var contract = await repEnterpriseEmployeeContract.AsQueryable() + .OrderByDescending(it => it.CreatedTime) + .Where(it => it.EnterpriseEmployeeId == request.Id) + .FirstOrDefaultAsync(); + if (contract == null) throw Oops.Oh(EnumErrorCodeType.s404, "鍚堝悓"); + var user = await repUser.AsQueryable().AsNoTracking() + .Include(it => it.UserAuth) + .Where(it => it.Id == entity.UserId) + .FirstOrDefaultAsync(); + if (user == null) throw Oops.Oh(EnumErrorCodeType.s404, "鐢ㄦ埛"); + if (entity.ContractTemplate.Access == EnumElectronSignAccess.BestSign && !user.IsReal) throw Oops.Oh(EnumErrorCodeType.s510, "璇峰厛瀹炲悕"); + var result = await new SendContractInput + { + OutContractId = contract.Id.ToString(), + TemplateId = entity.ContractTemplate.ElectronSignContractTemplateId!.Value, + Title = entity.ContractTemplate.Name, + OutUserId = entity.UserId.ToString(), + Values = entity.ContractTemplate.Values + .Where(it => it.UserType == EnumUserType.Personal) + .Select(it => + { + string? value = null; + switch (it.BindProperty) + { + case "Name": + value = user.UserAuth.Name; + break; + case "PhoneNumber": + value = user.ContactPhoneNumber; + break; + case "Identity": + value = user.UserAuth.Identity; + break; + default: + break; + } + return new SendContractInputValue + { + Name = it.Name, + Value = value + }; + }) + .ToList(), + UserCount = 2 + }.SendHttpAsync<SendContractInput, ElectronSignServerResult<SendContractOutput>>(EnumResourceHttpProvider.ElectronSignServerCustomer); + if (result?.Success != true) + { + throw Oops.Oh(EnumErrorCodeType.s510, result?.Message ?? "绛剧害澶辫触"); + } + var model = result.Result.Adapt<PersonalUserElectronSignCommandResult>(); + model.SignContractLongUrl = model.SignContractLongUrl + .Replace("https://openapi.bestsign.info:443", "https://wx115.bestsign.info") + .Replace("https://openapi.bestsign.cn:443", "https://wx115.bestsign.cn"); + + if (request.SmsCode.IsNull() && entity.ContractTemplate.Access == EnumElectronSignAccess.AlipaySign) + { + var codeUrl = new SaveCodeUrlCommand + { + Scene = EnumCodeUrlScene.ElectronSignUrl, + Url = model.SignContractLongUrl, + ExpiredTime = DateTime.Now.AddMonths(1) + }; + var code = await mediator.Send(codeUrl); + await smsUtils.Send(new SendSmsModel + { + PhoneNumber = entity.ContactPhoneNumber, + TemplateCode = EnumSmsTemplateCode.ElectronSignUrl, + }, + new + { + name = entity.Enterprise.EnterpriseName, + code = code + }); + } + + return model; + } + + /// <summary> + /// 浼佷笟鐢ㄦ埛绛剧害 + /// </summary> + /// <param name="request"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + public async Task<EnterpriseUserElectronSignCommandResult> Handle(EnterpriseUserElectronSignCommand request, CancellationToken cancellationToken) + { + var logier = JwtUtils.GetCurrentLogier(); + var entity = await rep.AsQueryable() + .Include(it => it.ContractTemplate).ThenInclude(it => it.Values) + .Where(it => it.EnterpriseId == logier.EnterpriseId && it.Id == request.Id) + .FirstOrDefaultAsync(); + if (entity == null) throw Oops.Oh(EnumErrorCodeType.s510, "鐏靛伐涓嶅瓨鍦�"); + if (entity.UserSignContractStatus == null) throw Oops.Oh(EnumErrorCodeType.s510, "鏈個璇风绾�"); + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Wait) throw Oops.Oh(EnumErrorCodeType.s510, "璇峰厛绛夊緟鐏靛伐绛剧害瀹屾垚"); + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Refuse) throw Oops.Oh(EnumErrorCodeType.s510, "宸叉嫆绛�"); + if (entity.UserSignContractStatus == EnumTaskUserSignContractStatus.Stop) throw Oops.Oh(EnumErrorCodeType.s510, "宸茬粓姝�"); + var contract = await repEnterpriseEmployeeContract.AsQueryable() + .OrderByDescending(it => it.CreatedTime) + .Where(it => it.EnterpriseEmployeeId == request.Id) + .FirstOrDefaultAsync(); + if (contract == null) throw Oops.Oh(EnumErrorCodeType.s404, "鍚堝悓"); + var enterprise = await repEnterprise.AsQueryable().AsNoTracking() + .Include(it => it.EnterpriseAuth) + .Where(it => it.Id == logier.EnterpriseId) + .FirstOrDefaultAsync(); + if (enterprise == null) throw Oops.Oh(EnumErrorCodeType.s404, "浼佷笟"); + if (entity.ContractTemplate.Access == EnumElectronSignAccess.BestSign && !enterprise.IsReal) throw Oops.Oh(EnumErrorCodeType.s510, "璇峰厛瀹炲悕"); + var result = await new SendContractInput + { + OutContractId = contract.Id.ToString(), + TemplateId = entity.ContractTemplate.ElectronSignContractTemplateId!.Value, + Title = entity.ContractTemplate.Name, + OutUserId = logier.EnterpriseId.ToString(), + Values = entity.ContractTemplate.Values + .Where(it => it.UserType == EnumUserType.Enterprise) + .Select(it => new SendContractInputValue + { + Name = it.Name, + }) + .ToList(), + UserCount = 2 + }.SendHttpAsync<SendContractInput, ElectronSignServerResult<SendContractOutput>>(EnumResourceHttpProvider.ElectronSignServerCustomer); + if (result?.Success != true) + { + throw Oops.Oh(EnumErrorCodeType.s510, result?.Message ?? "绛剧害澶辫触"); + } + var model = result.Result.Adapt<EnterpriseUserElectronSignCommandResult>(); + model.SignContractLongUrl = model.SignContractLongUrl + .Replace("https://openapi.bestsign.info:443", "https://wx115.bestsign.info") + .Replace("https://openapi.bestsign.cn:443", "https://wx115.bestsign.cn"); + + if (entity.ContractTemplate.Access == EnumElectronSignAccess.AlipaySign) + { + var codeUrl = new SaveCodeUrlCommand + { + Scene = EnumCodeUrlScene.ElectronSignUrl, + Url = model.SignContractLongUrl, + ExpiredTime = DateTime.Now.AddMonths(1) + }; + var code = await mediator.Send(codeUrl); + await smsUtils.Send(new SendSmsModel + { + PhoneNumber = entity.Enterprise.ContactPhoneNumber, + TemplateCode = EnumSmsTemplateCode.ElectronSignUrl, + }, + new + { + name = entity.Name, + code = code + }); + } + + return model; + } + + /// <summary> + /// 鐏靛伐瑙g害 + /// </summary> + /// <param name="request"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + public async Task<int> Handle(StopElectronSignCommand request, CancellationToken cancellationToken) + { + var logier = JwtUtils.GetCurrentLogier(); + var entities = await rep.AsQueryable() + .Include(it => it.Contracts) + .Where(it => it.EnterpriseId == logier.EnterpriseId && request.Ids.Contains(it.Id)) + .ToListAsync(); + foreach (var id in request.Ids) + { + var entity = entities.FirstOrDefault(it => it.Id == id); + if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "鐏靛伐"); + if (entity.UserSignContractStatus != EnumTaskUserSignContractStatus.Pass) throw Oops.Oh(EnumErrorCodeType.s400, $"鏈绾entity.Name}"); + entity.UserSignContractStatus = EnumTaskUserSignContractStatus.Stop; + entity.EnterpriseSignContractStatus = EnumTaskUserSignContractStatus.Stop; + await rep.UpdateAsync(entity); + + var contract = entity.Contracts + .OrderByDescending(it => it.CreatedTime) + .FirstOrDefault(); + if (contract == null) throw Oops.Oh(EnumErrorCodeType.s404, $"涓巤entity.Name}鐨勫悎鍚�"); + contract.UserSignContractStatus = EnumTaskUserSignContractStatus.Stop; + contract.EnterpriseSignContractStatus = EnumTaskUserSignContractStatus.Stop; + await repEnterpriseEmployeeContract.UpdateAsync(contract); + } + + var taskUsers = await repTaskInfoUser.AsQueryable() + .Where(it => + it.HireStatus == EnumTaskUserHireStatus.Pass + && request.Ids.Contains(it.EnterpriseEmployeeId)) + .ToListAsync(); + if (taskUsers.IsNotNull()) + { + foreach (var taskUser in taskUsers) + { + taskUser.HireStatus = EnumTaskUserHireStatus.Wait; + } + await repTaskInfoUser.UpdateAsync(taskUsers); + } + + return entities.Count; + } + } } -- Gitblit v1.9.1