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

226 lines
9.2 KiB
C#

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<ICurrentUser>();
_devicePermissionAnalyzeService = serviceProvider.GetService<IDevicePermissionAnalyzeService>();
_myDataPermissionService = serviceProvider.GetService<IMyDataPermissionService>();
DbContext = serviceProvider.GetService<IDbContext>();
CurrentTenantId = _currentUser.GetStringTenantId();
}
private string CurrentTenantId { get; }
public ISugarQueryable<DevicePermissionEntity> DevicePermission => DbContext.Queryable<DevicePermissionEntity>();
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<Guid> codesToAdd, List<Guid> codesToDelete) = await GetDiffAsync(request.UniqueType, dps, request.Codes);
if (codesToAdd.IsEmpty() && codesToDelete.IsEmpty())
{
return;
}
var devicesToAdd = await DbContext.Queryable<DeviceEntity>().Where(x => codesToAdd.Contains(x.Code)).Distinct().ToListAsync();
var devicesToDelete = await DbContext.Queryable<DeviceEntity>().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<string, List<TenantAssignTypeDeviceCode>>();
var tasks = new List<DeviceTaskEntity>();
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<T>(List<T> batch) where T : class, new()
{
foreach (var tasks in batch.Chunk(500))
{
await DbContext.InsertAsync(tasks);
}
}
/// <summary>
/// 获取分配当前类型关联的用户
/// </summary>
/// <param name="assignValue"></param>
/// <returns></returns>
protected abstract Task<List<string>> 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<IDbContext>();
await currentDb.IgnoreAsync<ITenantId>(async () =>
{
var dgs = await currentDb.Queryable<DeviceGroupEntity>().Where(x => request.Codes.Contains(x.Code)).ToListAsync();
dgs.Any(x => x.TenantId.IsEmpty()).ThrowIfTrue("不可分配顶级分组节点");
});
});
}
}
private async Task PersistDataAsync(List<DevicePermissionEntity> 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<Guid> GetMyUniqueValues(DeviceAssignmentTypeEnumType uniqueType)
{
var searchAll = _currentUser.GetRole() is "admin" or "tenant-admin";
//_myDataPermissionService
if (!searchAll && uniqueType == DeviceAssignmentTypeEnumType.Device)
{
return _myDataPermissionService.GetMyDeviceCodes();
}
return new List<Guid>();
}
private async Task<List<DevicePermissionEntity>> 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<Guid>, List<Guid>)> GetDiffAsync(DeviceAssignmentTypeEnumType type, List<DevicePermissionEntity> dps, List<Guid> uniqueValues)
{
var beforeCodes = dps.Select(x => x.UniqueValue).ToList();
var presentCodes = uniqueValues.IsPresent() ? uniqueValues : new List<Guid>();
if (type == DeviceAssignmentTypeEnumType.Group)
{
var deviceGroups = await DbContext.Queryable<DeviceGroupEntity>().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<List<Guid>> GetDeviceCodeByGroupAsync(List<DeviceGroupEntity> deviceGroups, List<Guid> codes)
{
var result = new List<Guid>();
foreach (var groupCode in codes)
{
result.AddRange(RecursionHelper.HandlerDeviceGroupNextCodes(groupCode, deviceGroups));
}
result = result.Distinct().ToList();
return await DbContext.Queryable<DeviceGroupRelationshipEntity>()
.Where(x => result.Contains(x.GroupCode))
.Select(x => x.DeviceCode)
.Distinct()
.ToListAsync();
}
}