Files
jinko.yikatong/Src/Dlhis.Basic/Organization/Services/Implements/GainfoOutsourceService.cs
2025-12-17 12:25:17 +08:00

322 lines
12 KiB
C#

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<GainfoOutsourceService> _logger;
public GainfoOutsourceService(IDbContext dbContext,
RedisCache redisCache,
IGainfoService gainfoService,
IFactorySettingService factorySettingService,
ILogger<GainfoOutsourceService> 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<GainfoEntity>()
.Where(x => x.Code == request.ExternalInfo.SapCode)
.AnyAsync();
sapCodeExists.ThrowIfFalse("对接人不存在");
var isOutsource = await _dbContext.Queryable<OutsourceEntity>()
.Where(x => x.Code == request.ExternalInfo.SapCode)
.AnyAsync();
isOutsource.ThrowIfTrue("对接人不可为外包人员");
if (!request.Id.HasValue)
{
if (!await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdNo == request.IdNo).AnyAsync())
{
var entity = request.Adapt<GainfoEntity>();
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<OutsourceEntity>().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<GainfoEntity>().FirstAsync(x => x.Id == request.Id);
entity.ThrowIfNull("档案数据不存在");
var outsource = await _dbContext.Queryable<OutsourceEntity>().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<GainfoOutSourceExternalInfoResponse> GetExternalInfoAsync(string userNo)
{
try
{
var data = await _dbContext.Queryable<OutsourceEntity>()
.LeftJoin<GainfoEntity>((a, b) => a.Code == b.Code)
.LeftJoin<GainfoEntity>((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<OutsourceWhiteListEntity>()
.Where(x => x.UserCode == data.UserCode)
.AnyAsync();
return data;
}
catch (Exception)
{
return null;
}
}
public async Task AutoResignAsync()
{
var outsources = await _dbContext.Queryable<GainfoEntity>()
.Where(x => x.Type == GainfoUserTypeEnumType.Outsource)
.Where(x => SqlFunc.Subqueryable<OutsourceWhiteListEntity>()
.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<FactorySettingResponse>
{
new FactorySettingResponse
{
Factory = "1234",
NoRecordAutoResignOutsourceDays = 1
},
};// await _factorySettingService.GetListAsync(false);
var holidaies = await _dbContext
.Queryable<HolidayEntity>()
.Select(x => new
{
x.Type,
x.Start,
x.End
})
.ToListAsync();
var weekends = new List<DayOfWeek>() { 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<DeviceUploadLogEntity>()
.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<DateOnly> GetDaysUntilToday(DateTime begin)
{
var start = DateOnly.FromDateTime(begin.Date);
var today = DateOnly.FromDateTime(DateTime.Today);
if (start > today) return new List<DateOnly>();
var days = new List<DateOnly>();
for (var d = start; d <= today; d = d.AddDays(1))
{
days.Add(d);
}
return days;
}
//********************************************************************** help methods ***********************************************************************************
private async Task<string> 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<BasicTypeEntity>().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<OutsourceEntity>().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');
}
/// <summary>
/// 检查证件号重复
/// </summary>
/// <param name="request"></param>
private async Task CheckDuplicate(GainfoOutsourceRequest request)
{
var gainfo = await _dbContext.Queryable<GainfoEntity>()
.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<OutsourceEntity>().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<GainfoEntity>()
.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<OutsourceEntity>().Where(x => x.Code == request.Code).SingleAsync();
if (outsource != null)
{
msg = $",对接人工号为{outsource.SapCode}";
}
gainfo.ThrowIfNotNull($"工号{request.Code}重复,厂区为{gainfo.Factory}" + msg);
}
}
}
}