317 lines
12 KiB
C#
317 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 Kurisu.AspNetCore.Authentication.Abstractions;
|
|
using Kurisu.AspNetCore.CustomClass;
|
|
using Kurisu.AspNetCore.DataAccess.Dto;
|
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions;
|
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
|
using Kurisu.AspNetCore.Utils.Extensions;
|
|
using SqlSugar;
|
|
|
|
namespace Dlhis.Basic.Organization.Services.Implements;
|
|
|
|
public class GainfoIdCardFaceCompareService : IGainfoIdCardFaceCompareService
|
|
{
|
|
private readonly IDbContext _dbContext;
|
|
private readonly IServiceProvider _serviceProvider;
|
|
private readonly IAliyunClient _aliyunClient;
|
|
private readonly ICurrentUser _currentUser;
|
|
|
|
public GainfoIdCardFaceCompareService(
|
|
IDbContext dbContext,
|
|
IServiceProvider serviceProvider,
|
|
IAliyunClient aliyunClient,
|
|
ICurrentUser currentUser)
|
|
{
|
|
_dbContext = dbContext;
|
|
_serviceProvider = serviceProvider;
|
|
_aliyunClient = aliyunClient;
|
|
_currentUser = currentUser;
|
|
}
|
|
|
|
public async Task<Pagination<IdCardFaceCompareRecordResponse>> GetPageAsync(IdCardFaceComparePageRequest request)
|
|
{
|
|
var factories = GetFactories(request.Factories);
|
|
|
|
return await _dbContext.Queryable<IdCardFaceCompareRecordEntity>()
|
|
.LeftJoin<GainfoEntity>((record, gainfo) => record.UserCode == gainfo.Code)
|
|
.LeftJoin<DepartmentEntity>((record, gainfo, department) => gainfo.DepartmentNo == department.No)
|
|
.WhereIF(factories.Any(), (record, gainfo) => factories.Contains(gainfo.Factory))
|
|
.WhereIF(request.UserType.HasValue, record => record.UserType == request.UserType.Value)
|
|
.WhereIF(request.CompareResult.HasValue, record => record.CompareResult == request.CompareResult.Value)
|
|
.WhereIF(request.Search.IsPresent(), (record, gainfo) =>
|
|
record.UserCode == request.Search
|
|
|| record.IdNo == request.Search
|
|
|| record.UserName.Contains(request.Search)
|
|
|| gainfo.Name.Contains(request.Search))
|
|
.OrderBy(record => record.LastCompareTime, OrderByType.Desc)
|
|
.OrderBy(record => record.CreateTime, OrderByType.Desc)
|
|
.Select((record, gainfo, department) => new IdCardFaceCompareRecordResponse
|
|
{
|
|
Id = record.Id,
|
|
UserCode = record.UserCode,
|
|
UserName = record.UserName,
|
|
UserType = record.UserType,
|
|
IdNo = record.IdNo,
|
|
DepartmentName = department.Name,
|
|
Factory = gainfo.Factory,
|
|
CompareResult = record.CompareResult,
|
|
IsPassed = record.IsPassed,
|
|
Similarity = record.Similarity,
|
|
CompareCount = record.CompareCount,
|
|
LastCompareTime = record.LastCompareTime,
|
|
ApiResponse = record.ApiResponse,
|
|
ErrorMessage = record.ErrorMessage,
|
|
CreateTime = record.CreateTime
|
|
})
|
|
.ToPageListAsync(request);
|
|
}
|
|
|
|
public async Task<IdCardFaceCompareRecordResponse> CompareAsync(IdCardFaceCompareRequest request)
|
|
{
|
|
var gainfo = await _dbContext.Queryable<GainfoEntity>()
|
|
.Where(x => x.Code == request.UserCode)
|
|
.SingleAsync();
|
|
gainfo.ThrowIfNull("人员档案信息不存在");
|
|
|
|
var face = string.Empty;
|
|
using (var scope = _serviceProvider.CreateScope())
|
|
{
|
|
var faceDbContext = scope.ServiceProvider.GetService<IDbContext>().ChangeDb("face");
|
|
face = await faceDbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == request.UserCode).Select(x => x.Face).SingleAsync();
|
|
}
|
|
|
|
face.IsEmpty().ThrowIfTrue("人脸照片未录入");
|
|
|
|
|
|
var now = DateTime.Now;
|
|
var userId = _currentUser.GetIntSubjectId();
|
|
var record = await _dbContext.Queryable<IdCardFaceCompareRecordEntity>()
|
|
.Where(x => x.UserCode == gainfo.Code)
|
|
.SingleAsync();
|
|
|
|
if (!gainfo.IdNo.IsPresent())
|
|
{
|
|
await SaveCompareRecordAsync(
|
|
gainfo,
|
|
record,
|
|
IdCardFaceCompareResultEnumType.NotCompared,
|
|
null,
|
|
null,
|
|
null,
|
|
"人员证件号为空,无法对比",
|
|
userId,
|
|
now,
|
|
false);
|
|
throw new UserFriendlyException("人员证件号为空,无法对比");
|
|
}
|
|
|
|
if (!request.Face.IsPresent())
|
|
{
|
|
await SaveCompareRecordAsync(
|
|
gainfo,
|
|
record,
|
|
IdCardFaceCompareResultEnumType.NotCompared,
|
|
null,
|
|
null,
|
|
null,
|
|
"人脸照片尚未录入",
|
|
userId,
|
|
now,
|
|
false);
|
|
throw new UserFriendlyException("人脸照片尚未录入");
|
|
}
|
|
|
|
AliyunId3MetaVerifyResponse response;
|
|
try
|
|
{
|
|
response = await _aliyunClient.Id3MetaVerifyAsync(gainfo.IdNo, gainfo.Name, request.Face);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
await SaveCompareRecordAsync(
|
|
gainfo,
|
|
record,
|
|
IdCardFaceCompareResultEnumType.NotCompared,
|
|
null,
|
|
null,
|
|
null,
|
|
$"人证人脸对比接口调用失败:{e.Message}",
|
|
userId,
|
|
now,
|
|
false);
|
|
throw;
|
|
}
|
|
|
|
record = await SaveCompareRecordAsync(
|
|
gainfo,
|
|
record,
|
|
IdCardFaceCompareResultEnumType.Compared,
|
|
response.Passed,
|
|
response.Similarity,
|
|
response.RawResponse,
|
|
GetAliyunErrorMessage(response),
|
|
userId,
|
|
now,
|
|
true);
|
|
|
|
return await GetRecordAsync(record.UserCode);
|
|
}
|
|
|
|
public async Task<IdCardFaceCompareRecordResponse> SaveAsync(IdCardFaceCompareRecordSaveRequest request)
|
|
{
|
|
var gainfo = await _dbContext.Queryable<GainfoEntity>()
|
|
.Where(x => x.Code == request.UserCode)
|
|
.SingleAsync();
|
|
gainfo.ThrowIfNull("人员档案信息不存在");
|
|
|
|
var now = DateTime.Now;
|
|
var compareTime = request.CompareTime ?? now;
|
|
var userId = _currentUser.GetIntSubjectId();
|
|
var record = await _dbContext.Queryable<IdCardFaceCompareRecordEntity>()
|
|
.Where(x => x.UserCode == gainfo.Code)
|
|
.SingleAsync();
|
|
|
|
if (record == null)
|
|
{
|
|
record = new IdCardFaceCompareRecordEntity
|
|
{
|
|
UserCode = gainfo.Code,
|
|
CompareCount = 0,
|
|
CreatedBy = userId,
|
|
CreateTime = now
|
|
};
|
|
}
|
|
|
|
record.UserType = gainfo.Type;
|
|
record.UserName = gainfo.Name;
|
|
record.IdNo = gainfo.IdNo;
|
|
record.CompareResult = request.CompareResult
|
|
?? (request.ApiResponse.IsPresent()
|
|
? IdCardFaceCompareResultEnumType.Compared
|
|
: request.ErrorMessage.IsPresent()
|
|
? IdCardFaceCompareResultEnumType.NotCompared
|
|
: IdCardFaceCompareResultEnumType.Compared);
|
|
record.ApiResponse = request.ApiResponse;
|
|
record.IsPassed = request.IsPassed;
|
|
record.Similarity = request.Similarity;
|
|
record.ErrorMessage = request.ErrorMessage;
|
|
record.CompareCount += 1;
|
|
record.LastCompareTime = compareTime;
|
|
record.ModifiedTime = now;
|
|
record.ModifiedBy = userId;
|
|
|
|
if (record.Id == 0)
|
|
{
|
|
await _dbContext.InsertAsync(record);
|
|
}
|
|
else
|
|
{
|
|
await _dbContext.UpdateAsync(record);
|
|
}
|
|
|
|
return await GetRecordAsync(record.UserCode);
|
|
}
|
|
|
|
private async Task<IdCardFaceCompareRecordEntity> SaveCompareRecordAsync(
|
|
GainfoEntity gainfo,
|
|
IdCardFaceCompareRecordEntity record,
|
|
IdCardFaceCompareResultEnumType compareResult,
|
|
bool? isPassed,
|
|
double? similarity,
|
|
string apiResponse,
|
|
string errorMessage,
|
|
int userId,
|
|
DateTime compareTime,
|
|
bool increaseCompareCount)
|
|
{
|
|
var now = DateTime.Now;
|
|
record ??= new IdCardFaceCompareRecordEntity
|
|
{
|
|
UserCode = gainfo.Code,
|
|
CompareCount = 0,
|
|
CreatedBy = userId,
|
|
CreateTime = now
|
|
};
|
|
|
|
record.UserType = gainfo.Type;
|
|
record.UserName = gainfo.Name;
|
|
record.IdNo = gainfo.IdNo;
|
|
record.CompareResult = compareResult;
|
|
record.ApiResponse = apiResponse;
|
|
record.IsPassed = isPassed;
|
|
record.Similarity = similarity;
|
|
record.ErrorMessage = errorMessage;
|
|
record.LastCompareTime = increaseCompareCount ? compareTime : record.LastCompareTime;
|
|
record.CompareCount += increaseCompareCount ? 1 : 0;
|
|
record.ModifiedTime = now;
|
|
record.ModifiedBy = userId;
|
|
|
|
if (record.Id == 0)
|
|
{
|
|
await _dbContext.InsertAsync(record);
|
|
return await _dbContext.Queryable<IdCardFaceCompareRecordEntity>()
|
|
.Where(x => x.UserCode == gainfo.Code)
|
|
.SingleAsync();
|
|
}
|
|
else
|
|
{
|
|
await _dbContext.UpdateAsync(record);
|
|
}
|
|
|
|
return record;
|
|
}
|
|
|
|
private static string GetAliyunErrorMessage(AliyunId3MetaVerifyResponse response)
|
|
{
|
|
if (response.Code != "200")
|
|
{
|
|
return response.Message.IsPresent()
|
|
? $"阿里云接口返回异常:{response.Message}"
|
|
: $"阿里云接口返回异常:{response.Code}";
|
|
}
|
|
|
|
return response.BizCode.IsPresent() ? null : "阿里云接口未返回业务核验结果";
|
|
}
|
|
|
|
private async Task<IdCardFaceCompareRecordResponse> GetRecordAsync(string userCode)
|
|
{
|
|
return await _dbContext.Queryable<IdCardFaceCompareRecordEntity>()
|
|
.LeftJoin<GainfoEntity>((record, gainfo) => record.UserCode == gainfo.Code)
|
|
.LeftJoin<DepartmentEntity>((record, gainfo, department) => gainfo.DepartmentNo == department.No)
|
|
.Where(record => record.UserCode == userCode)
|
|
.Select((record, gainfo, department) => new IdCardFaceCompareRecordResponse
|
|
{
|
|
Id = record.Id,
|
|
UserCode = record.UserCode,
|
|
UserName = record.UserName,
|
|
UserType = record.UserType,
|
|
IdNo = record.IdNo,
|
|
DepartmentName = department.Name,
|
|
Factory = gainfo.Factory,
|
|
CompareResult = record.CompareResult,
|
|
IsPassed = record.IsPassed,
|
|
Similarity = record.Similarity,
|
|
CompareCount = record.CompareCount,
|
|
LastCompareTime = record.LastCompareTime,
|
|
ApiResponse = record.ApiResponse,
|
|
ErrorMessage = record.ErrorMessage,
|
|
CreateTime = record.CreateTime
|
|
})
|
|
.SingleAsync();
|
|
}
|
|
|
|
private List<string> GetFactories(List<string> requestFactories)
|
|
{
|
|
var currentFactories = _currentUser.GetUserClaim("tenants")?.Split(",").Where(x => x.IsPresent()).ToList() ?? new List<string>();
|
|
if (requestFactories == null || !requestFactories.Any())
|
|
{
|
|
return currentFactories;
|
|
}
|
|
|
|
return requestFactories.Where(x => currentFactories.Contains(x)).ToList();
|
|
}
|
|
}
|