fix 任务图片连接处理

This commit is contained in:
2024-06-28 14:03:40 +08:00
parent 0214309e64
commit 9446ba6ffa
20 changed files with 427 additions and 14 deletions

View File

@@ -0,0 +1,37 @@
using System.Text;
using Dlhis.Middle.Response;
using Kurisu.AspNetCore.UnifyResultAndValidation;
using Kurisu.RemoteCall.Abstractions;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
namespace Dlhis.Middle.Api
{
public class FaceBearerTokenHandler : IAuthTokenHandler
{
/// <inheritdoc />
public string GetToken(IServiceProvider serviceProvider)
{
var cache = serviceProvider.GetService<IMemoryCache>();
if (cache.TryGetValue("token", out string token)) return "Bearer " + token;
var httpClient = serviceProvider.GetService<IHttpClientFactory>().CreateClient("face");
var hostName = serviceProvider.GetService<IConfiguration>().GetSection("HostName").Value;
var tokenResponse = httpClient.PostAsync($"https://{hostName}/api/user/oauth2/clientgrant", new StringContent(JsonConvert.SerializeObject(new
{
ClientId = "e509c2aaa98e300c",
ClientSecret = "6184d8979fc48105"
}), Encoding.UTF8, "application/json")).GetAwaiter().GetResult();
var tokenJson = tokenResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var tokenInfo = JsonConvert.DeserializeObject<DefaultApiResult<TokenResponse>>(tokenJson);
token = tokenInfo.Data.AccessToken;
cache.Set("token", token, TimeSpan.FromSeconds(tokenInfo.Data.Expires));
return token;
}
}
}

View File

@@ -0,0 +1,14 @@
using Dlhis.Middle.Request;
using Dlhis.Middle.Response;
using Kurisu.AspNetCore.UnifyResultAndValidation;
using Kurisu.RemoteCall.Attributes;
namespace Dlhis.Middle.Api;
[EnableRemoteClient(Name = "face-service", BaseUrl = "${Authority}")]
public interface IAssignmentDeviceTaskApi
{
[Auth(TokenHandler = typeof(FaceBearerTokenHandler))]
[Post("/api/scheduled/assignments/deviceTasks")]
Task<DefaultApiResult<List<DeviceTaskToDeviceByDeviceResponse>>> DeviceGetTasksAsync(DeviceTaskGetRequest request);
}

View File

@@ -0,0 +1,15 @@
using Dlhis.Middle.Request;
using Dlhis.Middle.Response;
using Kurisu.AspNetCore.UnifyResultAndValidation;
using Kurisu.RemoteCall.Attributes;
namespace Dlhis.Middle.Api;
[EnableRemoteClient(Name = "face-service", BaseUrl = "${Authority}")]
public interface ICanteenApi
{
[Auth(TokenHandler = typeof(FaceBearerTokenHandler))]
[Post("/api/canteen/orders")]
Task<DefaultApiResult<OrderResultResponse>> AddAsync(OrderAddRequest request);
}

View File

@@ -0,0 +1,76 @@
using Dlhis.Entity.Device.Enums;
using Dlhis.Middle.Api;
using Dlhis.Middle.Request;
using Dlhis.Middle.Response;
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
using Kurisu.AspNetCore.UnifyResultAndValidation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Newtonsoft.Json.Linq;
namespace Dlhis.Middle.Controllers;
/// <summary>
/// 任务分配
/// </summary>
[Route("api/scheduled/[controller]")]
[ApiController]
public class AssignmentsController : ControllerBase
{
private readonly IAssignmentDeviceTaskApi _assignmentDeviceTaskApi;
private readonly string _internalIp;
public AssignmentsController(IAssignmentDeviceTaskApi assignmentDeviceTaskApi, IConfiguration configuration)
{
_assignmentDeviceTaskApi = assignmentDeviceTaskApi;
_internalIp = configuration.GetSection("InternalIP").Value;
}
/// <summary>
/// 获取设备任务(按设备)
/// </summary>
/// <returns></returns>
[IgnoreTenant]
[HttpGet("deviceTasks")]
public async Task<DefaultApiResult<List<DeviceTaskToDeviceByDeviceResponse>>> DeviceGetTasksGetAsync([FromQuery] DeviceTaskGetRequest request)
{
var result = await _assignmentDeviceTaskApi.DeviceGetTasksAsync(request);
foreach (var data in result.Data)
{
foreach (var task in data.Tasks.Where(x => x.Type != DeviceTaskEnumType.Delete))
{
var currentUser = JObject.FromObject(task.Info).ToObject<UserToDeviceResponse>();
var token = QueryHelpers.ParseQuery(currentUser.Face).First().Value;
currentUser.Face = $"http://{_internalIp}/api/basic/gainfos/face?token=" + token;
task.Info = currentUser;
}
}
return result;
}
/// <summary>
/// 获取设备任务(按设备)
/// </summary>
/// <returns></returns>
[HttpPost("deviceTasks")]
[IgnoreTenant]
public async Task<DefaultApiResult<List<DeviceTaskToDeviceByDeviceResponse>>> DeviceGetTasksPostAsync(DeviceTaskGetRequest request)
{
var result = await _assignmentDeviceTaskApi.DeviceGetTasksAsync(request);
foreach (var data in result.Data)
{
foreach (var task in data.Tasks.Where(x => x.Type != DeviceTaskEnumType.Delete))
{
var currentUser = JObject.FromObject(task.Info).ToObject<UserToDeviceResponse>();
var token = QueryHelpers.ParseQuery(currentUser.Face).First().Value;
currentUser.Face = $"http://{_internalIp}/api/basic/gainfos/face?token=" + token;
task.Info = currentUser;
}
}
return result;
}
}

