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.Utils.Extensions; using Kurisu.SqlSugar.Attributes; using Kurisu.SqlSugar.Services; namespace Dlhis.Basic.Device.Services.Implements; public class DevicePermissionService : IDevicePermissionService { private readonly IDbContext _dbContext; public DevicePermissionService(IDbContext dbContext) { _dbContext = dbContext; } [Transactional] public async Task AssignAsync(DevicePermissionSaveReuqest reuqest) { await GenerateDeviceTasksAsync(async () => { await _dbContext.Client.Deleteable() .Where(x => x.AssignType == reuqest.AssignType) .Where(x => x.AssignValue == reuqest.AssignValue) .ExecuteCommandAsync(); var devicePermissions = reuqest.Codes.Select(x => new DevicePermissionEntity { AssignType = reuqest.AssignType, AssignValue = reuqest.AssignValue, UniqueType = reuqest.UniqueType, UniqueValue = x, }).ToList(); await _dbContext.InsertAsync(devicePermissions); }, null); } public async Task> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue) { var devicePermissions = await _dbContext.Queryable() .Where(x => x.UniqueType == uniqueType) .Where(x => x.AssignType == assignType) .Where(x => x.AssignValue == assignValue) .Select(x => x.UniqueValue) .ToListAsync(); if (uniqueType == DeviceAssignmentTypeEnumType.Group) { var deviceGroups = await _dbContext.Queryable().ToListAsync(); var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList(); tops.ForEach(x => { RecursionGetNext(x, deviceGroups, devicePermissions, devicePermissions.Contains(x.Code)); }); } return devicePermissions.Distinct().ToList(); void RecursionGetNext(DeviceGroupEntity current, List deviceGroups, List result, bool add) { var next = deviceGroups.Where(x => x.PCode == current.Code).ToList(); foreach (var item in next) { if (add) result.Add(item.Code); RecursionGetNext(item, deviceGroups, result, result.Contains(item.Code)); } } } public async Task GenerateDeviceTasksAsync(Func func, List userNos) { if (userNos.IsEmpty()) { userNos = await GetPermissionUserNosAsync(); } var beforeDic = new Dictionary>(userNos.Count); foreach (var userNo in userNos) { beforeDic.TryAdd(userNo, await GetAssignDeviceCodesAsync(userNo)); } //获取处理 await func(); //获取当前的权限code var currentDic = new Dictionary>(userNos.Count); userNos = await GetPermissionUserNosAsync(); foreach (var userNo in userNos) { currentDic.TryAdd(userNo, await GetAssignDeviceCodesAsync(userNo)); } foreach (var userNo in userNos) { beforeDic.TryGetValue(userNo, out var beforeCodes); if (beforeCodes == null) beforeCodes = new List(); currentDic.TryGetValue(userNo, out var currentCodes); if (currentCodes == null) currentCodes = 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 deivces = await _dbContext.Queryable().Where(x => deletedItems.Contains(x.Code) || addItems.Contains(x.Code)).ToListAsync(); var deviceCodes = deivces.Select(x => x.Code).ToList(); deletedItems = deletedItems.Where(x => deviceCodes.Contains(x)).ToList(); addItems = addItems.Where(x => deviceCodes.Contains(x)).ToList(); var userInfo = await _dbContext.Queryable() .LeftJoin((ga, department) => department.No == ga.DepartmentNo) .Where(ga => ga.No == userNo) .Select(ga => new { ga.Code }) .SingleAsync(); //下发任务创建 var toDeleted = deletedItems.Select(x => new DeviceTaskEntity { DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo, Status = DeviceTaskStatusEnumType.Wait, Type = DeviceTaskEnumType.Delete, UserNo = userNo, Version = 0, UserCode = userInfo.Code, }).ToList(); var toAdd = addItems.Select(x => new DeviceTaskEntity { DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo, Status = DeviceTaskStatusEnumType.Wait, Type = DeviceTaskEnumType.Add, UserNo = userNo, Version = 0, UserCode = userInfo.Code, }).ToList(); var tasks = toDeleted.Concat(toAdd).ToList(); await _dbContext.InsertAsync(tasks); } } //************************************************ 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).ToList(); //Group var groupCode = permissions.Where(x => x.AssignType == AssignTypeEnumType.Group).Select(x => Guid.Parse(x.AssignValue)).ToList(); var userNosByGroup = await _dbContext.Queryable() .Where(x => groupCode.Contains(x.GroupCode)) .Select(x => x.UserNo) .ToListAsync(); //Department var departmentNos = permissions.Where(x => x.AssignType == AssignTypeEnumType.Department).Select(x => x.AssignValue).ToList(); var userNosByDepartment = await _dbContext.Queryable().Where(x => departmentNos.Contains(x.DepartmentNo)).Select(x => x.No).ToListAsync(); //Tenant var tenants = permissions.Where(x => x.AssignType == AssignTypeEnumType.Tenant).Select(x => x.AssignValue).ToList(); var userNosByWerk = await _dbContext.Queryable().Where(x => tenants.Contains(x.Werks)).Select(x => x.No).ToListAsync(); return userNos.Concat(userNosByGroup).Concat(userNosByDepartment).Concat(userNosByWerk).ToList(); } /// /// 获取用户所有设备权限 /// /// /// private async Task> GetAssignDeviceCodesAsync(string userNo) { var gainfo = await _dbContext.Queryable().Where(x => x.No == userNo).SingleAsync(); var gainfoGroups = await _dbContext.Queryable().Where(x => x.UserNo == userNo).Select(x => x.GroupCode).ToListAsync(); var deviceCodes = new List(); var deviceGroupCodes = new List(); var du = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, userNo); var gu = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo); deviceCodes.AddRange(du); deviceGroupCodes.AddRange(gu); foreach (var group in gainfoGroups) { var dg = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, group.ToString()); var gg = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, group.ToString()); deviceCodes.AddRange(dg); deviceGroupCodes.AddRange(gg); } var dd = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, gainfo.DepartmentNo); var gd = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, gainfo.DepartmentNo); deviceCodes.AddRange(dd); deviceGroupCodes.AddRange(gd); var dt = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Werks); var gt = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Werks); deviceCodes.AddRange(du); deviceGroupCodes.AddRange(gu); var deveiceCodesByGroup = await _dbContext.Queryable().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync(); deviceCodes.AddRange(deveiceCodesByGroup); return deviceCodes.Distinct().ToList(); } }