fix datapermission crosstenant

This commit is contained in:
2024-07-24 15:48:57 +08:00
parent 9cd31df6fc
commit 70edac18a3
20 changed files with 57 additions and 193 deletions

View File

@@ -106,8 +106,8 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
entity.ShiftCode = shift.Code; entity.ShiftCode = shift.Code;
entity.ShiftCustomCode = shift.CustomCode; entity.ShiftCustomCode = shift.CustomCode;
entity.Start = request.TimePeriod.Start!.Value; entity.Start = request.TimePeriod.Start;
entity.End = request.TimePeriod.End!.Value; entity.End = request.TimePeriod.End;
await _dbContext.InsertAsync(entity); await _dbContext.InsertAsync(entity);
} }
@@ -119,8 +119,8 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
entity.ThrowIfNull("餐次段不存在"); entity.ThrowIfNull("餐次段不存在");
entity.Start = request.TimePeriod.Start!.Value; entity.Start = request.TimePeriod.Start;
entity.End = request.TimePeriod.End!.Value; entity.End = request.TimePeriod.End;
request.Adapt(entity); request.Adapt(entity);
await _dbContext.UpdateAsync(entity); await _dbContext.UpdateAsync(entity);

View File

@@ -69,7 +69,7 @@ public class DeviceGroupsController : ControllerBase
/// <returns></returns> /// <returns></returns>
[HttpPost("assign")] [HttpPost("assign")]
[Transactional] [Transactional]
[DataPermission] [CrossTenant]
public async Task AssignDevicesAsync(DeviceAssignRequest request) public async Task AssignDevicesAsync(DeviceAssignRequest request)
{ {
await _deviceGroupService.AssignDevicesAsync(request); await _deviceGroupService.AssignDevicesAsync(request);

View File

@@ -30,7 +30,7 @@ public class DevicePermissionsController : ControllerBase
[HttpPost("assign")] [HttpPost("assign")]
[AssignPermissionLimit] [AssignPermissionLimit]
[Transactional] [Transactional]
[DataPermission] [CrossTenant]
public async Task AssignAsync(DevicePermissionSaveRequest request) public async Task AssignAsync(DevicePermissionSaveRequest request)
{ {
await _devicePermissionService.AssignAsync(request); await _devicePermissionService.AssignAsync(request);
@@ -43,7 +43,7 @@ public class DevicePermissionsController : ControllerBase
[HttpPost("assign-unique")] [HttpPost("assign-unique")]
[AssignPermissionLimit] [AssignPermissionLimit]
[Transactional] [Transactional]
[DataPermission] [CrossTenant]
public async Task AssignToUniqueAsync(DevicePermissionsAssignToDeviceRequest request) public async Task AssignToUniqueAsync(DevicePermissionsAssignToDeviceRequest request)
{ {
await _devicePermissionService.AssignToUniqueAsync(request); await _devicePermissionService.AssignToUniqueAsync(request);
@@ -54,8 +54,8 @@ public class DevicePermissionsController : ControllerBase
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[DataPermission(ignoreTenant: true, includeCustom: true)]
[HttpGet("assignments")] [HttpGet("assignments")]
[CrossTenant]
public async Task<List<Guid>> GetAssignmentsAsync([FromQuery] DeviceGetAssignmentsRequest request) public async Task<List<Guid>> GetAssignmentsAsync([FromQuery] DeviceGetAssignmentsRequest request)
{ {
return await _devicePermissionService.GetAssignmentsAsync(request); return await _devicePermissionService.GetAssignmentsAsync(request);

View File

@@ -3,6 +3,7 @@ using Dlhis.Basic.Device.Dtos;
using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Request;
using Dlhis.Basic.Device.Services; using Dlhis.Basic.Device.Services;
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
using Kurisu.AspNetCore.UnifyResultAndValidation.Aop;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -28,6 +29,7 @@ public class DevicesConnectController : ControllerBase
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[DisableApiLog]
[HttpPost("heartbeat")] [HttpPost("heartbeat")]
[IgnoreTenant] [IgnoreTenant]
public async Task HeartbeatAsync(DeviceHeartbeatRequest request) public async Task HeartbeatAsync(DeviceHeartbeatRequest request)

View File

@@ -45,7 +45,6 @@ public class DevicesController : ControllerBase
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[Authorize(Roles = "admin")]
[HttpPost("template")] [HttpPost("template")]
public async Task SaveTemplateAsync(DeviceTemplateSaveRequest request) public async Task SaveTemplateAsync(DeviceTemplateSaveRequest request)
{ {
@@ -85,7 +84,7 @@ public class DevicesController : ControllerBase
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("page")] [HttpGet("page")]
[DataPermission(ignoreTenant: true, includeCustom: true)] [DataPermission]
public async Task<Pagination<DevicePageResponse>> GetPageAsync([FromQuery] DevicePageRequest request) public async Task<Pagination<DevicePageResponse>> GetPageAsync([FromQuery] DevicePageRequest request)
{ {
return await _deviceService.GetPageAsync(request); return await _deviceService.GetPageAsync(request);
@@ -125,26 +124,6 @@ public class DevicesController : ControllerBase
await _deviceConnectService.SetRegisterBusinessPlaceAsync(request); await _deviceConnectService.SetRegisterBusinessPlaceAsync(request);
} }
/// <summary>
/// 检查设备是否存在
/// </summary>
/// <returns></returns>
[HttpGet("exists")]
public async Task<bool> CheckExistsAsync(string deviceUniqueNo)
{
return await _deviceService.CheckExistsAsync(deviceUniqueNo);
}
/// <summary>
/// 获取考勤设备
/// </summary>
/// <returns></returns>
[HttpGet("attendances")]
public async Task<List<DeviceResponse>> GetAttendanceDevicesAsync()
{
return await _deviceService.GetAttendanceDevicesAsync();
}
/// <summary> /// <summary>
/// 获取考勤在线/离线设备详情列表 /// 获取考勤在线/离线设备详情列表
/// </summary> /// </summary>

View File

@@ -10,10 +10,6 @@ public interface IDeviceService : IScopeDependency
Task SaveAsync(DeviceSaveRequest request); Task SaveAsync(DeviceSaveRequest request);
Task<bool> CheckExistsAsync(string deviceUniqueNo);
Task<List<DeviceResponse>> GetAttendanceDevicesAsync();
Task<Pagination<DevicePageResponse>> GetOnlineStatusPageAsync(DeviceOnlineAndOfflineRequest request); Task<Pagination<DevicePageResponse>> GetOnlineStatusPageAsync(DeviceOnlineAndOfflineRequest request);
Task ImportAsync(List<DeviceImportRequest> request); Task ImportAsync(List<DeviceImportRequest> request);

View File

@@ -98,7 +98,7 @@ public class DeviceGroupService : IDeviceGroupService
public async Task AssignDevicesAsync(DeviceAssignRequest request) public async Task AssignDevicesAsync(DeviceAssignRequest request)
{ {
var group = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Code == request.GroupCode).FirstAsync(); var group = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Code == request.GroupCode).SingleAsync();
group.ThrowIfNull("设备分组不存在,无法进行分配"); group.ThrowIfNull("设备分组不存在,无法进行分配");
await CheckNoNextGroupAsync(group.Code); await CheckNoNextGroupAsync(group.Code);

View File

@@ -34,13 +34,10 @@ public class DeviceService : IDeviceService
public async Task<Pagination<DevicePageResponse>> GetPageAsync(DevicePageRequest request) public async Task<Pagination<DevicePageResponse>> GetPageAsync(DevicePageRequest request)
{ {
var tenantId = _currentUser.GetStringTenantId();
var page = await _dbContext.Queryable<DeviceEntity>() var page = await _dbContext.Queryable<DeviceEntity>()
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code) .LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
.LeftJoin<DeviceRegistryEntity>((d, dt, dr) => d.UniqueNo == dr.DeviceUniqueNo) .LeftJoin<DeviceRegistryEntity>((d, dt, dr) => d.UniqueNo == dr.DeviceUniqueNo)
.LeftJoin<BusinessPlaceEntity>((d, dt, dr, bp) => dr.BusinessPlaceCode == bp.Code) .LeftJoin<BusinessPlaceEntity>((d, dt, dr, bp) => dr.BusinessPlaceCode == bp.Code)
.Where(d => tenantId == d.TenantId)
.Where((d, dt) => d.Type == request.Type) .Where((d, dt) => d.Type == request.Type)
.WhereIF(request.Enable.HasValue, (d, dt) => d.Enable == request.Enable) .WhereIF(request.Enable.HasValue, (d, dt) => d.Enable == request.Enable)
.WhereIF(request.Search.IsPresent(), d => d.UniqueNo == request.Search || d.DeployPlace.Contains(request.Search)) .WhereIF(request.Search.IsPresent(), d => d.UniqueNo == request.Search || d.DeployPlace.Contains(request.Search))
@@ -232,71 +229,37 @@ public class DeviceService : IDeviceService
/// <returns></returns> /// <returns></returns>
private async Task CheckUniqueNoExistsAsync(DeviceSaveRequest request) private async Task CheckUniqueNoExistsAsync(DeviceSaveRequest request)
{ {
var currentTenantId = _currentUser.GetStringTenantId(); await _dbContext.IgnoreAsync<ITenantId>(async () =>
_dbContext.Client.QueryFilter.ClearAndBackup<ITenantId>(); {
try var currentTenantId = _currentUser.GetStringTenantId();
{
//查询设备是否存在
var device = await _dbContext.Queryable<DeviceEntity>()
.Where(x => x.UniqueNo == request.UniqueNo)
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
.FirstAsync();
if (device != null) //查询设备是否存在
{ var device = await _dbContext.Queryable<DeviceEntity>()
(device.TenantId == currentTenantId).ThrowIfTrue("设备已经存在,请检查"); .Where(x => x.UniqueNo == request.UniqueNo)
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
.SingleAsync();
var factory = device.TenantId; if (device != null)
try {
{ (device.TenantId == currentTenantId).ThrowIfTrue("设备已经存在,请检查");
var tenantResult = await _tenantApi.GetTenantByCodeAsync(device.TenantId);
factory = tenantResult?.Data?.Name ?? string.Empty;
}
catch (Exception)
{
//ignore
}
true.ThrowIfTrue($"设备已添加{factory}厂区"); var factory = device.TenantId;
} try
} {
finally var tenantResult = await _tenantApi.GetTenantByCodeAsync(device.TenantId);
{ factory = tenantResult?.Data?.Name ?? string.Empty;
_dbContext.Client.QueryFilter.Restore(); }
} catch (Exception)
{
//ignore
}
true.ThrowIfTrue($"设备已添加{factory}厂区");
}
});
} }
public async Task<bool> CheckExistsAsync(string deviceUniqueNo)
{
_dbContext.Client.QueryFilter.ClearAndBackup<ITenantId>();
try
{
return await _dbContext.Queryable<DeviceEntity>()
.Where(x => x.UniqueNo == deviceUniqueNo && x.Enable)
.AnyAsync();
}
finally
{
_dbContext.Client.QueryFilter.Restore();
}
}
public async Task<List<DeviceResponse>> GetAttendanceDevicesAsync()
{
var devices = await _dbContext.Queryable<DeviceEntity>()
.Where(x => x.Enable)
.Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance))
.Select(x => new DeviceResponse
{
FuncsStr = x.Funcs.ToString()
}, true)
.ToListAsync();
return devices.Where(x => x.Type == DeviceTypeEnumType.Attendance).ToList();
}
/// <summary> /// <summary>
/// 获取离线设备 /// 获取离线设备
/// </summary> /// </summary>

View File

@@ -64,7 +64,7 @@ public class GainfoGroupsController : ControllerBase
[HttpPost("assign")] [HttpPost("assign")]
[AssignPermissionLimit] [AssignPermissionLimit]
[Transactional] [Transactional]
[DataPermission] [CrossTenant]
public async Task AssignGainfosAsync(GainfoAssignRequest request) public async Task AssignGainfosAsync(GainfoAssignRequest request)
{ {
await _gainfoGroupService.AssignGainfosAsync(request); await _gainfoGroupService.AssignGainfosAsync(request);

View File

@@ -30,7 +30,7 @@ public class GainfoOutsourceSettingController : ControllerBase
[HttpPost("save")] [HttpPost("save")]
[AssignPermissionLimit] [AssignPermissionLimit]
[Transactional] [Transactional]
[DataPermission] [CrossTenant]
public async Task SaveAsync(GainfoOutsourceSettingSaveRequest request) public async Task SaveAsync(GainfoOutsourceSettingSaveRequest request)
{ {
await _gainfoOutSourceService.SaveAsync(request); await _gainfoOutSourceService.SaveAsync(request);

View File

@@ -125,7 +125,8 @@ public class BusinessPlacesController : ControllerBase
/// <returns></returns> /// <returns></returns>
[HttpPost("device/assign")] [HttpPost("device/assign")]
[AssignPermissionLimit] [AssignPermissionLimit]
[DataPermission] [Transactional]
[CrossTenant]
public async Task Assign(DispositionDeviceRequest request) public async Task Assign(DispositionDeviceRequest request)
{ {
await _businessPlaceShiftService.AssignAsync(request); await _businessPlaceShiftService.AssignAsync(request);

View File

@@ -196,7 +196,7 @@ public class OrderService : BaseOrderService, IOrderService
{ {
Start = x.Start, Start = x.Start,
End = x.End End = x.End
}.IsPresent1(request.CostDateTime)); }.IsPresent(request.CostDateTime));
var costDate = await GetCostDateAsync(shift, request.CostDateTime); var costDate = await GetCostDateAsync(shift, request.CostDateTime);
@@ -323,7 +323,7 @@ public class OrderService : BaseOrderService, IOrderService
{ {
Start = x.Start, Start = x.Start,
End = x.End End = x.End
}.IsPresent1(request.CostDateTime)); }.IsPresent(request.CostDateTime));
shift.ThrowIfNull("非就餐时间,无法消费"); shift.ThrowIfNull("非就餐时间,无法消费");
_logs.Add("检验设备和营业点参数:" + _sw.ElapsedMilliseconds); _logs.Add("检验设备和营业点参数:" + _sw.ElapsedMilliseconds);

View File

@@ -1,42 +0,0 @@
using Kurisu.AspNetCore.CustomClass;
namespace Dlhis.Canteen.Order;
/// <summary>
/// 临时的扩展类 todo: 嵌入框架
/// </summary>
public static class TimePeriodExtensions
{
public static bool IsPresent1(this TimePeriod period, DateTime dateTime)
{
DateTime start;
DateTime end;
if (period.IsCrossDay())
{
//period = [22:00:00,03:00:00]
var currentStart = dateTime.Date.Add(period.Start.Value.ToTimeSpan());
var endOfDay = dateTime.Date.AddDays(1).AddSeconds(-1);
//assume is left range . then currentStart is 2024-04-16 22:00:00 and endOfDay is 2024-04-16 23:59:59
if (dateTime >= currentStart && dateTime <= endOfDay)
{
start = currentStart; //2024-04-16 22:00:00
end = dateTime.Date.AddDays(1).Add(period.End.Value.ToTimeSpan());//2024-04-17 03:00:00
}
else
{
start = dateTime.Date.AddDays(-1).Add(period.Start.Value.ToTimeSpan());
end = dateTime.Date.Add(period.End.Value.ToTimeSpan());
}
}
else
{
start = dateTime.Date.Add(period.Start.Value.ToTimeSpan());
end = dateTime.Date.Add(period.End.Value.ToTimeSpan());
}
return dateTime >= start && dateTime <= end;
}
}

View File

@@ -2,6 +2,7 @@
using Dlhis.Common.ApiLog.Response; using Dlhis.Common.ApiLog.Response;
using Dlhis.Common.ApiLog.Services.Implements; using Dlhis.Common.ApiLog.Services.Implements;
using Kurisu.AspNetCore.DataAccess.Dto; using Kurisu.AspNetCore.DataAccess.Dto;
using Kurisu.AspNetCore.UnifyResultAndValidation.Aop;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -26,7 +27,7 @@ public class ApiLogController : ControllerBase
/// 获取api日志 /// 获取api日志
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[Authorize(Roles = "admin")] [DisableApiLog]
[HttpGet("logs")] [HttpGet("logs")]
public async Task<Pagination<ApiLogResponse>> GetLogsAsync([FromQuery] ApiLogRequest request) public async Task<Pagination<ApiLogResponse>> GetLogsAsync([FromQuery] ApiLogRequest request)
{ {

View File

@@ -3,6 +3,7 @@ using Dlhis.Common.FileOperation.Response;
using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Basic.Entity;
using Kurisu.AspNetCore.CustomClass; using Kurisu.AspNetCore.CustomClass;
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
using Kurisu.AspNetCore.UnifyResultAndValidation.Aop;
using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.AspNetCore.Utils.Extensions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -29,6 +30,7 @@ public class EnumsController : ControllerBase
/// </summary> /// </summary>
/// <param name="code">code</param> /// <param name="code">code</param>
/// <returns></returns> /// <returns></returns>
[DisableApiLog]
[HttpGet] [HttpGet]
public List<CommonEnumResponse> GetEnums(string code) public List<CommonEnumResponse> GetEnums(string code)
{ {

View File

@@ -11,7 +11,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Kurisu.AspNetCore" Version="0.9.23" /> <PackageReference Include="Kurisu.AspNetCore" Version="0.9.24" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -146,7 +146,7 @@ public class OrderService : IOrderService
{ {
Start = TimeOnly.FromDateTime(x.Start), Start = TimeOnly.FromDateTime(x.Start),
End = TimeOnly.FromDateTime(x.End) End = TimeOnly.FromDateTime(x.End)
}.IsPresent1(request.CostDateTime)); }.IsPresent(request.CostDateTime));
shift.ThrowIfNull("非就餐时间,无法消费"); shift.ThrowIfNull("非就餐时间,无法消费");
var costDate = await GetCostDateAsync(shift, request.CostDateTime); var costDate = await GetCostDateAsync(shift, request.CostDateTime);

View File

@@ -1,42 +0,0 @@
using Kurisu.AspNetCore.CustomClass;
namespace Dlhis.Middle;
/// <summary>
/// 临时的扩展类 todo: 嵌入框架
/// </summary>
public static class TimePeriodExtensions
{
public static bool IsPresent1(this TimePeriod period, DateTime dateTime)
{
DateTime start;
DateTime end;
if (period.IsCrossDay())
{
//period = [22:00:00,03:00:00]
var currentStart = dateTime.Date.Add(period.Start.Value.ToTimeSpan());
var endOfDay = dateTime.Date.AddDays(1).AddSeconds(-1);
//assume is left range . then currentStart is 2024-04-16 22:00:00 and endOfDay is 2024-04-16 23:59:59
if (dateTime >= currentStart && dateTime <= endOfDay)
{
start = currentStart; //2024-04-16 22:00:00
end = dateTime.Date.AddDays(1).Add(period.End.Value.ToTimeSpan());//2024-04-17 03:00:00
}
else
{
start = dateTime.Date.AddDays(-1).Add(period.Start.Value.ToTimeSpan());
end = dateTime.Date.Add(period.End.Value.ToTimeSpan());
}
}
else
{
start = dateTime.Date.Add(period.Start.Value.ToTimeSpan());
end = dateTime.Date.Add(period.End.Value.ToTimeSpan());
}
return dateTime >= start && dateTime <= end;
}
}

View File

@@ -2,6 +2,7 @@
using Dlhis.ScheduledTask.TaskAssignment.Response; using Dlhis.ScheduledTask.TaskAssignment.Response;
using Dlhis.ScheduledTask.TaskAssignment.Services; using Dlhis.ScheduledTask.TaskAssignment.Services;
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
using Kurisu.AspNetCore.UnifyResultAndValidation.Aop;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@@ -26,6 +27,7 @@ public class AssignmentsController : ControllerBase
/// 获取设备任务(按设备) /// 获取设备任务(按设备)
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[DisableApiLog]
[IgnoreTenant] [IgnoreTenant]
[HttpGet("deviceTasks")] [HttpGet("deviceTasks")]
public async Task<List<DeviceTaskToDeviceByDeviceResponse>> DeviceGetTasksGetAsync([FromQuery] DeviceTaskGetRequest request) public async Task<List<DeviceTaskToDeviceByDeviceResponse>> DeviceGetTasksGetAsync([FromQuery] DeviceTaskGetRequest request)
@@ -37,6 +39,7 @@ public class AssignmentsController : ControllerBase
/// 获取设备任务(按设备) /// 获取设备任务(按设备)
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[DisableApiLog]
[HttpPost("deviceTasks")] [HttpPost("deviceTasks")]
[IgnoreTenant] [IgnoreTenant]
public async Task<List<DeviceTaskToDeviceByDeviceResponse>> DeviceGetTasksPostAsync(DeviceTaskGetRequest request) public async Task<List<DeviceTaskToDeviceByDeviceResponse>> DeviceGetTasksPostAsync(DeviceTaskGetRequest request)
@@ -49,7 +52,8 @@ public class AssignmentsController : ControllerBase
/// </summary> /// </summary>
/// <param name="requests"></param> /// <param name="requests"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("taskstatus")] [DisableApiLog]
[HttpPost("taskStatus")]
[IgnoreTenant] [IgnoreTenant]
public async Task UpdateDeviceTaskStatusAsync(List<UpdateDeviceTaskStatusRequest> requests) public async Task UpdateDeviceTaskStatusAsync(List<UpdateDeviceTaskStatusRequest> requests)
{ {

View File

@@ -28,8 +28,8 @@ public class DeviceTaskAssignmentsController : ControllerBase
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[DataPermission]
[HttpGet("page")] [HttpGet("page")]
[CrossTenant]
public async Task<Pagination<DeviceTaskAssignmentResponse>> GetPageAsync([FromQuery] DeviceTaskAssignmentRequest request) public async Task<Pagination<DeviceTaskAssignmentResponse>> GetPageAsync([FromQuery] DeviceTaskAssignmentRequest request)
{ {
return await _deviceTaskAssignmentService.GetPageAsync(request); return await _deviceTaskAssignmentService.GetPageAsync(request);