using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Basic.Enums; using Dlhis.Entity.Device.Entities; using Kurisu.AspNetCore.Cache; using Kurisu.AspNetCore.CustomClass; using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; using Kurisu.AspNetCore.Utils.Extensions; using Mapster; using SqlSugar; namespace Dlhis.Basic.Organization.Services.Implements; public class GainfoOutsourceService : IGainfoOutsourceService { private readonly IDbContext _dbContext; private readonly RedisCache _redisCache; private readonly IGainfoService _gainfoService; private readonly IFactorySettingService _factorySettingService; private readonly ILogger _logger; public GainfoOutsourceService(IDbContext dbContext, RedisCache redisCache, IGainfoService gainfoService, IFactorySettingService factorySettingService, ILogger logger) { _dbContext = dbContext; _redisCache = redisCache; _gainfoService = gainfoService; _factorySettingService = factorySettingService; _logger = logger; } public async Task SaveAsync(GainfoOutsourceRequest request) { await CheckDuplicate(request); var sapCodeExists = await _dbContext.Queryable() .Where(x => x.Code == request.ExternalInfo.SapCode) .AnyAsync(); sapCodeExists.ThrowIfFalse("对接人不存在"); var isOutsource = await _dbContext.Queryable() .Where(x => x.Code == request.ExternalInfo.SapCode) .AnyAsync(); isOutsource.ThrowIfTrue("对接人不可为外包人员"); if (!request.Id.HasValue) { if (!await _dbContext.Queryable().Where(x => x.IdNo == request.IdNo).AnyAsync()) { var entity = request.Adapt(); entity.No = Guid.NewGuid().ToString(); entity.Type = GainfoUserTypeEnumType.Outsource; entity.Code = request.Code.IsPresent() ? request.Code : await GetOutSourceCodeAsync(); await _dbContext.InsertAsync(entity); if (!await _dbContext.Queryable().Where(x => x.Code == entity.Code).AnyAsync()) { await _dbContext.InsertAsync(new OutsourceEntity { Code = entity.Code, Supplier = request.ExternalInfo.Supplier, SapCode = request.ExternalInfo.SapCode, SapPhone = request.ExternalInfo.SapPhone }); } } } else { var entity = await _dbContext.Queryable().FirstAsync(x => x.Id == request.Id); entity.ThrowIfNull("档案数据不存在"); var outsource = await _dbContext.Queryable().FirstAsync(x => x.Code == entity.Code); (outsource == null).ThrowIfTrue("不可编辑非外包人员档案数据"); var idNo = entity.IdNo; var phone = entity.Phone; request.Adapt(entity); entity.IdNo = idNo; entity.Phone = phone; outsource!.Code = entity.Code; request.ExternalInfo.Adapt(outsource); await _dbContext.UpdateAsync(entity); await _dbContext.UpdateAsync(outsource); } } public async Task GetExternalInfoAsync(string userNo) { try { var data = await _dbContext.Queryable() .LeftJoin((a, b) => a.Code == b.Code) .LeftJoin((a, b, c) => a.SapCode == c.Code) .Where((a, b, c) => b.No == userNo) .Select((a, b, c) => new GainfoOutSourceExternalInfoResponse { UserCode = b.Code, Supplier = a.Supplier, SapCode = a.SapCode, SapPhone = a.SapPhone, SapName = c.Name, EntryDate = b.EntryDate, ResignationDate = b.ResignationDate, Factory = b.Factory }) .SingleAsync(); data.IsWhiteListInAutoResign = await _dbContext.Queryable() .Where(x => x.UserCode == data.UserCode) .AnyAsync(); return data; } catch (Exception) { return null; } } public async Task AutoResignAsync() { var outsources = await _dbContext.Queryable() .Where(x => x.Type == GainfoUserTypeEnumType.Outsource) .Where(x => SqlFunc.Subqueryable() .Where(p => p.UserCode == x.Code) .Where(p => p.IsDeleted == false) .NotAny() )//不存在白名单中 .Select(x => new { x.Id, x.Code, x.Factory, x.CreateTime }) .ToListAsync(); var settings = new List { new FactorySettingResponse { Factory = "1234", NoRecordAutoResignOutsourceDays = 1 }, };// await _factorySettingService.GetListAsync(false); var holidaies = await _dbContext .Queryable() .Select(x => new { x.Type, x.Start, x.End }) .ToListAsync(); var weekends = new List() { DayOfWeek.Saturday, DayOfWeek.Sunday }; foreach (var grp in outsources.GroupBy(x => x.Factory)) { var setting = settings.First(x => x.Factory == grp.Key); if (setting.NoRecordAutoResignOutsourceDays == 0) { continue; } foreach (var outsource in grp) { DateTime? raiseDateTime = await _dbContext.Queryable() .Where(x => x.UserUniqueNo == outsource.Code) .Where(x => x.TenantId == grp.Key) //本厂区的 .GroupBy(x => x.UserUniqueNo) .Select(x => SqlFunc.IsNull(SqlFunc.AggregateMax(x.RaiseDateTime), default(DateTime?))) .SingleAsync(); if (raiseDateTime.HasValue) { var checkDates = GetDaysUntilToday(raiseDateTime.Value); var days = checkDates.Count; foreach (var date in checkDates) { //date.DayOfWeek foreach (var holiday in holidaies) { var isPresent = date >= holiday.Start && date <= holiday.Start; if (isPresent) { if (holiday.Type == HolidayEnumType.Rest) { days--; } } } if (weekends.Contains(date.DayOfWeek)) { days--; } } if (days >= setting.NoRecordAutoResignOutsourceDays) { try { await _gainfoService.ResignAsync(new GainfoResignRequest { Id = outsource.Id, Reason = $"{setting.NoRecordAutoResignOutsourceDays}天无通行记录", Date = DateTime.Now }); } catch (Exception e) { _logger.LogError(e, "自动离职外包异常:{msg}", e.Message); } } } } } } public List GetDaysUntilToday(DateTime begin) { var start = DateOnly.FromDateTime(begin.Date); var today = DateOnly.FromDateTime(DateTime.Today); if (start > today) return new List(); var days = new List(); for (var d = start; d <= today; d = d.AddDays(1)) { days.Add(d); } return days; } //********************************************************************** help methods *********************************************************************************** private async Task GetOutSourceCodeAsync() { await using var handler = await _redisCache.LockAsync("gainfo:outsource:code-generate", expiry: TimeSpan.FromSeconds(3), retryInterval: TimeSpan.FromSeconds(1), retryCount: 3); handler.Acquired.ThrowIfFalse("生成虚拟工号失败"); // var value = await _dbContext.Queryable().Where(x => x.Type == "gainfoExternalMaxNum").Select(x => x.Code).SingleAsync(); // if (value.IsEmpty()) // { // code = 1; // await _dbContext.InsertAsync(new BasicTypeEntity // { // Type = "gainfoExternalMaxNum", // Code = "1", // Display = "外部人员序号", // DisplayEn = "外部人员序号", // Sequence = 1 // }); // } // else // { // code = int.Parse(value) + 1; // } // // return "EXT" + code.ToString().PadLeft(6, '0'); int code; var entity = await _dbContext.Queryable().Where(x => x.Code.StartsWith("LS")).OrderBy(x => x.Id, OrderByType.Desc).FirstAsync(); if (entity == null) { code = 1; } else { code = int.Parse(entity.Code.Replace("LS", "").TrimStart('0')) + 1; } return "LS" + code.ToString().PadLeft(6, '0'); } /// /// 检查证件号重复 /// /// private async Task CheckDuplicate(GainfoOutsourceRequest request) { var gainfo = await _dbContext.Queryable() .WhereIF(request.Id.HasValue, x => x.Id != request.Id) .Where(x => x.IdNo == request.IdNo).SingleAsync(); if (gainfo != null) { var msg = string.Empty; var outsource = await _dbContext.Queryable().Where(x => x.Code == request.Code).SingleAsync(); if (outsource != null) { msg = $",对接人工号为{outsource.SapCode}"; } gainfo.ThrowIfNotNull($"证件号{request.IdNo}重复,厂区为{gainfo.Factory}" + msg); } if (request.Code.IsPresent()) { gainfo = await _dbContext.Queryable() .WhereIF(request.Id.HasValue, x => x.Id != request.Id) .Where(x => x.Code == request.Code).SingleAsync(); if (gainfo != null) { var msg = string.Empty; var outsource = await _dbContext.Queryable().Where(x => x.Code == request.Code).SingleAsync(); if (outsource != null) { msg = $",对接人工号为{outsource.SapCode}"; } gainfo.ThrowIfNotNull($"工号{request.Code}重复,厂区为{gainfo.Factory}" + msg); } } } }