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

201 lines
7.9 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,
IAliyunClient aliyunClient,
ICurrentUser currentUser)
{
_dbContext = dbContext;
_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 now = DateTime.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,
UserType = gainfo.Type,
UserName = gainfo.Name,
IdNo = gainfo.IdNo,
CompareResult = IdCardFaceCompareResultEnumType.NotCompared,
CompareCount = 0,
ErrorMessage = null,
CreatedBy = userId,
ModifiedBy = userId,
CreateTime = now,
ModifiedTime = now
};
await _dbContext.InsertAsync(record);
}
else
{
record.UserType = gainfo.Type;
record.UserName = gainfo.Name;
record.IdNo = gainfo.IdNo;
record.CompareResult = IdCardFaceCompareResultEnumType.NotCompared;
record.IsPassed = null;
record.Similarity = null;
record.ApiResponse = null;
record.ErrorMessage = null;
record.ModifiedTime = now;
record.ModifiedBy = userId;
await _dbContext.UpdateAsync(record);
}
if (!gainfo.IdNo.IsPresent())
{
await UpdateRecordErrorAndThrowAsync(record, "人员证件号为空,无法对比", userId);
}
if (!request.Face.IsPresent())
{
await UpdateRecordErrorAndThrowAsync(record, "人脸照片尚未录入", userId);
}
AliyunId3MetaVerifyResponse response;
try
{
response = await _aliyunClient.Id3MetaVerifyAsync(gainfo.IdNo, gainfo.Name, request.Face);
}
catch (Exception e)
{
await UpdateRecordErrorAndThrowAsync(record, $"人证人脸对比接口调用失败:{e.Message}", userId);
throw;
}
record.CompareResult = IdCardFaceCompareResultEnumType.Compared;
record.ApiResponse = response.RawResponse;
record.IsPassed = response.Passed;
record.Similarity = response.Similarity;
record.CompareCount += 1;
record.LastCompareTime = now;
record.ErrorMessage = null;
record.ModifiedTime = DateTime.Now;
record.ModifiedBy = userId;
await _dbContext.UpdateAsync(record);
return await GetRecordAsync(record.UserCode);
}
private async Task UpdateRecordErrorAndThrowAsync(IdCardFaceCompareRecordEntity record, string message, int userId)
{
record.ErrorMessage = message;
record.ModifiedTime = DateTime.Now;
record.ModifiedBy = userId;
await _dbContext.UpdateAsync(record);
throw new UserFriendlyException(message);
}
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();
}
}