Files
jinko.yikatong/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs

422 lines
17 KiB
C#

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.SqlSugar.Attributes;
using Kurisu.SqlSugar.Services;
using System.Collections.Generic;
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 () =>
{
var p = await _dbContext.Queryable<DevicePermissionEntity>()
.Where(x => x.AssignType == reuqest.AssignType)
.Where(x => x.AssignValue == reuqest.AssignValue)
.Where(x => x.UniqueType == reuqest.UniqueType)
.ToListAsync();
await _dbContext.DeleteReallyAsync(p);
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<List<Guid>> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue)
{
var devicePermissions = await _dbContext.Queryable<DevicePermissionEntity>()
.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<DeviceGroupEntity>().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<DeviceGroupEntity> deviceGroups, List<Guid> 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<Task> func, List<string> userNos)
{
if (userNos.IsEmpty())
{
userNos = await GetPermissionUserNosAsync();
}
var beforeDic = await GetAssignDeviceCodesAsync(userNos);
//获取处理
await func();
//获取当前的权限code
var nextUserNos = await GetPermissionUserNosAsync();
if (nextUserNos.Any())
{
userNos = nextUserNos;
}
var currentDic = await GetAssignDeviceCodesAsync(userNos);
var deivces = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
foreach (var userNo in userNos)
{
beforeDic.TryGetValue(userNo, out var beforeCodes);
beforeCodes ??= new List<Guid>();
currentDic.TryGetValue(userNo, out var currentCodes);
currentCodes ??= new List<Guid>();
//被删除
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 userInfo = await _dbContext.Queryable<GainfoEntity>()
.LeftJoin<DepartmentEntity>((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);
}
}
public async Task GenerateDeviceTasksAsync(string userNo, DeviceTaskEnumType taskType)
{
var deviceCodes = await GetAssignDeviceCodesAsync(userNo);
if (!deviceCodes.Any())
{
return;
}
var deivces = await _dbContext.Queryable<DeviceEntity>().Where(x => deviceCodes.Contains(x.Code)).ToListAsync();
deviceCodes = deivces.Select(x => x.Code).ToList();
var userInfo = await _dbContext.Queryable<GainfoEntity>()
.LeftJoin<DepartmentEntity>((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,
UserCode = userInfo.Code,
}).ToList();
await _dbContext.InsertAsync(tasks);
}
public async Task<List<string>> GetCanteenDeviceUniqueNosByUserNoAsync(string userNo)
{
var all = await GetAssignDeviceCodesAsync(userNo);
return await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Meal)
.Where(x => all.Contains(x.Code))
.Select(x => x.UniqueNo)
.ToListAsync();
}
/// <summary>
/// 获取用户所有设备权限
/// </summary>
/// <param name="userNo"></param>
/// <returns></returns>
public async Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo)
{
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.No == userNo).SingleAsync();
var gainfoGroups = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().Where(x => x.UserNo == userNo).Select(x => x.GroupCode).ToListAsync();
var deviceCodes = new List<Guid>();
var deviceGroupCodes = new List<Guid>();
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<DeviceGroupRelationshipEntity>().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync();
deviceCodes.AddRange(deveiceCodesByGroup);
return deviceCodes.Distinct().ToList();
}
private async Task<Dictionary<string, List<Guid>>> GetAssignDeviceCodesAsync(List<string> userNos)
{
var gainfos = await _dbContext.Queryable<GainfoEntity>().Where(x => userNos.Contains(x.No)).ToListAsync();
if (!gainfos.Any())
{
return new Dictionary<string, List<Guid>>();
}
var gainfoGroupRelationships = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().ToListAsync();
var devicePermissions = await _dbContext.Queryable<DevicePermissionEntity>().ToListAsync();
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
var result = new Dictionary<string, List<Guid>>();
foreach (var gainfo in gainfos)
{
var userNo = gainfo.No;
var gainfoGroups = gainfoGroupRelationships.Where(x => x.UserNo == userNo).ToList();
var deviceCodes = new List<Guid>();
var deviceGroupCodes = new List<Guid>();
var du = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, userNo);
var gu = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo);
deviceCodes.AddRange(du);
deviceGroupCodes.AddRange(gu);
foreach (var group in gainfoGroups)
{
var dg = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, group.ToString());
var gg = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, group.ToString());
deviceCodes.AddRange(dg);
deviceGroupCodes.AddRange(gg);
}
var dd = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, gainfo.DepartmentNo);
var gd = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, gainfo.DepartmentNo);
deviceCodes.AddRange(dd);
deviceGroupCodes.AddRange(gd);
var dt = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Werks);
var gt = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Werks);
deviceCodes.AddRange(du);
deviceGroupCodes.AddRange(gu);
var deveiceCodesByGroup = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync();
deviceCodes.AddRange(deveiceCodesByGroup);
result.Add(userNo, deviceCodes.Distinct().ToList());
}
return result;
List<Guid> GetAssignmentsInternal(DeviceAssignmentTypeEnumType uniqueTypeInternal, AssignTypeEnumType assignTypeInternal, string assignValueInternal)
{
var devicePermissionsInternal = devicePermissions.Where(x => x.UniqueType == uniqueTypeInternal)
.Where(x => x.AssignType == assignTypeInternal)
.Where(x => x.AssignValue == assignValueInternal)
.Select(x => x.UniqueValue)
.ToList();
if (uniqueTypeInternal == DeviceAssignmentTypeEnumType.Group)
{
var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList();
tops.ForEach(x =>
{
RecursionGetNext(x, deviceGroups, devicePermissionsInternal, devicePermissionsInternal.Contains(x.Code));
});
}
return devicePermissionsInternal.Distinct().ToList();
void RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups, List<Guid> 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));
}
}
}
}
/// <summary>
/// 获取用户权限设备
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public async Task<Pagination<AssigmentByCodeResponse>> GetAssigmentByCodeAsync(AssigmentByCodeRequest request)
{
//所有设备guid
var gds = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, request.No);
//所有设备组guid
var ggs = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, request.No);
var devices = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
if (ggs != null && ggs.Count > 0)
{
foreach (var gid in ggs)
{
var ds = await _dbContext.Queryable<DeviceGroupRelationshipEntity>()
.Where(x => x.GroupCode == gid)
.Select(x => x.DeviceCode)
.ToListAsync();
gds.AddRange(ds);
}
}
var dds = gds.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<AssigmentByCodeResponse>
{
PageIndex = request.PageIndex,
PageSize = request.PageSize,
Total = lst.Count, // 使用原始列表的总数进行分页
Data = pagedData
};
return pagination;
}
//************************************************ help methods *******************************************************
/// <summary>
/// 获取当前基地有权限的用户
/// </summary>
/// <returns></returns>
private async Task<List<string>> GetPermissionUserNosAsync()
{
var permissions = await _dbContext.Queryable<DevicePermissionEntity>().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<GainfoGroupRelationshipEntity>()
.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<GainfoEntity>().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<GainfoEntity>().Where(x => tenants.Contains(x.Werks)).Select(x => x.No).ToListAsync();
return userNos.Concat(userNosByGroup).Concat(userNosByDepartment).Concat(userNosByWerk).ToList();
}
}