View File

@@ -0,0 +1,52 @@
using Dlhis.Middle.Filters;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Middle.Controllers;
/// <summary>
/// sap档案表
/// </summary>
[Route("api/basic/[controller]")]
[ApiController]
public class GainfosController : ControllerBase
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IConfiguration _configuration;
public GainfosController(IHttpClientFactory httpClientFactory, IConfiguration configuration)
{
_httpClientFactory = httpClientFactory;
_configuration = configuration;
}
/// <summary>
/// 通过token获取人脸照片,失效或者找不到返回HttpStatus404状态码
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
[NotFound]
[AllowAnonymous]
[HttpGet("face")]
public async Task<IActionResult> GetFaceAsync(string token)
{
var hostName = _configuration.GetSection("HostName").Value;
var httpClient = _httpClientFactory.CreateClient();
try
{
var faceBytes = await httpClient.GetByteArrayAsync($"https://{hostName}/api/basic/gainfos/face?token={token}");
if (faceBytes.Length == 0)
{
return new NotFoundResult();
}
return new FileContentResult(faceBytes, "image/png");
}
catch (Exception)
{
return new NotFoundResult();
}
}
}

View File

@@ -1,9 +1,8 @@
using Dlhis.Middle.Request; using Dlhis.Middle.Api;
using Dlhis.Middle.Request;
using Dlhis.Middle.Response; using Dlhis.Middle.Response;
using Dlhis.Middle.Services;
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
using Kurisu.AspNetCore.UnifyResultAndValidation; using Kurisu.AspNetCore.UnifyResultAndValidation;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Middle.Controllers; namespace Dlhis.Middle.Controllers;
@@ -15,11 +14,11 @@ namespace Dlhis.Middle.Controllers;
[ApiController] [ApiController]
public class OrdersController : ControllerBase public class OrdersController : ControllerBase
{ {
private readonly IOrderService _orderService; private readonly ICanteenApi _canteenApi;
public OrdersController(IOrderService orderService) public OrdersController(ICanteenApi canteenApi)
{ {
_orderService = orderService; _canteenApi = canteenApi;
} }
/// <summary> /// <summary>
@@ -31,6 +30,6 @@ public class OrdersController : ControllerBase
[IgnoreTenant] [IgnoreTenant]
public async Task<DefaultApiResult<OrderResultResponse>> AddAsync(OrderAddRequest request) public async Task<DefaultApiResult<OrderResultResponse>> AddAsync(OrderAddRequest request)
{ {
return await _orderService.AddAsync(request); return await _canteenApi.AddAsync(request);
} }
} }

View File

@@ -17,6 +17,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Kurisu.RemoteCall" Version="0.4.2" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.6" /> <PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.6" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.1.8" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.1.8" />

View File

