feat 人脸上传,内部支持客户端授权

This commit is contained in:
2024-01-11 19:38:23 +08:00
parent d35b0043c3
commit 15e90d4d16
15 changed files with 243 additions and 14 deletions

View File

@@ -36,6 +36,6 @@ public class DevicePermissionsController : ControllerBase
[HttpGet("assignments")] [HttpGet("assignments")]
public async Task<List<Guid>> GetAssignmentsAsync([FromQuery] DeviceGetAssignmentsRequest request) public async Task<List<Guid>> GetAssignmentsAsync([FromQuery] DeviceGetAssignmentsRequest request)
{ {
return await _devicePermissionService.GetAssignmentsAsync(request.UserNo, request.UniqueType, request.UniqueValue); return await _devicePermissionService.GetAssignmentsAsync(request.UserNo, request.UniqueType);
} }
} }

View File

@@ -16,9 +16,4 @@ public class DeviceGetAssignmentsRequest
/// </summary> /// </summary>
[EnumDataType(typeof(DeviceAssignmentTypeEnumType))] [EnumDataType(typeof(DeviceAssignmentTypeEnumType))]
public DeviceAssignmentTypeEnumType UniqueType { get; set; } public DeviceAssignmentTypeEnumType UniqueType { get; set; }
/// <summary>
/// 类型对应的唯一值(可为空)
/// </summary>
public Guid? UniqueValue { get; set; }
} }

View File

@@ -12,5 +12,11 @@ public interface IDevicePermissionService : IScopeDependency
/// <returns></returns> /// <returns></returns>
Task AssignmentAsync(List<DevicePermissionSaveReuqest> reuqests); Task AssignmentAsync(List<DevicePermissionSaveReuqest> reuqests);
Task<List<Guid>> GetAssignmentsAsync(string userNo, DeviceAssignmentTypeEnumType uniqueType, Guid? uniqueValue); /// <summary>
/// 获取分配的权限
/// </summary>
/// <param name="userNo"></param>
/// <param name="uniqueType"></param>
/// <returns></returns>
Task<List<Guid>> GetAssignmentsAsync(string userNo, DeviceAssignmentTypeEnumType? uniqueType);
} }

View File

@@ -1,4 +1,5 @@
using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Request;
using Dlhis.Entity.Device.Entities;
using Dlhis.Entity.Sys.Entities; using Dlhis.Entity.Sys.Entities;
using Dlhis.Entity.Sys.Enums; using Dlhis.Entity.Sys.Enums;
using Kurisu.SqlSugar.Services; using Kurisu.SqlSugar.Services;
@@ -36,15 +37,69 @@ public class DevicePermissionService : IDevicePermissionService
} }
} }
public async Task<List<Guid>> GetAssignmentsAsync(string userNo, DeviceAssignmentTypeEnumType uniqueType, Guid? uniqueValue) public async Task<List<Guid>> GetAssignmentsAsync(string userNo, DeviceAssignmentTypeEnumType? uniqueType)
{ {
var assignments = await _dbContext.Queryable<DevicePermissionEntity>() var assignments = await _dbContext.Queryable<DevicePermissionEntity>()
.Where(x => x.UniqueType == uniqueType) .WhereIF(uniqueType.HasValue, x => x.UniqueType == uniqueType)
.WhereIF(uniqueValue.HasValue, x => x.UniqueValue == uniqueValue)
.Where(x => x.UserNo == userNo) .Where(x => x.UserNo == userNo)
.Select(x => x.UniqueValue) .Select(x => x.UniqueValue)
.ToListAsync(); .ToListAsync();
return assignments; return assignments;
} }
public async Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo)
{
var groupCodes = await GetAssignmentsAsync(userNo, DeviceAssignmentTypeEnumType.Group);
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
return null;
//var deviceCodes = await GetAssignmentsAsync(userNo, DeviceAssignmentTypeEnumType.Device);
//var permissionCodes = await _dbContext.Queryable<MenuPermissionEntity>()
// .Where(x => x.UniqueType == uniqueType)
// .Where(x => x.UniqueValue == uniqueData)
// .Select(x => x.Code)
// .ToListAsync();
//var menus = await GetListAsync(PlatformEnumType.PCAdmin);
//foreach (var menu in menus)
//{
// if (menu.Items.Any())
// {
// var codes = RecursionHandler(menu.Items, permissionCodes);
// permissionCodes.RemoveAll(x => codes.Contains(x));
// }
//}
//return permissionCodes;
//static List<string> RecursionHandler(List<MenuResponse> menus, List<string> innerPermissions)
//{
// var codes = new HashSet<string>();
// foreach (var menu in menus)
// {
// if (menu.Items.Any())
// {
// var innerPermissionCodes = RecursionHandler(menu.Items, innerPermissions);
// foreach (var item in innerPermissionCodes)
// {
// codes.Add(item);
// }
// }
// if (!innerPermissions.Contains(menu.Code))
// {
// foreach (var item in menu.Items.Select(x => x.Code))
// {
// codes.Add(item);
// }
// }
// }
// return codes.ToList();
//}
}
} }

