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 Dlhis.Entity.Visitor.Entity; using Dlhis.Sys.Api; using Kurisu.AspNetCore.Authentication.Abstractions; using Kurisu.AspNetCore.DataAccess.Dto; using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions; using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; using Kurisu.AspNetCore.Utils.Extensions; using OfficeOpenXml; using SqlSugar; namespace Dlhis.Basic.Device.Services.Implements; public class DevicePermissionService : IDevicePermissionService { private readonly IDbContext _dbContext; private readonly ITenantApi _tenantApi; private readonly INamedResolver _namedResolver; private readonly IDevicePermissionAnalyzeService _devicePermissionAnalyzeService; private readonly ICurrentUser _currentUser; public DevicePermissionService(IDbContext dbContext, ITenantApi tenantApi, INamedResolver namedResolver, IDevicePermissionAnalyzeService devicePermissionAnalyzeService, ICurrentUser currentUser) { _dbContext = dbContext; _tenantApi = tenantApi; _namedResolver = namedResolver; _devicePermissionAnalyzeService = devicePermissionAnalyzeService; _currentUser = currentUser; } public async Task AssignAsync(DevicePermissionSaveRequest request) { return await _namedResolver .GetService(PermissionAnalyzeConstants.GetTypeName(request.AssignType)) .AnalyzeAsync(request); } public async Task AssignToUniqueAsync(DevicePermissionsAssignToDeviceRequest request) { var currentTenantId = _currentUser.GetStringTenantId(); var today = DateTime.Today; var factories = _currentUser.GetUserClaim("tenants").Split(",").ToList(); var device = await _dbContext.Queryable().Where(x => x.Code == request.UniqueValue).SingleAsync(); device.ThrowIfNull("设备不存在"); //删除当前匹配的基地权限 var p = await _dbContext.Queryable() .Where(x => x.UniqueType == request.UniqueType) .Where(x => x.UniqueValue == request.UniqueValue) .Where(x => x.AssignType == request.AssignType) .Where(x => x.Type == request.Type) .Where(x => x.TenantId == currentTenantId) .ToListAsync(); var beforeNos = p.Select(x => x.AssignValue).ToList(); var presentNos = new List(); if (request.Values.IsPresent()) { presentNos = await _dbContext.Client.Queryable() .Where(gainfo => factories.Contains(gainfo.Factory) || SqlFunc.Subqueryable() .Where(x => factories.Contains(x.Destination) && SqlFunc.DateIsSame(x.BeginDate, today)) .Any() ) .Where(gainfo => request.Values.Contains(gainfo.Code) || request.Values.Contains(gainfo.No) || request.Values.Contains(gainfo.IdNo)) .Select(gainfo => gainfo.No) .ToListAsync(); //gainfoNos = gainfoNos.Concat(nos).Distinct().ToList(); } var adds = presentNos.Except(beforeNos); var deletes = beforeNos.Except(presentNos); await _dbContext.DeleteAsync(p); var devicePermissions = presentNos.Select(v => new DevicePermissionEntity { UniqueType = request.UniqueType, UniqueValue = request.UniqueValue, AssignType = request.AssignType, AssignValue = v, TenantId = currentTenantId, Type = request.Type }).ToList(); await _dbContext.InsertAsync(devicePermissions); await _dbContext.InsertAsync(adds.Select(x => new DeviceTaskEntity { Type = DeviceTaskEnumType.Add, DeviceType = device.Type, UserId = null, UserNo = x, DeviceUniqueNo = device.UniqueNo, Status = DeviceTaskStatusEnumType.Wait, Version = 0, ResultMessage = null, CancellationId = 0, Source = DeviceTaskSourceEnumType.Manually, Priority = 0, TenantId = currentTenantId, }).ToList()); await _dbContext.InsertAsync(deletes.Select(x => new DeviceTaskEntity { Type = DeviceTaskEnumType.Delete, DeviceType = device.Type, UserId = null, UserNo = x, DeviceUniqueNo = device.UniqueNo, Status = DeviceTaskStatusEnumType.Wait, Version = 0, ResultMessage = null, CancellationId = 0, Source = DeviceTaskSourceEnumType.Manually, Priority = 0, TenantId = currentTenantId }).ToList()); // await GenerateDeviceTasksAsync(async () => // { // await _dbContext.DeleteAsync(p); // // //保存配置的权限 // if (request.Values.IsPresent()) // { // var nos = await _dbContext.Client.Queryable() // .Where(gainfo => factories.Contains(gainfo.Factory) || SqlFunc.Subqueryable() // .Where(x => factories.Contains(x.Destination) && SqlFunc.DateIsSame(x.BeginDate, today)) // .Any() // ) // .Where(gainfo => request.Values.Contains(gainfo.Code) || request.Values.Contains(gainfo.No) || request.Values.Contains(gainfo.IdNo)) // .Select(gainfo => gainfo.No) // .ToListAsync(); // // //todo 临时注释 // //(gainfoNos.Count != request.Values.Count).ThrowIfTrue("存在非当前权限访问的人员,操作禁止!"); // // var devicePermissions = nos.Select(v => new DevicePermissionEntity // { // UniqueType = request.UniqueType, // UniqueValue = request.UniqueValue, // AssignType = request.AssignType, // AssignValue = v, // TenantId = currentTenantId, // Type = request.Type // }).ToList(); // // await _dbContext.InsertAsync(devicePermissions); // } // }, gainfoNos); } /// public async Task AssignToUniqueImportAsync(IFormFile file) { var deviceNo = Path.GetFileNameWithoutExtension(file.FileName); var device = await _dbContext.Queryable().Where(x => x.UniqueNo == deviceNo).SingleAsync(); device.ThrowIfNull("设备不存在"); ExcelPackage.LicenseContext = LicenseContext.NonCommercial; using (var package = new ExcelPackage(file.OpenReadStream())) { ExcelWorksheet worksheet = package.Workbook.Worksheets[0]; int rowCount = worksheet.Dimension.Rows; // 获取行数 int colCount = worksheet.Dimension.Columns; // 获取列数 var list = new List(); for (int i = 1; i < rowCount; i++) { var userCode = worksheet.Cells[i + 1, 2].GetCellValue(); list.Add(userCode); } foreach (var items in list.Chunk(500)) { var gainfoNos = await _dbContext.Queryable().Where(x => items.Contains(x.Code)).Select(x => x.No).ToListAsync(); var permissions = gainfoNos.Select(x => new DevicePermissionEntity { AssignType = AssignTypeEnumType.User, AssignValue = x, UniqueType = DeviceAssignmentTypeEnumType.Device, UniqueValue = device.Code, Type = device.Type, TenantId = device.TenantId, IsDeleted = false }).ToList(); await _dbContext.InsertAsync(permissions); var tasks = permissions.Select(x => new DeviceTaskEntity { Type = DeviceTaskEnumType.Add, DeviceType = x.Type, UserId = null, UserNo = x.AssignValue, DeviceUniqueNo = device.UniqueNo, Status = DeviceTaskStatusEnumType.Wait, Version = 0, ResultMessage = null, CancellationId = 0, Source = DeviceTaskSourceEnumType.Manually, Priority = 0, TenantId = device.TenantId, }).ToList(); await _dbContext.InsertAsync(tasks); } } } /// public async Task>> GetUserDevicePermissionsAsync(string code) { var userNo = await _dbContext.Queryable().Where(x => x.Code == code).Select(x => x.No).SingleAsync(); var result = await _devicePermissionAnalyzeService.GetUserAssignDeviceCodesWithTypeInTenantAsync(new List { userNo }); return result.ToDictionary(x => x.Key, x => x.Value.GroupBy(p => p.Tenant).Select(item => { return new UserTenantDeviceCodeDto { Tenant = item.Key, Codes = item.SelectMany(p => p.AssignTypes).SelectMany(p => p.Codes).Distinct().ToList(), }; })); } public async Task> GetGainfoPageByDeviceAsync(DeviceWithGainfoRequest request) { var device = await _dbContext.Queryable().Where(x => x.UniqueNo == request.DeviceUniqueNo).SingleAsync(); device.ThrowIfNull("设备不存在"); var departments = await _dbContext.Queryable().ToListAsync(); //当前设备的分组 var groups = await _dbContext.Queryable() .Where(x => x.DeviceCode == device.Code) .Select(x => x.GroupCode) .ToListAsync(); var permissions = await _dbContext.Queryable() .Where(x => (x.UniqueType == DeviceAssignmentTypeEnumType.Device && x.UniqueValue == device.Code) || (x.UniqueType == DeviceAssignmentTypeEnumType.Group && groups.Contains(x.UniqueValue))) .ToListAsync(); var ids = new List(); foreach (var permission in permissions) { switch (permission.AssignType) { case AssignTypeEnumType.User: ids.Add(await _dbContext.Queryable().Where(x => x.No == permission.AssignValue).Select(x => x.Id).SingleAsync()); break; case AssignTypeEnumType.Group: { var code = Guid.Parse(permission.AssignValue); ids.AddRange(await _dbContext.Queryable().Where(x => x.Code == code) .LeftJoin((a, b) => a.Code == b.GroupCode) .LeftJoin((a, b, c) => b.UserNo == c.No) .Select((a, b, c) => c.Id).ToListAsync()); } break; case AssignTypeEnumType.Department: { //递归向上获取 assignValue = department.No var arr = permission.AssignValue.Split(":"); var tenantId = arr.First(); var currentDepartmentNo = arr.Last(); var departmentNos = new List { currentDepartmentNo }; DepartmentRecursionGetNext(currentDepartmentNo, departments, departmentNos); ids.AddRange(await _dbContext.Queryable().Where(x => x.Factory == tenantId && departmentNos.Contains(x.DepartmentNo)).Select(x => x.Id).ToListAsync()); } break; case AssignTypeEnumType.Tenant: { ids.AddRange(await _dbContext.Queryable().Where(x => x.Factory == permission.AssignValue).Select(x => x.Id).ToListAsync()); } break; default: throw new ArgumentOutOfRangeException(); } } ids = ids.Distinct().ToList(); var page = await _dbContext.Queryable() .Where(x => ids.Contains(x.Id)) .WhereIF(request.Search.IsPresent(), x => x.Code == request.Search || x.Name.Contains(request.Search)) .Select() .ToPageListAsync(request); var userNos = page.Data.Select(x => x.No).ToList(); var downStatus = await _dbContext.Queryable() .Where(x => userNos.Contains(x.UserNo)) .Where(x => x.DeviceUniqueNo == device.UniqueNo) .Where(x => x.Status == DeviceTaskStatusEnumType.Success) .Select(x => new { num = SqlFunc.RowNumber(SqlFunc.Desc(x.ModifiedTime), x.UserNo), x.UserNo, x.Status, x.ResultMessage, x.ModifiedTime }).MergeTable() .Where(x => x.num == 1) .ToListAsync(); var tenants = await _tenantApi.GetTenantsInternalAsync(); page.Data.ForEach(x => { x.Workplace = tenants.FirstOrDefault(item => item.Code == x.Workplace)?.Name; x.Factory = tenants.FirstOrDefault(item => item.Code == x.Factory)?.Name; var d = downStatus.FirstOrDefault(item => item.UserNo == x.No); if (d == null) { return; } x.Status = d.Status; x.ResultMessage = d.ResultMessage; x.ModifiedTime = d.ModifiedTime; }); return page; } /// public async Task ResetGainfoPageByDeviceAsync(DeviceGainfoReset request) { var device = await _dbContext.Queryable().Where(x => x.Code == request.Code).SingleAsync(); device.ThrowIfNull("设备不存在"); var departments = await _dbContext.Queryable().ToListAsync(); //当前设备的分组 var groups = await _dbContext.Queryable() .Where(x => x.DeviceCode == device.Code) .Select(x => x.GroupCode) .ToListAsync(); var permissions = await _dbContext.Queryable() .Where(x => (x.UniqueType == DeviceAssignmentTypeEnumType.Device && x.UniqueValue == device.Code) || (x.UniqueType == DeviceAssignmentTypeEnumType.Group && groups.Contains(x.UniqueValue))) .ToListAsync(); var gainfoNos = new List(); foreach (var permission in permissions) { switch (permission.AssignType) { case AssignTypeEnumType.User: gainfoNos.Add(await _dbContext.Queryable().Where(x => x.No == permission.AssignValue).Select(x => x.No).SingleAsync()); break; case AssignTypeEnumType.Group: { var code = Guid.Parse(permission.AssignValue); gainfoNos.AddRange(await _dbContext.Queryable().Where(x => x.Code == code) .LeftJoin((a, b) => a.Code == b.GroupCode) .LeftJoin((a, b, c) => b.UserNo == c.No) .Select((a, b, c) => c.No).ToListAsync()); } break; case AssignTypeEnumType.Department: { //递归向上获取 assignValue = department.No var arr = permission.AssignValue.Split(":"); var tenantId = arr.First(); var currentDepartmentNo = arr.Last(); var departmentNos = new List { currentDepartmentNo }; DepartmentRecursionGetNext(currentDepartmentNo, departments, departmentNos); gainfoNos.AddRange(await _dbContext.Queryable().Where(x => x.Factory == tenantId && departmentNos.Contains(x.DepartmentNo)).Select(x => x.No).ToListAsync()); } break; case AssignTypeEnumType.Tenant: { gainfoNos.AddRange(await _dbContext.Queryable().Where(x => x.Factory == permission.AssignValue).Select(x => x.No).ToListAsync()); } break; default: throw new ArgumentOutOfRangeException(); } } gainfoNos = gainfoNos.Distinct().ToList(); await _dbContext.InsertAsync(gainfoNos.Select(x => new DeviceTaskEntity { DeviceUniqueNo = device.UniqueNo, Status = DeviceTaskStatusEnumType.Wait, Type = DeviceTaskEnumType.Delete, CancellationId = 0, DeviceType = device.Type, UserNo = x, Version = 0, TenantId = device.TenantId, Source = DeviceTaskSourceEnumType.Manually }).ToList()); } void DepartmentRecursionGetNext(string current, List data, List result) { var next = data.Where(x => x.PNo == current); foreach (var item in next) { result.Add(item.No); DepartmentRecursionGetNext(item.No, data, result); } } public async Task GenerateDeviceTasksAsync(string userNo, DeviceTaskEnumType taskType, DeviceTaskSourceEnumType source) { var deviceCodes = await GetAssignDeviceCodesAsync(userNo); if (!deviceCodes.Any()) return; var devices = await _dbContext.Queryable() .Where(x => x.Enable) .Where(x => deviceCodes.Contains(x.Code)) .ToListAsync(); var tasks = devices.Select(x => new DeviceTaskEntity { DeviceUniqueNo = x.UniqueNo, Status = DeviceTaskStatusEnumType.Wait, Type = taskType, DeviceType = x.Type, UserNo = userNo, CancellationId = 0, Priority = 0, Version = 0, TenantId = x.TenantId, Source = source }).ToList(); await _dbContext.InsertAsync(tasks); } /// /// 获取用户所有设备权限 /// /// /// 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 _devicePermissionAnalyzeService.GetUserAssignDeviceCodesWithTypeInTenantAsync(new List { userNo }); return result.First().Value.SelectMany(x => x.AssignTypes.SelectMany(p => p.Codes)).Distinct().ToList(); } }