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 IAliyunClient _aliyunClient; private readonly ICurrentUser _currentUser; public GainfoIdCardFaceCompareService( IDbContext dbContext, IAliyunClient aliyunClient, ICurrentUser currentUser) { _dbContext = dbContext; _aliyunClient = aliyunClient; _currentUser = currentUser; } public async Task> GetPageAsync(IdCardFaceComparePageRequest request) { var factories = GetFactories(request.Factories); return await _dbContext.Queryable() .LeftJoin((record, gainfo) => record.UserCode == gainfo.Code) .LeftJoin((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 CompareAsync(IdCardFaceCompareRequest request) { var gainfo = await _dbContext.Queryable() .Where(x => x.Code == request.UserCode) .SingleAsync(); gainfo.ThrowIfNull("人员档案信息不存在"); var now = DateTime.Now; var userId = _currentUser.GetIntSubjectId(); var record = await _dbContext.Queryable() .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 SaveAsync(IdCardFaceCompareRecordSaveRequest request) { var gainfo = await _dbContext.Queryable() .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() .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 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() .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 GetRecordAsync(string userCode) { return await _dbContext.Queryable() .LeftJoin((record, gainfo) => record.UserCode == gainfo.Code) .LeftJoin((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 GetFactories(List requestFactories) { var currentFactories = _currentUser.GetUserClaim("tenants")?.Split(",").Where(x => x.IsPresent()).ToList() ?? new List(); if (requestFactories == null || !requestFactories.Any()) { return currentFactories; } return requestFactories.Where(x => currentFactories.Contains(x)).ToList(); } }