View File

@@ -88,5 +88,15 @@ public class GainfosController : ControllerBase
{ {
return await _gainfoService.CurrentUserInfoAsync(); return await _gainfoService.CurrentUserInfoAsync();
} }
/// <summary>
/// 上传人脸头像
/// </summary>
/// <returns></returns>
[HttpPost("face")]
public async Task UploadFaceAsync(GainfoUploadFaceRequest request)
{
await _gainfoService.UploadFaceAsync(request);
}
} }

View File

@@ -0,0 +1,36 @@
using System.ComponentModel.DataAnnotations;
namespace Dlhis.Basic.Organization.Request;
public class GainfoUploadFaceRequest : IValidatableObject
{
/// <summary>
/// 用户档案号
/// </summary>
[Required(ErrorMessage = "用户档案号")]
public string UserNo { get; set; }
/// <summary>
/// 人脸照片
/// </summary>
[Required(ErrorMessage = "人脸照片不能为空")]
public string Face { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
bool v = true;
try
{
Convert.FromBase64String(Face);
}
catch (Exception)
{
v = false;
}
if (!v)
{
yield return new ValidationResult("人脸照片需要为Base64格式", new[] { nameof(Face) });
}
}
}

View File

@@ -18,4 +18,7 @@ public interface IGainfoService : IScopeDependency
Task OnboardingAsync(GainfoDImissionRequest request); Task OnboardingAsync(GainfoDImissionRequest request);
Task<GainfoCurrentResponse> CurrentUserInfoAsync(); Task<GainfoCurrentResponse> CurrentUserInfoAsync();
Task UploadFaceAsync(GainfoUploadFaceRequest request);
} }

View File

@@ -1,7 +1,10 @@
using Dlhis.Basic.Organization.Request; using System.Configuration;
using Dlhis.Basic.Organization.Request;
using Dlhis.Basic.Organization.Response; using Dlhis.Basic.Organization.Response;
using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Basic.Enums; using Dlhis.Entity.Basic.Enums;
using Kurisu.AspNetCore.Scope;
using Kurisu.AspNetCore.UnifyResultAndValidation;
using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.AspNetCore.Utils.Extensions;
using Kurisu.Core.DataAccess.Dto; using Kurisu.Core.DataAccess.Dto;
using Kurisu.Core.User.Abstractions; using Kurisu.Core.User.Abstractions;
@@ -181,4 +184,45 @@ public class GainfoService : IGainfoService
} }
} }
} }
public async Task UploadFaceAsync(GainfoUploadFaceRequest request)
{
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("人员档案信息不存在");
await Scoped.Request.Value.CreateAsync(async (sp) =>
{
var configuration = sp.GetService<IConfiguration>();
var faceConnectionString = configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value;
if (faceConnectionString.IsEmpty())
{
throw new UserFriendlyException("暂不支持人脸上传");
}
var dbContext = sp.GetService<IDbContext>();
//todo 切换连接字符串
dbContext.Client.CurrentConnectionConfig.ConnectionString = faceConnectionString;
var face = await dbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
if (face == null)
{
face = new GainfoFaceEntity
{
UserCode = gainfo.Code,
Face = request.Face
};
await dbContext.InsertAsync(face);
}
else
{
face.Face = request.Face;
await dbContext.UpdateAsync(face);
}
});
}
} }

View File

@@ -1,4 +1,5 @@
using Kurisu.AspNetCore; using Dlhis.Entity.Basic.Entity;
using Kurisu.AspNetCore;
using Kurisu.AspNetCore.Startup; using Kurisu.AspNetCore.Startup;
using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Extensions;
using SqlSugar; using SqlSugar;
@@ -25,6 +26,14 @@ public class SqlSugarPack : BaseAppPack
db.DbMaintenance.CreateDatabase(); db.DbMaintenance.CreateDatabase();
db.CodeFirst.InitTables(tables); db.CodeFirst.InitTables(tables);
using var scopeFace = app.ApplicationServices.CreateScope();
var dbFace = scopeFace.ServiceProvider.GetService<ISqlSugarClient>();
var faceConnectionString = Configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value;
dbFace.CurrentConnectionConfig.ConnectionString = faceConnectionString;
dbFace.DbMaintenance.CreateDatabase();
dbFace.CodeFirst.InitTables<GainfoFaceEntity>();
#endif #endif
} }
} }

