using Dlhis.Basic.Device.Dtos; using Dlhis.Basic.Device.Request; using Dlhis.Basic.Device.Response; 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.Core.DataAccess.Dto; using Kurisu.Core.DataAccess.Entity; using Kurisu.Core.User.Abstractions; using Kurisu.SqlSugar.Services; using SqlSugar; namespace Dlhis.Basic.Device.Services.Implements; public class DevicePermissionService : IDevicePermissionService { private readonly IDbContext _dbContext; private readonly ICurrentUser _currentUser; public DevicePermissionService(IDbContext dbContext, ICurrentUser currentUser) { _dbContext = dbContext; _currentUser = currentUser; } public async Task AssignAsync(DevicePermissionSaveReuqest reuqest) { await GenerateDeviceTasksAsync(async () => { var tenantId = reuqest.AssignType == AssignTypeEnumType.Department ? reuqest.TenantId : _currentUser.GetStringTenantId(); //删除当前匹配的基地权限 var p = await _dbContext.Queryable() .Where(x => x.AssignType == reuqest.AssignType) .Where(x => x.AssignValue == reuqest.AssignValue) .Where(x => x.UniqueType == reuqest.UniqueType) .Where(x => x.TenantId == tenantId) .ToListAsync(); await _dbContext.DeleteReallyAsync(p); //保存配置的权限 if (reuqest.Codes.IsPresent()) { var devicePermissions = reuqest.Codes.Select(code => new DevicePermissionEntity { AssignType = reuqest.AssignType, AssignValue = reuqest.AssignValue, UniqueType = reuqest.UniqueType, UniqueValue = code, TenantId = tenantId }) .ToList(); await _dbContext.InsertAsync(devicePermissions); } }, null); } public async Task> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue) { var devicePermissions = await _dbContext.Queryable().ToListAsync(); var deviceGroups = await _dbContext.Queryable().ToListAsync(); var result = GetAssignCodesInternal(devicePermissions, deviceGroups, uniqueType, assignType, assignValue); return result.FirstOrDefault(x => x.Tenant == _currentUser.GetStringTenantId())?.Codes; } public async Task GenerateDeviceTasksAsync(Func func, List userNos) { _dbContext.Client.QueryFilter.ClearAndBackup(); try { //获取所有人的权限 if (userNos.IsEmpty()) userNos = await GetPermissionUserNosAsync(); var before = await GetAssignDeviceCodesInternalAsync(userNos); _dbContext.Client.QueryFilter.Restore(); //业务处理 await func(); _dbContext.Client.QueryFilter.ClearAndBackup(); //获取业务处理后所有人的权限 var nextUserNos = await GetPermissionUserNosAsync(); if (nextUserNos.Any()) userNos = userNos.Concat(nextUserNos).Distinct().ToList(); var current = await GetAssignDeviceCodesInternalAsync(userNos); var deivces = await _dbContext.Queryable().ToListAsync(); var waitTasks = new List(); foreach (var userNo in userNos) { before.TryGetValue(userNo, out var beforeTenantDeviceCodes); beforeTenantDeviceCodes ??= new(); current.TryGetValue(userNo, out var currentTenantDeviceCodes); currentTenantDeviceCodes ??= new(); var tenants = beforeTenantDeviceCodes.Select(x => x.Tenant).Concat(currentTenantDeviceCodes.Select(x => x.Tenant)).Distinct().ToList(); foreach (var tenant in tenants) { var currentCodes = currentTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes ?? new(); var beforeCodes = beforeTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes ?? new(); //被删除 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 = deivces.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(); //下发任务创建 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, TenantId = tenant, }).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, TenantId = tenant, }).ToList(); waitTasks.AddRange(toDeleted.Concat(toAdd).ToList()); } } if (waitTasks.Any()) { await _dbContext.InsertAsync(waitTasks); } } finally { _dbContext.Client.QueryFilter.Restore(); } } public async Task GetPermissionUsersInfoAsync() { //获取所有人的权限 var userNos = await GetPermissionUserNosAsync(); var permissions = await GetAssignDeviceCodesInternalAsync(userNos); return new PermissionUsersInfoDto { UserNos = userNos, PermissionInfos = permissions }; } public async Task ReGeneratePermissionUsersInfoAsync(PermissionUsersInfoDto beforeDto) { var userNos = beforeDto.UserNos; var before = beforeDto.PermissionInfos.ToDictionary(x => x.Key, x => x.Value, StringComparer.OrdinalIgnoreCase); //获取业务处理后所有人的权限 var nextUserNos = await GetPermissionUserNosAsync(); if (nextUserNos.Any()) userNos = userNos.Concat(nextUserNos).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); var current = await GetAssignDeviceCodesInternalAsync(userNos); var deivces = await _dbContext.Queryable().ToListAsync(); var waitTasks = new List(); foreach (var userNo in userNos) { before.TryGetValue(userNo, out var beforeTenantDeviceCodes); beforeTenantDeviceCodes ??= new(); current.TryGetValue(userNo, out var currentTenantDeviceCodes); currentTenantDeviceCodes ??= new(); var tenants = beforeTenantDeviceCodes.Select(x => x.Tenant).Concat(currentTenantDeviceCodes.Select(x => x.Tenant)).Distinct().ToList(); foreach (var tenant in tenants) { var currentCodes = currentTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes ?? new(); var beforeCodes = beforeTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes ?? new(); //被删除 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 = deivces.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(); //下发任务创建 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, TenantId = tenant, }).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, TenantId = tenant, }).ToList(); waitTasks.AddRange(toDeleted.Concat(toAdd).ToList()); } } if (waitTasks.Any()) { await _dbContext.InsertAsync(waitTasks); } return waitTasks.Count; } public async Task GenerateDeviceTasksAsync(string userNo, DeviceTaskEnumType taskType) { var deviceCodes = await GetAssignDeviceCodesAsync(userNo); if (!deviceCodes.Any()) { return; } var deivces = await _dbContext.Queryable().Where(x => deviceCodes.Contains(x.Code)).ToListAsync(); deviceCodes = deivces.Select(x => x.Code).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 tasks = deviceCodes.Select(x => new DeviceTaskEntity { DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo, Status = DeviceTaskStatusEnumType.Wait, Type = taskType, UserNo = userNo, Version = 0, }).ToList(); await _dbContext.InsertAsync(tasks); } public async Task> GetCanteenDeviceUniqueNosByUserNoAsync(string userNo) { var all = await GetAssignDeviceCodesAsync(userNo); return await _dbContext.Queryable().Where(x => x.Type == DeviceTypeEnumType.Meal) .Where(x => all.Contains(x.Code)) .Select(x => x.UniqueNo) .ToListAsync(); } /// /// 获取用户所有设备权限 /// /// /// public async Task> GetAssignDeviceCodesAsync(string userNo) { var devices = await _dbContext.Queryable().ToListAsync(); var deviceRegistries = await _dbContext.Queryable().ToListAsync(); var gainfo = await _dbContext.Queryable().Where(x => x.No == userNo).SingleAsync(); var gainfoGroups = await _dbContext.Queryable().ToListAsync(); var devicePermissions = await _dbContext.Queryable().ToListAsync(); var deviceGroups = await _dbContext.Queryable().ToListAsync(); var deviceRelationships = await _dbContext.Queryable().ToListAsync(); var result = GetAssignDeviceCodesInternal(gainfo, gainfoGroups, devicePermissions, deviceGroups, deviceRelationships, deviceRegistries, devices); return result.SelectMany(x => x.Codes).ToList(); } /// /// 获取用户权限设备 /// /// /// public async Task> GetAssigmentByCodeAsync(AssigmentByCodeRequest request) { var lst1 = new List(); //所有设备guid var gds = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, request.No); if (gds != null && gds.Count > 0) { lst1.AddRange(gds); } //所有设备组guid var ggs = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, request.No); //所有营业点guid var gps = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.User, request.No); var devices = await _dbContext.Queryable().ToListAsync(); var regiss = await _dbContext.Queryable().ToListAsync(); if (ggs != null && ggs.Count > 0) { foreach (var gid in ggs) { var ds = await _dbContext.Queryable() .Where(x => x.GroupCode == gid) .Select(x => x.DeviceCode) .ToListAsync(); lst1.AddRange(ds); } } if (gps != null && gps.Count > 0) { foreach (var placeCode in gps) { var nos = regiss.Where(x => x.BusinessPlaceCode == placeCode) .Select(x => x.DeviceUniqueNo).ToList(); var dcodes = devices.Where(d => nos.Contains(d.UniqueNo)) .Select(d => d.Code).ToList(); lst1.AddRange(dcodes); } } var dds = lst1.Distinct().ToList(); var lst = devices.Where(x => dds.Contains(x.Code)) .Select(x => new AssigmentByCodeResponse { UniqueNo = x.UniqueNo, UniqueName = x.Supplier }).ToList(); // 分页操作 var startIndex = (request.PageIndex - 1) * request.PageSize; var pagedData = lst.Skip(startIndex).Take(request.PageSize).ToList(); var pagination = new Pagination { PageIndex = request.PageIndex, PageSize = request.PageSize, Total = lst.Count, // 使用原始列表的总数进行分页 Data = pagedData }; return pagination; } //************************************************ 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).Distinct().ToList(); } private static List GetAssignCodesInternal( List devicePermissions, List deviceGroups, DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue) { var tenantDevicePermissions = devicePermissions .Where(x => x.UniqueType == uniqueType) .Where(x => x.AssignType == assignType) .Where(x => x.AssignValue == assignValue) .GroupBy(x => x.TenantId) .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(x => x.UniqueValue).ToList() }) .ToList(); //处理获取设备分组的情况 if (uniqueType == DeviceAssignmentTypeEnumType.Group) { //开始递归处理 var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList(); tops.ForEach(x => { RecursionGetNext(x, deviceGroups, tenantDevicePermissions, tenantDevicePermissions.SelectMany(x => x.Codes).Contains(x.Code)); }); } 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(); 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(new UserTenantDeviceCodeDto { Tenant = item.TenantId, Codes = new List { item.Code } }); } RecursionGetNext(item, deviceGroups, result, result.SelectMany(x => x.Codes).Contains(item.Code)); } } } private async Task>> GetAssignDeviceCodesInternalAsync(List userNos) { var devices = await _dbContext.Queryable().ToListAsync(); var regiss = await _dbContext.Queryable().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 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 result = new Dictionary>(gainfos.Count, StringComparer.OrdinalIgnoreCase); foreach (var gainfo in gainfos) { var codes = GetAssignDeviceCodesInternal(gainfo, gainfoGroupRelationships, devicePermissions, deviceGroups, deviceRelationships, regiss, devices); result.Add(gainfo.No, codes); } return result; } private static List GetAssignDeviceCodesInternal( GainfoEntity gainfo, List gainfoGroupRelationships, List devicePermissions, List deviceGroups, List deviceGroupRelationships, List deviceRegistries, List devices ) { var userNo = gainfo.No; var deviceCodes = new List(); var deviceGroupCodes = new List(); var placeCodes = new List(); //获取人员的分组,跨基地 var gainfoGroups = gainfoGroupRelationships.Where(x => x.UserNo == userNo).Select(x => x.GroupCode).ToList(); //按用户 var du = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, userNo); var gu = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo); var pu = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.User, userNo); deviceCodes.AddRange(du); deviceGroupCodes.AddRange(gu); placeCodes.AddRange(pu); //按用户组 foreach (var groupCode in gainfoGroups) { var dg = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, groupCode.ToString()); var gg = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, groupCode.ToString()); var pg = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Group, groupCode.ToString()); deviceCodes.AddRange(dg); deviceGroupCodes.AddRange(gg); placeCodes.AddRange(pg); } //按部门 var gainfoFactoryDevicePermissions = devicePermissions.Where(x => x.TenantId == gainfo.Factory).ToList(); var dd = GetAssignCodesInternal(gainfoFactoryDevicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, gainfo.DepartmentNo); var gd = GetAssignCodesInternal(gainfoFactoryDevicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, gainfo.DepartmentNo); var pd = GetAssignCodesInternal(gainfoFactoryDevicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Department, gainfo.DepartmentNo); deviceCodes.AddRange(dd); deviceGroupCodes.AddRange(gd); placeCodes.AddRange(pd); //按厂区 var dt = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Factory); var gt = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Factory); var pt = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.BusinessPlace, AssignTypeEnumType.Tenant, gainfo.Factory); placeCodes.AddRange(pt); deviceCodes.AddRange(dt); deviceGroupCodes.AddRange(gt); var groupCodes = deviceGroupCodes.SelectMany(x => x.Codes).Distinct().ToList(); var placecodes = placeCodes.SelectMany(x => x.Codes).Distinct().ToList(); var deveiceCodesByGroup = deviceGroupRelationships.Where(x => groupCodes.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 => placecodes.Contains((Guid)x.BusinessPlaceCode)).GroupBy(x => x.TenantId) .Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, }).ToList(); placeGroup.ForEach(t => { var nos = deviceRegistries.Where(x => placecodes.Contains((Guid)x.BusinessPlaceCode)) .Where(x => x.TenantId == t.Tenant) .Select(x => x.DeviceUniqueNo) .ToList(); t.Codes = devices.Where(d => nos.Contains(d.UniqueNo)).Select(d => d.Code).ToList(); }); deviceCodes.AddRange(deveiceCodesByGroup); deviceCodes.AddRange(placeGroup); return deviceCodes.GroupBy(x => x.Tenant).Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.SelectMany(item => item.Codes).Distinct().ToList() }).ToList(); } }