265 lines
10 KiB
C#
265 lines
10 KiB
C#
using System.Text;
|
|
using Dlhis.Entity.Basic.Entity;
|
|
using Dlhis.Entity.Basic.Enums;
|
|
using Dlhis.Entity.Visitor.Entity;
|
|
using Dlhis.Entity.Visitor.Enums;
|
|
using Dlhis.External.Appointment.Request;
|
|
using Kurisu.AspNetCore.Cache;
|
|
using Kurisu.AspNetCore.CustomClass;
|
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
|
using Kurisu.AspNetCore.Utils.Extensions;
|
|
|
|
namespace Dlhis.External.Appointment.Services.Implements;
|
|
|
|
public class AppointmentService : IAppointmentService
|
|
{
|
|
private readonly IDbContext _dbContext;
|
|
private readonly RedisCache _redisCache;
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
private readonly ILogger<AppointmentService> _logger;
|
|
|
|
public AppointmentService(IDbContext dbContext,
|
|
RedisCache redisCache,
|
|
IHttpClientFactory httpClientFactory,
|
|
ILogger<AppointmentService> logger)
|
|
{
|
|
_dbContext = dbContext;
|
|
_redisCache = redisCache;
|
|
_httpClientFactory = httpClientFactory;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task ReceiveAsync(VisitorAppointmentReceiveRequest request)
|
|
{
|
|
if (request.Factory == "501")
|
|
{
|
|
await ReSendTo501Async(request);
|
|
return;
|
|
}
|
|
|
|
var exists = await _dbContext.Queryable<VisitorAppointmentEntity>().Where(x => x.No == request.No).AnyAsync();
|
|
exists.ThrowIfTrue("已经存在申请");
|
|
|
|
var areas = await _dbContext.Queryable<AppointmentAreaEntity>().Where(x => x.TenantId == request.Factory).ToListAsync();
|
|
|
|
var mst = new VisitorAppointmentEntity
|
|
{
|
|
No = request.No,
|
|
Title = request.Title,
|
|
Code = request.Code,
|
|
Source = request.Source,
|
|
Date = request.Date,
|
|
Factory = request.Factory,
|
|
Reason = request.Reason,
|
|
Remark = request.Remark,
|
|
};
|
|
|
|
await _dbContext.InsertAsync(mst);
|
|
|
|
var invalids = new[] { GainfoUserTypeEnumType.Normal, GainfoUserTypeEnumType.SecurityWhite };
|
|
|
|
var idNos = request.Items.Where(x => x.IsEnterDoorArea).Select(x => x.IdNo).Distinct().ToList();
|
|
var errors = await _dbContext.Queryable<GainfoEntity>()
|
|
.Where(x => idNos.Contains(x.IdNo) || idNos.Contains(x.Code))
|
|
.Where(x => invalids.Contains(x.Type))
|
|
.Select(x => x.IdNo + x.Name)
|
|
.ToListAsync();
|
|
|
|
errors.ThrowIfExists($"内部人员无法发起门岗预约({errors.Join(",")})");
|
|
|
|
foreach (var item in request.Items)
|
|
{
|
|
if (item.IsEnterDoorArea && areas.Where(x => x.Type == AppointmentAreaEnumType.Door)
|
|
.Select(x => x.CustomCode)
|
|
.Contains(item.ApplyDoorArea) == false)
|
|
{
|
|
throw new UserFriendlyException($"门岗区域{item.ApplyDoorArea}无效");
|
|
}
|
|
|
|
if (item.IsEnterWorkplace &&
|
|
item.ApplyWorkplaceAreas.All(p => areas.Where(x => x.Type == AppointmentAreaEnumType.Workplace)
|
|
.Select(x => x.CustomCode)
|
|
.Contains(p)) == false)
|
|
{
|
|
var workplaceAreas = areas.Where(x => x.Type == AppointmentAreaEnumType.Workplace).Select(x => x.CustomCode);
|
|
var notExistsAreas = item.ApplyWorkplaceAreas.Where(x => !workplaceAreas.Contains(x));
|
|
throw new UserFriendlyException($"车间区域{notExistsAreas.Join(",")}无效");
|
|
}
|
|
|
|
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdNo == item.IdNo || x.Code == item.IdNo).SingleAsync();
|
|
//外部人员
|
|
if (gainfo == null)
|
|
{
|
|
gainfo = new GainfoEntity
|
|
{
|
|
No = Guid.NewGuid().ToString(),
|
|
Code = await GetNextExternalCodeAsync(),
|
|
Gender = GetGender(item.IdNo),
|
|
Type = GainfoUserTypeEnumType.External,
|
|
IdNo = item.IdNo,
|
|
Name = item.Name,
|
|
Source = request.Source,
|
|
Phone = item.Phone,
|
|
Factory = mst.Factory
|
|
};
|
|
await _dbContext.InsertAsync(gainfo);
|
|
}
|
|
else
|
|
{
|
|
(invalids.Contains(gainfo.Type) && item.IsEnterDoorArea).ThrowIfTrue("内部人员无法发起门岗预约");
|
|
|
|
if (gainfo.Type == GainfoUserTypeEnumType.External)
|
|
{
|
|
gainfo.Source = request.Source;
|
|
gainfo.Phone = item.Phone;
|
|
gainfo.Factory = mst.Factory;
|
|
|
|
await _dbContext.UpdateAsync(gainfo);
|
|
}
|
|
}
|
|
|
|
var detail = new VisitorAppointmentDetailEntity
|
|
{
|
|
UserNo = gainfo.No,
|
|
No = request.No,
|
|
IdType = item.IdType,
|
|
IdNo = item.IdNo,
|
|
Name = item.Name,
|
|
Phone = item.Phone,
|
|
Remark = item.Remark,
|
|
DoorStatus = item.IsEnterDoorArea && areas.Where(x => x.Type == AppointmentAreaEnumType.Door)
|
|
.Select(x => x.CustomCode)
|
|
.Contains(item.ApplyDoorArea)
|
|
? VisitorAppointmentDetailStatusEnumType.Wait
|
|
: VisitorAppointmentDetailStatusEnumType.Obsolete,
|
|
LicensePlate = item.LicensePlate,
|
|
IsEnterDoorArea = item.IsEnterDoorArea,
|
|
ApplyDoorArea = item.ApplyDoorArea,
|
|
DoorStart = item.DoorStart,
|
|
DoorEnd = item.DoorEnd,
|
|
IsEnterWorkplace = item.IsEnterWorkplace,
|
|
WorkplaceStatus = item.IsEnterWorkplace &&
|
|
item.ApplyWorkplaceAreas.All(p => areas.Where(x => x.Type == AppointmentAreaEnumType.Workplace)
|
|
.Select(x => x.CustomCode)
|
|
.Contains(p))
|
|
? VisitorAppointmentDetailStatusEnumType.Wait
|
|
: VisitorAppointmentDetailStatusEnumType.Obsolete,
|
|
ApplyWorkplaceAreas = item.ApplyWorkplaceAreas,
|
|
WorkplaceStart = item.WorkplaceStart,
|
|
WorkplaceEnd = item.WorkplaceEnd,
|
|
ImageUrl = item.ImageUrl
|
|
};
|
|
|
|
await _dbContext.InsertAsync(detail);
|
|
}
|
|
}
|
|
|
|
private static GenderEnumType GetGender(string idNo)
|
|
{
|
|
try
|
|
{
|
|
if (idNo.Length == 18)
|
|
{
|
|
return int.Parse(idNo.ToCharArray()[16].ToString()) % 2 == 0
|
|
? GenderEnumType.Female
|
|
: GenderEnumType.Male;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//ignore
|
|
}
|
|
|
|
return GenderEnumType.Unknown;
|
|
}
|
|
|
|
public async Task<string> GetNextExternalCodeAsync()
|
|
{
|
|
await using var handler = await _redisCache.LockAsync("gainfo:external:code-generate", expiry: TimeSpan.FromSeconds(3), retryInterval: TimeSpan.FromSeconds(1), retryCount: 3);
|
|
handler.Acquired.ThrowIfFalse("生成虚拟工号失败");
|
|
|
|
int code;
|
|
|
|
var entity = await _dbContext.Queryable<BasicTypeEntity>().Where(x => x.Type == "gainfoExternalMaxNum").SingleAsync();
|
|
if (entity == null)
|
|
{
|
|
code = 1;
|
|
await _dbContext.InsertAsync(new BasicTypeEntity
|
|
{
|
|
Type = "gainfoExternalMaxNum",
|
|
Code = "1",
|
|
Display = "外部人员序号",
|
|
DisplayEn = "外部人员序号",
|
|
Remark = string.Empty,
|
|
Sequence = 1
|
|
});
|
|
}
|
|
else
|
|
{
|
|
code = int.Parse(entity.Code) + 1;
|
|
entity.Code = code.ToString();
|
|
await _dbContext.UpdateAsync(entity);
|
|
}
|
|
|
|
return "EXT" + code.ToString().PadLeft(6, '0');
|
|
}
|
|
|
|
|
|
private async Task ReSendTo501Async(VisitorAppointmentReceiveRequest request)
|
|
{
|
|
var gainfo = await _dbContext.Queryable<GainfoEntity>()
|
|
.LeftJoin<DepartmentEntity>((ga, dept) => ga.DepartmentNo == dept.No)
|
|
.Where((ga, dept) => ga.Code == request.Code)
|
|
.Select((ga, dept) => new
|
|
{
|
|
ga.No,
|
|
ga.Name,
|
|
ga.Phone,
|
|
DeptName = dept.Name
|
|
})
|
|
.SingleAsync();
|
|
|
|
gainfo.ThrowIfNull("501被访人工号不存在");
|
|
|
|
//501厂区发送访客预约
|
|
var httpClient = _httpClientFactory.CreateClient();
|
|
|
|
var list = request.Items.Where(x => x.IsEnterDoorArea).ToList();
|
|
var areas = await _dbContext.Queryable<AppointmentAreaEntity>().Where(x => x.TenantId == request.Factory).ToListAsync();
|
|
|
|
foreach (var dto in list)
|
|
{
|
|
var json = new
|
|
{
|
|
arr = dto.DoorStart!.Value.ToString("yyyy-MM-dd HH:mm:ss"), // [必填] 到达时间
|
|
dep = dto.DoorEnd!.Value.ToString("yyyy-MM-dd HH:mm:ss"), // 离开时间
|
|
company = request.Source, // 公司
|
|
deptdes = gainfo.DeptName, // 被访人部门
|
|
askName = request.Code, // 被访人姓名
|
|
askPhone = gainfo.Phone, //被访人手机号
|
|
gname = dto.Name, // 访客姓名
|
|
idNo = dto.IdNo, // 访客身份证号
|
|
phone = dto.Phone, // 访客电话
|
|
reason = request.Reason, // 访问原因
|
|
carNo = dto.LicensePlate, // 车牌号
|
|
carDes = "", // 物品描述
|
|
remark = dto.Remark, // 备注
|
|
//logId = null, // 操作员ID,null或空时后台保存为"face"
|
|
//logShift = null, // 操作员班别 null或空时后台保存为"1"
|
|
//sta = null, //状态 null或空时后台保存为"R"
|
|
|
|
newFunc = dto.IsEnterWorkplace ? 1 : 0, // 是否进入车间
|
|
yqgw = dto.IsEnterWorkplace
|
|
? areas.Where(x => x.Type == AppointmentAreaEnumType.Workplace)
|
|
.Where(x => dto.ApplyWorkplaceAreas.Contains(x.CustomCode))
|
|
.Select(x => x.Name)
|
|
.Distinct().Join(",")
|
|
: string.Empty // 门岗名称
|
|
}.ToJson();
|
|
var response = await httpClient.PostAsync("https://pay.aizhuhotel.com/jschuneng", new StringContent(json, Encoding.UTF8, "application/json"));
|
|
var responseJson = await response.Content.ReadAsStringAsync();
|
|
|
|
_logger.LogInformation("发送到501访客预约{idNo}--{name},发送:{json} ,返回:{responseJson}", dto.IdNo, dto.Name, json, responseJson);
|
|
}
|
|
}
|
|
} |