View File

@@ -13,6 +13,7 @@
"SqlSugarOptions": { "SqlSugarOptions": {
"DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;", "DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;",
"SlaveConnectionString": [], "SlaveConnectionString": [],
"FaceConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=face;charset=utf8mb4;",
"Timeout": 30, "Timeout": 30,
"SlowSqlTime": 1, "SlowSqlTime": 1,
"EnableSqlLog": true "EnableSqlLog": true

View File

@@ -0,0 +1,27 @@
using Kurisu.SqlSugar;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
namespace Dlhis.Entity.Basic.Entity;
/// <summary>
/// 档案人脸信息
/// </summary>
[SkipScan]
[SugarTable(TableName = "GainfoFace", TableDescription = "档案人脸信息")]
public class GainfoFaceEntity : SugarBaseEntity
{
/// <summary>
/// 学工号
/// </summary>
[SugarColumn(IsNullable = false)]
public string UserCode { get; set; }
/// <summary>
/// 人脸
/// </summary>
[SugarColumn(ColumnDataType = "text", IsNullable = false)]
public string Face { get; set; }
}

View File

@@ -25,4 +25,8 @@
<ProjectReference Include="..\Dlhis.User.Api\Dlhis.User.Api.csproj" /> <ProjectReference Include="..\Dlhis.User.Api\Dlhis.User.Api.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="新文件夹\" />
</ItemGroup>
</Project> </Project>

View File

@@ -4,6 +4,7 @@ using Dlhis.Sys.Menu.Request;
using Dlhis.Sys.Menu.Response; using Dlhis.Sys.Menu.Response;
using Dlhis.User.Api; using Dlhis.User.Api;
using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.AspNetCore.Utils.Extensions;
using Kurisu.Core.Result;
using Kurisu.Core.User.Abstractions; using Kurisu.Core.User.Abstractions;
using Kurisu.SqlSugar.Attributes; using Kurisu.SqlSugar.Attributes;
using Kurisu.SqlSugar.Services; using Kurisu.SqlSugar.Services;
@@ -268,7 +269,7 @@ public class MenuService : IMenuService
private async Task<List<string>> GetAllAssignmentCodesAsync() private async Task<List<string>> GetAllAssignmentCodesAsync()
{ {
var userApiResult = await _userApi.GetUserByIdAsync(_currentUser.GetIntSubjectId()); var userApiResult = await _userApi.GetUserByIdAsync(_currentUser.GetIntSubjectId());
(userApiResult.Code == Kurisu.Core.Result.ApiStateCode.Success).ThrowIfFalse(userApiResult.Msg); (userApiResult.Code == ApiStateCode.Success).ThrowIfFalse(userApiResult.Msg);
var user = userApiResult.Data; var user = userApiResult.Data;
// var groupCodes = await GetAssignmentCodesAsync(MenuPermissionTypeEnumType.Group, manager.usergrp); // var groupCodes = await GetAssignmentCodesAsync(MenuPermissionTypeEnumType.Group, manager.usergrp);

View File

@@ -0,0 +1,38 @@
using System.Text;
using Dlhis.User.Identity.Request;
using Kurisu.AspNetCore.Authentication.Options;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
namespace Dlhis.User.Identity.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class OAuth2Controller : ControllerBase
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IOptions<IdentityServerOptions> _identityServerOption;
private readonly IServiceProvider _serviceProvider;
public OAuth2Controller(IHttpClientFactory httpClientFactory, IOptions<IdentityServerOptions> identityServerOption, IServiceProvider serviceProvider)
{
_httpClientFactory = httpClientFactory;
_identityServerOption = identityServerOption;
_serviceProvider = serviceProvider;
}
[HttpPost("clientgrant")]
public async Task<object> ClientGrant(ClientGrantRequest request)
{
var authority = _identityServerOption.Value.Authority;
var httpClient = _httpClientFactory.CreateClient("oauth2");
var content = new StringContent($"grant_type=client_credentials&client_id={request.ClientId}&client_secret={request.ClientSecret}&scope={request.Scope}", Encoding.UTF8, "application/x-www-form-urlencoded");
var response = await httpClient.PostAsync($"{authority}/connect/token", content);
var result = await response.Content.ReadAsStringAsync();
return JObject.Parse(result);
}
}
}

View File

@@ -1,7 +1,7 @@
using Kurisu.AspNetCore.Startup; using Kurisu.AspNetCore.Startup;
using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Extensions;
namespace Dlhis.User; namespace Dlhis.User.Packs;
public class SqlSugarPack : BaseAppPack public class SqlSugarPack : BaseAppPack
{ {