diff --git a/Src/Dlhis.Basic/Device/Controllers/DevicePermissionsController.cs b/Src/Dlhis.Basic/Device/Controllers/DevicePermissionsController.cs index d0f468c4..d42822b9 100644 --- a/Src/Dlhis.Basic/Device/Controllers/DevicePermissionsController.cs +++ b/Src/Dlhis.Basic/Device/Controllers/DevicePermissionsController.cs @@ -17,10 +17,12 @@ namespace Dlhis.Basic.Device.Controllers; public class DevicePermissionsController : ControllerBase { private readonly IDevicePermissionService _devicePermissionService; + private readonly IDevicePermissionAnalyzeService _devicePermissionAnalyzeService; - public DevicePermissionsController(IDevicePermissionService devicePermissionService) + public DevicePermissionsController(IDevicePermissionService devicePermissionService, IDevicePermissionAnalyzeService devicePermissionAnalyzeService) { _devicePermissionService = devicePermissionService; + _devicePermissionAnalyzeService = devicePermissionAnalyzeService; } /// @@ -67,7 +69,7 @@ public class DevicePermissionsController : ControllerBase [HttpGet("assignments")] public async Task> GetAssignmentsAsync([FromQuery] DeviceGetAssignmentsRequest request) { - return await _devicePermissionService.GetAssignmentsAsync(request); + return await _devicePermissionAnalyzeService.GetAssignmentsAsync(request); } /// @@ -78,7 +80,7 @@ public class DevicePermissionsController : ControllerBase [HttpGet("assignments-unique")] public async Task> GetAssignmentUniqueAsync([FromQuery] DeviceGetAssignmentUniquesRequest request) { - return await _devicePermissionService.GetAssignmentUniqueAsync(request); + return await _devicePermissionAnalyzeService.GetAssignmentUniqueAsync(request); } /// @@ -114,13 +116,4 @@ public class DevicePermissionsController : ControllerBase { return await _devicePermissionService.GetUserDevicePermissionsAsync(code); } - - - [AllowAnonymous] - [HttpGet("test2")] - [IgnoreTenant] - public async Task GetUserDevicePermissions2Async() - { - await _devicePermissionService.GetUserDevicePermissions2Async(); - } } \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Dtos/UserTenantDeviceCodeDto.cs b/Src/Dlhis.Basic/Device/Dtos/UserTenantDeviceCodeDto.cs index 688e5e53..52065902 100644 --- a/Src/Dlhis.Basic/Device/Dtos/UserTenantDeviceCodeDto.cs +++ b/Src/Dlhis.Basic/Device/Dtos/UserTenantDeviceCodeDto.cs @@ -1,4 +1,6 @@ -namespace Dlhis.Basic.Device.Dtos; +using Dlhis.Entity.Sys.Enums; + +namespace Dlhis.Basic.Device.Dtos; public class UserTenantDeviceCodeDto { @@ -12,3 +14,29 @@ public class UserTenantDeviceCodeDto /// public IEnumerable Codes { get; set; } } + +public class TenantAssignTypeDeviceCode +{ + /// + /// 租户 + /// + public string Tenant { get; set; } + + /// + /// 设备权限 + /// + public IEnumerable Codes { get; set; } +} + +public class AssignTypeDeviceCode +{ + /// + /// 分配类型 + /// + public AssignTypeEnumType AssignType { get; set; } + + /// + /// 设备权限 + /// + public IEnumerable Codes { get; set; } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Filters/AssignPermissionLimitAttribute.cs b/Src/Dlhis.Basic/Device/Filters/AssignPermissionLimitAttribute.cs index 348b430c..fa96d0d8 100644 --- a/Src/Dlhis.Basic/Device/Filters/AssignPermissionLimitAttribute.cs +++ b/Src/Dlhis.Basic/Device/Filters/AssignPermissionLimitAttribute.cs @@ -10,22 +10,14 @@ public class AssignPermissionLimitAttribute : Attribute, IAsyncActionFilter { public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { - //10966 55184 var currentUser = context.HttpContext.RequestServices.GetRequiredService(); - var userId = currentUser.GetIntSubjectId(); - if (userId is 10966 or 55184) - { - await next(); - } - else - { - var redisCache = context.HttpContext.RequestServices.GetRequiredService(); + //var userId = currentUser.GetIntSubjectId(); + var redisCache = context.HttpContext.RequestServices.GetRequiredService(); - var currentTenantId = currentUser.GetStringTenantId(); + var currentTenantId = currentUser.GetStringTenantId(); - await using var handler = await redisCache.LockAsync($"permission:generate:{currentTenantId}"); - handler.Acquired.ThrowIfFalse("请勿频繁分配"); - await next(); - } + await using var handler = await redisCache.LockAsync($"permission:generate:{currentTenantId}"); + handler.Acquired.ThrowIfFalse("请勿频繁分配"); + await next(); } } \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/PermissionAnalyzeConstants.cs b/Src/Dlhis.Basic/Device/PermissionAnalyzeConstants.cs new file mode 100644 index 00000000..6f0e1221 --- /dev/null +++ b/Src/Dlhis.Basic/Device/PermissionAnalyzeConstants.cs @@ -0,0 +1,18 @@ +using Dlhis.Entity.Sys.Enums; + +namespace Dlhis.Basic.Device; + +public class PermissionAnalyzeConstants +{ + private const string _verb = "PermissionAnalyze"; + public const string User = nameof(AssignTypeEnumType.User) + _verb; + public const string Group = nameof(AssignTypeEnumType.Group) + _verb; + public const string Department = nameof(AssignTypeEnumType.Department) + _verb; + public const string Tenant = nameof(AssignTypeEnumType.Tenant) + _verb; + + + public static string GetTypeName(AssignTypeEnumType assignTypeEnumType) + { + return assignTypeEnumType + _verb; + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Request/DevicePermissionSaveRequest.cs b/Src/Dlhis.Basic/Device/Request/DevicePermissionSaveRequest.cs index 572f9c30..067b7d5f 100644 --- a/Src/Dlhis.Basic/Device/Request/DevicePermissionSaveRequest.cs +++ b/Src/Dlhis.Basic/Device/Request/DevicePermissionSaveRequest.cs @@ -1,5 +1,7 @@ using System.ComponentModel.DataAnnotations; +using System.Linq.Expressions; using Dlhis.Entity.Device.Enums; +using Dlhis.Entity.Sys.Entities; using Dlhis.Entity.Sys.Enums; using Kurisu.AspNetCore.Utils.Extensions; diff --git a/Src/Dlhis.Basic/Device/Services/IDevicePermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/IDevicePermissionAnalyzeService.cs new file mode 100644 index 00000000..43b4ea4a --- /dev/null +++ b/Src/Dlhis.Basic/Device/Services/IDevicePermissionAnalyzeService.cs @@ -0,0 +1,26 @@ +using Dlhis.Basic.Device.Dtos; +using Dlhis.Basic.Device.Request; +using Dlhis.Basic.Device.Response; +using Dlhis.Basic.Organization.Dto; +using Dlhis.Entity.Sys.Enums; + +namespace Dlhis.Basic.Device.Services; + +/// +/// 权限数据分析 +/// +public interface IDevicePermissionAnalyzeService : IScopeDependency +{ + Task GenerateDeviceTasksAsync(Func func, List userNos); + + Task>> GetAssignDeviceCodesInternalAsync(List userNos); + + Task>> GetAssignDeviceCodesInternalAsync(List userNos, params AssignTypeEnumType[] ignoreAssignTypes); + + Task> GetAssignmentsAsync(DeviceGetAssignmentsRequest request); + + Task> GetAssignmentUniqueAsync(DeviceGetAssignmentUniquesRequest request); + + + Task> GetAssignDeviceCodesAsync(string userCode); +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/IDevicePermissionService.cs b/Src/Dlhis.Basic/Device/Services/IDevicePermissionService.cs index 1f118f91..10ac7f8a 100644 --- a/Src/Dlhis.Basic/Device/Services/IDevicePermissionService.cs +++ b/Src/Dlhis.Basic/Device/Services/IDevicePermissionService.cs @@ -26,29 +26,9 @@ public interface IDevicePermissionService : IScopeDependency Task AssignToUniqueImportAsync(IFormFile file); - /// - /// 获取分配的权限 - /// - /// - Task> GetAssignmentsAsync(DeviceGetAssignmentsRequest request); - - - Task> GetAssignmentUniqueAsync(DeviceGetAssignmentUniquesRequest request); Task>> GetUserDevicePermissionsAsync(string code); - - Task GetUserDevicePermissions2Async(); - - /// - /// 生成下发任务 - /// - /// - /// - /// - Task GenerateDeviceTasksAsync(Func func, List userNos); - - /// /// 生成下发任务(主动生成) /// diff --git a/Src/Dlhis.Basic/Device/Services/IPermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/IPermissionAnalyzeService.cs new file mode 100644 index 00000000..c2806f9e --- /dev/null +++ b/Src/Dlhis.Basic/Device/Services/IPermissionAnalyzeService.cs @@ -0,0 +1,8 @@ +using Dlhis.Basic.Device.Request; + +namespace Dlhis.Basic.Device.Services; + +public interface IPermissionAnalyzeService +{ + Task AnalyzeAsync(DevicePermissionSaveRequest request); +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/Implements/BasePermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/Implements/BasePermissionAnalyzeService.cs new file mode 100644 index 00000000..c48916ee --- /dev/null +++ b/Src/Dlhis.Basic/Device/Services/Implements/BasePermissionAnalyzeService.cs @@ -0,0 +1,226 @@ +using Dlhis.Basic.DataPermissions; +using Dlhis.Basic.Device.Dtos; +using Dlhis.Basic.Device.Request; +using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Device.Entities; +using Dlhis.Entity.Device.Enums; +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.Services; +using Kurisu.AspNetCore.Scope; +using Kurisu.AspNetCore.Utils.Extensions; +using SqlSugar; + +namespace Dlhis.Basic.Device.Services.Implements; + +public abstract class BasePermissionAnalyzeService : IPermissionAnalyzeService +{ + private readonly ICurrentUser _currentUser; + private readonly IDevicePermissionAnalyzeService _devicePermissionAnalyzeService; + private readonly IMyDataPermissionService _myDataPermissionService; + protected IDbContext DbContext { get; } + + protected BasePermissionAnalyzeService(IServiceProvider serviceProvider) + { + _currentUser = serviceProvider.GetService(); + _devicePermissionAnalyzeService = serviceProvider.GetService(); + _myDataPermissionService = serviceProvider.GetService(); + DbContext = serviceProvider.GetService(); + CurrentTenantId = _currentUser.GetStringTenantId(); + } + + private string CurrentTenantId { get; } + + public ISugarQueryable DevicePermission => DbContext.Queryable(); + + + public async Task AnalyzeAsync(DevicePermissionSaveRequest request) + { + var currentAssignValue = request.AssignType == AssignTypeEnumType.Department ? request.TenantId + ":" + request.AssignValue : request.AssignValue; + + await CheckAssignTopDoorDeviceGroupAsync(request); + + var dps = await GetAssignedDevicePermissionsAsync(request); + + (List codesToAdd, List codesToDelete) = await GetDiffAsync(request.UniqueType, dps, request.Codes); + if (codesToAdd.IsEmpty() && codesToDelete.IsEmpty()) + { + return; + } + + var devicesToAdd = await DbContext.Queryable().Where(x => codesToAdd.Contains(x.Code)).Distinct().ToListAsync(); + var devicesToDelete = await DbContext.Queryable().Where(x => codesToDelete.Contains(x.Code)).Distinct().ToListAsync(); + + var gainfoNos = await GetGainfoNosAsync(currentAssignValue); + + var userTenantDeviceCodes = + devicesToDelete.IsPresent() && request.AssignType != AssignTypeEnumType.Tenant + ? await _devicePermissionAnalyzeService.GetAssignDeviceCodesInternalAsync(gainfoNos, request.AssignType) + : new Dictionary>(); + + var tasks = new List(); + foreach (var gainfoNo in gainfoNos) + { + tasks.AddRange(devicesToAdd.Select(x => new DeviceTaskEntity + { + Type = DeviceTaskEnumType.Add, + DeviceType = x.Type, + UserId = null, + UserNo = gainfoNo, + DeviceUniqueNo = x.UniqueNo, + Status = DeviceTaskStatusEnumType.Wait, + Version = 0, + ResultMessage = null, + CancellationId = 0, + Source = DeviceTaskSourceEnumType.Manually, + Priority = 0, + TenantId = x.TenantId, + }).ToList()); + + if (userTenantDeviceCodes.Any()) + { + var myDeviceCodes = userTenantDeviceCodes[gainfoNo].SelectMany(x => x.Codes).SelectMany(x => x.Codes); + devicesToDelete = devicesToDelete.Where(p => devicesToDelete.Select(x => x.Code).Except(myDeviceCodes).Contains(p.Code)).ToList(); + } + + tasks.AddRange(devicesToDelete.Select(x => new DeviceTaskEntity + { + Type = DeviceTaskEnumType.Delete, + DeviceType = x.Type, + UserId = null, + UserNo = gainfoNo, + DeviceUniqueNo = x.UniqueNo, + Status = DeviceTaskStatusEnumType.Wait, + Version = 0, + ResultMessage = null, + CancellationId = 0, + Source = DeviceTaskSourceEnumType.Manually, + Priority = 0, + TenantId = x.TenantId, + }).ToList()); + } + + await ChunkInsertAsync(tasks); + await PersistDataAsync(dps, request); + } + + private async Task ChunkInsertAsync(List batch) where T : class, new() + { + foreach (var tasks in batch.Chunk(500)) + { + await DbContext.InsertAsync(tasks); + } + } + + /// + /// 获取分配当前类型关联的用户 + /// + /// + /// + protected abstract Task> GetGainfoNosAsync(string assignValue); + + + // --------------------------------------------------------------------------------------------------------------------- // + + private async Task CheckAssignTopDoorDeviceGroupAsync(DevicePermissionSaveRequest request) + { + if (request.UniqueType == DeviceAssignmentTypeEnumType.Group) + { + await Scoped.Temp.Value.CreateAsync(async sp => + { + var currentDb = sp.GetService(); + await currentDb.IgnoreAsync(async () => + { + var dgs = await currentDb.Queryable().Where(x => request.Codes.Contains(x.Code)).ToListAsync(); + dgs.Any(x => x.TenantId.IsEmpty()).ThrowIfTrue("不可分配顶级分组节点"); + }); + }); + } + } + + + private async Task PersistDataAsync(List dps, DevicePermissionSaveRequest request) + { + await DbContext.DeleteAsync(dps); + //保存配置的权限 + if (request.Codes.IsPresent()) + { + var currentAssignValue = request.AssignType == AssignTypeEnumType.Department ? request.TenantId + ":" + request.AssignValue : request.AssignValue; + var devicePermissions = request.Codes.Select(code => new DevicePermissionEntity + { + AssignType = request.AssignType, + AssignValue = currentAssignValue, + UniqueType = request.UniqueType, + UniqueValue = code, + Type = request.Type, + TenantId = CurrentTenantId + }).ToList(); + + await DbContext.InsertAsync(devicePermissions); + } + } + + private List GetMyUniqueValues(DeviceAssignmentTypeEnumType uniqueType) + { + var searchAll = _currentUser.GetRole() is "admin" or "tenant-admin"; + //_myDataPermissionService + if (!searchAll && uniqueType == DeviceAssignmentTypeEnumType.Device) + { + return _myDataPermissionService.GetMyDeviceCodes(); + } + + return new List(); + } + + private async Task> GetAssignedDevicePermissionsAsync(DevicePermissionSaveRequest request) + { + var myData = GetMyUniqueValues(request.UniqueType); + + var currentAssignValue = request.AssignType == AssignTypeEnumType.Department ? request.TenantId + ":" + request.AssignValue : request.AssignValue; + return await DevicePermission.Where(x => x.AssignType == request.AssignType + && x.AssignValue == currentAssignValue + && x.UniqueType == request.UniqueType + && x.Type == request.Type + && x.TenantId == CurrentTenantId) + .WhereIF(myData.Any(), x => myData.Contains(x.UniqueValue)) + .ToListAsync(); + } + + private async Task<(List, List)> GetDiffAsync(DeviceAssignmentTypeEnumType type, List dps, List uniqueValues) + { + var beforeCodes = dps.Select(x => x.UniqueValue).ToList(); + var presentCodes = uniqueValues.IsPresent() ? uniqueValues : new List(); + + if (type == DeviceAssignmentTypeEnumType.Group) + { + var deviceGroups = await DbContext.Queryable().ToListAsync(); + beforeCodes = await GetDeviceCodeByGroupAsync(deviceGroups, beforeCodes); + presentCodes = await GetDeviceCodeByGroupAsync(deviceGroups, presentCodes); + } + + var codesToAdd = presentCodes.Except(beforeCodes).ToList(); + var codesToDelete = beforeCodes.Except(presentCodes).ToList(); + + return (codesToAdd, codesToDelete); + } + + + private async Task> GetDeviceCodeByGroupAsync(List deviceGroups, List codes) + { + var result = new List(); + foreach (var groupCode in codes) + { + result.AddRange(RecursionHelper.HandlerDeviceGroupNextCodes(groupCode, deviceGroups)); + } + + result = result.Distinct().ToList(); + + return await DbContext.Queryable() + .Where(x => result.Contains(x.GroupCode)) + .Select(x => x.DeviceCode) + .Distinct() + .ToListAsync(); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs index 7770d0cc..a123326e 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs @@ -14,18 +14,18 @@ namespace Dlhis.Basic.Device.Services.Implements; public class DeviceGroupService : IDeviceGroupService { private readonly IDbContext _dbContext; - private readonly IDevicePermissionService _devicePermissionService; + private readonly IDevicePermissionAnalyzeService _devicePermissionAnalyzeService; private readonly ICurrentUser _currentUser; private readonly ITenantApi _tenantApi; private readonly IParallelService _parallelService; public DeviceGroupService(IDbContext dbContext, - IDevicePermissionService devicePermissionService, + IDevicePermissionAnalyzeService devicePermissionAnalyzeService, ICurrentUser currentUser, ITenantApi tenantApi, IParallelService parallelService) { _dbContext = dbContext; - _devicePermissionService = devicePermissionService; + _devicePermissionAnalyzeService = devicePermissionAnalyzeService; _currentUser = currentUser; _tenantApi = tenantApi; _parallelService = parallelService; @@ -107,7 +107,7 @@ public class DeviceGroupService : IDeviceGroupService _parallelService.Enable = true; //下发任务 - await _devicePermissionService.GenerateDeviceTasksAsync(async () => + await _devicePermissionAnalyzeService.GenerateDeviceTasksAsync(async () => { var relationships = await _dbContext.Queryable().Where(x => x.GroupCode == request.GroupCode).ToListAsync(); await _dbContext.DeleteAsync(relationships); diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionAnalyzeService.cs new file mode 100644 index 00000000..03267ad4 --- /dev/null +++ b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionAnalyzeService.cs @@ -0,0 +1,855 @@ +using System.Collections.Concurrent; +using System.Runtime.CompilerServices; +using Dlhis.Basic.DataPermissions; +using Dlhis.Basic.Device.Dtos; +using Dlhis.Basic.Device.Request; +using Dlhis.Basic.Device.Response; +using Dlhis.Basic.Organization.Dto; +using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Basic.Enums; +using Dlhis.Entity.Device.Entities; +using Dlhis.Entity.Device.Enums; +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.Services; +using Kurisu.AspNetCore.Utils.Extensions; +using SqlSugar; + +namespace Dlhis.Basic.Device.Services.Implements; + +public class DevicePermissionAnalyzeService : IDevicePermissionAnalyzeService +{ + private readonly IDbContext _dbContext; + private readonly IParallelService _parallelService; + private readonly ICurrentUser _currentUser; + private readonly ILogger _logger; + private readonly IMyDataPermissionService _myDataPermissionService; + + public DevicePermissionAnalyzeService(IDbContext dbContext, + IParallelService parallelService, + ICurrentUser currentUser, + IMyDataPermissionService myDataPermissionService, + ILogger logger) + { + _dbContext = dbContext; + _parallelService = parallelService; + _currentUser = currentUser; + _logger = logger; + _myDataPermissionService = myDataPermissionService; + } + + public async Task GenerateDeviceTasksAsync(Func func, List userNos) + { + var getAllUser = userNos.IsEmpty(); + + //获取所有人的权限 + if (getAllUser) + userNos = await GetPermissionUserNosAsync(); + + var before = await GetAssignDeviceCodesInternalAsync(userNos); + + //业务处理 + _dbContext.Client.QueryFilter.Restore(); + await func(); + _dbContext.Client.QueryFilter.ClearAndBackup(); + + //获取业务处理后所有人的权限 + if (getAllUser) + { + var nextUserNos = await GetPermissionUserNosAsync(); + if (nextUserNos.Any()) + userNos = userNos.Concat(nextUserNos).Distinct().ToList(); + } + + var current = await GetAssignDeviceCodesInternalAsync(userNos); + + var devices = await _dbContext.Queryable().Where(x => x.Enable).ToListAsync(); + + var waitAddTasks = new List(); + var waitDeleteTasks = new List(); + + foreach (var userNo in userNos) + { + before.TryGetValue(userNo, out var beforeTenantDeviceCodes); + beforeTenantDeviceCodes ??= new List(); + current.TryGetValue(userNo, out var currentTenantDeviceCodes); + currentTenantDeviceCodes ??= new List(); + + var tenants = new HashSet(); + foreach (var item in beforeTenantDeviceCodes) + tenants.Add(item.Tenant); + foreach (var item in currentTenantDeviceCodes) + tenants.Add(item.Tenant); + + foreach (var tenant in tenants) + { + var currentCodes = currentTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes?.ToList() ?? new List(); + var beforeCodes = beforeTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes?.ToList() ?? new List(); + + //被删除 + var deletedItems = beforeCodes.Where(x => !currentCodes.Contains(x)).ToList(); + //新增 + var addItems = currentCodes.Where(x => !beforeCodes.Contains(x)).ToList(); + + if (!deletedItems.Any() && !addItems.Any()) + { + continue; + } + + var deviceCodes = devices.Where(x => deletedItems.Contains(x.Code) || addItems.Contains(x.Code)).Select(x => x.Code).ToList(); + deletedItems = deletedItems.Where(x => deviceCodes.Contains(x)).ToList(); + addItems = addItems.Where(x => deviceCodes.Contains(x)).ToList(); + + //下发任务创建 + deletedItems.ForEach(x => waitDeleteTasks.Add(new DeviceTaskEntity + { + DeviceUniqueNo = devices.First(item => item.Code == x).UniqueNo, + Status = DeviceTaskStatusEnumType.Wait, + Type = DeviceTaskEnumType.Delete, + CancellationId = 0, + DeviceType = devices.First(item => item.Code == x).Type, + UserNo = userNo, + Version = 0, + TenantId = tenant, + Source = DeviceTaskSourceEnumType.Manually + })); + + addItems.ForEach(x => waitAddTasks.Add(new DeviceTaskEntity + { + DeviceUniqueNo = devices.First(item => item.Code == x).UniqueNo, + Status = DeviceTaskStatusEnumType.Wait, + Type = DeviceTaskEnumType.Add, + DeviceType = devices.First(item => item.Code == x).Type, + UserNo = userNo, + Version = 0, + TenantId = tenant, + Source = DeviceTaskSourceEnumType.Manually + })); + } + } + + await ChunkInsertAsync(waitAddTasks); + await ChunkInsertAsync(waitDeleteTasks); + + return new DevicePermissionAssignResponse + { + AddCount = waitAddTasks.Count, + DeleteCount = waitDeleteTasks.Count + }; + } + + + public async Task GenerateDeviceTasksV2Async(Func func, List userNos) + { + var before = await GetAssignDeviceCodesInternalAsync(userNos); + //业务处理 + await _dbContext.IgnoreAsync(async () => { await func(); }); + + var current = await GetAssignDeviceCodesInternalAsync(userNos); + + var devices = await _dbContext.Queryable().Where(x => x.Enable).ToListAsync(); + + var waitAddTasks = new List(); + var waitDeleteTasks = new List(); + + foreach (var userNo in userNos) + { + before.TryGetValue(userNo, out var beforeTenantDeviceCodes); + beforeTenantDeviceCodes ??= new List(0); + current.TryGetValue(userNo, out var currentTenantDeviceCodes); + currentTenantDeviceCodes ??= new List(0); + + var tenants = new HashSet(); + foreach (var item in beforeTenantDeviceCodes) + tenants.Add(item.Tenant); + foreach (var item in currentTenantDeviceCodes) + tenants.Add(item.Tenant); + + foreach (var tenant in tenants) + { + var currentCodes = currentTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes?.ToList() ?? new List(); + var beforeCodes = beforeTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes?.ToList() ?? new List(); + + var addItems = currentCodes.Except(beforeCodes).ToList(); + var deletedItems = beforeCodes.Except(currentCodes).ToList(); + + if (!deletedItems.Any() && !addItems.Any()) + { + continue; + } + + //下发任务创建 + deletedItems.ForEach(x => waitDeleteTasks.Add(new DeviceTaskEntity + { + DeviceUniqueNo = devices.First(item => item.Code == x).UniqueNo, + Status = DeviceTaskStatusEnumType.Wait, + Type = DeviceTaskEnumType.Delete, + CancellationId = 0, + DeviceType = devices.First(item => item.Code == x).Type, + UserNo = userNo, + Version = 0, + TenantId = tenant, + Source = DeviceTaskSourceEnumType.Manually + })); + + addItems.ForEach(x => waitAddTasks.Add(new DeviceTaskEntity + { + DeviceUniqueNo = devices.First(item => item.Code == x).UniqueNo, + Status = DeviceTaskStatusEnumType.Wait, + Type = DeviceTaskEnumType.Add, + DeviceType = devices.First(item => item.Code == x).Type, + UserNo = userNo, + Version = 0, + TenantId = tenant, + Source = DeviceTaskSourceEnumType.Manually + })); + } + } + + await ChunkInsertAsync(waitAddTasks); + await ChunkInsertAsync(waitDeleteTasks); + + return new DevicePermissionAssignResponse + { + AddCount = waitAddTasks.Count, + DeleteCount = waitDeleteTasks.Count + }; + } + + private async Task ChunkInsertAsync(List batch) where T : class, new() + { + foreach (var tasks in batch.Chunk(500)) + { + await _dbContext.InsertAsync(tasks.ToList()); + } + } + + + public async Task>> GetAssignDeviceCodesInternalAsync(List userNos, params AssignTypeEnumType[] ignoreAssignTypes) + { + var gainfos = await _dbContext.Queryable().Where(x => userNos.Contains(x.No)).ToListAsync(); + if (!gainfos.Any()) + { + return new Dictionary>(); + } + + var devices = await _dbContext.Queryable().Where(x => x.Enable).ToListAsync(); + + var enableFactoryPermissions = await _dbContext.Queryable().ToListAsync(); + + var gainfoGroupRelationships = await _dbContext.Queryable().Where(x => userNos.Contains(x.UserNo)).ToListAsync(); + var gainfoGroups = await _dbContext.Queryable().ToListAsync(); + + var devicePermissions = await _dbContext.Queryable().WhereIF(ignoreAssignTypes.IsPresent(), x => !ignoreAssignTypes.Contains(x.AssignType)).ToListAsync(); + var deviceGroups = await _dbContext.Queryable().ToListAsync(); + var deviceRelationships = await _dbContext.Queryable().ToListAsync(); + var departments = await _dbContext.Queryable().ToListAsync(); + + var result = new ConcurrentDictionary>(); + //var total = gainfos.Count; + + gainfos.ParallelForEach(gainfo => + { + var gainfoDto = new GainfoDto + { + Id = gainfo.Id, + No = gainfo.No, + Code = gainfo.Code, + Name = gainfo.Name, + Workplace = gainfo.Workplace, + Factory = gainfo.Factory, + DepartmentNo = gainfo.DepartmentNo, + IsOutsource = gainfo.Type == GainfoUserTypeEnumType.Outsource, + EnableFactoryPermission = enableFactoryPermissions.FirstOrDefault(x => x.TenantId == gainfo.Factory)?.EnableOutsourceDown ?? true + }; + + var codes = GetAssignDeviceCodesInternal2(gainfoDto, gainfoGroups, gainfoGroupRelationships, devicePermissions, deviceGroups, deviceRelationships, devices, departments, ignoreAssignTypes); + result.TryAdd(gainfo.No, codes); + + // Interlocked.Decrement(ref total); + // _logger.LogInformation("剩余:{count}", total); + }); + + return result.ToDictionary(x => x.Key, x => x.Value); + } + + + public async Task>> GetAssignDeviceCodesInternalAsync(List userNos) + { + var devices = await _dbContext.Queryable().Where(x => x.Enable).ToListAsync(); + var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList(); + var registries = await _dbContext.Queryable() + .Where(x => deviceUniqueNos.Contains(x.DeviceUniqueNo)) + .Where(x => !SqlFunc.IsNullOrEmpty(x.BusinessPlaceCode)) + .ToListAsync(); + + var gainfos = await _dbContext.Queryable().Where(x => userNos.Contains(x.No)).ToListAsync(); + if (!gainfos.Any()) + { + return new Dictionary>(); + } + + var enableFactoryPermissions = await _dbContext.Queryable().ToListAsync(); + + var gainfoGroupRelationships = await _dbContext.Queryable().Where(x => userNos.Contains(x.UserNo)).ToListAsync(); + var devicePermissions = await _dbContext.Queryable().ToListAsync(); + var deviceGroups = await _dbContext.Queryable().ToListAsync(); + var deviceRelationships = await _dbContext.Queryable().ToListAsync(); + var departments = await _dbContext.Queryable().ToListAsync(); + + if (_parallelService.Enable) + { + var result = new ConcurrentDictionary>(); + var total = gainfos.Count; + Parallel.ForEach(gainfos, new ParallelOptions { MaxDegreeOfParallelism = 4 }, gainfo => + { + var gainfoDto = new GainfoDto + { + Id = gainfo.Id, + No = gainfo.No, + Code = gainfo.Code, + Name = gainfo.Name, + Workplace = gainfo.Workplace, + Factory = gainfo.Factory, + DepartmentNo = gainfo.DepartmentNo, + IsOutsource = gainfo.Type == GainfoUserTypeEnumType.Outsource, + EnableFactoryPermission = enableFactoryPermissions.FirstOrDefault(x => x.TenantId == gainfo.Factory)?.EnableOutsourceDown ?? true + }; + + var codes = GetAssignDeviceCodesInternal(gainfoDto, gainfoGroupRelationships, devicePermissions, deviceGroups, deviceRelationships, registries, devices, departments); + result.TryAdd(gainfo.No, codes); + + Interlocked.Decrement(ref total); + _logger.LogInformation("剩余:{count}", total); + }); + + return result.ToDictionary(x => x.Key, x => x.Value); + } + else + { + var result = new Dictionary>(); + var total = gainfos.Count; + foreach (var gainfo in gainfos) + { + var gainfoDto = new GainfoDto + { + Id = gainfo.Id, + No = gainfo.No, + Code = gainfo.Code, + Name = gainfo.Name, + Workplace = gainfo.Workplace, + Factory = gainfo.Factory, + DepartmentNo = gainfo.DepartmentNo, + IsOutsource = gainfo.Type == GainfoUserTypeEnumType.Outsource, + EnableFactoryPermission = enableFactoryPermissions.FirstOrDefault(x => x.TenantId == gainfo.Factory)?.EnableOutsourceDown ?? true + }; + + var codes = GetAssignDeviceCodesInternal(gainfoDto, gainfoGroupRelationships, devicePermissions, deviceGroups, deviceRelationships, registries, devices, departments); + result.Add(gainfo.No, codes); + total--; + _logger.LogInformation("剩余:{count}", total); + } + + return result; + } + } + + public async Task> GetAssignmentsAsync(DeviceGetAssignmentsRequest request) + { + request.AssignValue = request.AssignType == AssignTypeEnumType.Department ? request.TenantId + ":" + request.AssignValue : request.AssignValue; + var role = _currentUser.GetRole(); + var isAll = role is "admin" or "tenant-admin"; + var deviceCodes = _myDataPermissionService.GetMyDeviceCodes(); + + return await _dbContext.Queryable() + .Where(x => x.AssignType == request.AssignType) + .Where(x => x.AssignValue == request.AssignValue) + .Where(x => x.UniqueType == request.UniqueType) + .WhereIF(request.UniqueType == DeviceAssignmentTypeEnumType.Device && !isAll, x => deviceCodes.Contains(x.UniqueValue)) + .Where(x => x.Type == request.Type) + .Select(x => x.UniqueValue) + .ToListAsync(); + } + + public async Task> GetAssignmentUniqueAsync(DeviceGetAssignmentUniquesRequest request) + { + var nos = await _dbContext.Queryable() + .Where(x => x.UniqueType == request.UniqueType) + .Where(x => x.UniqueValue == request.UniqueValue) + .Where(x => x.AssignType == AssignTypeEnumType.User) + .Where(x => x.Type == request.Type) + .Select(x => x.AssignValue) + .ToListAsync(); + + return await _dbContext.Queryable().Where(x => nos.Contains(x.No)).Select(x => new GainfoDto + { + Id = x.Id, + Code = x.Code, + Name = x.Name, + Workplace = x.Workplace, + Factory = x.Factory + }).ToListAsync(); + } + + public async Task> GetAssignDeviceCodesAsync(string userCode) + { + var userNo = await _dbContext.Queryable().Where(x => x.Code == userCode || x.No == userCode).Select(x => x.No).SingleAsync(); + var result = await GetAssignDeviceCodesInternalAsync(new List { userNo }); + return result.First().Value.SelectMany(x => x.Codes).ToList(); + } + + private static List GetAssignDeviceCodesInternal( + GainfoDto gainfo, + List gainfoGroupRelationships, + List devicePermissions, + List deviceGroups, + List deviceGroupRelationships, + List deviceRegistries, + List devices, List departments) + { + if (gainfo.IsOutsource) + { + //外包人员不允许餐饮 + devices = devices.Where(x => x.Type != DeviceTypeEnumType.Meal).ToList(); + } + + var userNo = gainfo.No; + + var deviceDtos = new List(); + var deviceGroupDtos = new List(); + var businessPlaceDtos = new List(); + + //获取人员的分组,跨基地 + var gainfoGroups = gainfoGroupRelationships.Where(x => x.UserNo == userNo).Select(x => x.GroupCode).ToList(); + + //按用户 + var du = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, userNo); + var gu = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo); + var pu = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.User, userNo); + deviceDtos.AddRange(du); + deviceGroupDtos.AddRange(gu); + businessPlaceDtos.AddRange(pu); + + //按用户组 + foreach (var groupCode in gainfoGroups) + { + var dg = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, groupCode.ToString()); + var gg = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, groupCode.ToString()); + var pg = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Group, groupCode.ToString()); + deviceDtos.AddRange(dg); + deviceGroupDtos.AddRange(gg); + businessPlaceDtos.AddRange(pg); + } + + //按部门 + var currentAssignValue = gainfo.Factory + ":" + gainfo.DepartmentNo; + var dd = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, currentAssignValue); + var gd = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, currentAssignValue); + var pd = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Department, currentAssignValue); + deviceDtos.AddRange(dd); + deviceGroupDtos.AddRange(gd); + businessPlaceDtos.AddRange(pd); + + //按厂区 + if (!gainfo.IsOutsource || gainfo.EnableFactoryPermission) + { + var dt = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Factory); + var gt = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Factory); + var pt = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Tenant, gainfo.Factory); + deviceDtos.AddRange(dt); + deviceGroupDtos.AddRange(gt); + businessPlaceDtos.AddRange(pt); + } + + var deviceGroupCodes = deviceGroupDtos.SelectMany(x => x.Codes).Distinct().ToList(); + var businessPlaceCodes = businessPlaceDtos.SelectMany(x => x.Codes).Distinct().ToList(); + + var deviceCodesByGroup = deviceGroupRelationships.Where(x => deviceGroupCodes.Contains(x.GroupCode)) + .GroupBy(x => x.TenantId) + .Select(x => new UserTenantDeviceCodeDto + { + Tenant = x.Key, + Codes = x.Select(item => item.DeviceCode).Distinct().ToList() + }); + + var placeGroup = deviceRegistries.Where(x => businessPlaceCodes.Contains(x.BusinessPlaceCode!.Value)) + .GroupBy(x => x.TenantId) + .Select(x => + { + var currentDeviceUniqueNos = x.Select(item => item.DeviceUniqueNo).ToList(); + + return new UserTenantDeviceCodeDto + { + Tenant = x.Key, + Codes = devices.Where(d => currentDeviceUniqueNos.Contains(d.UniqueNo)).Select(d => d.Code).Distinct().ToList() + }; + }).ToList(); + + deviceDtos.AddRange(deviceCodesByGroup); + deviceDtos.AddRange(placeGroup); + + return deviceDtos.GroupBy(x => x.Tenant).Select(x => + { + var dto = new UserTenantDeviceCodeDto + { + Tenant = x.Key, + Codes = x.SelectMany(item => item.Codes).Distinct().ToList() + }; + + dto.Codes = dto.Codes.Where(p => devices.Any(item => item.Code == p)).ToList(); + + return dto; + }).ToList(); + } + + public static List GetAssignDeviceCodesInternal2( + GainfoDto gainfo, + List gainfoGroups, + List gainfoGroupRelationships, + List devicePermissions, + List deviceGroups, + List deviceGroupRelationships, + List devices, List departments, params AssignTypeEnumType[] ignoreAssignTypes) + { + if (gainfo.IsOutsource) + { + //外包人员不允许餐饮 + devices = devices.Where(x => x.Type != DeviceTypeEnumType.Meal).ToList(); + } + + var deviceCodes = devices.Select(x => x.Code).ToList(); + + var deviceDtos = new List(); + var deviceGroupDtos = new List(); + + //获取人员的分组,跨基地 + var myGainfoGroups = gainfoGroupRelationships.Where(x => x.UserNo == gainfo.No).Select(x => x.GroupCode).ToList(); + + if (ignoreAssignTypes.IsEmpty() || !ignoreAssignTypes.Contains(AssignTypeEnumType.User)) + { + //按用户 + deviceDtos.AddRange(GetMyTypeDevicePermissionAsync(devicePermissions, gainfoGroups, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, gainfo.No)); + deviceGroupDtos.AddRange(GetMyTypeDevicePermissionAsync(devicePermissions, gainfoGroups, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, gainfo.No)); + } + + if (ignoreAssignTypes.IsEmpty() || !ignoreAssignTypes.Contains(AssignTypeEnumType.Group)) + { + //按用户组 + foreach (var groupCode in myGainfoGroups) + { + deviceDtos.AddRange(GetMyTypeDevicePermissionAsync(devicePermissions, gainfoGroups, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, groupCode.ToString())); + deviceGroupDtos.AddRange(GetMyTypeDevicePermissionAsync(devicePermissions, gainfoGroups, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, groupCode.ToString())); + } + } + + if (ignoreAssignTypes.IsEmpty() || !ignoreAssignTypes.Contains(AssignTypeEnumType.Department)) + { + //按部门 + var currentAssignValue = gainfo.Factory + ":" + gainfo.DepartmentNo; + deviceDtos.AddRange(GetMyTypeDevicePermissionAsync(devicePermissions, gainfoGroups, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, currentAssignValue)); + deviceGroupDtos.AddRange(GetMyTypeDevicePermissionAsync(devicePermissions, gainfoGroups, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, currentAssignValue)); + } + + if (ignoreAssignTypes.IsEmpty() || !ignoreAssignTypes.Contains(AssignTypeEnumType.Tenant)) + { + //按厂区 + if (!gainfo.IsOutsource || gainfo.EnableFactoryPermission) + { + deviceDtos.AddRange(GetMyTypeDevicePermissionAsync(devicePermissions, gainfoGroups, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Factory)); + deviceGroupDtos.AddRange(GetMyTypeDevicePermissionAsync(devicePermissions, gainfoGroups, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Factory)); + } + } + + //设备组转设备 + deviceDtos.AddRange(deviceGroupDtos.Select(x => + { + var tenant = x.Tenant; + + var deviceGroupCodes = x.Codes.SelectMany(item => item.Codes); + var type = x.Codes.ElementAt(0).AssignType; + return new TenantAssignTypeDeviceCode + { + Tenant = tenant, + Codes = new List + { + new() + { + AssignType = type, + Codes = deviceGroupRelationships.Where(item => deviceGroupCodes.Contains(item.GroupCode)).Select(item => item.DeviceCode).ToList() + } + } + }; + })); + + return deviceDtos.GroupBy(x => x.Tenant).Select(x => + { + var dto = new TenantAssignTypeDeviceCode + { + Tenant = x.Key, + Codes = x.SelectMany(p => p.Codes) + .GroupBy(p => p.AssignType) + .Select(p => new AssignTypeDeviceCode + { + AssignType = p.Key, + Codes = p.SelectMany(item => deviceCodes.Where(it => item.Codes.Contains(it))) + }) + }; + + return dto; + }).ToList(); + } + + private static List GetAssignCodesInternal( + List devicePermissions, List deviceGroups, List departments, + DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue) + { + var tenantDevicePermissions = devicePermissions + .Where(x => x.UniqueType == uniqueType + && x.AssignType == assignType + && x.AssignValue == assignValue) + .GroupBy(x => x.TenantId) + .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(p => p.UniqueValue) }) + .ToList(); + + //处理获取设备分组的情况 + if (uniqueType == DeviceAssignmentTypeEnumType.Group) + { + //开始递归处理 + var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList(); + tops.ForEach(x => { DeviceGroupRecursionGetNext(x, deviceGroups, tenantDevicePermissions, tenantDevicePermissions.SelectMany(item => item.Codes).Contains(x.Code)); }); + } + + if (assignType == AssignTypeEnumType.Department) + { + //递归向上获取 assignValue = department.No + var arr = assignValue.Split(":"); + var tenantId = arr.First(); + var currentDepartmentNo = arr.Last(); + var departmentNos = new List(12) { currentDepartmentNo }; + DepartmentRecursionGetPNo(currentDepartmentNo, departments, departmentNos); + + departmentNos = departmentNos.Select(x => tenantId + ":" + x).ToList(); + + tenantDevicePermissions = devicePermissions + .Where(x => x.UniqueType == uniqueType) + .Where(x => x.AssignType == assignType) + .Where(x => departmentNos.Contains(x.AssignValue)) + .GroupBy(x => x.TenantId) + .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(p => p.UniqueValue) }) + .ToList(); + } + + return tenantDevicePermissions.GroupBy(x => x.Tenant).Select(x => + { + var tenant = x.Key; + + return new UserTenantDeviceCodeDto + { + Tenant = tenant, + Codes = x.SelectMany(item => item.Codes).ToList() + }; + }).ToList(); + } + + private static List GetCurrentAssignTypePermissions( + List devicePermissions, + List gainfoGroups, + List departments, + DeviceAssignmentTypeEnumType uniqueType, + AssignTypeEnumType assignType, + string assignValue) + { + //处理分配到部门 + if (assignType == AssignTypeEnumType.Department) + { + // 2401:00001 + //递归向上获取 assignValue = department.No + var arr = assignValue.Split(":"); + var tenantId = arr[0]; + var currentDepartmentNo = arr[1]; + + var departmentNos = RecursionHelper.HandlerDepartmentPreviousCodes(currentDepartmentNo, departments).Select(x => tenantId + ":" + x).ToList(); + + return devicePermissions + .Where(x => x.UniqueType == uniqueType) + .Where(x => x.AssignType == assignType) + .Where(x => departmentNos.Contains(x.AssignValue)) + .GroupBy(x => x.TenantId) + .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(p => p.UniqueValue) }) + .ToList(); + } + + if (assignType == AssignTypeEnumType.Group) + { + var gainfoGroupCodes = RecursionHelper.HandlerGainfoGroupPreviousCodes(Guid.Parse(assignValue), gainfoGroups).Select(x => x.ToString()); + return devicePermissions + .Where(x => x.UniqueType == uniqueType) + .Where(x => x.AssignType == assignType) + .Where(x => gainfoGroupCodes.Contains(x.AssignValue)) + .GroupBy(x => x.TenantId) + .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(p => p.UniqueValue) }) + .ToList(); + } + + //user / tenant + return devicePermissions + .Where(x => x.UniqueType == uniqueType //设备/设备组 + && x.AssignType == assignType // user/group/department/tenant + && x.AssignValue == assignValue) + .GroupBy(x => x.TenantId) + .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(p => p.UniqueValue) }) + .ToList(); + } + + private static List GetMyTypeDevicePermissionAsync( + List devicePermissions, + List gainfoGroups, + List deviceGroups, + List departments, + DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue) + { + var tenantDevicePermissions = GetCurrentAssignTypePermissions(devicePermissions, gainfoGroups, departments, uniqueType, assignType, assignValue); + + //处理获取设备分组的情况,递归向下查询子分组 + if (uniqueType == DeviceAssignmentTypeEnumType.Group) + { + foreach (var tenantDevicePermission in tenantDevicePermissions) + { + var deviceGroupCodes = tenantDevicePermission.Codes; + var r = tenantDevicePermission.Codes.ToList(); + + foreach (var deviceGroupCode in deviceGroupCodes) + { + r.AddRange(RecursionHelper.HandlerDeviceGroupNextCodes(deviceGroupCode, deviceGroups)); + } + + tenantDevicePermission.Codes = r.Distinct().ToList(); + } + } + + return tenantDevicePermissions.GroupBy(x => x.Tenant).Select(x => + { + var tenant = x.Key; + + return new TenantAssignTypeDeviceCode + { + Tenant = tenant, + Codes = new List + { + new() + { + AssignType = assignType, + Codes = x.SelectMany(item => item.Codes), + } + } + }; + }).ToList(); + } + + + /// + /// 获取当前基地有权限的用户 + /// + /// + private async Task> GetPermissionUserNosAsync() + { + var permissions = await _dbContext.Queryable().ToListAsync(); + + //User + var userNos = permissions.Where(x => x.AssignType == AssignTypeEnumType.User) + .Select(x => x.AssignValue) + .Distinct() + .ToList(); + + //Group + var groupCodes = permissions.Where(x => x.AssignType == AssignTypeEnumType.Group) + .Select(x => Guid.Parse(x.AssignValue)) + .Distinct() + .ToList(); + var userNosByGroup = await _dbContext.Queryable() + .Where(x => groupCodes.Contains(x.GroupCode)) + .Select(x => x.UserNo) + .ToListAsync(); + + //Department + var tenantDepartmentNos = permissions.Where(x => x.AssignType == AssignTypeEnumType.Department) + .Where(x => x.AssignValue.Contains(':')) + .Select(x => + { + var arr = x.AssignValue.Split(':'); + return new + { + Factory = arr[0], DepartmentNo = arr[1] + }; + }) + .GroupBy(x => x.Factory) + .ToDictionary(x => x.Key, x => x.Select(p => p.DepartmentNo).Distinct().ToList()); + var departments = await _dbContext.Queryable().ToListAsync(); + + var gainfoByDeptWhere = LinqExpressionExtensions.False(); + foreach ((string factory, List departmentNos) in tenantDepartmentNos) + { + var departmentNosToSearch = new List(); + foreach (var d in departmentNos) + { + departmentNosToSearch.Add(d); + RecursionGetNextAllDepartment(d, departments, departmentNosToSearch); + } + + gainfoByDeptWhere = gainfoByDeptWhere.Or(x => x.Factory == factory && departmentNosToSearch.Contains(x.DepartmentNo)); + } + + var userNosByDepartment = await _dbContext.Queryable() + .Where(gainfoByDeptWhere) + .Select(x => x.No) + .ToListAsync(); + + + //Tenant + var tenants = permissions.Where(x => x.AssignType == AssignTypeEnumType.Tenant).Select(x => x.AssignValue).Distinct().ToList(); + var userNosByWerk = await _dbContext.Queryable().Where(x => tenants.Contains(x.Factory)).Select(x => x.No).ToListAsync(); + + return userNos.Concat(userNosByGroup).Concat(userNosByDepartment).Concat(userNosByWerk).Distinct().ToList(); + + void RecursionGetNextAllDepartment(string current, List data, List result) + { + var next = data.Where(x => x.PNo == current); + foreach (var item in next.Select(x => x.No)) + { + result.Add(item); + RecursionGetNextAllDepartment(item, data, result); + } + } + } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void DepartmentRecursionGetPNo(string current, List data, List result) + { + var p = data.FirstOrDefault(x => x.No == current)?.PNo; + if (!p.IsPresent()) + { + return; + } + + result.Add(p); + DepartmentRecursionGetPNo(p, data, result); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static void DeviceGroupRecursionGetNext(DeviceGroupEntity current, List currentDeviceGroups, List result, bool add) + { + var next = currentDeviceGroups.Where(x => x.PCode == current.Code).ToList(); + foreach (var item in next) + { + if (add) + { + result.Add(new UserTenantDeviceCodeDto { Tenant = item.TenantId, Codes = new List { item.Code } }); + } + + DeviceGroupRecursionGetNext(item, currentDeviceGroups, result, result.SelectMany(x => x.Codes).Contains(item.Code)); + } + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs index b6ced392..c0a38b64 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs @@ -1,13 +1,8 @@ -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using Dlhis.Basic.DataPermissions; +using Dlhis.Basic.DataPermissions; using Dlhis.Basic.Device.Dtos; using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Response; -using Dlhis.Basic.Organization.Dto; using Dlhis.Entity.Basic.Entity; -using Dlhis.Entity.Basic.Enums; using Dlhis.Entity.Device.Entities; using Dlhis.Entity.Device.Enums; using Dlhis.Entity.Sys.Entities; @@ -32,52 +27,41 @@ public class DevicePermissionService : IDevicePermissionService private readonly IMyDataPermissionService _myDataPermissionService; private readonly ITenantApi _tenantApi; private readonly IParallelService _parallelService; + private readonly INamedResolver _namedResolver; + private readonly IDevicePermissionAnalyzeService _devicePermissionAnalyzeService; private readonly ICurrentUser _currentUser; public DevicePermissionService(IDbContext dbContext, IMyDataPermissionService myDataPermissionService, ITenantApi tenantApi, IParallelService parallelService, + INamedResolver namedResolver, + IDevicePermissionAnalyzeService devicePermissionAnalyzeService, ICurrentUser currentUser) { _dbContext = dbContext; _myDataPermissionService = myDataPermissionService; _tenantApi = tenantApi; _parallelService = parallelService; + _namedResolver = namedResolver; + _devicePermissionAnalyzeService = devicePermissionAnalyzeService; _currentUser = currentUser; } public async Task AssignAsync(DevicePermissionSaveRequest request) { + await _namedResolver.GetService(PermissionAnalyzeConstants.GetTypeName(request.AssignType)).AnalyzeAsync(request); + + return null; await CheckAssignTopDoorDeviceGroupAsync(request); var currentTenantId = _currentUser.GetStringTenantId(); var role = _currentUser.GetRole(); var isAll = role is "admin" or "tenant-admin"; - var deviceCodes = _myDataPermissionService.GetMyDeviceCodes(); - - if (request.AssignType == AssignTypeEnumType.Tenant && request.UniqueType == DeviceAssignmentTypeEnumType.Device) - { - return await AssignDeviceToTenantAsync(currentTenantId, isAll, deviceCodes, request); - } - - if (request.AssignType == AssignTypeEnumType.Tenant && request.UniqueType == DeviceAssignmentTypeEnumType.Group) - { - return await AssignDeviceGroupToTenantAsync(currentTenantId, request); - } - - if (request.AssignType == AssignTypeEnumType.Department && request.UniqueType == DeviceAssignmentTypeEnumType.Device) - { - return await AssignDeviceToDepartmentAsync(currentTenantId, isAll, deviceCodes, request); - } - - if (request.AssignType == AssignTypeEnumType.Department && request.UniqueType == DeviceAssignmentTypeEnumType.Group) - { - return await AssignDeviceGroupToDepartmentAsync(currentTenantId, request); - } + var deviceCodes = isAll ? new List() : _myDataPermissionService.GetMyDeviceCodes(); _parallelService.Enable = true; - return await GenerateDeviceTasksAsync(async () => + return await _devicePermissionAnalyzeService.GenerateDeviceTasksAsync(async () => { request.AssignValue = request.AssignType == AssignTypeEnumType.Department ? request.TenantId + ":" + request.AssignValue : request.AssignValue; @@ -114,211 +98,6 @@ public class DevicePermissionService : IDevicePermissionService }, null); } - public async Task AssignDeviceToDepartmentAsync(string currentTenantId, bool isAll, List deviceCodes, DevicePermissionSaveRequest request) - { - var departmentValue = request.TenantId + ":" + request.AssignValue; - - var p = await _dbContext.Queryable() - .Where(x => x.AssignType == AssignTypeEnumType.Department) - .Where(x => x.AssignValue == departmentValue) - .Where(x => x.UniqueType == request.UniqueType) - .WhereIF(!isAll, x => deviceCodes.Contains(x.UniqueValue)) - .Where(x => x.Type == request.Type) - .Where(x => x.TenantId == currentTenantId) - .ToListAsync(); - - var departments = await _dbContext.Queryable().ToListAsync(); - var departmentNos = new List { request.AssignValue }; - DepartmentRecursionGetNext(request.AssignValue, departments, departmentNos); - - var gainfoNos = await _dbContext.Queryable() - .Where(x => x.Factory == request.TenantId && departmentNos.Contains(x.DepartmentNo)) - .Select(x => x.No) - .ToListAsync(); - - var beforeDeviceCodes = p.Select(x => x.UniqueValue).ToList(); - var presentDeviceCodes = request.Codes.IsPresent() ? request.Codes : new List(); - - var addDeviceCodes = presentDeviceCodes.Except(beforeDeviceCodes).ToList(); - var deleteDeviceCodes = beforeDeviceCodes.Except(presentDeviceCodes).ToList(); - - await _dbContext.DeleteAsync(p); - //保存配置的权限 - if (request.Codes.IsPresent()) - { - var devicePermissions = request.Codes.Select(code => new DevicePermissionEntity - { - AssignType = request.AssignType, - AssignValue = departmentValue, - UniqueType = request.UniqueType, - UniqueValue = code, - Type = request.Type, - TenantId = currentTenantId - }).ToList(); - - await _dbContext.InsertAsync(devicePermissions); - } - - var allDeviceCodes = addDeviceCodes.Concat(deleteDeviceCodes).ToList(); - var devices = await _dbContext.Queryable() - .Where(x => allDeviceCodes.Contains(x.Code)) - .Select(x => new { x.Code, x.UniqueNo, x.Type, x.TenantId }) - .ToListAsync(); - - var tasks = new List(); - foreach (var gainfoNo in gainfoNos) - { - tasks.AddRange(addDeviceCodes.Select(x => - { - var d = devices.First(item => item.Code == x); - return new DeviceTaskEntity - { - Type = DeviceTaskEnumType.Add, - DeviceType = d.Type, - UserId = null, - UserNo = gainfoNo, - DeviceUniqueNo = d.UniqueNo, - Status = DeviceTaskStatusEnumType.Wait, - Version = 0, - ResultMessage = null, - CancellationId = 0, - Source = DeviceTaskSourceEnumType.Manually, - Priority = 0, - TenantId = d.TenantId, - }; - }).ToList()); - - tasks.AddRange(deleteDeviceCodes.Select(x => - { - var d = devices.First(item => item.Code == x); - return new DeviceTaskEntity - { - Type = DeviceTaskEnumType.Delete, - DeviceType = d.Type, - UserId = null, - UserNo = gainfoNo, - DeviceUniqueNo = d.UniqueNo, - Status = DeviceTaskStatusEnumType.Wait, - Version = 0, - ResultMessage = null, - CancellationId = 0, - Source = DeviceTaskSourceEnumType.Manually, - Priority = 0, - TenantId = d.TenantId, - }; - }).ToList()); - } - - foreach (var items in tasks.Where(x => x.Type == DeviceTaskEnumType.Add).Chunk(500)) - { - await _dbContext.InsertAsync(items.ToList()); - } - - return new DevicePermissionAssignResponse - { - AddCount = addDeviceCodes.Count * gainfoNos.Count, - DeleteCount = deleteDeviceCodes.Count * gainfoNos.Count - }; - } - - - public async Task AssignDeviceGroupToDepartmentAsync(string currentTenantId, DevicePermissionSaveRequest request) - { - var departmentValue = request.TenantId + ":" + request.AssignValue; - - var groupData = await _dbContext.Queryable() - .Where(x => x.AssignType == AssignTypeEnumType.Department) - .Where(x => x.AssignValue == departmentValue) - .Where(x => x.UniqueType == request.UniqueType) - .Where(x => x.Type == request.Type) - .Where(x => x.TenantId == currentTenantId) - .ToListAsync(); - - var departments = await _dbContext.Queryable().ToListAsync(); - var departmentNos = new List { request.AssignValue }; - DepartmentRecursionGetNext(request.AssignValue, departments, departmentNos); - - var gainfoNos = await _dbContext.Queryable() - .Where(x => x.Factory == request.TenantId && departmentNos.Contains(x.DepartmentNo)) - .Select(x => x.No) - .ToListAsync(); - - var beforeDeviceCodes = groupData.Select(x => x.UniqueValue).ToList(); - var presentDeviceCodes = request.Codes.IsPresent() ? request.Codes : new List(); - - var addDeviceGroupCodes = presentDeviceCodes.Except(beforeDeviceCodes).ToList(); - var deleteDeviceGroupCodes = beforeDeviceCodes.Except(presentDeviceCodes).ToList(); - - await _dbContext.DeleteAsync(groupData); - //保存配置的权限 - if (request.Codes.IsPresent()) - { - var devicePermissions = request.Codes.Select(code => new DevicePermissionEntity - { - AssignType = request.AssignType, - AssignValue = departmentValue, - UniqueType = request.UniqueType, - UniqueValue = code, - Type = request.Type, - TenantId = currentTenantId - }).ToList(); - - await _dbContext.InsertAsync(devicePermissions); - } - - var deviceGroups = await _dbContext.Queryable().ToListAsync(); - - var addDevices = await GetDevicesByGroupsAsync(deviceGroups, deviceGroups.Where(x => addDeviceGroupCodes.Contains(x.Code)).ToList()); - var deleteDevices = await GetDevicesByGroupsAsync(deviceGroups, deviceGroups.Where(x => deleteDeviceGroupCodes.Contains(x.Code)).ToList()); - - var tasks = new List(); - foreach (var gainfoNo in gainfoNos) - { - tasks.AddRange(addDevices.Select(x => new DeviceTaskEntity - { - Type = DeviceTaskEnumType.Add, - DeviceType = x.Type, - UserId = null, - UserNo = gainfoNo, - DeviceUniqueNo = x.UniqueNo, - Status = DeviceTaskStatusEnumType.Wait, - Version = 0, - ResultMessage = null, - CancellationId = 0, - Source = DeviceTaskSourceEnumType.Manually, - Priority = 0, - TenantId = x.TenantId, - }).ToList()); - - tasks.AddRange(deleteDevices.Select(x => new DeviceTaskEntity - { - Type = DeviceTaskEnumType.Delete, - DeviceType = x.Type, - UserId = null, - UserNo = gainfoNo, - DeviceUniqueNo = x.UniqueNo, - Status = DeviceTaskStatusEnumType.Wait, - Version = 0, - ResultMessage = null, - CancellationId = 0, - Source = DeviceTaskSourceEnumType.Manually, - Priority = 0, - TenantId = x.TenantId, - }).ToList()); - } - - foreach (var items in tasks.Where(x => x.Type == DeviceTaskEnumType.Add).Chunk(500)) - { - await _dbContext.InsertAsync(items.ToList()); - } - - return new DevicePermissionAssignResponse - { - AddCount = addDevices.Count * gainfoNos.Count, - DeleteCount = deleteDevices.Count * gainfoNos.Count - }; - } - private async Task CheckAssignTopDoorDeviceGroupAsync(DevicePermissionSaveRequest request) { @@ -337,42 +116,8 @@ public class DevicePermissionService : IDevicePermissionService } - public async Task AssignDeviceToTenantAsync(string currentTenantId, bool isAll, List deviceCodes, DevicePermissionSaveRequest request) + public async Task GenerateTasksAsync(List addDeviceCodes, List deleteDeviceCodes, List gainfoNos) { - var p = await _dbContext.Queryable() - .Where(x => x.AssignType == AssignTypeEnumType.Tenant) - .Where(x => x.AssignValue == request.AssignValue) - .Where(x => x.UniqueType == request.UniqueType) - .WhereIF(request.UniqueType == DeviceAssignmentTypeEnumType.Device && !isAll, x => deviceCodes.Contains(x.UniqueValue)) - .Where(x => x.Type == request.Type) - .Where(x => x.TenantId == currentTenantId) - .ToListAsync(); - - var gainfoNos = await _dbContext.Queryable().Where(x => x.Factory == request.AssignValue).Select(x => x.No).ToListAsync(); - - var beforeDeviceCodes = p.Select(x => x.UniqueValue).ToList(); - var presentDeviceCodes = request.Codes.IsPresent() ? request.Codes : new List(); - - var addDeviceCodes = presentDeviceCodes.Except(beforeDeviceCodes).ToList(); - var deleteDeviceCodes = beforeDeviceCodes.Except(presentDeviceCodes).ToList(); - - await _dbContext.DeleteAsync(p); - //保存配置的权限 - if (request.Codes.IsPresent()) - { - var devicePermissions = request.Codes.Select(code => new DevicePermissionEntity - { - AssignType = request.AssignType, - AssignValue = request.AssignValue, - UniqueType = request.UniqueType, - UniqueValue = code, - Type = request.Type, - TenantId = currentTenantId - }).ToList(); - - await _dbContext.InsertAsync(devicePermissions); - } - var allDeviceCodes = addDeviceCodes.Concat(deleteDeviceCodes).ToList(); var devices = await _dbContext.Queryable() .Where(x => allDeviceCodes.Contains(x.Code)) @@ -729,211 +474,13 @@ public class DevicePermissionService : IDevicePermissionService } } - public async Task> GetAssignmentsAsync(DeviceGetAssignmentsRequest request) - { - request.AssignValue = request.AssignType == AssignTypeEnumType.Department ? request.TenantId + ":" + request.AssignValue : request.AssignValue; - var role = _currentUser.GetRole(); - var isAll = role is "admin" or "tenant-admin"; - var deviceCodes = _myDataPermissionService.GetMyDeviceCodes(); - - return await _dbContext.Queryable() - .Where(x => x.AssignType == request.AssignType) - .Where(x => x.AssignValue == request.AssignValue) - .Where(x => x.UniqueType == request.UniqueType) - .WhereIF(request.UniqueType == DeviceAssignmentTypeEnumType.Device && !isAll, x => deviceCodes.Contains(x.UniqueValue)) - .Where(x => x.Type == request.Type) - .Select(x => x.UniqueValue) - .ToListAsync(); - } - - - public async Task> GetAssignmentUniqueAsync(DeviceGetAssignmentUniquesRequest request) - { - var nos = await _dbContext.Queryable() - .Where(x => x.UniqueType == request.UniqueType) - .Where(x => x.UniqueValue == request.UniqueValue) - .Where(x => x.AssignType == AssignTypeEnumType.User) - .Where(x => x.Type == request.Type) - .Select(x => x.AssignValue) - .ToListAsync(); - - return await _dbContext.Queryable().Where(x => nos.Contains(x.No)).Select(x => new GainfoDto - { - Id = x.Id, - Code = x.Code, - Name = x.Name, - Workplace = x.Workplace, - Factory = x.Factory - }).ToListAsync(); - } - /// public async Task>> GetUserDevicePermissionsAsync(string code) { var userNo = await _dbContext.Queryable().Where(x => x.Code == code).Select(x => x.No).SingleAsync(); - return await GetAssignDeviceCodesInternalAsync(new List { userNo }); + return await _devicePermissionAnalyzeService.GetAssignDeviceCodesInternalAsync(new List { userNo }); } - /// - public async Task GetUserDevicePermissions2Async() - { - var today = DateTime.Today; - var yesterday = today.AddDays(-1); - - var tripInfos = await _dbContext.Queryable() - .LeftJoin((x, ga) => x.Code == ga.Code) - .Where(x => SqlFunc.DateIsSame(x.BeginDate, today) || SqlFunc.DateIsSame(x.BeginDate, yesterday)) - .Where(x => !SqlFunc.IsNullOrEmpty(x.Destination)) - .Select((x, ga) => new - { - x.Code, UserNo = ga.No - }) - .ToListAsync(); - - - //获取人员的设备权限 - - var userNos = tripInfos.Select(x => x.UserNo).Distinct().ToList(); - var result = await GetAssignDeviceCodesInternalAsync(userNos); - - foreach (var tripInfo in tripInfos.Where(x => x.UserNo.IsPresent())) - { - var myDeviceCodes = result[tripInfo.UserNo].SelectMany(x => x.Codes); - - var devices = await _dbContext.Queryable().Where(x => myDeviceCodes.Contains(x.Code)).ToListAsync(); - - var tasks = devices.Select(x => new DeviceTaskEntity - { - DeviceUniqueNo = x.UniqueNo, - Status = DeviceTaskStatusEnumType.Wait, - Version = 0, - UserNo = tripInfo.UserNo, - Type = DeviceTaskEnumType.Add, - DeviceType = x.Type, - TenantId = x.TenantId, - Priority = 10, - Source = DeviceTaskSourceEnumType.Manually - }).ToList(); - - await _dbContext.InsertAsync(tasks); - } - } - - public async Task GenerateDeviceTasksAsync(Func func, List userNos) - { - var getAllUser = userNos.IsEmpty(); - - //获取所有人的权限 - if (getAllUser) - userNos = await GetPermissionUserNosAsync(); - - var before = await GetAssignDeviceCodesInternalAsync(userNos); - - //业务处理 - _dbContext.Client.QueryFilter.Restore(); - await func(); - _dbContext.Client.QueryFilter.ClearAndBackup(); - - //获取业务处理后所有人的权限 - if (getAllUser) - { - var nextUserNos = await GetPermissionUserNosAsync(); - if (nextUserNos.Any()) - userNos = userNos.Concat(nextUserNos).Distinct().ToList(); - } - - var current = await GetAssignDeviceCodesInternalAsync(userNos); - - var devices = await _dbContext.Queryable().Where(x => x.Enable).ToListAsync(); - // var waitAddTasks = new ConcurrentBag(); - // var waitDeleteTasks = new ConcurrentBag(); - - var waitAddTasks = new List(); - var waitDeleteTasks = new List(); - - // Parallel.ForEach(userNos, userNo => - // { - foreach (var userNo in userNos) - { - before.TryGetValue(userNo, out var beforeTenantDeviceCodes); - beforeTenantDeviceCodes ??= new List(); - current.TryGetValue(userNo, out var currentTenantDeviceCodes); - currentTenantDeviceCodes ??= new List(); - - var tenants = new HashSet(); - foreach (var item in beforeTenantDeviceCodes) - tenants.Add(item.Tenant); - foreach (var item in currentTenantDeviceCodes) - tenants.Add(item.Tenant); - - foreach (var tenant in tenants) - { - var currentCodes = currentTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes?.ToList() ?? new List(); - var beforeCodes = beforeTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes?.ToList() ?? new List(); - - //被删除 - var deletedItems = beforeCodes.Where(x => !currentCodes.Contains(x)).ToList(); - //新增 - var addItems = currentCodes.Where(x => !beforeCodes.Contains(x)).ToList(); - - if (!deletedItems.Any() && !addItems.Any()) - { - continue; - } - - var deviceCodes = devices.Where(x => deletedItems.Contains(x.Code) || addItems.Contains(x.Code)).Select(x => x.Code).ToList(); - deletedItems = deletedItems.Where(x => deviceCodes.Contains(x)).ToList(); - addItems = addItems.Where(x => deviceCodes.Contains(x)).ToList(); - - //下发任务创建 - deletedItems.ForEach(x => waitDeleteTasks.Add(new DeviceTaskEntity - { - DeviceUniqueNo = devices.First(item => item.Code == x).UniqueNo, - Status = DeviceTaskStatusEnumType.Wait, - Type = DeviceTaskEnumType.Delete, - CancellationId = 0, - DeviceType = devices.First(item => item.Code == x).Type, - UserNo = userNo, - Version = 0, - TenantId = tenant, - Source = DeviceTaskSourceEnumType.Manually - })); - - addItems.ForEach(x => waitAddTasks.Add(new DeviceTaskEntity - { - DeviceUniqueNo = devices.First(item => item.Code == x).UniqueNo, - Status = DeviceTaskStatusEnumType.Wait, - Type = DeviceTaskEnumType.Add, - DeviceType = devices.First(item => item.Code == x).Type, - UserNo = userNo, - Version = 0, - TenantId = tenant, - Source = DeviceTaskSourceEnumType.Manually - })); - } - } - // }); - - if (waitAddTasks.Any()) - await ChunkInsertAsync(waitAddTasks.ToList()); - - if (waitDeleteTasks.Any()) - await ChunkInsertAsync(waitDeleteTasks.ToList()); - - return new DevicePermissionAssignResponse - { - AddCount = waitAddTasks.Count, - DeleteCount = waitDeleteTasks.Count - }; - - async Task ChunkInsertAsync(List batch) where T : class, new() - { - foreach (var tasks in batch.Chunk(500)) - { - await _dbContext.InsertAsync(tasks.ToList()); - } - } - } public async Task> GetGainfoPageByDeviceAsync(DeviceWithGainfoRequest request) { @@ -1154,344 +701,7 @@ public class DevicePermissionService : IDevicePermissionService public async Task> GetAssignDeviceCodesAsync(string userCode) { var userNo = await _dbContext.Queryable().Where(x => x.Code == userCode || x.No == userCode).Select(x => x.No).SingleAsync(); - var result = await GetAssignDeviceCodesInternalAsync(new List { userNo }); + var result = await _devicePermissionAnalyzeService.GetAssignDeviceCodesInternalAsync(new List { userNo }); return result.First().Value.SelectMany(x => x.Codes).ToList(); } - - //************************************************ help methods ******************************************************* - - /// - /// 获取当前基地有权限的用户 - /// - /// - private async Task> GetPermissionUserNosAsync() - { - var permissions = await _dbContext.Queryable().ToListAsync(); - - //User - var userNos = permissions.Where(x => x.AssignType == AssignTypeEnumType.User) - .Select(x => x.AssignValue) - .Distinct() - .ToList(); - - //Group - var groupCodes = permissions.Where(x => x.AssignType == AssignTypeEnumType.Group) - .Select(x => Guid.Parse(x.AssignValue)) - .Distinct() - .ToList(); - var userNosByGroup = await _dbContext.Queryable() - .Where(x => groupCodes.Contains(x.GroupCode)) - .Select(x => x.UserNo) - .ToListAsync(); - - //Department - var tenantDepartmentNos = permissions.Where(x => x.AssignType == AssignTypeEnumType.Department) - .Where(x => x.AssignValue.Contains(':')) - .Select(x => - { - var arr = x.AssignValue.Split(':'); - return new - { - Factory = arr[0], DepartmentNo = arr[1] - }; - }) - .GroupBy(x => x.Factory) - .ToDictionary(x => x.Key, x => x.Select(p => p.DepartmentNo).Distinct().ToList()); - var departments = await _dbContext.Queryable().ToListAsync(); - - var gainfoByDeptWhere = LinqExpressionExtensions.False(); - foreach ((string factory, List departmentNos) in tenantDepartmentNos) - { - var departmentNosToSearch = new List(); - foreach (var d in departmentNos) - { - departmentNosToSearch.Add(d); - RecursionGetNextAllDepartment(d, departments, departmentNosToSearch); - } - - gainfoByDeptWhere = gainfoByDeptWhere.Or(x => x.Factory == factory && departmentNosToSearch.Contains(x.DepartmentNo)); - } - - var userNosByDepartment = await _dbContext.Queryable() - .Where(gainfoByDeptWhere) - .Select(x => x.No) - .ToListAsync(); - - - //Tenant - var tenants = permissions.Where(x => x.AssignType == AssignTypeEnumType.Tenant).Select(x => x.AssignValue).Distinct().ToList(); - var userNosByWerk = await _dbContext.Queryable().Where(x => tenants.Contains(x.Factory)).Select(x => x.No).ToListAsync(); - - return userNos.Concat(userNosByGroup).Concat(userNosByDepartment).Concat(userNosByWerk).Distinct().ToList(); - - void RecursionGetNextAllDepartment(string current, List data, List result) - { - var next = data.Where(x => x.PNo == current); - foreach (var item in next.Select(x => x.No)) - { - result.Add(item); - RecursionGetNextAllDepartment(item, data, result); - } - } - } - - private static List GetAssignCodesInternal( - List devicePermissions, List deviceGroups, List departments, - DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue) - { - var tenantDevicePermissions = devicePermissions - .Where(x => x.UniqueType == uniqueType - && x.AssignType == assignType - && x.AssignValue == assignValue) - .GroupBy(x => x.TenantId) - .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(p => p.UniqueValue) }) - .ToList(); - - //处理获取设备分组的情况 - if (uniqueType == DeviceAssignmentTypeEnumType.Group) - { - //开始递归处理 - var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList(); - tops.ForEach(x => { DeviceGroupRecursionGetNext(x, deviceGroups, tenantDevicePermissions, tenantDevicePermissions.SelectMany(item => item.Codes).Contains(x.Code)); }); - } - - if (assignType == AssignTypeEnumType.Department) - { - //递归向上获取 assignValue = department.No - var arr = assignValue.Split(":"); - var tenantId = arr.First(); - var currentDepartmentNo = arr.Last(); - var departmentNos = new List(12) { currentDepartmentNo }; - DepartmentRecursionGetPNo(currentDepartmentNo, departments, departmentNos); - - departmentNos = departmentNos.Select(x => tenantId + ":" + x).ToList(); - - tenantDevicePermissions = devicePermissions - .Where(x => x.UniqueType == uniqueType) - .Where(x => x.AssignType == assignType) - .Where(x => departmentNos.Contains(x.AssignValue)) - .GroupBy(x => x.TenantId) - .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(p => p.UniqueValue) }) - .ToList(); - } - - return tenantDevicePermissions.GroupBy(x => x.Tenant).Select(x => - { - var tenant = x.Key; - - return new UserTenantDeviceCodeDto - { - Tenant = tenant, - Codes = x.SelectMany(item => item.Codes).ToList() - }; - }).ToList(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static void DepartmentRecursionGetPNo(string current, List data, List result) - { - var p = data.FirstOrDefault(x => x.No == current)?.PNo; - if (!p.IsPresent()) - { - return; - } - - result.Add(p); - DepartmentRecursionGetPNo(p, data, result); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static void DeviceGroupRecursionGetNext(DeviceGroupEntity current, List currentDeviceGroups, List result, bool add) - { - var next = currentDeviceGroups.Where(x => x.PCode == current.Code).ToList(); - foreach (var item in next) - { - if (add) - { - result.Add(new UserTenantDeviceCodeDto { Tenant = item.TenantId, Codes = new List { item.Code } }); - } - - DeviceGroupRecursionGetNext(item, currentDeviceGroups, result, result.SelectMany(x => x.Codes).Contains(item.Code)); - } - } - - - private async Task>> GetAssignDeviceCodesInternalAsync(List userNos) - { - var devices = await _dbContext.Queryable().Where(x => x.Enable).ToListAsync(); - var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList(); - var registries = await _dbContext.Queryable() - .Where(x => deviceUniqueNos.Contains(x.DeviceUniqueNo)) - .Where(x => !SqlFunc.IsNullOrEmpty(x.BusinessPlaceCode)) - .ToListAsync(); - - var gainfos = await _dbContext.Queryable().Where(x => userNos.Contains(x.No)).ToListAsync(); - if (!gainfos.Any()) - { - return new Dictionary>(); - } - - var enableFactoryPermissions = await _dbContext.Queryable().ToListAsync(); - - var gainfoGroupRelationships = await _dbContext.Queryable().Where(x => userNos.Contains(x.UserNo)).ToListAsync(); - var devicePermissions = await _dbContext.Queryable().ToListAsync(); - var deviceGroups = await _dbContext.Queryable().ToListAsync(); - var deviceRelationships = await _dbContext.Queryable().ToListAsync(); - var departments = await _dbContext.Queryable().ToListAsync(); - - if (_parallelService.Enable) - { - var result = new ConcurrentDictionary>(); - - Parallel.ForEach(gainfos, new ParallelOptions { MaxDegreeOfParallelism = 4 }, gainfo => - { - var gainfoDto = new GainfoDto - { - Id = gainfo.Id, - No = gainfo.No, - Code = gainfo.Code, - Name = gainfo.Name, - Workplace = gainfo.Workplace, - Factory = gainfo.Factory, - DepartmentNo = gainfo.DepartmentNo, - IsOutsource = gainfo.Type == GainfoUserTypeEnumType.Outsource, - EnableFactoryPermission = enableFactoryPermissions.FirstOrDefault(x => x.TenantId == gainfo.Factory)?.EnableOutsourceDown ?? true - }; - - var codes = GetAssignDeviceCodesInternal(gainfoDto, gainfoGroupRelationships, devicePermissions, deviceGroups, deviceRelationships, registries, devices, departments); - result.TryAdd(gainfo.No, codes); - }); - - return result.ToDictionary(x => x.Key, x => x.Value); - } - else - { - var result = new Dictionary>(); - foreach (var gainfo in gainfos) - { - var gainfoDto = new GainfoDto - { - Id = gainfo.Id, - No = gainfo.No, - Code = gainfo.Code, - Name = gainfo.Name, - Workplace = gainfo.Workplace, - Factory = gainfo.Factory, - DepartmentNo = gainfo.DepartmentNo, - IsOutsource = gainfo.Type == GainfoUserTypeEnumType.Outsource, - EnableFactoryPermission = enableFactoryPermissions.FirstOrDefault(x => x.TenantId == gainfo.Factory)?.EnableOutsourceDown ?? true - }; - - var codes = GetAssignDeviceCodesInternal(gainfoDto, gainfoGroupRelationships, devicePermissions, deviceGroups, deviceRelationships, registries, devices, departments); - result.Add(gainfo.No, codes); - } - - return result; - } - } - - - private List GetAssignDeviceCodesInternal( - GainfoDto gainfo, - List gainfoGroupRelationships, - List devicePermissions, - List deviceGroups, - List deviceGroupRelationships, - List deviceRegistries, - List devices, List departments) - { - if (gainfo.IsOutsource) - { - //外包人员不允许餐饮 - devices = devices.Where(x => x.Type != DeviceTypeEnumType.Meal).ToList(); - } - - var userNo = gainfo.No; - - var deviceDtos = new List(); - var deviceGroupDtos = new List(); - var businessPlaceDtos = new List(); - - //获取人员的分组,跨基地 - var gainfoGroups = gainfoGroupRelationships.Where(x => x.UserNo == userNo).Select(x => x.GroupCode).ToList(); - - //按用户 - var du = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, userNo); - var gu = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo); - var pu = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.User, userNo); - deviceDtos.AddRange(du); - deviceGroupDtos.AddRange(gu); - businessPlaceDtos.AddRange(pu); - - //按用户组 - foreach (var groupCode in gainfoGroups) - { - var dg = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, groupCode.ToString()); - var gg = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, groupCode.ToString()); - var pg = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Group, groupCode.ToString()); - deviceDtos.AddRange(dg); - deviceGroupDtos.AddRange(gg); - businessPlaceDtos.AddRange(pg); - } - - //按部门 - var currentAssignValue = gainfo.Factory + ":" + gainfo.DepartmentNo; - var dd = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, currentAssignValue); - var gd = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, currentAssignValue); - var pd = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Department, currentAssignValue); - deviceDtos.AddRange(dd); - deviceGroupDtos.AddRange(gd); - businessPlaceDtos.AddRange(pd); - - //按厂区 - if (!gainfo.IsOutsource || gainfo.EnableFactoryPermission) - { - var dt = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Factory); - var gt = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Factory); - var pt = GetAssignCodesInternal(devicePermissions, deviceGroups, departments, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Tenant, gainfo.Factory); - deviceDtos.AddRange(dt); - deviceGroupDtos.AddRange(gt); - businessPlaceDtos.AddRange(pt); - } - - var deviceGroupCodes = deviceGroupDtos.SelectMany(x => x.Codes).Distinct().ToList(); - var businessPlaceCodes = businessPlaceDtos.SelectMany(x => x.Codes).Distinct().ToList(); - - var deviceCodesByGroup = deviceGroupRelationships.Where(x => deviceGroupCodes.Contains(x.GroupCode)) - .GroupBy(x => x.TenantId) - .Select(x => new UserTenantDeviceCodeDto - { - Tenant = x.Key, - Codes = x.Select(item => item.DeviceCode).Distinct().ToList() - }); - - var placeGroup = deviceRegistries.Where(x => businessPlaceCodes.Contains(x.BusinessPlaceCode!.Value)) - .GroupBy(x => x.TenantId) - .Select(x => - { - var currentDeviceUniqueNos = x.Select(item => item.DeviceUniqueNo).ToList(); - - return new UserTenantDeviceCodeDto - { - Tenant = x.Key, - Codes = devices.Where(d => currentDeviceUniqueNos.Contains(d.UniqueNo)).Select(d => d.Code).Distinct().ToList() - }; - }).ToList(); - - deviceDtos.AddRange(deviceCodesByGroup); - deviceDtos.AddRange(placeGroup); - - return deviceDtos.GroupBy(x => x.Tenant).Select(x => - { - var dto = new UserTenantDeviceCodeDto - { - Tenant = x.Key, - Codes = x.SelectMany(item => item.Codes).Distinct().ToList() - }; - - dto.Codes = dto.Codes.Where(p => devices.Any(item => item.Code == p)).ToList(); - - return dto; - }).ToList(); - } } \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/DepartmentPermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/DepartmentPermissionAnalyzeService.cs new file mode 100644 index 00000000..6a96a821 --- /dev/null +++ b/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/DepartmentPermissionAnalyzeService.cs @@ -0,0 +1,28 @@ +using Dlhis.Entity.Basic.Entity; + +namespace Dlhis.Basic.Device.Services.Implements.PermissionAnalyze; + +[Service(PermissionAnalyzeConstants.Department)] +public class DepartmentPermissionAnalyzeService : BasePermissionAnalyzeService +{ + /// + public DepartmentPermissionAnalyzeService(IServiceProvider serviceProvider) : base(serviceProvider) + { + } + + /// + protected override async Task> GetGainfoNosAsync(string assignValue) + { + var data = assignValue.Split(":"); + var factory = data[0]; + var departmentNo = data[1]; + + var departments = await DbContext.Queryable().ToListAsync(); + var departmentNos = RecursionHelper.HandlerDepartmentNextCodes(departmentNo, departments); + + return await DbContext.Queryable() + .Where(x => x.Factory == factory && departmentNos.Contains(x.DepartmentNo)) + .Select(x => x.No) + .ToListAsync(); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/GroupPermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/GroupPermissionAnalyzeService.cs new file mode 100644 index 00000000..d68de6f8 --- /dev/null +++ b/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/GroupPermissionAnalyzeService.cs @@ -0,0 +1,27 @@ +using Dlhis.Entity.Basic.Entity; + +namespace Dlhis.Basic.Device.Services.Implements.PermissionAnalyze; + +[Service(PermissionAnalyzeConstants.Group)] +public class GroupPermissionAnalyzeService : BasePermissionAnalyzeService +{ + /// + public GroupPermissionAnalyzeService(IServiceProvider serviceProvider) : base(serviceProvider) + { + } + + /// + protected override async Task> GetGainfoNosAsync(string assignValue) + { + var code = Guid.Parse(assignValue); + + var gainfoGroups = await DbContext.Queryable().ToListAsync(); + var gainfoGroupCodes = RecursionHelper.HandlerGainfoGroupNextCodes(code, gainfoGroups); + + return await DbContext.Queryable() + .Where(x => gainfoGroupCodes.Contains(x.GroupCode)) + .Select(x => x.UserNo) + .Distinct() + .ToListAsync(); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/TenantPermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/TenantPermissionAnalyzeService.cs new file mode 100644 index 00000000..d26b9673 --- /dev/null +++ b/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/TenantPermissionAnalyzeService.cs @@ -0,0 +1,18 @@ +using Dlhis.Entity.Basic.Entity; + +namespace Dlhis.Basic.Device.Services.Implements.PermissionAnalyze; + +[Service(PermissionAnalyzeConstants.Tenant)] +public class TenantPermissionAnalyzeService : BasePermissionAnalyzeService +{ + /// + public TenantPermissionAnalyzeService(IServiceProvider serviceProvider) : base(serviceProvider) + { + } + + /// + protected override async Task> GetGainfoNosAsync(string assignValue) + { + return await DbContext.Queryable().Where(x => x.Factory == assignValue).Select(x => x.No).ToListAsync(); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/UserPermissionAnalyzeService.cs b/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/UserPermissionAnalyzeService.cs new file mode 100644 index 00000000..3e819ae4 --- /dev/null +++ b/Src/Dlhis.Basic/Device/Services/Implements/PermissionAnalyze/UserPermissionAnalyzeService.cs @@ -0,0 +1,16 @@ +namespace Dlhis.Basic.Device.Services.Implements.PermissionAnalyze; + +[Service(PermissionAnalyzeConstants.User)] +public class UserPermissionAnalyzeService : BasePermissionAnalyzeService +{ + /// + public UserPermissionAnalyzeService(IServiceProvider serviceProvider) : base(serviceProvider) + { + } + + /// + protected override async Task> GetGainfoNosAsync(string assignValue) + { + return await Task.FromResult(new List { assignValue }); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs index 619dddde..5cd582d7 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs @@ -13,13 +13,13 @@ public class GainfoGroupService : IGainfoGroupService { private readonly IDbContext _dbContext; private readonly ICurrentUser _currentUser; - private readonly IDevicePermissionService _devicePermissionService; + private readonly IDevicePermissionAnalyzeService _devicePermissionAnalyzeService; - public GainfoGroupService(IDbContext dbContext, ICurrentUser currentUser, IDevicePermissionService devicePermissionService) + public GainfoGroupService(IDbContext dbContext, ICurrentUser currentUser, IDevicePermissionAnalyzeService devicePermissionAnalyzeService) { _dbContext = dbContext; _currentUser = currentUser; - _devicePermissionService = devicePermissionService; + _devicePermissionAnalyzeService = devicePermissionAnalyzeService; } public async Task> GetTreeAsync() @@ -82,7 +82,7 @@ public class GainfoGroupService : IGainfoGroupService var existsNextGroup = await _dbContext.Queryable().Where(x => x.PCode == request.GroupCode).AnyAsync(); existsNextGroup.ThrowIfTrue("存在下级分组,无法分配人员"); - await _devicePermissionService.GenerateDeviceTasksAsync(async () => + await _devicePermissionAnalyzeService.GenerateDeviceTasksAsync(async () => { var relations = await _dbContext.Queryable() .Where(x => x.GroupCode == request.GroupCode) diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoPermissionService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoPermissionService.cs index b5a809eb..5889d5ef 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoPermissionService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoPermissionService.cs @@ -18,13 +18,13 @@ namespace Dlhis.Basic.Organization.Services.Implements; public class GainfoPermissionService : IGainfoPermissionService { private readonly IGainfoStore _gainfoStore; - private readonly IDevicePermissionService _devicePermissionService; + private readonly IDevicePermissionAnalyzeService _devicePermissionAnalyzeService; private readonly IDbContext _dbContext; - public GainfoPermissionService(IGainfoStore gainfoStore, IDevicePermissionService devicePermissionService, IDbContext dbContext) + public GainfoPermissionService(IGainfoStore gainfoStore, IDevicePermissionAnalyzeService devicePermissionAnalyzeService, IDbContext dbContext) { _gainfoStore = gainfoStore; - _devicePermissionService = devicePermissionService; + _devicePermissionAnalyzeService = devicePermissionAnalyzeService; _dbContext = dbContext; } @@ -40,7 +40,7 @@ public class GainfoPermissionService : IGainfoPermissionService } //用户所有deviceCode权限 - var deviceCodes = await _devicePermissionService.GetAssignDeviceCodesAsync(gainfo.Code); + var deviceCodes = await _devicePermissionAnalyzeService.GetAssignDeviceCodesAsync(gainfo.Code); return await _dbContext.Queryable() .LeftJoin((x, dr) => x.UniqueNo == dr.DeviceUniqueNo) @@ -120,7 +120,7 @@ public class GainfoPermissionService : IGainfoPermissionService public async Task> GetAssignDeviceCodesAsync(DeviceAssRequest request) { - var ids = await _devicePermissionService.GetAssignDeviceCodesAsync(request.UserNo); + var ids = await _devicePermissionAnalyzeService.GetAssignDeviceCodesAsync(request.UserNo); var page = await _dbContext.Queryable() .LeftJoin((d, dt) => d.TemplateCode == dt.Code) @@ -149,10 +149,6 @@ public class GainfoPermissionService : IGainfoPermissionService .Where(x => x.No == userNo) .SingleAsync(); - - var msg = gainfo == null ? "不存在职数据" : string.Empty; - - //如果找不到就为离职人员 if (gainfo == null) { gainfo = await _dbContext.Queryable().AS("GainfoLeave") @@ -163,16 +159,14 @@ public class GainfoPermissionService : IGainfoPermissionService { gainfo.Id = gainfo.IdentityUserId; } - - msg += gainfo == null ? "并且不存在离职数据" : string.Empty; } - gainfo.ThrowIfNull($"档案数据有误:{msg}"); + gainfo.ThrowIfNull("档案数据不存在"); //获取人员的设备权限 if (deviceCodes.IsEmpty()) { - deviceCodes = await _devicePermissionService.GetAssignDeviceCodesAsync(gainfo!.Code); + deviceCodes = await _devicePermissionAnalyzeService.GetAssignDeviceCodesAsync(gainfo!.Code); } var devices = await _dbContext.Queryable().Where(x => deviceCodes.Contains(x.Code)).ToListAsync(); @@ -198,7 +192,7 @@ public class GainfoPermissionService : IGainfoPermissionService public async Task> GetAssignGroupAsync(string userNo) { //(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo - var groups = await _devicePermissionService.GetAssignmentsAsync(new DeviceGetAssignmentsRequest + var groups = await _devicePermissionAnalyzeService.GetAssignmentsAsync(new DeviceGetAssignmentsRequest { UniqueType = DeviceAssignmentTypeEnumType.Group, AssignType = AssignTypeEnumType.User, diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs index 5681b72c..15fded70 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoUpdateService.cs @@ -16,7 +16,7 @@ public class GainfoUpdateService : IGainfoUpdateService private readonly ILogger _logger; private readonly ITenantApi _tenantApi; private readonly IJinkoSapService _jinkoSapService; - private readonly IDevicePermissionService _devicePermissionService; + private readonly IDevicePermissionAnalyzeService _devicePermissionAnalyzeService; private readonly IIdentityUserSyncService _identityUserSyncService; private List _tenants; @@ -25,7 +25,7 @@ public class GainfoUpdateService : IGainfoUpdateService ILogger logger, ITenantApi tenantApi, IJinkoSapService jinkoSapService, - IDevicePermissionService devicePermissionService, + IDevicePermissionAnalyzeService devicePermissionAnalyzeService, IIdentityUserSyncService identityUserSyncService) { _dbContext = dbContext; @@ -33,7 +33,7 @@ public class GainfoUpdateService : IGainfoUpdateService _logger = logger; _tenantApi = tenantApi; _jinkoSapService = jinkoSapService; - _devicePermissionService = devicePermissionService; + _devicePermissionAnalyzeService = devicePermissionAnalyzeService; _identityUserSyncService = identityUserSyncService; } @@ -169,7 +169,7 @@ public class GainfoUpdateService : IGainfoUpdateService if (item.isowner == "T") { - await _devicePermissionService.GenerateDeviceTasksAsync(async () => + await _devicePermissionAnalyzeService.GenerateDeviceTasksAsync(async () => { await _dbContext.InsertAsync(info); await _identityUserSyncService.SyncAccountAsync(info.Code, info.Name, info.IdNo, info.Factory); @@ -259,7 +259,7 @@ public class GainfoUpdateService : IGainfoUpdateService { if (item.isowner == "T") { - await _devicePermissionService.GenerateDeviceTasksAsync(async () => + await _devicePermissionAnalyzeService.GenerateDeviceTasksAsync(async () => { await _dbContext.Updateable().SetColumns(g => new GainfoEntity { @@ -287,7 +287,7 @@ public class GainfoUpdateService : IGainfoUpdateService } else { - await _devicePermissionService.GenerateDeviceTasksAsync(async () => + await _devicePermissionAnalyzeService.GenerateDeviceTasksAsync(async () => { await _dbContext.Updateable().SetColumns(g => new GainfoEntity { diff --git a/Src/Dlhis.Basic/ParallelExtensions.cs b/Src/Dlhis.Basic/ParallelExtensions.cs new file mode 100644 index 00000000..d8bf78d7 --- /dev/null +++ b/Src/Dlhis.Basic/ParallelExtensions.cs @@ -0,0 +1,9 @@ +namespace Dlhis.Basic; + +public static class ParallelExtensions +{ + public static void ParallelForEach(this IEnumerable source, Action action) + { + Parallel.ForEach(source, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, action); + } +} \ No newline at end of file diff --git a/Src/Dlhis.Basic/RecursionHelper.cs b/Src/Dlhis.Basic/RecursionHelper.cs new file mode 100644 index 00000000..9a953c94 --- /dev/null +++ b/Src/Dlhis.Basic/RecursionHelper.cs @@ -0,0 +1,109 @@ +using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Device.Entities; +using Kurisu.AspNetCore.Utils.Extensions; + +namespace Dlhis.Basic; + +public static class RecursionHelper +{ + public static List HandlerGainfoGroupNextCodes(Guid current, List data) + { + var result = new List { current }; + + InternalHandlerCodes(current, data, result); + + return result; + + static void InternalHandlerCodes(Guid internalCurrent, List internalData, List internalResult) + { + var next = internalData.Where(x => x.PCode == internalCurrent); + foreach (var item in next) + { + internalResult.Add(item.Code); + InternalHandlerCodes(item.Code, internalData, internalResult); + } + } + } + + public static List HandlerGainfoGroupPreviousCodes(Guid current, List data) + { + var result = new List { current }; + + InternalHandlerCodes(current, data, result); + + return result; + + static void InternalHandlerCodes(Guid internalCurrent, List internalData, List internalResult) + { + var pno = internalData.FirstOrDefault(x => x.Code == internalCurrent)?.PCode; + if (!pno.HasValue) + { + return; + } + + internalResult.Add(pno.Value); + InternalHandlerCodes(pno.Value, internalData, internalResult); + } + } + + + public static List HandlerDepartmentNextCodes(string current, List data) + { + var result = new List { current }; + + InternalHandlerCodes(current, data, result); + + return result; + + static void InternalHandlerCodes(string internalCurrent, List internalData, List internalResult) + { + var next = internalData.Where(x => x.PNo == internalCurrent); + foreach (var item in next) + { + internalResult.Add(item.No); + InternalHandlerCodes(item.No, internalData, internalResult); + } + } + } + + public static List HandlerDepartmentPreviousCodes(string current, List data) + { + var result = new List { current }; + + InternalHandlerCodes(current, data, result); + + return result; + + static void InternalHandlerCodes(string internalCurrent, List internalData, List internalResult) + { + var pno = internalData.FirstOrDefault(x => x.No == internalCurrent)?.PNo; + if (pno.IsEmpty()) + { + return; + } + + internalResult.Add(pno); + InternalHandlerCodes(pno, internalData, internalResult); + } + } + + + public static List HandlerDeviceGroupNextCodes(Guid current, List data) + { + var result = new List { current }; + + InternalHandlerCodes(current, data, result); + + return result; + + static void InternalHandlerCodes(Guid internalCurrent, List internalData, List internalResult) + { + var next = internalData.Where(x => x.PCode == internalCurrent); + foreach (var item in next) + { + internalResult.Add(item.Code); + InternalHandlerCodes(item.Code, internalData, internalResult); + } + } + } +} \ No newline at end of file