Files
jinko.yikatong/Src/Dlhis.Basic/Organization/Services/Implements/GainfoIdCardFaceCompareService.cs
2026-06-29 16:03:06 +08:00

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();
}
}