Merge branch 'development'
This commit is contained in:
@@ -47,7 +47,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Message", "Src\Dlhis.
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.InfoCheck", "Src\Dlhis.InfoCheck\Dlhis.InfoCheck.csproj", "{4D656761-8CE7-4316-A3DF-8C1722D69CCE}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.InfoCheck", "Src\Dlhis.InfoCheck\Dlhis.InfoCheck.csproj", "{4D656761-8CE7-4316-A3DF-8C1722D69CCE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dlhis.Middle", "Src\Dlhis.Middle\Dlhis.Middle.csproj", "{762C944C-36A1-4F1A-803F-08F9BD8891D1}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Middle", "Src\Dlhis.Middle\Dlhis.Middle.csproj", "{762C944C-36A1-4F1A-803F-08F9BD8891D1}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.DataPermission.Model", "Src\Dlhis.DataPermission.Model\Dlhis.DataPermission.Model.csproj", "{CA1427E2-CC70-4489-8653-1C05630C8392}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
@@ -123,6 +125,10 @@ Global
|
|||||||
{762C944C-36A1-4F1A-803F-08F9BD8891D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{762C944C-36A1-4F1A-803F-08F9BD8891D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{762C944C-36A1-4F1A-803F-08F9BD8891D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{762C944C-36A1-4F1A-803F-08F9BD8891D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{762C944C-36A1-4F1A-803F-08F9BD8891D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
{762C944C-36A1-4F1A-803F-08F9BD8891D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{CA1427E2-CC70-4489-8653-1C05630C8392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{CA1427E2-CC70-4489-8653-1C05630C8392}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{CA1427E2-CC70-4489-8653-1C05630C8392}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{CA1427E2-CC70-4489-8653-1C05630C8392}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public class BusinessPlaceShiftSaveMealShiftRequest : IValidatableObject
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 时间段
|
/// 时间段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "时间段不可为空")]
|
||||||
public TimePeriod TimePeriod { get; set; }
|
public TimePeriod TimePeriod { get; set; }
|
||||||
|
|
||||||
|
|
||||||
@@ -37,12 +38,12 @@ public class BusinessPlaceShiftSaveMealShiftRequest : IValidatableObject
|
|||||||
yield return new ValidationResult("时间段配置错误", new[] { nameof(TimePeriod) });
|
yield return new ValidationResult("时间段配置错误", new[] { nameof(TimePeriod) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TimePeriod?.Start == null || TimePeriod?.End == null)
|
if (TimePeriod!.Start == null || TimePeriod!.End == null)
|
||||||
{
|
{
|
||||||
yield return new ValidationResult("时间段配置错误", new[] { nameof(TimePeriod) });
|
yield return new ValidationResult("时间段配置错误", new[] { nameof(TimePeriod) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TimePeriod.Start == TimePeriod.End)
|
if (TimePeriod!.Start == TimePeriod!.End)
|
||||||
{
|
{
|
||||||
yield return new ValidationResult("时间段设置区间有误,开始时段不能等于结束时段.", new[] { nameof(TimePeriod) });
|
yield return new ValidationResult("时间段设置区间有误,开始时段不能等于结束时段.", new[] { nameof(TimePeriod) });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public interface IBusinessPlaceShiftService : IScopeDependency
|
|||||||
|
|
||||||
Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeAsync(string placeCustomCode);
|
Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeAsync(string placeCustomCode);
|
||||||
|
|
||||||
Task<Pagination<DeviceCodeNameDetail>> GetDevicesByCode(BusinessPlaceGetByCodeRequest request);
|
Task<List<DeviceCodeNameDetail>> GetAssignmentsAsync(Guid code);
|
||||||
|
|
||||||
Task DispositionDeviceAsync(DispositionDeviceRequest request);
|
Task AssignAsync(DispositionDeviceRequest request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,8 +102,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!.Value;
|
||||||
entity.End = request.TimePeriod.End.Value;
|
entity.End = request.TimePeriod.End!.Value;
|
||||||
|
|
||||||
await _dbContext.InsertAsync(entity);
|
await _dbContext.InsertAsync(entity);
|
||||||
}
|
}
|
||||||
@@ -115,8 +115,8 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
|
|||||||
|
|
||||||
entity.ThrowIfNull("餐次段不存在");
|
entity.ThrowIfNull("餐次段不存在");
|
||||||
|
|
||||||
entity.Start = request.TimePeriod.Start.Value;
|
entity.Start = request.TimePeriod.Start!.Value;
|
||||||
entity.End = request.TimePeriod.End.Value;
|
entity.End = request.TimePeriod.End!.Value;
|
||||||
|
|
||||||
request.Adapt(entity);
|
request.Adapt(entity);
|
||||||
await _dbContext.UpdateAsync(entity);
|
await _dbContext.UpdateAsync(entity);
|
||||||
@@ -183,62 +183,30 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Pagination<DeviceCodeNameDetail>> GetDevicesByCode(BusinessPlaceGetByCodeRequest request)
|
public async Task<List<DeviceCodeNameDetail>> GetAssignmentsAsync(Guid code)
|
||||||
{
|
{
|
||||||
var regiss = await _dbContext.Queryable<DeviceRegistryEntity>()
|
return await _dbContext.Queryable<DeviceRegistryEntity>()
|
||||||
.Where(x => x.BusinessPlaceCode.ToString() == request.Code)
|
.LeftJoin<DeviceEntity>((x, d) => x.DeviceUniqueNo == d.UniqueNo)
|
||||||
|
.Where(x => x.BusinessPlaceCode == code)
|
||||||
|
.Select((x, d) => new DeviceCodeNameDetail
|
||||||
|
{
|
||||||
|
UniqueNo = x.DeviceUniqueNo,
|
||||||
|
UniqueName = d.DeployPlace
|
||||||
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
|
|
||||||
|
|
||||||
var list = new List<DeviceCodeNameDetail>();
|
|
||||||
if (regiss.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var regis in regiss)
|
|
||||||
{
|
|
||||||
var device = devices.Where(x => x.UniqueNo == regis.DeviceUniqueNo)
|
|
||||||
.FirstOrDefault();
|
|
||||||
if (device != null)
|
|
||||||
{
|
|
||||||
var detail = new DeviceCodeNameDetail
|
|
||||||
{
|
|
||||||
UniqueNo = regis.DeviceUniqueNo,
|
|
||||||
UniqueName = device.Supplier
|
|
||||||
};
|
|
||||||
list.Add(detail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//分页
|
|
||||||
var startIndex = (request.PageIndex - 1) * request.PageSize;
|
|
||||||
var pagedData = list.Skip(startIndex).Take(request.PageSize).ToList();
|
|
||||||
|
|
||||||
var pagination = new Pagination<DeviceCodeNameDetail>
|
|
||||||
{
|
|
||||||
PageIndex = request.PageIndex,
|
|
||||||
PageSize = request.PageSize,
|
|
||||||
Total = list.Count, // 使用原始列表的总数进行分页
|
|
||||||
Data = pagedData
|
|
||||||
};
|
|
||||||
|
|
||||||
return pagination;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task DispositionDeviceAsync(DispositionDeviceRequest request)
|
public async Task AssignAsync(DispositionDeviceRequest request)
|
||||||
{
|
{
|
||||||
var place = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.Code == request.PlaceCode).SingleAsync();
|
var place = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.Code == request.PlaceCode).SingleAsync();
|
||||||
place.ThrowIfNull("营业点不存在");
|
place.ThrowIfNull("营业点不存在");
|
||||||
|
|
||||||
var registries = await _dbContext.Queryable<DeviceRegistryEntity>()
|
var registries = await _dbContext.Queryable<DeviceRegistryEntity>()
|
||||||
.Where(x => request.UniqueNos.Contains(x.DeviceUniqueNo))
|
.Where(x => x.BusinessPlaceCode == request.PlaceCode || request.UniqueNos.Contains(x.DeviceUniqueNo))
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
foreach (var item in registries)
|
registries.ForEach(item => { item.BusinessPlaceCode = request.UniqueNos.Contains(item.DeviceUniqueNo) ? request.PlaceCode : null; });
|
||||||
{
|
|
||||||
item.BusinessPlaceCode = request.PlaceCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
await _dbContext.UpdateAsync(registries);
|
await _dbContext.UpdateAsync(registries);
|
||||||
}
|
}
|
||||||
|
|||||||
93
Src/Dlhis.Basic/DataPermissions/GetDataPermissionService.cs
Normal file
93
Src/Dlhis.Basic/DataPermissions/GetDataPermissionService.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using Dlhis.Entity.Device.Entities;
|
||||||
|
using Dlhis.Entity.Sys.Entities;
|
||||||
|
using Dlhis.Entity.Sys.Enums;
|
||||||
|
using Kurisu.AspNetCore.Authentication.Abstractions;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.Entity;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Attributes;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.DataPermissions;
|
||||||
|
|
||||||
|
public class GetDataPermissionService : IGetDataPermissions, ISingletonDependency
|
||||||
|
{
|
||||||
|
private readonly ICurrentUser _currentUser;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
public GetDataPermissionService(ICurrentUser currentUser, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_currentUser = currentUser;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Dictionary<string, List<Guid>> GetData<T>()
|
||||||
|
{
|
||||||
|
var dict = new Dictionary<string, List<Guid>>(2);
|
||||||
|
var currentRole = _currentUser.GetRole();
|
||||||
|
if (currentRole is "admin" or "tenant-admin")
|
||||||
|
{
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var scope = _serviceProvider.CreateScope();
|
||||||
|
|
||||||
|
var db = scope.ServiceProvider.GetService<IDbContext>();
|
||||||
|
db.Ignore<ITenantId>(() =>
|
||||||
|
{
|
||||||
|
var userDataPermissions = db.Queryable<DataPermissionEntity>()
|
||||||
|
.Where(x => x.AssignType == AssignTypeEnumType.User)
|
||||||
|
.Where(x => x.AssignValue == _currentUser.GetStringSubjectId())
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var deviceCodeProperty = typeof(T)
|
||||||
|
.GetProperties()
|
||||||
|
.FirstOrDefault(x => x.IsDefined(typeof(DeviceCodeAttribute), false));
|
||||||
|
|
||||||
|
var deviceGroupCodeProperty = typeof(T)
|
||||||
|
.GetProperties()
|
||||||
|
.FirstOrDefault(x => x.IsDefined(typeof(DeviceGroupCodeAttribute), false));
|
||||||
|
|
||||||
|
var deviceCodes = new List<Guid>();
|
||||||
|
|
||||||
|
//先计算分组权限下的设备
|
||||||
|
var deviceGroupCodes = userDataPermissions.Where(x => x.UniqueType == DeviceAssignmentTypeEnumType.Group).Select(x => x.UniqueValue).ToList();
|
||||||
|
if (deviceGroupCodes.Any() && deviceCodeProperty != null)
|
||||||
|
{
|
||||||
|
var data = db.Queryable<DeviceGroupEntity>().ToList();
|
||||||
|
//开始递归处理
|
||||||
|
var tops = data.Where(x => !x.PCode.HasValue).ToList();
|
||||||
|
tops.ForEach(x => { DeviceGroupRecursionGetNext(x, data, deviceGroupCodes, deviceGroupCodes.Contains(x.Code)); });
|
||||||
|
deviceGroupCodes = deviceGroupCodes.Distinct().ToList();
|
||||||
|
deviceCodes = db.Queryable<DeviceGroupRelationshipEntity>().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceGroupCodeProperty != null && deviceGroupCodes.Any())
|
||||||
|
{
|
||||||
|
dict.Add(deviceGroupCodeProperty.Name, deviceGroupCodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceCodeProperty != null)
|
||||||
|
{
|
||||||
|
var currentDeviceCodes = userDataPermissions.Where(x => x.UniqueType == DeviceAssignmentTypeEnumType.Device).Select(x => x.UniqueValue).ToList();
|
||||||
|
deviceCodes.AddRange(currentDeviceCodes);
|
||||||
|
dict.Add(deviceCodeProperty.Name, deviceCodes.Distinct().ToList());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeviceGroupRecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> data, List<Guid> result, bool add)
|
||||||
|
{
|
||||||
|
var next = data.Where(x => x.PCode == current.Code).ToList();
|
||||||
|
foreach (var item in next)
|
||||||
|
{
|
||||||
|
if (add)
|
||||||
|
{
|
||||||
|
result.Add(item.Code);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceGroupRecursionGetNext(item, data, result, result.Contains(item.Code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -83,13 +83,13 @@ public class DevicesController : ControllerBase
|
|||||||
return await _deviceConnectService.RegisterAsync(request);
|
return await _deviceConnectService.RegisterAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备分页
|
/// 设备分页
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("page")]
|
[HttpGet("page")]
|
||||||
|
[DataPermission(true)]
|
||||||
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);
|
||||||
@@ -173,44 +173,14 @@ public class DevicesController : ControllerBase
|
|||||||
return await _deviceService.GetDeviceNumberAsync();
|
return await _deviceService.GetDeviceNumberAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取考勤设备详情列表
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("attendancestotal")]
|
|
||||||
public async Task<Pagination<DevicePageResponse>> GetAttendanceTotalAsync([FromQuery] AttendanceTotalRequest request)
|
|
||||||
{
|
|
||||||
return await _deviceService.GetAttendanceTotalAsync(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取考勤在线/离线设备详情列表
|
/// 获取考勤在线/离线设备详情列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("attendancesoffline")]
|
[HttpGet("onlineStatus/page")]
|
||||||
public async Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync([FromQuery] DeviceOnlineAndOfflineRequest request)
|
public async Task<Pagination<DevicePageResponse>> GetOnlineStatusPageAsync([FromQuery] DeviceOnlineAndOfflineRequest request)
|
||||||
{
|
{
|
||||||
return await _deviceService.GetAttendanceOfflineAsync(request);
|
return await _deviceService.GetOnlineStatusPageAsync(request);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取门禁在线/离线设备详情列表
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("dooroffline")]
|
|
||||||
public async Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync([FromQuery] GetDoorOfflineRequest request)
|
|
||||||
{
|
|
||||||
return await _deviceService.GetDoorOfflineAsync(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取近期30天考勤新增设备数
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("recentnumbers")]
|
|
||||||
public async Task<List<RecentNumberResponse>> GetRecentNumbersAsync()
|
|
||||||
{
|
|
||||||
return await _deviceService.GetRecentNumbersAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -15,10 +15,8 @@ public class AssignPermissionLimitAttribute : Attribute, IAsyncActionFilter
|
|||||||
|
|
||||||
var currentTenantId = currentUser.GetStringTenantId();
|
var currentTenantId = currentUser.GetStringTenantId();
|
||||||
|
|
||||||
await using (var handler = await redisCache.LockAsync($"permission:generate:{currentTenantId}"))
|
await using var handler = await redisCache.LockAsync($"permission:generate:{currentTenantId}");
|
||||||
{
|
|
||||||
handler.Acquired.ThrowIfFalse("请勿频繁分配");
|
handler.Acquired.ThrowIfFalse("请勿频繁分配");
|
||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.Dto;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Device.Request;
|
||||||
|
|
||||||
|
public class DeviceOnlineAndOfflineRequest : PageDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否在线
|
||||||
|
/// </summary>
|
||||||
|
public bool IsOnline { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备类型
|
||||||
|
/// </summary>
|
||||||
|
[EnumDataType(typeof(DeviceTypeEnumType))]
|
||||||
|
public DeviceTypeEnumType Type { get; set; }
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using Kurisu.AspNetCore.DataAccess.Dto;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Request
|
|
||||||
{
|
|
||||||
public class DeviceOnlineAndOfflineRequest : PageDto
|
|
||||||
{
|
|
||||||
public bool IsOnAndOff { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,13 +16,7 @@ public interface IDeviceService : IScopeDependency
|
|||||||
|
|
||||||
Task<DeviceNumberResponse> GetDeviceNumberAsync();
|
Task<DeviceNumberResponse> GetDeviceNumberAsync();
|
||||||
|
|
||||||
Task<Pagination<DevicePageResponse>> GetAttendanceTotalAsync(AttendanceTotalRequest request);
|
Task<Pagination<DevicePageResponse>> GetOnlineStatusPageAsync(DeviceOnlineAndOfflineRequest request);
|
||||||
|
|
||||||
Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync(DeviceOnlineAndOfflineRequest request);
|
|
||||||
|
|
||||||
Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync(GetDoorOfflineRequest request);
|
|
||||||
|
|
||||||
Task<List<RecentNumberResponse>> GetRecentNumbersAsync();
|
|
||||||
|
|
||||||
Task ImportAsync(List<DeviceImportRequest> request);
|
Task ImportAsync(List<DeviceImportRequest> request);
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class DeviceService : IDeviceService
|
|||||||
var registry = await _dbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync();
|
var registry = await _dbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync();
|
||||||
if (registry == null)
|
if (registry == null)
|
||||||
{
|
{
|
||||||
registry = new DeviceRegistryEntity()
|
registry = new DeviceRegistryEntity
|
||||||
{
|
{
|
||||||
DeviceUniqueNo = request.UniqueNo,
|
DeviceUniqueNo = request.UniqueNo,
|
||||||
LastHeartbeatTime = DateTime.Now,
|
LastHeartbeatTime = DateTime.Now,
|
||||||
@@ -180,12 +180,10 @@ public class DeviceService : IDeviceService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="templateCode"></param>
|
/// <param name="templateCode"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<DeviceTemplateEntity> CheckTemplateExistsAsync(Guid templateCode)
|
private async Task CheckTemplateExistsAsync(Guid templateCode)
|
||||||
{
|
{
|
||||||
var entity = await _dbContext.Queryable<DeviceTemplateEntity>().Where(x => x.Code == templateCode).FirstAsync();
|
var entity = await _dbContext.Queryable<DeviceTemplateEntity>().Where(x => x.Code == templateCode).FirstAsync();
|
||||||
entity.ThrowIfNull("设备模板不存在");
|
entity.ThrowIfNull("设备模板不存在");
|
||||||
|
|
||||||
return entity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -246,6 +244,7 @@ public class DeviceService : IDeviceService
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
//ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
true.ThrowIfTrue($"设备已添加{factory}厂区");
|
true.ThrowIfTrue($"设备已添加{factory}厂区");
|
||||||
@@ -344,82 +343,29 @@ public class DeviceService : IDeviceService
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<Pagination<DevicePageResponse>> GetAttendanceTotalAsync(AttendanceTotalRequest request)
|
public async Task<Pagination<DevicePageResponse>> GetOnlineStatusPageAsync(DeviceOnlineAndOfflineRequest request)
|
||||||
{
|
{
|
||||||
var page = await _dbContext.Queryable<DeviceEntity>()
|
return await GetDeviceStatusPageAsync(request.IsOnline, request, request.Type);
|
||||||
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
|
||||||
.Where(d => d.Type == DeviceTypeEnumType.Attendance || (d.Type == DeviceTypeEnumType.Door && d.AsAttendance))
|
|
||||||
.Select((d, dt) => new DevicePageResponse
|
|
||||||
{
|
|
||||||
FuncsStr = d.Funcs.ToString(),
|
|
||||||
Brand = dt.Brand,
|
|
||||||
Type = d.Type,
|
|
||||||
}, true)
|
|
||||||
.ToPageListAsync(request);
|
|
||||||
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync(DeviceOnlineAndOfflineRequest request)
|
|
||||||
{
|
|
||||||
return await GetDeviceStatusPageAsync(request.IsOnAndOff, request, DeviceTypeEnumType.Attendance);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync(GetDoorOfflineRequest request)
|
|
||||||
{
|
|
||||||
return await GetDeviceStatusPageAsync(request.IsOnAndOff, request, DeviceTypeEnumType.Door);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<List<RecentNumberResponse>> GetRecentNumbersAsync()
|
|
||||||
{
|
|
||||||
//获取近30天并转化为"yyyy-MM-dd"集合
|
|
||||||
DateTime currentDate = DateTime.Now;
|
|
||||||
var times = new List<string>();
|
|
||||||
for (int i = 0; i < 30; i++)
|
|
||||||
{
|
|
||||||
DateTime date = currentDate.AddDays(-i);
|
|
||||||
string dateString = date.ToString("yyyy-MM-dd");
|
|
||||||
times.Add(dateString);
|
|
||||||
}
|
|
||||||
|
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync();
|
|
||||||
|
|
||||||
var list = new List<RecentNumberResponse>();
|
|
||||||
times.ForEach(time =>
|
|
||||||
{
|
|
||||||
var count = devices.Count(x => x.CreateTime.ToString("yyyy-MM-dd") == time);
|
|
||||||
var res = new RecentNumberResponse
|
|
||||||
{
|
|
||||||
Date = time,
|
|
||||||
Num = count,
|
|
||||||
};
|
|
||||||
list.Add(res);
|
|
||||||
});
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//************************************************************* help methods ************************************************************************
|
//************************************************************* help methods ************************************************************************
|
||||||
|
|
||||||
private async Task<Pagination<DevicePageResponse>> GetDeviceStatusPageAsync(bool isOnAndOff, PageDto pageDto, DeviceTypeEnumType deviceType)
|
private async Task<Pagination<DevicePageResponse>> GetDeviceStatusPageAsync(bool isOnline, PageDto pageDto, DeviceTypeEnumType type)
|
||||||
{
|
{
|
||||||
var devices = deviceType == DeviceTypeEnumType.Attendance
|
var devices = type == DeviceTypeEnumType.Attendance
|
||||||
? await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync()
|
? await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance).ToListAsync()
|
||||||
: await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Door).ToListAsync();
|
: await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Door).ToListAsync();
|
||||||
|
|
||||||
var offDevices = await GetOfflineDevicesCount(devices);
|
var offDevices = await GetOfflineDevicesCount(devices);
|
||||||
//离线
|
//离线
|
||||||
var ids = offDevices.Select(x => x.Id).ToList();
|
var ids = offDevices.Select(x => x.Id).ToList();
|
||||||
if (!isOnAndOff)
|
if (!isOnline)
|
||||||
{
|
{
|
||||||
ids = devices.Select(x => x.Id).Except(ids).ToList();
|
ids = devices.Select(x => x.Id).Except(ids).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _dbContext.Queryable<DeviceEntity>()
|
return await _dbContext.Queryable<DeviceEntity>()
|
||||||
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
.Where(d => d.Type == DeviceTypeEnumType.Attendance)
|
|
||||||
.Where(d => ids.Contains(d.Id))
|
.Where(d => ids.Contains(d.Id))
|
||||||
.WhereIF(pageDto.Search.IsPresent(), d => d.UniqueNo == pageDto.Search
|
.WhereIF(pageDto.Search.IsPresent(), d => d.UniqueNo == pageDto.Search
|
||||||
|| d.DeployPlace.Contains(pageDto.Search))
|
|| d.DeployPlace.Contains(pageDto.Search))
|
||||||
@@ -427,7 +373,7 @@ public class DeviceService : IDeviceService
|
|||||||
{
|
{
|
||||||
FuncsStr = d.Funcs.ToString(),
|
FuncsStr = d.Funcs.ToString(),
|
||||||
Brand = dt.Brand,
|
Brand = dt.Brand,
|
||||||
Type = d.Type,
|
Type = d.Type
|
||||||
}, true)
|
}, true)
|
||||||
.ToPageListAsync(pageDto);
|
.ToPageListAsync(pageDto);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dlhis.Basic.BusinessShift.Services;
|
using Dlhis.Basic.BusinessShift.Services;
|
||||||
|
using Dlhis.Basic.Device.Filters;
|
||||||
using Dlhis.Basic.Places.Request;
|
using Dlhis.Basic.Places.Request;
|
||||||
using Dlhis.Basic.Places.Response;
|
using Dlhis.Basic.Places.Response;
|
||||||
using Dlhis.Basic.Places.Services;
|
using Dlhis.Basic.Places.Services;
|
||||||
@@ -109,12 +110,12 @@ public class BusinessPlacesController : ControllerBase
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据营业点获取下面的设备
|
/// 根据营业点获取下面的设备
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="code"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("devicenos")]
|
[HttpGet("device/assignments")]
|
||||||
public async Task<Pagination<DeviceCodeNameDetail>> GetDevicesByCode([FromQuery] BusinessPlaceGetByCodeRequest request)
|
public async Task<List<DeviceCodeNameDetail>> GetAssignments(Guid code)
|
||||||
{
|
{
|
||||||
return await _businessPlaceShiftService.GetDevicesByCode(request);
|
return await _businessPlaceShiftService.GetAssignmentsAsync(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -122,9 +123,11 @@ public class BusinessPlacesController : ControllerBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("disposition")]
|
[HttpPost("device/assign")]
|
||||||
public async Task DispositionDeviceAsync(DispositionDeviceRequest request)
|
[AssignPermissionLimit]
|
||||||
|
[DataPermission]
|
||||||
|
public async Task Assign(DispositionDeviceRequest request)
|
||||||
{
|
{
|
||||||
await _businessPlaceShiftService.DispositionDeviceAsync(request);
|
await _businessPlaceShiftService.AssignAsync(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Kurisu.AspNetCore.DataAccess.Dto;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Places.Request
|
|
||||||
{
|
|
||||||
public class BusinessPlaceGetByCodeRequest : PageDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 营业点号
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "营业点号不能为空")]
|
|
||||||
public string Code { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
namespace Dlhis.Basic.Places.Response
|
namespace Dlhis.Basic.Places.Response;
|
||||||
|
|
||||||
|
public class DeviceCodeNameDetail
|
||||||
{
|
{
|
||||||
public class DeviceCodeNameDetail
|
|
||||||
{
|
|
||||||
public string UniqueNo { get; set; }
|
public string UniqueNo { get; set; }
|
||||||
public string UniqueName { get; set; }
|
public string UniqueName { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using Dlhis.Basic.Summary.Response;
|
using Dlhis.Basic.Summary.Response;
|
||||||
using Dlhis.Basic.Summary.Services;
|
using Dlhis.Basic.Summary.Services;
|
||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
@@ -18,32 +19,12 @@ public class SummariesController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 考勤首页
|
/// 首页
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("attendance-summary")]
|
[HttpGet("home-summary")]
|
||||||
public async Task<AttendanceSummaryResponse> GetKaoQingSummary()
|
public async Task<HomeSummaryResponse> GetHomeSummaryAsync(DeviceTypeEnumType type)
|
||||||
{
|
{
|
||||||
return await _summaryService.GetAttendanceSummaryAsync();
|
return await _summaryService.GetHomeSummaryAsync(type);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 门禁首页设备数据
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("door-summary")]
|
|
||||||
public async Task<DoorHomeDataResponse> GetDoorHomeDataAsync()
|
|
||||||
{
|
|
||||||
return await _summaryService.GetDoorHomeDataAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 门禁首页数据
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("door-data")]
|
|
||||||
public async Task<DoorDataResponse> GetDoorDataAsync()
|
|
||||||
{
|
|
||||||
return await _summaryService.GetDoorDataAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace Dlhis.Basic.Summary.Response
|
|
||||||
{
|
|
||||||
public class AttendanceSummaryResponse
|
|
||||||
{
|
|
||||||
public AttendanceDeviceSummary DeviceSummary { get; set; }
|
|
||||||
|
|
||||||
public AttendanceDetailSummary AttendanceDetailSummary { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Dlhis.Basic.Summary.Response;
|
namespace Dlhis.Basic.Summary.Response;
|
||||||
|
|
||||||
public class AttendanceDeviceSummary
|
public class DeviceSummary
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 总数
|
/// 总数
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
namespace Dlhis.Basic.Summary.Response;
|
|
||||||
|
|
||||||
public class DoorDataResponse
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 门禁总人数
|
|
||||||
/// </summary>
|
|
||||||
public int Total => Employed + Unemployed;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在职人数
|
|
||||||
/// </summary>
|
|
||||||
public int Employed { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 非在职人数
|
|
||||||
/// </summary>
|
|
||||||
public int Unemployed { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 人员趋势 7天
|
|
||||||
/// </summary>
|
|
||||||
public GainfoTrendResponse GainfoTrend { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using Dlhis.Basic.Summary.Dto;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Summary.Response
|
|
||||||
{
|
|
||||||
public class DoorHomeDataResponse
|
|
||||||
{
|
|
||||||
public int OffNum { get; set; }
|
|
||||||
public int TotalNum { get; set; }
|
|
||||||
public List<TrendDto> Trend { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace Dlhis.Basic.Summary.Response;
|
namespace Dlhis.Basic.Summary.Response;
|
||||||
|
|
||||||
public class AttendanceDetailSummary
|
public class GainfoDetailSummary
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 考勤总人数
|
/// 考勤总人数
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using Dlhis.Basic.Summary.Dto;
|
using Dlhis.Basic.Summary.Dto;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Summary.Response
|
namespace Dlhis.Basic.Summary.Response;
|
||||||
|
|
||||||
|
public class GainfoTrendResponse
|
||||||
{
|
{
|
||||||
public class GainfoTrendResponse
|
|
||||||
{
|
|
||||||
public List<TrendDto> EmployedTrend { get; set; }
|
public List<TrendDto> EmployedTrend { get; set; }
|
||||||
public List<TrendDto> UnemployedTrend { get; set; }
|
public List<TrendDto> UnemployedTrend { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
14
Src/Dlhis.Basic/Summary/Response/HomeSummaryResponse.cs
Normal file
14
Src/Dlhis.Basic/Summary/Response/HomeSummaryResponse.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Dlhis.Basic.Summary.Response;
|
||||||
|
|
||||||
|
public class HomeSummaryResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 设备
|
||||||
|
/// </summary>
|
||||||
|
public DeviceSummary DeviceSummary { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 明细
|
||||||
|
/// </summary>
|
||||||
|
public GainfoDetailSummary DetailSummary { get; set; }
|
||||||
|
}
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
using Dlhis.Basic.Summary.Response;
|
using Dlhis.Basic.Summary.Response;
|
||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Summary.Services;
|
namespace Dlhis.Basic.Summary.Services;
|
||||||
|
|
||||||
public interface ISummaryService : IScopeDependency
|
public interface ISummaryService : IScopeDependency
|
||||||
{
|
{
|
||||||
Task<AttendanceSummaryResponse> GetAttendanceSummaryAsync();
|
Task<HomeSummaryResponse> GetHomeSummaryAsync(DeviceTypeEnumType type);
|
||||||
|
|
||||||
Task<DoorHomeDataResponse> GetDoorHomeDataAsync();
|
|
||||||
|
|
||||||
Task<DoorDataResponse> GetDoorDataAsync();
|
|
||||||
}
|
}
|
||||||
@@ -23,7 +23,7 @@ public class SummaryService : ISummaryService
|
|||||||
_currentUser = currentUser;
|
_currentUser = currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AttendanceSummaryResponse> GetAttendanceSummaryAsync()
|
public async Task<HomeSummaryResponse> GetHomeSummaryAsync(DeviceTypeEnumType type)
|
||||||
{
|
{
|
||||||
var now = DateTime.Now;
|
var now = DateTime.Now;
|
||||||
var tenantId = _currentUser.GetStringTenantId();
|
var tenantId = _currentUser.GetStringTenantId();
|
||||||
@@ -33,7 +33,7 @@ public class SummaryService : ISummaryService
|
|||||||
var before7Day = DateTime.Today.AddDays(-6);
|
var before7Day = DateTime.Today.AddDays(-6);
|
||||||
|
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>()
|
var devices = await _dbContext.Queryable<DeviceEntity>()
|
||||||
.Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance))
|
.Where(x => x.Type == type)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
|
var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
|
||||||
@@ -54,9 +54,9 @@ public class SummaryService : ISummaryService
|
|||||||
.Where(x => x.Factory == tenantId)
|
.Where(x => x.Factory == tenantId)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
return new AttendanceSummaryResponse
|
return new HomeSummaryResponse
|
||||||
{
|
{
|
||||||
DeviceSummary = new AttendanceDeviceSummary
|
DeviceSummary = new DeviceSummary
|
||||||
{
|
{
|
||||||
Total = devices.Count,
|
Total = devices.Count,
|
||||||
EnableCount = devices.Count(x => x.Enable),
|
EnableCount = devices.Count(x => x.Enable),
|
||||||
@@ -73,7 +73,7 @@ public class SummaryService : ISummaryService
|
|||||||
.GroupBy(x => x.CreateTime.Date)
|
.GroupBy(x => x.CreateTime.Date)
|
||||||
.Select(x => new TrendDto { Date = x.Key, Count = x.Count() }), before30Day, currentDay)
|
.Select(x => new TrendDto { Date = x.Key, Count = x.Count() }), before30Day, currentDay)
|
||||||
},
|
},
|
||||||
AttendanceDetailSummary = new AttendanceDetailSummary
|
DetailSummary = new GainfoDetailSummary
|
||||||
{
|
{
|
||||||
Employed = workingGainfos.Count,
|
Employed = workingGainfos.Count,
|
||||||
Unemployed = leaveGainfos.Count,
|
Unemployed = leaveGainfos.Count,
|
||||||
@@ -90,64 +90,7 @@ public class SummaryService : ISummaryService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DoorHomeDataResponse> GetDoorHomeDataAsync()
|
//********************************************************************************************************************************************
|
||||||
{
|
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Door).ToListAsync();
|
|
||||||
|
|
||||||
var offDevices = await GetOfflineDevicesCount(devices);
|
|
||||||
|
|
||||||
DateTime currentDate = DateTime.Now;
|
|
||||||
var times = new List<string>();
|
|
||||||
for (int i = 0; i < 30; i++)
|
|
||||||
{
|
|
||||||
DateTime date = currentDate.AddDays(-i);
|
|
||||||
string dateString = date.ToString("yyyy-MM-dd");
|
|
||||||
times.Add(dateString);
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = new List<TrendDto>();
|
|
||||||
times.ForEach(time =>
|
|
||||||
{
|
|
||||||
var count = devices.Count(x => x.CreateTime.ToString("yyyy-MM-dd") == time);
|
|
||||||
var trend = new TrendDto
|
|
||||||
{
|
|
||||||
Date = DateTime.ParseExact(time, "yyyy-MM-dd", null),
|
|
||||||
Count = count,
|
|
||||||
};
|
|
||||||
list.Add(trend);
|
|
||||||
});
|
|
||||||
var res = new DoorHomeDataResponse
|
|
||||||
{
|
|
||||||
OffNum = offDevices.Count,
|
|
||||||
TotalNum = devices.Count,
|
|
||||||
Trend = list
|
|
||||||
};
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<DoorDataResponse> GetDoorDataAsync()
|
|
||||||
{
|
|
||||||
var workingGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).ToListAsync();
|
|
||||||
var leaveGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Leave).ToListAsync();
|
|
||||||
|
|
||||||
var currentDay = DateTime.Today.AddDays(1).AddSeconds(-1);
|
|
||||||
var before7Day = DateTime.Today.AddDays(-6);
|
|
||||||
|
|
||||||
return new DoorDataResponse
|
|
||||||
{
|
|
||||||
Employed = workingGainfos.Count,
|
|
||||||
Unemployed = leaveGainfos.Count,
|
|
||||||
GainfoTrend = new GainfoTrendResponse()
|
|
||||||
{
|
|
||||||
EmployedTrend = FixTrend(workingGainfos.Where(x => x.EntryDate >= before7Day && x.EntryDate <= currentDay)
|
|
||||||
.GroupBy(x => x.EntryDate)
|
|
||||||
.Select(x => new TrendDto { Date = x.Key!.Value, Count = x.Count() }), before7Day, currentDay),
|
|
||||||
UnemployedTrend = FixTrend(leaveGainfos.Where(x => x.ResignationDate >= before7Day && x.ResignationDate <= currentDay)
|
|
||||||
.GroupBy(x => x.ResignationDate)
|
|
||||||
.Select(x => new TrendDto { Date = x.Key!.Value, Count = x.Count() }), before7Day, currentDay)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static List<TrendDto> FixTrend(IEnumerable<TrendDto> dtos, DateTime start, DateTime end)
|
private static List<TrendDto> FixTrend(IEnumerable<TrendDto> dtos, DateTime start, DateTime end)
|
||||||
@@ -173,48 +116,4 @@ public class SummaryService : ISummaryService
|
|||||||
|
|
||||||
return result.OrderBy(x => x.Date).ToList();
|
return result.OrderBy(x => x.Date).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取离线设备
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task<List<DeviceEntity>> GetOfflineDevicesCount(List<DeviceEntity> devices)
|
|
||||||
{
|
|
||||||
var now = DateTime.Now;
|
|
||||||
|
|
||||||
var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
|
|
||||||
|
|
||||||
var deviceRegistries = await _dbContext.Queryable<DeviceRegistryEntity>()
|
|
||||||
.LeftJoin<DeviceEntity>((x, d) => x.DeviceUniqueNo == d.UniqueNo)
|
|
||||||
.Where(x => deviceUniqueNos.Contains(x.DeviceUniqueNo))
|
|
||||||
.Select((x, d) => new
|
|
||||||
{
|
|
||||||
UniqueNo = d.UniqueNo,
|
|
||||||
d.HeartbeatInterval,
|
|
||||||
x.LastHeartbeatTime
|
|
||||||
})
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
var onlineDevices = deviceRegistries
|
|
||||||
.Where(x =>
|
|
||||||
{
|
|
||||||
if (x.HeartbeatInterval <= 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval) >= now;
|
|
||||||
})
|
|
||||||
.Select(x => new
|
|
||||||
{
|
|
||||||
UniqueNo = x.UniqueNo,
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
var onlineUniqueNos = new List<string>();
|
|
||||||
onlineDevices.ForEach(x => onlineUniqueNos.Add(x.UniqueNo));
|
|
||||||
|
|
||||||
var offUniqueNos = deviceUniqueNos.Except(onlineUniqueNos).ToList();
|
|
||||||
var list = devices.Where(x => offUniqueNos.Contains(x.UniqueNo)).ToList();
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ public class MealSupplementRecordService : IMealSupplementRecordService
|
|||||||
.Where(x => x.Status == BalanceRecordStatusEnumType.Valid)
|
.Where(x => x.Status == BalanceRecordStatusEnumType.Valid)
|
||||||
.Where(x => x.ApplicationType == CanteenApplicationTypeEnumType.MealSupplement)
|
.Where(x => x.ApplicationType == CanteenApplicationTypeEnumType.MealSupplement)
|
||||||
.Where(x => x.UserCode == code)
|
.Where(x => x.UserCode == code)
|
||||||
.OrderBy(x => x.CostDateTime, OrderByType.Desc)
|
.OrderBy(x => x.CostDateTime)
|
||||||
.Select(x => new MealSupplementRecordItemResponse
|
.Select(x => new MealSupplementRecordItemResponse
|
||||||
{
|
{
|
||||||
CurrentAmount = x.Amount,
|
CurrentAmount = x.Amount,
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ public class BalanceService : IBalanceService
|
|||||||
.WhereIF(request.SearchDateTimePeriod?.End.HasValue == true, record => record.CostDate <= request.SearchDateTimePeriod.End)
|
.WhereIF(request.SearchDateTimePeriod?.End.HasValue == true, record => record.CostDate <= request.SearchDateTimePeriod.End)
|
||||||
.WhereIF(request.ApplicationType.HasValue, record => record.ApplicationType == request.ApplicationType)
|
.WhereIF(request.ApplicationType.HasValue, record => record.ApplicationType == request.ApplicationType)
|
||||||
.Where((record, ga) => ga.Code == jinkoCode)
|
.Where((record, ga) => ga.Code == jinkoCode)
|
||||||
.OrderBy(record => record.CreateTime, OrderByType.Desc)
|
.OrderBy(record => record.CostDateTime)
|
||||||
.Select((record, ga, department, bPlace) => new BalanceRecordUserPageResponse
|
.Select((record, ga, department, bPlace) => new BalanceRecordUserPageResponse
|
||||||
{
|
{
|
||||||
Id = record.Id,
|
Id = record.Id,
|
||||||
@@ -523,20 +523,21 @@ public class BalanceService : IBalanceService
|
|||||||
await _dbContext.InsertAsync(gainfoMeal);
|
await _dbContext.InsertAsync(gainfoMeal);
|
||||||
}
|
}
|
||||||
|
|
||||||
var businessPlace = await _dbContext.Queryable<BusinessPlaceEntity>()
|
var businessPlaceInfo = await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||||
.LeftJoin<BusinessPlaceShiftRelationshipEntity>((a, b) => a.Code == b.PlaceCode)
|
.LeftJoin<BusinessPlaceShiftRelationshipEntity>((a, b) => a.Code == b.PlaceCode)
|
||||||
.LeftJoin<BusinessShiftEntity>((a, b, c) => b.ShiftCode == c.Code)
|
.LeftJoin<BusinessShiftEntity>((a, b, c) => b.ShiftCode == c.Code)
|
||||||
.Where((a, b, c) => a.CustomCode == request.BusinessPlaceCode)
|
.Where((a, b, c) => a.CustomCode == request.BusinessPlaceCode)
|
||||||
.Select((a, b, c) => new
|
.Select((a, b, c) => new
|
||||||
{
|
{
|
||||||
a.Code,
|
a.Code,
|
||||||
ShiftCode = c.Code
|
ShiftCode = c.Code,
|
||||||
|
a.TenantId
|
||||||
})
|
})
|
||||||
.SingleAsync();
|
.SingleAsync();
|
||||||
|
|
||||||
if (request.Type == BalanceRecordTypeEnumType.Out)
|
if (request.Type == BalanceRecordTypeEnumType.Out)
|
||||||
{
|
{
|
||||||
businessPlace.ThrowIfNull($"营业点{request.BusinessPlaceCode}不存在");
|
businessPlaceInfo.ThrowIfNull($"营业点{request.BusinessPlaceCode}不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
await _dbContext.InsertAsync(new BalanceRecordEntity
|
await _dbContext.InsertAsync(new BalanceRecordEntity
|
||||||
@@ -544,8 +545,8 @@ public class BalanceService : IBalanceService
|
|||||||
Amount = request.Amount,
|
Amount = request.Amount,
|
||||||
ApplicationType = request.ApplicationType,
|
ApplicationType = request.ApplicationType,
|
||||||
Type = request.Type,
|
Type = request.Type,
|
||||||
BusinessPlaceCode = businessPlace?.Code,
|
BusinessPlaceCode = businessPlaceInfo?.Code,
|
||||||
BusinessShiftCode = businessPlace?.ShiftCode,
|
BusinessShiftCode = businessPlaceInfo?.ShiftCode,
|
||||||
ShiftType = request.ShiftType,
|
ShiftType = request.ShiftType,
|
||||||
CostDate = request.CostDate,
|
CostDate = request.CostDate,
|
||||||
CostDateTime = request.CostDateTime,
|
CostDateTime = request.CostDateTime,
|
||||||
@@ -557,7 +558,7 @@ public class BalanceService : IBalanceService
|
|||||||
Remark = request.Remark,
|
Remark = request.Remark,
|
||||||
CostId = gainfo.CostId,
|
CostId = gainfo.CostId,
|
||||||
SubsidiesFromMonth = request.CostDate.ToString("yyyyMM"),
|
SubsidiesFromMonth = request.CostDate.ToString("yyyyMM"),
|
||||||
TenantId = request.Factory,
|
TenantId = businessPlaceInfo?.TenantId ?? request.Factory,
|
||||||
OriginTenantId = gainfo.Factory,
|
OriginTenantId = gainfo.Factory,
|
||||||
Werks = gainfo.Werks,
|
Werks = gainfo.Werks,
|
||||||
Name = gainfo.Name,
|
Name = gainfo.Name,
|
||||||
@@ -621,7 +622,7 @@ public class BalanceService : IBalanceService
|
|||||||
.Where(x => x.Code == request.UserCode)
|
.Where(x => x.Code == request.UserCode)
|
||||||
.SingleAsync();
|
.SingleAsync();
|
||||||
|
|
||||||
(gainfo == null).ThrowIfTrue($"工号{request.UserCode}不存在");
|
gainfo.ThrowIfNull($"工号{request.UserCode}不存在");
|
||||||
|
|
||||||
await _dbContext.InsertAsync(new BalanceRecordEntity
|
await _dbContext.InsertAsync(new BalanceRecordEntity
|
||||||
{
|
{
|
||||||
|
|||||||
8
Src/Dlhis.DataPermission.Model/DeviceCodeAttribute.cs
Normal file
8
Src/Dlhis.DataPermission.Model/DeviceCodeAttribute.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Attributes;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.DataPermissions;
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class DeviceCodeAttribute : BaseDataPermissionAttribute
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Attributes;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.DataPermissions;
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class DeviceGroupCodeAttribute : BaseDataPermissionAttribute
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Kurisu.AspNetCore" Version="0.9.20" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dlhis.Entity.Device.Enums;
|
using Dlhis.Basic.DataPermissions;
|
||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
using Kurisu.AspNetCore.DataAccess.Entity;
|
using Kurisu.AspNetCore.DataAccess.Entity;
|
||||||
using Kurisu.AspNetCore.DataAccess.SqlSugar;
|
using Kurisu.AspNetCore.DataAccess.SqlSugar;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
@@ -16,6 +17,7 @@ namespace Dlhis.Entity.Basic.Entity
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备code
|
/// 设备code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[DeviceCode]
|
||||||
[SugarColumn(ColumnDescription = "设备code")]
|
[SugarColumn(ColumnDescription = "设备code")]
|
||||||
public Guid Code { get; set; }
|
public Guid Code { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,11 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Kurisu.AspNetCore" Version="0.9.20" />
|
<ProjectReference Include="..\Dlhis.DataPermission.Model\Dlhis.DataPermission.Model.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Kurisu.AspNetCore" Version="0.9.22" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
17
Src/Dlhis.Entity/Sys/Entities/DataPermissionEntity.cs
Normal file
17
Src/Dlhis.Entity/Sys/Entities/DataPermissionEntity.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using Dlhis.Entity.Sys.Enums;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar;
|
||||||
|
using SqlSugar;
|
||||||
|
|
||||||
|
namespace Dlhis.Entity.Sys.Entities;
|
||||||
|
|
||||||
|
[SugarTable(TableName = "DataPermissions")]
|
||||||
|
public class DataPermissionEntity : SugarBaseEntity
|
||||||
|
{
|
||||||
|
public AssignTypeEnumType AssignType { get; set; }
|
||||||
|
|
||||||
|
public string AssignValue { get; set; }
|
||||||
|
|
||||||
|
public DeviceAssignmentTypeEnumType UniqueType { get; set; }
|
||||||
|
|
||||||
|
public Guid UniqueValue { get; set; }
|
||||||
|
}
|
||||||
71
Src/Dlhis.Entity/Visitor/Entity/BusinessTripEntity.cs
Normal file
71
Src/Dlhis.Entity/Visitor/Entity/BusinessTripEntity.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar;
|
||||||
|
using SqlSugar;
|
||||||
|
|
||||||
|
namespace Dlhis.Entity.Visitor.Entity;
|
||||||
|
|
||||||
|
[SugarTable(TableName = "BusinessTrip")]
|
||||||
|
public class BusinessTripEntity : SugarBaseEntity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 工号
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = false, UniqueGroupNameList = new[] { "unique_BusinessTrip_code_begin_end" })]
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 姓名
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始日期
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = false, UniqueGroupNameList = new[] { "unique_BusinessTrip_code_begin_end" })]
|
||||||
|
public string BeginDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束日期
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = false, UniqueGroupNameList = new[] { "unique_BusinessTrip_code_begin_end" })]
|
||||||
|
public string EndDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime BeginDateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime EndDateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差类型
|
||||||
|
/// </summary>
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差类型描述
|
||||||
|
/// </summary>
|
||||||
|
public string TypeDesc { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差时数
|
||||||
|
/// </summary>
|
||||||
|
public int Hour { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差天数
|
||||||
|
/// </summary>
|
||||||
|
public double Day { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差目的地
|
||||||
|
/// </summary>
|
||||||
|
public string Destination { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差目的地描述
|
||||||
|
/// </summary>
|
||||||
|
public string DestinationDesc { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Dlhis.ScheduledTask.Common.Response;
|
||||||
|
|
||||||
|
public class SapBusinessTripInfoResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 明细数据
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OT_2002")]
|
||||||
|
public List<SapBusinessTripInfoItem> Items { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SapBusinessTripInfoItem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 工号
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_GONGH")]
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 姓名
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_ENAME")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始日期
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_BEGDA")]
|
||||||
|
public string BeginDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束日期
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_ENDDA")]
|
||||||
|
public string EndDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始时间
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_BEGUZ")]
|
||||||
|
public DateTime BeginDateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束时间
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_ENDUZ")]
|
||||||
|
public DateTime EndDateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差类型
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_AWART")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差类型描述
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_ATEXT")]
|
||||||
|
public string TypeDesc { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差时数
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_STDAZ")]
|
||||||
|
public int Hour { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差天数
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_ABWTG")]
|
||||||
|
public double Day { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差目的地
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_CCMDD")]
|
||||||
|
public string Destination { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出差目的地描述
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty("OV_CCMDDM")]
|
||||||
|
public string DestinationDesc { get; set; }
|
||||||
|
}
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Dlhis.ScheduledTask.Common.Response
|
|
||||||
{
|
|
||||||
public class SapTravelInfoResponse
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 明细数据
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OT_2002")]
|
|
||||||
public List<SapTravelInfoItem> Items { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SapTravelInfoItem
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 工号
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_GONGH")]
|
|
||||||
public string Code { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 姓名
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_ENAME")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开始日期
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_BEGDA")]
|
|
||||||
public string BeginDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 结束日期
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_ENDDA")]
|
|
||||||
public string EndDate { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开始时间
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_BEGUZ")]
|
|
||||||
public DateTime BeginDateTime { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 结束时间
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_ENDUZ")]
|
|
||||||
public DateTime EndDateTime { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 出差类型
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_AWART")]
|
|
||||||
public string Type { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 出差类型描述
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_ATEXT")]
|
|
||||||
public string TypeDesc { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 出差时数
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_STDAZ")]
|
|
||||||
public int Hour { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 出差天数
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_ABWTG")]
|
|
||||||
public double Day { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 出差目的地
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_CCMDD")]
|
|
||||||
public string Destination { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 出差目的地描述
|
|
||||||
/// </summary>
|
|
||||||
[JsonProperty("OV_CCMDDM")]
|
|
||||||
public string DestinationDesc { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,5 +9,15 @@ public interface IJinkoJIPService : ISingletonDependency
|
|||||||
|
|
||||||
Task<string> SyncMealSupplementRecordsAsync(List<SyncMealSupplementRecordRequest> requests);
|
Task<string> SyncMealSupplementRecordsAsync(List<SyncMealSupplementRecordRequest> requests);
|
||||||
|
|
||||||
public string IssueToken();
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取出差信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="begin"></param>
|
||||||
|
/// <param name="end"></param>
|
||||||
|
/// <param name="departmentNo"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<SapBusinessTripInfoResponse> GetTravelInfosAsync(DateTime begin, DateTime end, string departmentNo);
|
||||||
|
|
||||||
|
string IssueToken();
|
||||||
}
|
}
|
||||||
@@ -11,12 +11,4 @@ public interface IJinkoSapService : IScopeDependency
|
|||||||
Task<SapPersonResponse> GetPersonsByWerkAsync(string werk);
|
Task<SapPersonResponse> GetPersonsByWerkAsync(string werk);
|
||||||
|
|
||||||
Task<SapPersonResponse> GetPersonsByCodeAsync(string code);
|
Task<SapPersonResponse> GetPersonsByCodeAsync(string code);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取出差信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="begin"></param>
|
|
||||||
/// <param name="end"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<SapTravelInfoResponse> GetTravelInfosAsync(DateTime begin, DateTime end);
|
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ using System.Security.Claims;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Dlhis.ScheduledTask.Common.Request;
|
using Dlhis.ScheduledTask.Common.Request;
|
||||||
using Dlhis.ScheduledTask.Common.Response;
|
using Dlhis.ScheduledTask.Common.Response;
|
||||||
using Dlhis.ScheduledTask.Common.Services;
|
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
@@ -85,6 +84,7 @@ public class JinkoJIPService : IJinkoJIPService
|
|||||||
{
|
{
|
||||||
true.ThrowIfTrue(exp.Value<string>());
|
true.ThrowIfTrue(exp.Value<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jobj.TryGetValue("message", out var message) && !jobj.ContainsKey("code"))
|
if (jobj.TryGetValue("message", out var message) && !jobj.ContainsKey("code"))
|
||||||
{
|
{
|
||||||
true.ThrowIfTrue(message.Value<string>());
|
true.ThrowIfTrue(message.Value<string>());
|
||||||
@@ -95,6 +95,39 @@ public class JinkoJIPService : IJinkoJIPService
|
|||||||
return responseJson;
|
return responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<SapBusinessTripInfoResponse> GetTravelInfosAsync(DateTime begin, DateTime end, string departmentNo)
|
||||||
|
{
|
||||||
|
const string apiUrl = "/JIP/HCM/HCM_TRAVELINFO";
|
||||||
|
|
||||||
|
var beginDay = begin.ToString("yyyyMMdd");
|
||||||
|
var endDay = end.ToString("yyyyMMdd");
|
||||||
|
|
||||||
|
var obj = new
|
||||||
|
{
|
||||||
|
IV_BEGDA = beginDay,
|
||||||
|
IV_ENDDA = endDay,
|
||||||
|
IT_2002GH = new List<object>
|
||||||
|
{
|
||||||
|
new
|
||||||
|
{
|
||||||
|
//IV_GONGH = "" 工号,
|
||||||
|
IV_ORGID = departmentNo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var body = obj.ToJson();
|
||||||
|
|
||||||
|
var content = new StringContent(body, Encoding.UTF8, "application/json");
|
||||||
|
var response = await GetHttpClient().PostAsync(apiUrl, content);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
var jsonResponse = await response.Content.ReadAsStringAsync();
|
||||||
|
return jsonResponse.ToObject<SapBusinessTripInfoResponse>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public string IssueToken()
|
public string IssueToken()
|
||||||
{
|
{
|
||||||
var jwtKey = _configuration.GetSection("JinkoOptions:Jip:Key").Value;
|
var jwtKey = _configuration.GetSection("JinkoOptions:Jip:Key").Value;
|
||||||
@@ -106,9 +139,9 @@ public class JinkoJIPService : IJinkoJIPService
|
|||||||
|
|
||||||
var claims = new List<Claim>
|
var claims = new List<Claim>
|
||||||
{
|
{
|
||||||
new (JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(now).ToUnixTimeSeconds()}"),
|
new(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(now).ToUnixTimeSeconds()}"),
|
||||||
new (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(expires).ToUnixTimeSeconds()}"),
|
new(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(expires).ToUnixTimeSeconds()}"),
|
||||||
new (JwtRegisteredClaimNames.Iss,jwtKey),
|
new(JwtRegisteredClaimNames.Iss, jwtKey),
|
||||||
};
|
};
|
||||||
|
|
||||||
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret));
|
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret));
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using Dlhis.Entity.Basic.Entity;
|
|||||||
using Dlhis.ScheduledTask.Common.Dto;
|
using Dlhis.ScheduledTask.Common.Dto;
|
||||||
using Dlhis.ScheduledTask.Common.Response;
|
using Dlhis.ScheduledTask.Common.Response;
|
||||||
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dlhis.ScheduledTask.Common.Services.Implements;
|
namespace Dlhis.ScheduledTask.Common.Services.Implements;
|
||||||
@@ -153,7 +152,7 @@ public class JinkoSapService : IJinkoSapService
|
|||||||
persons.AddRange(personResp.Person.Items);
|
persons.AddRange(personResp.Person.Items);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SapPersonResponse()
|
return new SapPersonResponse
|
||||||
{
|
{
|
||||||
Person = new SapPerson<SapPersonItem>
|
Person = new SapPerson<SapPersonItem>
|
||||||
{
|
{
|
||||||
@@ -161,29 +160,4 @@ public class JinkoSapService : IJinkoSapService
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<SapTravelInfoResponse> GetTravelInfosAsync(DateTime begin, DateTime end)
|
|
||||||
{
|
|
||||||
const string apiUrl = "/JIP/HCM/HCM_TRAVELINFO";
|
|
||||||
|
|
||||||
var beginDay = begin.ToString("yyyyMMdd");
|
|
||||||
var endDay = end.ToString("yyyyMMdd");
|
|
||||||
|
|
||||||
var obj = new
|
|
||||||
{
|
|
||||||
IV_BEGDA = beginDay,
|
|
||||||
IV_ENDDA = endDay
|
|
||||||
};
|
|
||||||
|
|
||||||
var body = obj.ToJson();
|
|
||||||
|
|
||||||
var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
|
|
||||||
var response = await GetHttpClient().PostAsync(apiUrl, content);
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
|
|
||||||
var jsonResponse = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
return JsonConvert.DeserializeObject<SapTravelInfoResponse>(jsonResponse);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,43 +1,43 @@
|
|||||||
using System.Net;
|
// using System.Net;
|
||||||
using System.Net.Sockets;
|
// using System.Net.Sockets;
|
||||||
using Dlhis.Entity.Basic.Entity;
|
// using Dlhis.Entity.Basic.Entity;
|
||||||
using Dlhis.Entity.Device.Entities;
|
// using Dlhis.Entity.Device.Entities;
|
||||||
using Dlhis.ScheduledTask.Attributes;
|
// using Dlhis.ScheduledTask.Attributes;
|
||||||
using Kurisu.AspNetCore.CustomClass;
|
// using Kurisu.AspNetCore.CustomClass;
|
||||||
using Newtonsoft.Json;
|
// using Newtonsoft.Json;
|
||||||
|
//
|
||||||
namespace Dlhis.ScheduledTask.Jobs;
|
// namespace Dlhis.ScheduledTask.Jobs;
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 设备心跳
|
// /// 设备心跳
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
[RecurringJob(nameof(HeartbeatJob), "0/30 * * * * ?", Name = "设备心跳")]
|
// [RecurringJob(nameof(HeartbeatJob), "0/30 * * * * ?", Name = "设备心跳")]
|
||||||
public class HeartbeatJob : BaseJob
|
// public class HeartbeatJob : BaseJob
|
||||||
{
|
// {
|
||||||
public HeartbeatJob(IServiceProvider serviceProvider) : base(serviceProvider)
|
// public HeartbeatJob(IServiceProvider serviceProvider) : base(serviceProvider)
|
||||||
{
|
// {
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override async Task RunAsync(IServiceProvider serviceProvider)
|
// protected override async Task RunAsync(IServiceProvider serviceProvider)
|
||||||
{
|
// {
|
||||||
var devices = await DbContext.Queryable<DeviceEntity>().Where(x => x.Enable).Where(x => x.HeartbeatInterval > 0).ToListAsync();
|
// var devices = await DbContext.Queryable<DeviceEntity>().Where(x => x.Enable).Where(x => x.HeartbeatInterval > 0).ToListAsync();
|
||||||
|
//
|
||||||
await Parallel.ForEachAsync(devices, async (device, cancellationToken) =>
|
// await Parallel.ForEachAsync(devices, async (device, cancellationToken) =>
|
||||||
{
|
// {
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
var ipInfo = JsonConvert.DeserializeObject<IPPortDto>(device.ConnectionInfo);
|
// var ipInfo = JsonConvert.DeserializeObject<IPPortDto>(device.ConnectionInfo);
|
||||||
await new TcpClient().ConnectAsync(IPAddress.Parse(ipInfo.IP), ipInfo.Port, cancellationToken);
|
// await new TcpClient().ConnectAsync(IPAddress.Parse(ipInfo.IP), ipInfo.Port, cancellationToken);
|
||||||
|
//
|
||||||
await DbContext.Updateable<DeviceRegistryEntity>()
|
// await DbContext.Updateable<DeviceRegistryEntity>()
|
||||||
.SetColumns(x => x.LastHeartbeatTime == DateTime.Now)
|
// .SetColumns(x => x.LastHeartbeatTime == DateTime.Now)
|
||||||
.Where(x => x.DeviceUniqueNo == device.UniqueNo)
|
// .Where(x => x.DeviceUniqueNo == device.UniqueNo)
|
||||||
.ExecuteCommandAsync(cancellationToken);
|
// .ExecuteCommandAsync(cancellationToken);
|
||||||
}
|
// }
|
||||||
catch (Exception)
|
// catch (Exception)
|
||||||
{
|
// {
|
||||||
//ignore
|
// //ignore
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
63
Src/Dlhis.ScheduledTask/Jobs/SyncBusinessTripJob.cs
Normal file
63
Src/Dlhis.ScheduledTask/Jobs/SyncBusinessTripJob.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using Dlhis.Entity.Basic.Entity;
|
||||||
|
using Dlhis.Entity.Visitor.Entity;
|
||||||
|
using Dlhis.ScheduledTask.Attributes;
|
||||||
|
using Dlhis.ScheduledTask.Common.Services;
|
||||||
|
using Mapster;
|
||||||
|
|
||||||
|
namespace Dlhis.ScheduledTask.Jobs;
|
||||||
|
|
||||||
|
[RecurringJob(nameof(SyncBusinessTripJob), "0 0 0/1 * * ? ", Name = "SAP同步出差信息")]
|
||||||
|
public class SyncBusinessTripJob : BaseJob
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public SyncBusinessTripJob(IServiceProvider serviceProvider) : base(serviceProvider)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override async Task RunAsync(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
var jipService = serviceProvider.GetService<IJinkoJIPService>();
|
||||||
|
var today = DateTime.Today;
|
||||||
|
|
||||||
|
var departments = await DbContext.Queryable<DepartmentEntity>().ToListAsync();
|
||||||
|
var tops = departments.Where(x => x.PNo == "00001000").ToList();
|
||||||
|
var validDepartments = tops.ToList();
|
||||||
|
tops.ForEach(x => RecursionGetNext(x, departments, validDepartments));
|
||||||
|
|
||||||
|
foreach (var department in validDepartments)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var tripResponse = await jipService.GetTravelInfosAsync(today, today, department.No);
|
||||||
|
foreach (var tripInfoItem in tripResponse.Items)
|
||||||
|
{
|
||||||
|
if (await DbContext.Queryable<BusinessTripEntity>().Where(x => x.Code == tripInfoItem.Code && x.BeginDate == tripInfoItem.BeginDate && x.EndDate == tripInfoItem.EndDate)
|
||||||
|
.AnyAsync())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var entity = tripInfoItem.Adapt<BusinessTripEntity>();
|
||||||
|
await DbContext.InsertAsync(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.LogError(e, "获取部门{departmentNo}{departmentName}出差数据执行失败:{message}", department.No, department.Name, e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//************************************************************************************************************************************************
|
||||||
|
|
||||||
|
private static void RecursionGetNext(DepartmentEntity current, List<DepartmentEntity> data, List<DepartmentEntity> result)
|
||||||
|
{
|
||||||
|
var next = data.Where(x => x.PNo == current.No).ToList();
|
||||||
|
foreach (var item in next)
|
||||||
|
{
|
||||||
|
result.Add(item);
|
||||||
|
RecursionGetNext(item, data, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,8 @@ public class TaskDto
|
|||||||
public string Brand { get; set; }
|
public string Brand { get; set; }
|
||||||
public string FuncStr { get; set; }
|
public string FuncStr { get; set; }
|
||||||
public string UserNo { get; set; }
|
public string UserNo { get; set; }
|
||||||
|
|
||||||
|
public string OldUserNo { get; set; }
|
||||||
public string UserCode { get; set; }
|
public string UserCode { get; set; }
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
public string DepartmentNo { get; set; }
|
public string DepartmentNo { get; set; }
|
||||||
|
|||||||
@@ -219,6 +219,43 @@ public class AssignmentService : IAssignmentService
|
|||||||
task.ModifiedTime = now;
|
task.ModifiedTime = now;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (await _dbContext.Queryable<OldDeviceGainfoEntity>().Where(x => x.Status != OldDeviceGainfoEnumType.Deleted).AnyAsync())
|
||||||
|
{
|
||||||
|
var dCodes = await _dbContext.Queryable<DeviceTaskEntity>()
|
||||||
|
.LeftJoin<GainfoEntity>((x, ga) => x.UserNo == ga.No)
|
||||||
|
.Where(x => taskIds.Contains(x.Id))
|
||||||
|
.Where(x => x.Status == DeviceTaskStatusEnumType.Process)
|
||||||
|
.Select((x, ga) => new
|
||||||
|
{
|
||||||
|
x.DeviceUniqueNo,
|
||||||
|
ga.Code,
|
||||||
|
ga.No
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var oldDeviceGainfoWhere = LinqExpressionExtensions.False<OldDeviceGainfoEntity>();
|
||||||
|
dCodes.ForEach(item => { oldDeviceGainfoWhere = oldDeviceGainfoWhere.Or(x => x.Code == item.Code && x.DeviceUniqueNo == item.DeviceUniqueNo); });
|
||||||
|
var oldData = await _dbContext.Queryable<OldDeviceGainfoEntity>().Where(x => x.Status == OldDeviceGainfoEnumType.Wait)
|
||||||
|
.Where(oldDeviceGainfoWhere)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
oldData.ForEach(d =>
|
||||||
|
{
|
||||||
|
var task = deviceTasks.FirstOrDefault(x => x.UserNo == d.No && x.DeviceUniqueNo == d.DeviceUniqueNo);
|
||||||
|
if (task != null)
|
||||||
|
{
|
||||||
|
d.Status = task.Status == DeviceTaskStatusEnumType.Success
|
||||||
|
? OldDeviceGainfoEnumType.Deleted
|
||||||
|
: OldDeviceGainfoEnumType.Error;
|
||||||
|
|
||||||
|
d.Remark = task.ResultMessage;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await _dbContext.UpdateAsync(oldData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
await _dbContext.UpdateAsync(deviceTasks);
|
await _dbContext.UpdateAsync(deviceTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,6 +336,22 @@ public class AssignmentService : IAssignmentService
|
|||||||
throw new VersionExceptions("version exceptions");
|
throw new VersionExceptions("version exceptions");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (await _dbContext.Queryable<OldDeviceGainfoEntity>().Where(x => x.Status != OldDeviceGainfoEnumType.Deleted).AnyAsync())
|
||||||
|
{
|
||||||
|
var oldDeviceGainfoWhere = LinqExpressionExtensions.False<OldDeviceGainfoEntity>();
|
||||||
|
page.Data.ForEach(item => { oldDeviceGainfoWhere = oldDeviceGainfoWhere.Or(x => x.Code == item.UserCode && x.DeviceUniqueNo == item.DeviceUniqueNo); });
|
||||||
|
var oldData = await _dbContext.Queryable<OldDeviceGainfoEntity>().Where(x => x.Status == OldDeviceGainfoEnumType.Wait || x.Status == OldDeviceGainfoEnumType.Error)
|
||||||
|
.Where(oldDeviceGainfoWhere)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
page.Data.ForEach(item =>
|
||||||
|
{
|
||||||
|
var o = oldData.FirstOrDefault(x => x.Code == item.UserCode && x.DeviceUniqueNo == item.DeviceUniqueNo);
|
||||||
|
if (o != null)
|
||||||
|
item.OldUserNo = o.No;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return page.Data;
|
return page.Data;
|
||||||
}, 5);
|
}, 5);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Dlhis.Entity.Sys.Enums;
|
||||||
|
using Dlhis.Sys.DataPermission.Request;
|
||||||
|
using Dlhis.Sys.DataPermission.Services;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Dlhis.Sys.DataPermission.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 数据权限
|
||||||
|
/// </summary>
|
||||||
|
[Authorize]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class DataPermissionsController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IDataPermissionService _dataPermissionService;
|
||||||
|
|
||||||
|
public DataPermissionsController(IDataPermissionService dataPermissionService)
|
||||||
|
{
|
||||||
|
_dataPermissionService = dataPermissionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("save")]
|
||||||
|
public async Task SaveAsync(DataPermissionSaveRequest request)
|
||||||
|
{
|
||||||
|
await _dataPermissionService.SaveAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpGet("assignments")]
|
||||||
|
public async Task<List<Guid>> GetAssignmentsAsync(string assignValue, [EnumDataType(typeof(DeviceAssignmentTypeEnumType))] DeviceAssignmentTypeEnumType uniqueType)
|
||||||
|
{
|
||||||
|
return await _dataPermissionService.GetAssignmentsAsync(assignValue, uniqueType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Dlhis.Entity.Sys.Enums;
|
||||||
|
|
||||||
|
namespace Dlhis.Sys.DataPermission.Request;
|
||||||
|
|
||||||
|
public class DataPermissionSaveRequest : IValidatableObject
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string AssignValue { get; set; }
|
||||||
|
|
||||||
|
[EnumDataType(typeof(DeviceAssignmentTypeEnumType))]
|
||||||
|
public DeviceAssignmentTypeEnumType UniqueType { get; set; }
|
||||||
|
|
||||||
|
public List<Guid> Codes { get; set; } = new();
|
||||||
|
|
||||||
|
|
||||||
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
if (UniqueType == DeviceAssignmentTypeEnumType.BusinessPlace)
|
||||||
|
{
|
||||||
|
yield return new ValidationResult("不支持营业点分配", new[] { nameof(UniqueType) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Dlhis.Entity.Sys.Enums;
|
||||||
|
using Dlhis.Sys.DataPermission.Request;
|
||||||
|
|
||||||
|
namespace Dlhis.Sys.DataPermission.Services;
|
||||||
|
|
||||||
|
public interface IDataPermissionService : IScopeDependency
|
||||||
|
{
|
||||||
|
Task SaveAsync(DataPermissionSaveRequest request);
|
||||||
|
|
||||||
|
Task<List<Guid>> GetAssignmentsAsync(string assignValue, DeviceAssignmentTypeEnumType uniqueType);
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using Dlhis.Entity.Sys.Entities;
|
||||||
|
using Dlhis.Entity.Sys.Enums;
|
||||||
|
using Dlhis.Sys.DataPermission.Request;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Services;
|
||||||
|
|
||||||
|
namespace Dlhis.Sys.DataPermission.Services.Implements;
|
||||||
|
|
||||||
|
public class DataPermissionService : IDataPermissionService
|
||||||
|
{
|
||||||
|
private readonly IDbContext _dbContext;
|
||||||
|
|
||||||
|
public DataPermissionService(IDbContext dbContext)
|
||||||
|
{
|
||||||
|
_dbContext = dbContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task SaveAsync(DataPermissionSaveRequest request)
|
||||||
|
{
|
||||||
|
var data = await _dbContext.Queryable<DataPermissionEntity>()
|
||||||
|
.Where(x => x.AssignValue == request.AssignValue)
|
||||||
|
.Where(x => x.AssignType == AssignTypeEnumType.User)
|
||||||
|
.Where(x => x.UniqueType == request.UniqueType)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
await _dbContext.DeleteReallyAsync(data);
|
||||||
|
|
||||||
|
await _dbContext.InsertAsync(request.Codes.Select(x => new DataPermissionEntity
|
||||||
|
{
|
||||||
|
AssignType = AssignTypeEnumType.User,
|
||||||
|
AssignValue = request.AssignValue,
|
||||||
|
UniqueType = request.UniqueType,
|
||||||
|
UniqueValue = x
|
||||||
|
}).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Guid>> GetAssignmentsAsync(string assignValue, DeviceAssignmentTypeEnumType uniqueType)
|
||||||
|
{
|
||||||
|
return await _dbContext.Queryable<DataPermissionEntity>()
|
||||||
|
.Where(x => x.AssignValue == assignValue)
|
||||||
|
.Where(x => x.AssignType == AssignTypeEnumType.User)
|
||||||
|
.Where(x => x.UniqueType == uniqueType)
|
||||||
|
.Select(x => x.UniqueValue)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Folder Include="DataPermission\Response\" />
|
||||||
<Folder Include="Server\Request\" />
|
<Folder Include="Server\Request\" />
|
||||||
<Folder Include="Server\Response\" />
|
<Folder Include="Server\Response\" />
|
||||||
<Folder Include="Server\Services\Implements\" />
|
<Folder Include="Server\Services\Implements\" />
|
||||||
|
|||||||
Reference in New Issue
Block a user