Files
jinko.yikatong/Src/Dlhis.Basic/Organization/Services/Implements/GainfoFaceService.cs

280 lines
9.6 KiB
C#

using Dlhis.Basic.Device.Services;
using Dlhis.Basic.Organization.Request;
using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Basic.Enums;
using Dlhis.Entity.Device.Enums;
using Kurisu.AspNetCore.Utils;
using Kurisu.AspNetCore.Utils.Extensions;
using Kurisu.Core.CustomClass;
using Kurisu.Core.User.Abstractions;
using Kurisu.SqlSugar.Services;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Basic.Organization.Services.Implements;
public class GainfoFaceService : IGainfoFaceService
{
private readonly IGainfoStore _gainfoStore;
private readonly IDbContext _dbContext;
private readonly ILogger<GainfoFaceService> _logger;
private readonly IConfiguration _configuration;
private readonly RedisCache _redisCache;
private readonly ICurrentUser _currentUser;
private readonly IDevicePermissionService _devicePermissionService;
private readonly IDataProtectionProvider _dataProtectionProvider;
public GainfoFaceService(IGainfoStore gainfoStore,
IDbContext dbContext,
ILogger<GainfoFaceService> logger,
IConfiguration configuration,
RedisCache redisCache,
ICurrentUser currentUser,
IDevicePermissionService devicePermissionService,
IDataProtectionProvider dataProtectionProvider)
{
_gainfoStore = gainfoStore;
_dbContext = dbContext;
_logger = logger;
_configuration = configuration;
_redisCache = redisCache;
_currentUser = currentUser;
_devicePermissionService = devicePermissionService;
_dataProtectionProvider = dataProtectionProvider;
}
public async Task UploadExternalFaceAsync(GainfoUploadFaceRequest request)
{
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
try
{
request.UserNo = protector.Unprotect(request.UserNo);
}
catch (Exception)
{
throw new UserFriendlyException("凭证有误,无法获取人脸数");
}
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External).Where(x => x.No == request.UserNo).FirstAsync();
gainfo.ThrowIfNull("人员信息不存在");
var faceContext = _dbContext.ChangeDb("face");
var face = await faceContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
if (face == null)
{
face = new GainfoFaceEntity
{
UserCode = gainfo.Code,
Face = request.Face,
CreateTime = DateTime.Now,
ModifiedTime = DateTime.Now,
CreatedBy = 1,
ModifiedBy = 1
};
await faceContext.InsertAsync(face);
}
else
{
face.Face = request.Face;
face.ModifiedBy = 1;
face.ModifiedTime = DateTime.Now;
await faceContext.UpdateAsync(face);
}
}
public async Task<string> GetExternalFaceAsync(string idno)
{
var protector = _dataProtectionProvider.CreateProtector("gainfo:external:idno");
try
{
idno = protector.Unprotect(idno);
}
catch (Exception)
{
throw new UserFriendlyException("凭证有误,无法获取人脸数");
}
var dbContext = _dbContext.ChangeDb("face");
var face = await dbContext.Queryable<GainfoFaceEntity>()
.Where(x => x.UserCode == idno)
.SingleAsync();
face.ThrowIfNull("人脸照片尚未录入");
var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector();
var faceUrl = _configuration.GetSection("FaceUrlOptions:Url").Value;
var limit = _configuration.GetSection("FaceUrlOptions:Limit").Get<int>();
var key = $"face:{idno}";
var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit));
return faceUrl + token;
}
public async Task<IActionResult> GetFaceAsync(string token)
{
var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector();
try
{
var password = timeLimitedDataProtector.Unprotect(token);
var userCode = password.Split(':')[1];
var faceCache = await _redisCache.HashGetAsync("faces", userCode);
if (faceCache.HasValue)
{
return new FileContentResult(Convert.FromBase64String(faceCache), "image/png");
}
var dbContext = _dbContext.ChangeDb("face");
var face = await dbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == userCode).SingleAsync();
if (face == null)
{
_logger.LogWarning("学工号:{userCode}不存在人脸照片", userCode);
return new NotFoundResult();
}
return new FileContentResult(Convert.FromBase64String(face.Face), "image/png");
}
catch (Exception ex)
{
_logger.LogError(ex, "获取人脸失败:{message}", ex.Message);
return new NotFoundResult();
}
}
public async Task UploadFaceAsync(GainfoUploadFaceRequest request)
{
var gainfo = await _gainfoStore.Queryable().Where(x => x.No == request.UserNo).FirstAsync();
gainfo.ThrowIfNull("人员档案信息不存在");
var userId = _currentUser.GetIntSubjectId();
var faceContext = _dbContext.ChangeDb("face");
var face = await faceContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update;
await _redisCache.HashSetAsync("faces", gainfo.Code, request.Face);
if (face == null)
{
face = new GainfoFaceEntity
{
UserCode = gainfo.Code,
Face = request.Face,
CreateTime = DateTime.Now,
ModifiedTime = DateTime.Now,
CreatedBy = userId,
ModifiedBy = userId
};
await faceContext.InsertAsync(face);
}
else
{
if (face.Face == request.Face)
{
_logger.LogWarning("相同的人脸照片更新忽略");
return;
}
face.Face = request.Face;
face.ModifiedBy = userId;
face.ModifiedTime = DateTime.Now;
await faceContext.UpdateAsync(face);
}
//生成任务
await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType);
}
public async Task UploadFacesAsync(List<GainfoUploadFaceRequest> requests)
{
foreach (var request in requests)
{
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).Where(x => x.No == request.UserNo).FirstAsync();
gainfo ??= await _gainfoStore.Queryable(GainfoStatusEnumType.External).Where(x => x.No == request.UserNo).FirstAsync();
gainfo.ThrowIfNull("人员档案信息不存在");
var dbContext = _dbContext.ChangeDb("face");
var face = await dbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update;
await _redisCache.HashSetAsync("faces", gainfo.Code, request.Face);
if (face == null)
{
face = new GainfoFaceEntity
{
UserCode = gainfo.Code,
Face = request.Face
};
await dbContext.InsertAsync(face);
}
else
{
if (face.Face == request.Face)
{
_logger.LogWarning("相同的人脸照片更新忽略");
return;
}
face.Face = request.Face;
await dbContext.UpdateAsync(face);
}
//生成任务
await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType);
}
}
public async Task<string> GetFaceByUserCodeAsync(string userCode)
{
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == userCode).SingleAsync();
gainfo.ThrowIfNull($"{userCode}人员信息不存在");
var dbContext = _dbContext.ChangeDb("face");
var face = await dbContext.Queryable<GainfoFaceEntity>()
.Where(x => x.UserCode == userCode)
.SingleAsync();
face.ThrowIfNull("人脸照片尚未录入");
var timeLimitedDataProtector = _dataProtectionProvider.CreateProtector("down:face").ToTimeLimitedDataProtector();
var faceUrl = _configuration.GetSection("FaceUrlOptions:Url").Value;
var limit = _configuration.GetSection("FaceUrlOptions:Limit").Get<int>();
var key = $"face:{userCode}";
var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit));
return faceUrl + token;
}
public async Task<Dictionary<string, string>> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request)
{
var faceDictionary = new Dictionary<string, string>();
foreach (var userCode in request.UserCodes)
{
try
{
var faceUrl = await GetFaceByUserCodeAsync(userCode);
faceDictionary.Add(userCode, faceUrl);
}
catch (Exception)
{
}
}
return faceDictionary;
}
}