diff --git a/Src/Dlhis.Middle/Api/FaceBearerTokenHandler.cs b/Src/Dlhis.Middle/Api/FaceBearerTokenHandler.cs
new file mode 100644
index 00000000..a0e806ff
--- /dev/null
+++ b/Src/Dlhis.Middle/Api/FaceBearerTokenHandler.cs
@@ -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
+ {
+ ///
+ public string GetToken(IServiceProvider serviceProvider)
+ {
+ var cache = serviceProvider.GetService();
+ if (cache.TryGetValue("token", out string token)) return "Bearer " + token;
+
+ var httpClient = serviceProvider.GetService().CreateClient("face");
+ var hostName = serviceProvider.GetService().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>(tokenJson);
+
+ token = tokenInfo.Data.AccessToken;
+
+ cache.Set("token", token, TimeSpan.FromSeconds(tokenInfo.Data.Expires));
+
+ return token;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Middle/Api/IAssignmentDeviceTaskApi.cs b/Src/Dlhis.Middle/Api/IAssignmentDeviceTaskApi.cs
new file mode 100644
index 00000000..8c856a82
--- /dev/null
+++ b/Src/Dlhis.Middle/Api/IAssignmentDeviceTaskApi.cs
@@ -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>> DeviceGetTasksAsync(DeviceTaskGetRequest request);
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Middle/Api/ICanteenApi.cs b/Src/Dlhis.Middle/Api/ICanteenApi.cs
new file mode 100644
index 00000000..a48aa144
--- /dev/null
+++ b/Src/Dlhis.Middle/Api/ICanteenApi.cs
@@ -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> AddAsync(OrderAddRequest request);
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Middle/Controllers/AssignmentsController.cs b/Src/Dlhis.Middle/Controllers/AssignmentsController.cs
new file mode 100644
index 00000000..86107959
--- /dev/null
+++ b/Src/Dlhis.Middle/Controllers/AssignmentsController.cs
@@ -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;
+
+///
+/// 任务分配
+///
+[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;
+ }
+
+ ///
+ /// 获取设备任务(按设备)
+ ///
+ ///
+ [IgnoreTenant]
+ [HttpGet("deviceTasks")]
+ public async Task>> 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();
+ var token = QueryHelpers.ParseQuery(currentUser.Face).First().Value;
+ currentUser.Face = $"http://{_internalIp}/api/basic/gainfos/face?token=" + token;
+
+ task.Info = currentUser;
+ }
+ }
+
+ return result;
+ }
+
+ ///
+ /// 获取设备任务(按设备)
+ ///
+ ///
+ [HttpPost("deviceTasks")]
+ [IgnoreTenant]
+ public async Task>> 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();
+ var token = QueryHelpers.ParseQuery(currentUser.Face).First().Value;
+ currentUser.Face = $"http://{_internalIp}/api/basic/gainfos/face?token=" + token;
+
+ task.Info = currentUser;
+ }
+ }
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Middle/Controllers/GainfosController.cs b/Src/Dlhis.Middle/Controllers/GainfosController.cs
new file mode 100644
index 00000000..dc60ef38
--- /dev/null
+++ b/Src/Dlhis.Middle/Controllers/GainfosController.cs
@@ -0,0 +1,52 @@
+using Dlhis.Middle.Filters;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Dlhis.Middle.Controllers;
+
+///
+/// sap档案表
+///
+[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;
+ }
+
+ ///
+ /// 通过token获取人脸照片,失效或者找不到返回HttpStatus404状态码
+ ///
+ ///
+ ///
+ [NotFound]
+ [AllowAnonymous]
+ [HttpGet("face")]
+ public async Task 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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Src/Dlhis.Middle/Controllers/OrdersController.cs b/Src/Dlhis.Middle/Controllers/OrdersController.cs
index cadefa56..0813c676 100644
--- a/Src/Dlhis.Middle/Controllers/OrdersController.cs
+++ b/Src/Dlhis.Middle/Controllers/OrdersController.cs
@@ -1,9 +1,8 @@
-using Dlhis.Middle.Request;
+using Dlhis.Middle.Api;
+using Dlhis.Middle.Request;
using Dlhis.Middle.Response;
-using Dlhis.Middle.Services;
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
using Kurisu.AspNetCore.UnifyResultAndValidation;
-using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Middle.Controllers;
@@ -15,11 +14,11 @@ namespace Dlhis.Middle.Controllers;
[ApiController]
public class OrdersController : ControllerBase
{
- private readonly IOrderService _orderService;
+ private readonly ICanteenApi _canteenApi;
- public OrdersController(IOrderService orderService)
+ public OrdersController(ICanteenApi canteenApi)
{
- _orderService = orderService;
+ _canteenApi = canteenApi;
}
///
@@ -31,6 +30,6 @@ public class OrdersController : ControllerBase
[IgnoreTenant]
public async Task> AddAsync(OrderAddRequest request)
{
- return await _orderService.AddAsync(request);
+ return await _canteenApi.AddAsync(request);
}
}
\ No newline at end of file
diff --git a/Src/Dlhis.Middle/Dlhis.Middle.csproj b/Src/Dlhis.Middle/Dlhis.Middle.csproj
index 1b0aef9f..accf19a9 100644
--- a/Src/Dlhis.Middle/Dlhis.Middle.csproj
+++ b/Src/Dlhis.Middle/Dlhis.Middle.csproj
@@ -17,6 +17,7 @@
+
diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Response/TaskCombineDto.cs b/Src/Dlhis.Middle/Dto/TaskCombineDto.cs
similarity index 90%
rename from Src/Dlhis.ScheduledTask/TaskAssignment/Response/TaskCombineDto.cs
rename to Src/Dlhis.Middle/Dto/TaskCombineDto.cs
index 6b1526c8..92119602 100644
--- a/Src/Dlhis.ScheduledTask/TaskAssignment/Response/TaskCombineDto.cs
+++ b/Src/Dlhis.Middle/Dto/TaskCombineDto.cs
@@ -1,7 +1,7 @@
using Dlhis.Entity.Device.Enums;
using Kurisu.AspNetCore.Utils.Extensions;
-namespace Dlhis.ScheduledTask.TaskAssignment.Response;
+namespace Dlhis.Middle.Dto;
public class TaskCombineDto
{
diff --git a/Src/Dlhis.Middle/Filters/NotFoundAttribute.cs b/Src/Dlhis.Middle/Filters/NotFoundAttribute.cs
new file mode 100644
index 00000000..015f49f9
--- /dev/null
+++ b/Src/Dlhis.Middle/Filters/NotFoundAttribute.cs
@@ -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