@@ -1,7 +1,7 @@
using Dlhis.Entity.Device.Enums; using Dlhis.Entity.Device.Enums;
using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.AspNetCore.Utils.Extensions;
namespace Dlhis.ScheduledTask.TaskAssignment.Response; namespace Dlhis.Middle.Dto;
public class TaskCombineDto public class TaskCombineDto
{ {

View File

@@ -0,0 +1,30 @@
using Kurisu.AspNetCore.UnifyResultAndValidation;
using Kurisu.AspNetCore.UnifyResultAndValidation.Abstractions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace Dlhis.Middle.Filters;
[AttributeUsage(AttributeTargets.Method)]
public class NotFoundAttribute : Attribute, IAsyncResultFilter
{
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
if (context.Result is ObjectResult result)
{
var type = result.Value?.GetType();
if (type.IsGenericType && type.IsAssignableTo(typeof(IApiResult)))
{
var apiResult = result.Value as DefaultApiResult<object>;
if (apiResult.Data is ProblemDetails _)
{
context.Result = new NotFoundResult();
//context.HttpContext.Response
}
}
}
await next();
}
}

View File

@@ -1,5 +1,6 @@
using Dlhis.Middle.Services; using Dlhis.Middle.Services;
using Dlhis.Middle.Services.Implements; using Dlhis.Middle.Services.Implements;
using Kurisu.AspNetCore;
using Kurisu.AspNetCore.Startup; using Kurisu.AspNetCore.Startup;
using Microsoft.IdentityModel.Logging; using Microsoft.IdentityModel.Logging;
@@ -23,6 +24,8 @@ public class Startup : DefaultStartup
public override void ConfigureServices(IServiceCollection services) public override void ConfigureServices(IServiceCollection services)
{ {
base.ConfigureServices(services); base.ConfigureServices(services);
services.AddRemoteCall(App.ActiveTypes);
services.AddHttpClient("face").ConfigurePrimaryHttpMessageHandler(() => services.AddHttpClient("face").ConfigurePrimaryHttpMessageHandler(() =>
{ {
var handler = new HttpClientHandler var handler = new HttpClientHandler

View File

@@ -0,0 +1,42 @@
using System.ComponentModel.DataAnnotations;
using Dlhis.Entity.Device.Enums;
using Kurisu.AspNetCore.DataAccess.Dto;
using Kurisu.AspNetCore.Utils.Extensions;
namespace Dlhis.Middle.Request;
public class DeviceTaskGetRequest : PageDto, IValidatableObject
{
/// <summary>
/// 品牌
/// </summary>
public string Brand { get; set; }
/// <summary>
/// 设备号
/// </summary>
public string DeviceUniqueNo { get; set; }
/// <summary>
/// 任务类型
/// </summary>
public List<DeviceTaskEnumType> Types { get; set; }
/// <summary>
/// 获取处理中的任务
/// </summary>
public bool IsProcess { get; set; } = false;
/// <summary>
/// 厂区
/// </summary>
public string Factory { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Brand.IsEmpty() && DeviceUniqueNo.IsEmpty() && Factory.IsEmpty())
{
yield return new ValidationResult("设备品牌,设备号和厂区不能都为空", new[] { nameof(Brand), nameof(DeviceUniqueNo), nameof(Factory) });
}
}
}

View File

@@ -0,0 +1,29 @@
using Dlhis.Middle.Dto;
namespace Dlhis.Middle.Response;
/// <summary>
/// 设备任务
/// </summary>
public class DeviceTaskToDeviceByDeviceResponse
{
/// <summary>
/// 品牌
/// </summary>
public string Brand { get; set; }
/// <summary>
/// 设备唯一号
/// </summary>
public string DeviceUniqueNo { get; set; }
/// <summary>
/// 设备信息
/// </summary>
public object DeviceInfo { get; set; }
/// <summary>
/// 任务
/// </summary>
public List<TaskCombineDto> Tasks { get; set; }
}

View File

@@ -0,0 +1,8 @@
using Kurisu.AspNetCore.CustomClass;
namespace Dlhis.Middle.Response;
public class UploadRecordToDeviceResponse
{
public DateTimePeriod DateTimePeriod { get; set; }
}

View File

@@ -0,0 +1,71 @@
using Kurisu.AspNetCore.CustomClass;
namespace Dlhis.Middle.Response;
public class UserToDeviceResponse
{
/// <summary>
/// 人员唯一id
/// </summary>
public long UserId { get; set; }
/// <summary>
/// 人员档案号
/// </summary>
public string UserNo { get; set; }
/// <summary>
/// 老系统档案号
/// </summary>
public string OldUserNo { get; set; }
/// <summary>
/// 人员学工号
/// </summary>
public string UserCode { get; set; }
/// <summary>
/// 人员名称
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 部门号
/// </summary>
public string DepartmentNo { get; set; }
/// <summary>
/// 部门名称
/// </summary>
public string DepartmentName { get; set; }
/// <summary>
/// 卡号
/// </summary>
public string CardNo { get; set; }
/// <summary>
/// 人脸
/// </summary>
public string Face { get; set; }
/// <summary>
/// 有效日期范围
/// </summary>
public DatePeriod ValidDatePeriod { get; set; }
/// <summary>
/// 控制门[1,2,3....]
/// </summary>
public List<int> Doors { get; set; }
/// <summary>
/// 时段[1,2,3....]
/// </summary>
public List<int> TimePeriods { get; set; }
/// <summary>
/// 假期计划id
/// </summary>
public int Schedule { get; set; }
}

View File

@@ -1,6 +1,6 @@
using Kurisu.AspNetCore.CustomClass; using Kurisu.AspNetCore.CustomClass;
namespace Dlhis.ScheduledTask.TaskAssignment.Response; namespace Dlhis.ScheduledTask.TaskAssignment.Dto;
public class ScheduleDto public class ScheduleDto
{ {

View File

@@ -0,0 +1,27 @@
using Dlhis.Entity.Device.Enums;
using Kurisu.AspNetCore.Utils.Extensions;
namespace Dlhis.ScheduledTask.TaskAssignment.Dto;
public class TaskCombineDto
{
/// <summary>
/// 任务id
/// </summary>
public long TaskId { get; set; }
/// <summary>
/// 任务类型
/// </summary>
public DeviceTaskEnumType Type { get; set; }
/// <summary>
/// 任务类型描述
/// </summary>
public string TypeDesc => Type.GetDescription();
/// <summary>
/// 下发信息
/// </summary>
public object Info { get; set; }
}

View File

@@ -1,4 +1,6 @@
namespace Dlhis.ScheduledTask.TaskAssignment.Response; using Dlhis.ScheduledTask.TaskAssignment.Dto;
namespace Dlhis.ScheduledTask.TaskAssignment.Response;
/// <summary> /// <summary>
/// 设备任务 /// 设备任务

View File

@@ -1,4 +1,6 @@
namespace Dlhis.ScheduledTask.TaskAssignment.Response; using Dlhis.ScheduledTask.TaskAssignment.Dto;
namespace Dlhis.ScheduledTask.TaskAssignment.Response;
public class ScheduleToDeviceResponse public class ScheduleToDeviceResponse
{ {

View File

@@ -14,6 +14,11 @@ public class UserToDeviceResponse
/// </summary> /// </summary>
public string UserNo { get; set; } public string UserNo { get; set; }
/// <summary>
/// 老系统档案号
/// </summary>
public string OldUserNo { get; set; }
/// <summary> /// <summary>
/// 人员学工号 /// 人员学工号
/// </summary> /// </summary>

View File

@@ -51,7 +51,7 @@ public class AssignmentService : IAssignmentService
var dc = x.Key.DeviceConnectionInfo ?? "{}"; var dc = x.Key.DeviceConnectionInfo ?? "{}";
var func = x.Key.FuncStr ?? "[]"; var func = x.Key.FuncStr ?? "[]";
var jobj = new JObject var jObj = new JObject
{ {
{ "connectionInfo", JToken.Parse(dc) }, { "connectionInfo", JToken.Parse(dc) },
{ "function", JArray.Parse(func) } { "function", JArray.Parse(func) }
@@ -61,7 +61,7 @@ public class AssignmentService : IAssignmentService
{ {
Brand = b, Brand = b,
DeviceUniqueNo = d, DeviceUniqueNo = d,
DeviceInfo = jobj, DeviceInfo = jObj,
Tasks = x.Select(item => Tasks = x.Select(item =>
{ {
var key = $"face:{item.UserCode}"; var key = $"face:{item.UserCode}";
@@ -83,7 +83,7 @@ public class AssignmentService : IAssignmentService
{ {
dto.Info = new UserToDeviceResponse dto.Info = new UserToDeviceResponse
{ {
UserId = item.UserId.HasValue ? item.UserId.Value : 0, UserId = item.UserId ?? 0,
UserNo = item.UserNo, UserNo = item.UserNo,
UserCode = item.UserCode, UserCode = item.UserCode,
UserName = item.UserName, UserName = item.UserName,