From 4bfb2660e8bdd88e5fd255395c64504463ab5133 Mon Sep 17 00:00:00 2001 From: liguoyang Date: Tue, 13 May 2025 14:06:12 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E6=8B=8D=E7=85=A7=E5=AF=B9=E7=85=A7?= =?UTF-8?q?=E7=89=87=E8=BF=9B=E8=A1=8C=E8=AF=86=E5=88=AB=E5=AF=B9=E6=AF=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Src/Dlhis.Basic/HikService.cs | 26 ++++++++ Src/Dlhis.Basic/IHikService.cs | 8 +++ .../Controllers/GainfoFacesController.cs | 20 ++++-- .../Controllers/GainfosController.cs | 5 +- .../Request/FaceValidationRequest.cs | 9 +++ .../Response/FaceValidationResponse.cs | 39 ++++++++++++ .../Organization/Response/HikResponse.cs | 8 +++ .../Services/IGainfoFaceService.cs | 7 ++- .../Services/Implements/GainfoFaceService.cs | 63 ++++++++++++++++++- 9 files changed, 175 insertions(+), 10 deletions(-) create mode 100644 Src/Dlhis.Basic/HikService.cs create mode 100644 Src/Dlhis.Basic/IHikService.cs create mode 100644 Src/Dlhis.Basic/Organization/Request/FaceValidationRequest.cs create mode 100644 Src/Dlhis.Basic/Organization/Response/FaceValidationResponse.cs create mode 100644 Src/Dlhis.Basic/Organization/Response/HikResponse.cs diff --git a/Src/Dlhis.Basic/HikService.cs b/Src/Dlhis.Basic/HikService.cs new file mode 100644 index 00000000..4d65e821 --- /dev/null +++ b/Src/Dlhis.Basic/HikService.cs @@ -0,0 +1,26 @@ +using System.Text; +using Dlhis.Basic.Organization.Request; +using Dlhis.Basic.Organization.Response; +using HttpUtil; +using Kurisu.AspNetCore.Utils.Extensions; + +namespace Dlhis.Basic; + +public class HikService : IHikService +{ + /// + public async Task GetSimilarityAsync(GainfoFaceValidateRequest request) + { + var body = request.ToJson(JsonExtensions.DefaultSetting); + var url = "/artemis/api/frs/v1/application/oneToOne"; + var key = "27390082"; + var secret = "MLl7Dv7p5Pgc9XYI3r4O"; + + HttpUtillib.SetPlatformInfo(key, secret, "10.32.0.10"); + var r = HttpUtillib.HttpPost(url, body, 15); + var result = Encoding.UTF8.GetString(r).ToObject>(); + (result.Code == "0").ThrowIfFalse($"海康人脸相似度对比失败:{result.Msg}"); + + return await Task.FromResult(result.Data); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/IHikService.cs b/Src/Dlhis.Basic/IHikService.cs new file mode 100644 index 00000000..e8d3988b --- /dev/null +++ b/Src/Dlhis.Basic/IHikService.cs @@ -0,0 +1,8 @@ +using Dlhis.Basic.Organization.Request; + +namespace Dlhis.Basic; + +public interface IHikService : IScopeDependency +{ + Task GetSimilarityAsync(GainfoFaceValidateRequest request); +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfoFacesController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfoFacesController.cs index 737f6889..40de97e1 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/GainfoFacesController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/GainfoFacesController.cs @@ -1,10 +1,9 @@ -using System.Net.Http.Headers; -using System.Security.Cryptography; -using System.Text; +using System.Text; using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; using Dlhis.Basic.Organization.Services; using HttpUtil; +using Kurisu.AspNetCore.DataAccess.Dto; using Kurisu.AspNetCore.Utils.Extensions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -39,9 +38,20 @@ public class GainfoFacesController : ControllerBase return await _gainfoFaceService.GetPageAsync(request); } + /// + /// 获取人脸识别记录分页 + /// + /// + /// + [HttpGet("uploadRecord/page")] + public async Task> GetUploadPageRecordsAsync([FromQuery] FaceValidationRequest request) + { + return await _gainfoFaceService.GetUploadPageRecordsAsync(request); + } + [AllowAnonymous] [HttpPost("test")] - public async Task TestAsync(GainfoFaceValidateRequest request) + public async Task> TestAsync(GainfoFaceValidateRequest request) { var client = _httpClientFactory.CreateClient("hik-openapi"); var body = request.ToJson(JsonExtensions.DefaultSetting); @@ -51,7 +61,7 @@ public class GainfoFacesController : ControllerBase HttpUtillib.SetPlatformInfo(key, secret, "10.32.0.10"); var r = HttpUtillib.HttpPost(url, body, 15); - return Encoding.UTF8.GetString(r); + return Encoding.UTF8.GetString(r).ToObject>(); // var headers = InitRequest(url, body, key, secret); // client.DefaultRequestHeaders.Accept.Clear(); diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs index e8747086..f3d377a7 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs @@ -4,6 +4,7 @@ using Dlhis.Basic.Organization.Response; using Dlhis.Basic.Organization.Services; using Kurisu.AspNetCore.DataAccess.Dto; using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; +using Kurisu.AspNetCore.UnifyResultAndValidation.Abstractions; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -77,9 +78,9 @@ public class GainfosController : ControllerBase [HttpPost("face")] [IgnoreTenant] [Transactional] - public async Task UploadFaceAsync(GainfoUploadFaceRequest request) + public async Task UploadFaceAsync(GainfoUploadFaceRequest request) { - await _gainfoFaceService.UploadFaceAsync(request); + return await _gainfoFaceService.UploadFaceAsync(request); } /// diff --git a/Src/Dlhis.Basic/Organization/Request/FaceValidationRequest.cs b/Src/Dlhis.Basic/Organization/Request/FaceValidationRequest.cs new file mode 100644 index 00000000..e591f2b0 --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Request/FaceValidationRequest.cs @@ -0,0 +1,9 @@ +using Kurisu.AspNetCore.DataAccess.Dto; + +namespace Dlhis.Basic.Organization.Request +{ + public class FaceValidationRequest : PageDto + { + public bool? IsSuccess { get; set; } + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Organization/Response/FaceValidationResponse.cs b/Src/Dlhis.Basic/Organization/Response/FaceValidationResponse.cs new file mode 100644 index 00000000..24f0c295 --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Response/FaceValidationResponse.cs @@ -0,0 +1,39 @@ +namespace Dlhis.Basic.Organization.Response; + +public class FaceValidationResponse +{ + /// + /// 工号 + /// + public string UserCode { get; set; } + + /// + /// 姓名 + /// + public string UserName { get; set; } + + /// + /// 识别相似度 + /// + public double Similarity { get; set; } + + /// + /// 可接受的相似度 + /// + public double AcceptSimilarity { get; set; } + + /// + /// 拍照前 + /// + public string CurrentFace { get; set; } + + /// + /// 上传 + /// + public string UploadFace { get; set; } + + /// + /// 操作时间 + /// + public DateTime CreateTime { get; set; } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Organization/Response/HikResponse.cs b/Src/Dlhis.Basic/Organization/Response/HikResponse.cs new file mode 100644 index 00000000..63397396 --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Response/HikResponse.cs @@ -0,0 +1,8 @@ +namespace Dlhis.Basic.Organization.Response; + +public class HikResponse +{ + public string Code { get; set; } + public string Msg { get; set; } + public T Data { get; set; } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Organization/Services/IGainfoFaceService.cs b/Src/Dlhis.Basic/Organization/Services/IGainfoFaceService.cs index 255fbaa4..bd11220d 100644 --- a/Src/Dlhis.Basic/Organization/Services/IGainfoFaceService.cs +++ b/Src/Dlhis.Basic/Organization/Services/IGainfoFaceService.cs @@ -1,5 +1,8 @@ using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; +using Kurisu.AspNetCore.DataAccess.Dto; +using Kurisu.AspNetCore.UnifyResultAndValidation; +using Kurisu.AspNetCore.UnifyResultAndValidation.Abstractions; using Microsoft.AspNetCore.Mvc; namespace Dlhis.Basic.Organization.Services; @@ -14,11 +17,13 @@ public interface IGainfoFaceService : IScopeDependency Task GetFaceAsync(string token); - Task UploadFaceAsync(GainfoUploadFaceRequest request); + Task UploadFaceAsync(GainfoUploadFaceRequest request); Task UploadFacesAsync(List request); Task GetFaceByUserCodeAsync(string userCode); Task> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request); + + Task> GetUploadPageRecordsAsync(FaceValidationRequest request); } \ No newline at end of file diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs index a0284fed..b329b722 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs @@ -13,11 +13,17 @@ using Dlhis.Jip.Api.Requests; using Dlhis.Sys.Api; using Kurisu.AspNetCore.Authentication.Abstractions; using Kurisu.AspNetCore.CustomClass; +using Kurisu.AspNetCore.DataAccess.Dto; using Kurisu.AspNetCore.DataAccess.Extensions; +using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions; using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; +using Kurisu.AspNetCore.UnifyResultAndValidation; +using Kurisu.AspNetCore.UnifyResultAndValidation.Abstractions; using Kurisu.AspNetCore.Utils.Extensions; +using Mapster; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Mvc; +using SqlSugar; namespace Dlhis.Basic.Organization.Services.Implements; @@ -35,6 +41,7 @@ public class GainfoFaceService : IGainfoFaceService private readonly IInfoCheckApi _infoCheckApi; private readonly IJinkoJipApi _jinkoJipApi; private readonly ITenantApi _tenantApi; + private readonly IHikService _hikService; private readonly IDataProtectionProvider _dataProtectionProvider; public GainfoFaceService(IGainfoStore gainfoStore, @@ -48,6 +55,7 @@ public class GainfoFaceService : IGainfoFaceService IInfoCheckApi infoCheckApi, IJinkoJipApi jinkoJipApi, ITenantApi tenantApi, + IHikService hikService, IDataProtectionProvider dataProtectionProvider) { _logger = logger; @@ -62,6 +70,7 @@ public class GainfoFaceService : IGainfoFaceService _infoCheckApi = infoCheckApi; _jinkoJipApi = jinkoJipApi; _tenantApi = tenantApi; + _hikService = hikService; _dataProtectionProvider = dataProtectionProvider; } @@ -80,6 +89,7 @@ public class GainfoFaceService : IGainfoFaceService .WhereIF(request.Exists.HasValue && request.Exists.Value, x => existsFaceCodes.Contains(x.Code)) .WhereIF(request.Exists.HasValue && !request.Exists.Value, x => !existsFaceCodes.Contains(x.Code)) .WhereIF(request.Search.IsPresent(), x => x.Code == request.Search) + .OrderBy(x => x.CreateTime, OrderByType.Desc) .Select((x, d) => new GainfoFacePageResponse { UserCode = x.Code, @@ -210,7 +220,7 @@ public class GainfoFaceService : IGainfoFaceService } } - public async Task UploadFaceAsync(GainfoUploadFaceRequest request) + public async Task UploadFaceAsync(GainfoUploadFaceRequest request) { var gainfo = await _gainfoStore.Queryable().Where(x => x.No == request.UserNo || x.Code == request.UserNo).SingleAsync(); gainfo.ThrowIfNull("人员档案信息不存在"); @@ -235,7 +245,33 @@ public class GainfoFaceService : IGainfoFaceService if (face.Face == request.Face) { _logger.LogWarning("相同的人脸照片更新忽略"); - return; + return DefaultApiResult.Success("操作成功"); + } + + var faceSimilaritySetting = await _dbContext.Queryable().Where(x => x.Type == "faceSimilarity").SingleAsync(); + if (faceSimilaritySetting != null) + { + var faceSimilarity = await _hikService.GetSimilarityAsync(new GainfoFaceValidateRequest + { + SrcFacePicBinaryData = face.Face, + DistFacePicBinaryData = request.Face + }); + var acceptSimilarity = faceSimilaritySetting.Code.Adapt(); + + var isError = faceSimilarity < acceptSimilarity; + await _dbContext.InsertAsync(new HikValidateResultEntity + { + UserCode = face.UserCode, + Similarity = faceSimilarity, + AcceptSimilarity = acceptSimilarity, + CurrentFace = face.Face, + UploadFace = request.Face + }); + + if (isError) + { + return DefaultApiResult.Error($"系统检测非本人更新,请重试(相似度{faceSimilarity})"); + } } face.Face = request.Face; @@ -278,6 +314,8 @@ public class GainfoFaceService : IGainfoFaceService //生成任务 await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType, "照片上传生成"); + + return DefaultApiResult.Success("操作成功"); } public async Task UploadFacesAsync(List requests) @@ -364,6 +402,27 @@ public class GainfoFaceService : IGainfoFaceService return faceDictionary; } + /// + public async Task> GetUploadPageRecordsAsync(FaceValidationRequest request) + { + return await _dbContext.Queryable() + .LeftJoin((x, ga) => x.UserCode == ga.Code) + .WhereIF(request.IsSuccess.HasValue && request.IsSuccess.Value, x => x.AcceptSimilarity >= x.Similarity) + .WhereIF(request.IsSuccess is false, x => x.AcceptSimilarity < x.Similarity) + .WhereIF(request.Search.IsPresent(), (x, ga) => x.UserCode == request.Search || ga.Name.Contains(request.Search)) + .Select((x, ga) => new FaceValidationResponse + { + UserCode = x.UserCode, + UserName = ga.Name, + Similarity = x.Similarity, + AcceptSimilarity = x.AcceptSimilarity, + CurrentFace = x.CurrentFace, + UploadFace = x.UploadFace, + CreateTime = x.CreateTime + }) + .ToPageListAsync(request); + } + //********************************************************************************************************************************************* ///