From 78b5e0a2e4c48239983e236c48f8c0b897d69f9e Mon Sep 17 00:00:00 2001
From: sunpengfei <i@angelzzz.com>
Date: 星期二, 09 九月 2025 09:38:00 +0800
Subject: [PATCH] feat:开发

---
 FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs |  519 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 507 insertions(+), 12 deletions(-)

diff --git a/FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs b/FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs
index cd62045..205542b 100644
--- a/FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs
+++ b/FlexJobApi.UserServer.Application/EnterpriseEmployees/Commands/EnterpriseEmployeesCommandHandler.cs
@@ -1,17 +1,28 @@
 锘縰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;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Security.Principal;
 using System.Text;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
+using static System.Runtime.InteropServices.JavaScript.JSType;
 
 namespace FlexJobApi.UserServer.Application
 {
@@ -19,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, int>,
-        IRequestHandler<EditEnterpriseEmployeeCommand, Guid>
+        IRequestHandler<ImportEnterpriseEmployeesCommand, ImportEnterpriseEmployeesCommandResult>,
+        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>
         /// 瀵煎叆鐏靛伐淇℃伅
@@ -32,11 +70,117 @@
         /// <param name="request"></param>
         /// <param name="cancellationToken"></param>
         /// <returns></returns>
-        public async Task<int> Handle(ImportEnterpriseEmployeesCommand request, CancellationToken cancellationToken)
+        public async Task<ImportEnterpriseEmployeesCommandResult> Handle(ImportEnterpriseEmployeesCommand request, CancellationToken cancellationToken)
         {
+            var logier = JwtUtils.GetCurrentLogier();
+            var result = new ImportEnterpriseEmployeesCommandResult();
             var models = await request.ExcelUrl.ImportExcelFromOSS<ImportEnterpriseEmployeesCommandModel>();
-            Console.WriteLine();
-            throw new NotImplementedException();
+            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)
+            {
+                var errors = new List<string>();
+                if (model.Name.IsNull())
+                {
+                    errors.Add("璇峰~鍐欏鍚�");
+                }
+                if (model.ContactPhoneNumber.IsNull())
+                {
+                    errors.Add("璇峰~鍐欐墜鏈哄彿");
+                }
+                else if (!model.ContactPhoneNumber.TryValidate(EnumValidationTypes.ValidPhoneNumber).IsValid)
+                {
+                    errors.Add("鎵嬫満鍙锋牸寮忎笉姝g‘");
+                }
+                if (model.Identity.IsNull())
+                {
+                    errors.Add("璇峰~鍐欒韩浠借瘉鍙�");
+                }
+                else if (!model.Identity.TryValidate(EnumValidationTypes.ValiIdentity).IsValid)
+                {
+                    errors.Add("韬唤璇佸彿鏍煎紡涓嶆纭�");
+                }
+                else if (successList.Any(it => it.Identity == model.Identity))
+                {
+                    errors.Add("韬唤璇佸彿閲嶅");
+                }
+                else
+                {
+                    model.Gender = model.Identity.GetGender();
+                    model.Birthday = model.Identity.GetBirthday();
+                    model.Age = model.Identity.GetAge();
+                }
+
+                if (errors.IsNull())
+                {
+                    var enterpriseEmployee = enterpriseEmployees.FirstOrDefault(it => it.Identity == model.Identity);
+                    if (enterpriseEmployee == null)
+                    {
+                        enterpriseEmployee = new EnterpriseEmployee
+                        {
+                            EnterpriseId = logier.EnterpriseId!.Value,
+                            Name = model.Name,
+                            Identity = model.Identity,
+                            ContactPhoneNumber = model.ContactPhoneNumber,
+                            Gender = model.Gender,
+                            Birthday = model.Birthday,
+                            Age = model.Age,
+                        };
+                        await rep.InsertAsync(enterpriseEmployee);
+                        successList.Add(model);
+                    }
+                    else
+                    {
+                        var canUpdate = true;
+                        if (enterpriseEmployee.UserId.HasValue)
+                        {
+                            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);
+                            }
+                        }
+                        if (canUpdate)
+                        {
+                            enterpriseEmployee.Name = model.Name;
+                            enterpriseEmployee.ContactPhoneNumber = model.ContactPhoneNumber;
+                            enterpriseEmployee.Gender = model.Gender;
+                            enterpriseEmployee.Birthday = model.Birthday;
+                            enterpriseEmployee.Age = model.Age;
+                            await rep.UpdateAsync(enterpriseEmployee);
+                            successList.Add(model);
+                        }
+                    }
+                }
+                else
+                {
+                    var error = model.Adapt<ImportEnterpriseEmployeesCommandResultError>();
+                    error.ErrorMessage = errors.SplitJoin("锛�");
+                    result.Errors.Add(error);
+                }
+            }
+            result.TotalCount = models.Count;
+            result.FailCount = result.Errors.Count;
+            result.SuccessCount = result.TotalCount - result.FailCount;
+            return result;
         }
 
         /// <summary>
@@ -45,20 +189,371 @@
         /// <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)
         {
-            return request.SaveData<EnterpriseEmployee, EditEnterpriseEmployeeCommand>(
-                null,
-                null,
-                (entity) =>
+            var logier = JwtUtils.GetCurrentLogier();
+            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,
+                 (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 mediator.Send(new SaveEnterpriseCostCommand
+                //{
+                //    EnterpriseId = logier.EnterpriseId!.Value,
+                //    ContractTemplateId = request.ContractTemplateId,
+                //    EnterpriseEmployeeContractId = contract.Id,
+                //    Type = EnumEnterpriseCostType.ElectronSign
+                //});
+                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();
+            var entities = await rep.AsQueryable()
+                .Include(it => it.Enterprise)
+                .Include(it => it.ContractTemplate)
+                .Where(it =>
+                    it.EnterpriseId == logier.EnterpriseId
+                    && request.Ids.Contains(it.Id)
+                    && it.UserSignContractStatus == EnumTaskUserSignContractStatus.Wait)
+                .ToListAsync();
+            foreach (var entity in entities)
+            {
+                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)
+        {
+            var logier = JwtUtils.GetCurrentLogier();
+            Guid userId;
+            if (logier != null)
+            {
+                userId = logier.Id;
+            }
+            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