Merge branch 'development' of https://git.dlhis.com/liguoyang/jinko.yikatong into development

This commit is contained in:
cheche
2024-01-16 14:04:18 +08:00
33 changed files with 604 additions and 152 deletions

View File

@@ -20,12 +20,12 @@ public class DevicePermissionsController : ControllerBase
/// <summary> /// <summary>
/// 分配权限 /// 分配权限
/// </summary> /// </summary>
/// <param name="requests"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("assign")] [HttpPost("assign")]
public async Task AssignmentAsync(List<DevicePermissionSaveReuqest> requests) public async Task AssignAsync(DevicePermissionSaveReuqest request)
{ {
await _devicePermissionService.AssignmentAsync(requests); await _devicePermissionService.AssignAsync(request);
} }
/// <summary> /// <summary>
@@ -36,18 +36,6 @@ public class DevicePermissionsController : ControllerBase
[HttpGet("assignments")] [HttpGet("assignments")]
public async Task<List<Guid>> GetAssignmentsAsync([FromQuery] DeviceGetAssignmentsRequest request) public async Task<List<Guid>> GetAssignmentsAsync([FromQuery] DeviceGetAssignmentsRequest request)
{ {
return await _devicePermissionService.GetAssignmentsAsync(request.UserNo, request.UniqueType); return await _devicePermissionService.GetAssignmentsAsync(request.UniqueType, request.AssignType, request.AssignValue);
}
/// <summary>
/// 重置
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("reset")]
public async Task ResetAssignmentsAsync(DeviceResetAssignmentsRequest request)
{
await _devicePermissionService.ResetAssignmentsAsync(request);
} }
} }

View File

@@ -145,8 +145,18 @@ public class DevicesController : ControllerBase
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
public async Task<Pagination<DeviceResponse>> GetDeviceByNoAsync([FromQuery]DevicePageRequest request) public async Task<Pagination<DeviceResponse>> GetDeviceByNoAsync([FromQuery] DevicePageRequest request)
{ {
return await _deviceService.GetDeviceByNoAsync(request); return await _deviceService.GetDeviceByNoAsync(request);
} }
/// <summary>
/// 获取考勤设备
/// </summary>
/// <returns></returns>
[HttpGet("attendances")]
public async Task<List<DeviceResponse>> GetAttendanceDevicesAsync()
{
return await _deviceService.GetAttendanceDevicesAsync();
}
} }

View File

@@ -6,14 +6,19 @@ namespace Dlhis.Basic.Device.Request;
public class DeviceGetAssignmentsRequest public class DeviceGetAssignmentsRequest
{ {
/// <summary> /// <summary>
/// 用户档案号 /// 权限分配类型 DeviceAssignmentTypeEnumType
/// </summary>
[Required]
public string UserNo { get; set; }
/// <summary>
/// 权限分配类型 MenuAssignmentTypeEnumType
/// </summary> /// </summary>
[EnumDataType(typeof(DeviceAssignmentTypeEnumType))] [EnumDataType(typeof(DeviceAssignmentTypeEnumType))]
public DeviceAssignmentTypeEnumType UniqueType { get; set; } public DeviceAssignmentTypeEnumType UniqueType { get; set; }
/// <summary>
/// 分配类型 AssignTypeEnumType
/// </summary>
[EnumDataType(typeof(AssignTypeEnumType))]
public AssignTypeEnumType AssignType { get; set; }
/// <summary>
/// 分配值
/// </summary>
public string AssignValue { get; set; }
} }

View File

@@ -5,14 +5,20 @@ namespace Dlhis.Basic.Device.Request;
public class DevicePermissionSaveReuqest public class DevicePermissionSaveReuqest
{ {
/// <summary>
/// 分配类型 AssignTypeEnumType
/// </summary>
[EnumDataType(typeof(AssignTypeEnumType), ErrorMessage = "枚举类型错误")]
public AssignTypeEnumType AssignType { get; set; }
/// <summary> /// <summary>
/// 人员档案号 /// 人员档案号
/// </summary> /// </summary>
[Required(ErrorMessage = "人员档案号不能为空")] [Required(ErrorMessage = "人员档案号不能为空")]
public string UserNo { get; set; } public string AssignValue { get; set; }
/// <summary> /// <summary>
/// 分配权限类型 DevicePermissionTypeEnumType /// 来源分配权限类型 DevicePermissionTypeEnumType
/// </summary> /// </summary>
[EnumDataType(typeof(DeviceAssignmentTypeEnumType), ErrorMessage = "枚举类型错误")] [EnumDataType(typeof(DeviceAssignmentTypeEnumType), ErrorMessage = "枚举类型错误")]
public DeviceAssignmentTypeEnumType UniqueType { get; set; } public DeviceAssignmentTypeEnumType UniqueType { get; set; }
@@ -20,6 +26,5 @@ public class DevicePermissionSaveReuqest
/// <summary> /// <summary>
/// 分配权限值不能为空 /// 分配权限值不能为空
/// </summary> /// </summary>
[Required(ErrorMessage = "分配权限值不能为空")] public List<Guid> Codes { get; set; } = new List<Guid>();
public Guid UniqueValue { get; set; }
} }

View File

@@ -74,17 +74,6 @@ public class DeviceResponse
/// </summary> /// </summary>
public string ConnectionInfo { get; set; } public string ConnectionInfo { get; set; }
/// <summary>
/// 最后使用人
/// </summary>
public DateTime LastLogId { get; set; }
/// <summary>
/// 最后使用日期
/// </summary>
public DateTime LastLogDateTime { get; set; }
/// <summary> /// <summary>
/// 是否启用 /// 是否启用
/// </summary> /// </summary>

View File

@@ -8,24 +8,18 @@ public interface IDevicePermissionService : IScopeDependency
/// <summary> /// <summary>
/// 保存设备权限 /// 保存设备权限
/// </summary> /// </summary>
/// <param name="reuqests"></param> /// <param name="reuqest"></param>
/// <returns></returns> /// <returns></returns>
Task AssignmentAsync(List<DevicePermissionSaveReuqest> reuqests); Task AssignAsync(DevicePermissionSaveReuqest reuqest);
/// <summary> /// <summary>
/// 获取分配的权限 /// 获取分配的权限
/// </summary> /// </summary>
/// <param name="userNo"></param>
/// <param name="uniqueType"></param> /// <param name="uniqueType"></param>
/// <param name="assignValue"></param>
/// <param name="assignType"></param>
/// <returns></returns> /// <returns></returns>
Task<List<Guid>> GetAssignmentsAsync(string userNo, DeviceAssignmentTypeEnumType? uniqueType); Task<List<Guid>> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue);
/// <summary>
/// 重置分配
/// </summary>
/// <returns></returns>
Task ResetAssignmentsAsync(DeviceResetAssignmentsRequest request);
/// <summary> /// <summary>
@@ -35,4 +29,12 @@ public interface IDevicePermissionService : IScopeDependency
/// <param name="userNos"></param> /// <param name="userNos"></param>
/// <returns></returns> /// <returns></returns>
Task GenerateDeviceTasksAsync(Func<Task> func, List<string> userNos); Task GenerateDeviceTasksAsync(Func<Task> func, List<string> userNos);
/// <summary>
/// 获取用户所有设备权限
/// </summary>
/// <param name="userNo"></param>
/// <returns></returns>
Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo);
} }

View File

@@ -13,4 +13,6 @@ public interface IDeviceService : IScopeDependency
Task<bool> CheckExistsAsync(string deviceUniqueNo); Task<bool> CheckExistsAsync(string deviceUniqueNo);
Task<Pagination<DeviceResponse>> GetDeviceByNoAsync(DevicePageRequest request); Task<Pagination<DeviceResponse>> GetDeviceByNoAsync(DevicePageRequest request);
Task<List<DeviceResponse>> GetAttendanceDevicesAsync();
} }

View File

@@ -20,81 +20,66 @@ public class DevicePermissionService : IDevicePermissionService
} }
[Transactional] [Transactional]
public async Task AssignmentAsync(List<DevicePermissionSaveReuqest> reuqests) public async Task AssignAsync(DevicePermissionSaveReuqest reuqest)
{ {
foreach (var grp in reuqests.GroupBy(x => x.UserNo)) await GenerateDeviceTasksAsync(async () =>
{ {
var userNo = grp.Key; await _dbContext.Client.Deleteable<DevicePermissionEntity>()
var data = grp.AsEnumerable().DistinctBy(x => x.UniqueValue).ToList(); .Where(x => x.AssignType == reuqest.AssignType)
.Where(x => x.AssignValue == reuqest.AssignValue)
.ExecuteCommandAsync();
await GenerateDeviceTasksAsync(async () => var devicePermissions = reuqest.Codes.Select(x => new DevicePermissionEntity
{ {
await _dbContext.Client.Deleteable<DevicePermissionEntity>() AssignType = reuqest.AssignType,
.Where(x => x.UserNo == userNo) AssignValue = reuqest.AssignValue,
.ExecuteCommandAsync(); UniqueType = reuqest.UniqueType,
UniqueValue = x,
}).ToList();
var devicePermissions = data.Select(x => new DevicePermissionEntity await _dbContext.InsertAsync(devicePermissions);
{
UserNo = x.UserNo,
UniqueType = x.UniqueType,
UniqueValue = x.UniqueValue,
}).ToList(); }, null);
await _dbContext.InsertAsync(devicePermissions);
}, new List<string> { userNo });
};
} }
public async Task<List<Guid>> GetAssignmentsAsync(string userNo, DeviceAssignmentTypeEnumType? uniqueType) public async Task<List<Guid>> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue)
{ {
var assignments = await _dbContext.Queryable<DevicePermissionEntity>() var devicePermissions = await _dbContext.Queryable<DevicePermissionEntity>()
.WhereIF(uniqueType.HasValue, x => x.UniqueType == uniqueType) .Where(x => x.UniqueType == uniqueType)
.Where(x => x.UserNo == userNo) .Where(x => x.AssignType == assignType)
.Where(x => x.AssignValue == assignValue)
.Select(x => x.UniqueValue) .Select(x => x.UniqueValue)
.ToListAsync(); .ToListAsync();
if (uniqueType.HasValue && uniqueType == DeviceAssignmentTypeEnumType.Group) if (uniqueType == DeviceAssignmentTypeEnumType.Group)
{ {
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync(); var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList(); var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList();
tops.ForEach(x => tops.ForEach(x =>
{ {
RecursionGetNext(x, deviceGroups, assignments, assignments.Contains(x.Code)); RecursionGetNext(x, deviceGroups, devicePermissions, devicePermissions.Contains(x.Code));
}); });
} }
return assignments.Distinct().ToList(); return devicePermissions.Distinct().ToList();
void RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups, List<Guid> result, bool add) void RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups, List<Guid> result, bool add)
{ {
var next = deviceGroups.Where(x => x.PCode == current.Code).ToList(); var next = deviceGroups.Where(x => x.PCode == current.Code).ToList();
foreach (var item in next) foreach (var item in next)
{ {
if (add) assignments.Add(item.Code); if (add) result.Add(item.Code);
RecursionGetNext(item, deviceGroups, result, assignments.Contains(item.Code)); RecursionGetNext(item, deviceGroups, result, result.Contains(item.Code));
} }
} }
} }
public async Task ResetAssignmentsAsync(DeviceResetAssignmentsRequest request)
{
await GenerateDeviceTasksAsync(async () =>
{
await _dbContext.Client.Deleteable<DevicePermissionEntity>()
.Where(x => x.UserNo == request.UserNo)
.ExecuteCommandAsync();
}, new List<string> { request.UserNo });
}
public async Task GenerateDeviceTasksAsync(Func<Task> func, List<string> userNos) public async Task GenerateDeviceTasksAsync(Func<Task> func, List<string> userNos)
{ {
if (userNos.IsEmpty()) if (userNos.IsEmpty())
{ {
userNos = await _dbContext.Queryable<DevicePermissionEntity>().Select(x => x.UserNo).Distinct().ToListAsync(); userNos = await GetPermissionUserNosAsync();
} }
var beforeDic = new Dictionary<string, List<Guid>>(userNos.Count); var beforeDic = new Dictionary<string, List<Guid>>(userNos.Count);
@@ -108,6 +93,7 @@ public class DevicePermissionService : IDevicePermissionService
//获取当前的权限code //获取当前的权限code
var currentDic = new Dictionary<string, List<Guid>>(userNos.Count); var currentDic = new Dictionary<string, List<Guid>>(userNos.Count);
userNos = await GetPermissionUserNosAsync();
foreach (var userNo in userNos) foreach (var userNo in userNos)
{ {
currentDic.TryAdd(userNo, await GetAssignDeviceCodesAsync(userNo)); currentDic.TryAdd(userNo, await GetAssignDeviceCodesAsync(userNo));
@@ -115,8 +101,11 @@ public class DevicePermissionService : IDevicePermissionService
foreach (var userNo in userNos) foreach (var userNo in userNos)
{ {
var beforeCodes = beforeDic[userNo]; beforeDic.TryGetValue(userNo, out var beforeCodes);
var currentCodes = currentDic[userNo]; if (beforeCodes == null) beforeCodes = new List<Guid>();
currentDic.TryGetValue(userNo, out var currentCodes);
if (currentCodes == null) currentCodes = new List<Guid>();
//被删除 //被删除
var deletedItems = beforeCodes.Where(x => !currentCodes.Contains(x)).ToList(); var deletedItems = beforeCodes.Where(x => !currentCodes.Contains(x)).ToList();
@@ -169,27 +158,78 @@ public class DevicePermissionService : IDevicePermissionService
} }
//************************************************ help methods *******************************************************
/// <summary> /// <summary>
/// 获取用户所有设备权限 /// 获取用户所有设备权限
/// </summary> /// </summary>
/// <param name="userNo"></param> /// <param name="userNo"></param>
/// <returns></returns> /// <returns></returns>
private async Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo) public async Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo)
{ {
var deviceCodes = await GetAssignmentsAsync(userNo, DeviceAssignmentTypeEnumType.Device); 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 groupCodes = await GetAssignmentsAsync(userNo, DeviceAssignmentTypeEnumType.Group); var deviceCodes = new List<Guid>();
var deviceCodeUnderGroups = await _dbContext.Queryable<DeviceGroupRelationshipEntity>() var deviceGroupCodes = new List<Guid>();
.Where(x => groupCodes.Contains(x.GroupCode))
.Select(x => x.DeviceCode)
.Distinct()
.ToListAsync();
deviceCodes.AddRange(deviceCodeUnderGroups); 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(); return deviceCodes.Distinct().ToList();
} }
//************************************************ 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();
}
} }

View File

@@ -2,6 +2,7 @@
using Dlhis.Basic.Device.Response; using Dlhis.Basic.Device.Response;
using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Device.Entities; using Dlhis.Entity.Device.Entities;
using Dlhis.Entity.Device.Enums;
using Kurisu.AspNetCore.UnifyResultAndValidation; using Kurisu.AspNetCore.UnifyResultAndValidation;
using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.AspNetCore.Utils.Extensions;
using Kurisu.Core.DataAccess.Dto; using Kurisu.Core.DataAccess.Dto;
@@ -154,7 +155,7 @@ public class DeviceService : IDeviceService
public async Task<Pagination<DeviceResponse>> GetDeviceByNoAsync(DevicePageRequest request) public async Task<Pagination<DeviceResponse>> GetDeviceByNoAsync(DevicePageRequest request)
{ {
var page = await _dbContext.Queryable<DeviceEntity>() var page = await _dbContext.Queryable<DeviceEntity>()
.Where(x=>x.UniqueNo == request.UniqueNo) .Where(x => x.UniqueNo == request.UniqueNo)
.Select(device => new DeviceResponse .Select(device => new DeviceResponse
{ {
FuncsStr = device.Funcs.ToString() FuncsStr = device.Funcs.ToString()
@@ -164,5 +165,18 @@ public class DeviceService : IDeviceService
return page; return page;
} }
public async Task<List<DeviceResponse>> GetAttendanceDevicesAsync()
{
var devices = await _dbContext.Queryable<DeviceEntity>()
.Where(x => x.Enable)
.Select(x => new DeviceResponse
{
FuncsStr = x.Funcs.ToString()
}, true)
.ToListAsync();
return devices.Where(x => x.Funcs.Contains(DeviceFuncEnumType.Attendance)).ToList();
}
} }

View File

@@ -17,7 +17,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Kurisu.AspNetCore" Version="0.4.8" /> <PackageReference Include="Kurisu.AspNetCore" Version="0.4.9" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="6.0.26" /> <PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="6.0.26" />
</ItemGroup> </ItemGroup>

View File

@@ -0,0 +1,80 @@
using Dlhis.Basic.Organization.Request;
using Dlhis.Basic.Organization.Response;
using Dlhis.Basic.Organization.Services;
using Kurisu.AspNetCore.MVC;
using Kurisu.Core.DataAccess.Dto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Basic.Organization.Controllers;
/// <summary>
/// 档案分组
/// </summary>
[Authorize]
[ApiDefinition("SAP", Description = "晶科sap组织架构信息")]
[Route("api/[controller]")]
[ApiController]
public class GainfoGroupsController : ControllerBase
{
private readonly IGainfoGroupService _gainfoGroupService;
public GainfoGroupsController(IGainfoGroupService gainfoGroupService)
{
_gainfoGroupService = gainfoGroupService;
}
/// <summary>
/// 获取档案组分页
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpGet("page")]
public async Task<Pagination<GainfoGroupResponse>> GetPageAsync([FromQuery] GainfoGroupPageRequest request)
{
return await _gainfoGroupService.GetPageAsync(request);
}
/// <summary>
/// 获取所有档案组
/// </summary>
/// <returns></returns>
[HttpGet("list")]
public async Task<List<GainfoGroupResponse>> GetListAsync()
{
return await _gainfoGroupService.GetListAsync();
}
/// <summary>
/// 保存档案组
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public async Task SaveAsync(GainfoGroupSaveRequest request)
{
await _gainfoGroupService.SaveAsync(request);
}
/// <summary>
/// 根据分组code获取人员档案
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
[HttpGet("gainfos")]
public async Task<List<GainfoPageResponse>> GetGainfosByGroupAsync(Guid code)
{
return await _gainfoGroupService.GetGainfosByGroupAsync(code);
}
/// <summary>
/// 分配人员
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("assign")]
public async Task AssignGainfosAsync(GainfoAssignRequest request)
{
await _gainfoGroupService.AssignGainfosAsync(request);
}
}

View File

@@ -1,5 +1,4 @@
using System.ComponentModel.DataAnnotations; using Dlhis.Basic.Organization.Filters;
using Dlhis.Basic.Organization.Filters;
using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Request;
using Dlhis.Basic.Organization.Response; using Dlhis.Basic.Organization.Response;
using Dlhis.Basic.Organization.Services; using Dlhis.Basic.Organization.Services;
@@ -65,7 +64,7 @@ public class GainfosController : ControllerBase
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("dimission")] [HttpPost("dimission")]
public async Task DimissionAsync(GainfoDImissionRequest request) public async Task DimissionAsync(GainfoDimissionRequest request)
{ {
await _gainfoService.DimissionAsync(request); await _gainfoService.DimissionAsync(request);
} }
@@ -76,7 +75,7 @@ public class GainfosController : ControllerBase
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("onboarding")] [HttpPost("onboarding")]
public async Task OnboardingAsync(GainfoDImissionRequest request) public async Task OnboardingAsync(GainfoDimissionRequest request)
{ {
await _gainfoService.OnboardingAsync(request); await _gainfoService.OnboardingAsync(request);
} }
@@ -113,5 +112,16 @@ public class GainfosController : ControllerBase
{ {
return await _gainfoService.GetFaceAsync(token); return await _gainfoService.GetFaceAsync(token);
} }
/// <summary>
/// 获取人脸照片
/// </summary>
/// <param name="userCode"></param>
/// <returns></returns>
[HttpGet("face/{userCode}")]
public async Task<string> GetFaceByUserCodeAsync(string userCode)
{
return await _gainfoService.GetFaceByUserCodeAsync(userCode);
}
} }

View File

@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations;
namespace Dlhis.Basic.Organization.Request;
public class GainfoAssignRequest
{
/// <summary>
/// 分组code
/// </summary>
[Required(ErrorMessage = "档案组code")]
public Guid GroupCode { get; set; }
/// <summary>
/// 档案号
/// </summary>
public List<string> UserNos { get; set; } = new List<string>();
}

View File

@@ -1,13 +1,12 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace Dlhis.Basic.Organization.Request namespace Dlhis.Basic.Organization.Request;
public class GainfoDimissionRequest
{ {
public class GainfoDImissionRequest /// <summary>
{ /// 档案号
/// <summary> /// </summary>
/// 档案号 [Required(ErrorMessage = "档案号不能为空")]
/// </summary> public string UserNo { get; set; }
[Required(ErrorMessage = "档案号不能为空")]
public string UserNo { get; set; }
}
} }

View File

@@ -0,0 +1,7 @@
using Kurisu.Core.DataAccess.Dto;
namespace Dlhis.Basic.Organization.Request;
public class GainfoGroupPageRequest: PageDto
{
}

View File

@@ -0,0 +1,16 @@
namespace Dlhis.Basic.Organization.Request;
public class GainfoGroupSaveRequest
{
public long? Id { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
}

View File

@@ -2,7 +2,7 @@
namespace Dlhis.Basic.Organization.Request; namespace Dlhis.Basic.Organization.Request;
public class GainfoUploadFaceRequest public class GainfoUploadFaceRequest : IValidatableObject
{ {
/// <summary> /// <summary>
/// 用户档案号 /// 用户档案号
@@ -15,4 +15,22 @@ public class GainfoUploadFaceRequest
/// </summary> /// </summary>
[Required(ErrorMessage = "人脸照片不能为空")] [Required(ErrorMessage = "人脸照片不能为空")]
public string Face { get; set; } public string Face { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
bool v = true;
try
{
Convert.FromBase64String(Face);
}
catch (Exception)
{
v = false;
}
if (!v)
{
yield return new ValidationResult("人脸照片需要为Base64格式", new[] { nameof(Face) });
}
}
} }

View File

@@ -0,0 +1,21 @@
namespace Dlhis.Basic.Organization.Response;
public class GainfoGroupResponse
{
public long Id { get; set; }
/// <summary>
/// 分组code
/// </summary>
public Guid Code { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
}

View File

@@ -0,0 +1,18 @@
using Dlhis.Basic.Organization.Request;
using Dlhis.Basic.Organization.Response;
using Kurisu.Core.DataAccess.Dto;
namespace Dlhis.Basic.Organization.Services;
public interface IGainfoGroupService : IScopeDependency
{
Task<Pagination<GainfoGroupResponse>> GetPageAsync(GainfoGroupPageRequest request);
Task<List<GainfoGroupResponse>> GetListAsync();
Task SaveAsync(GainfoGroupSaveRequest request);
Task<List<GainfoPageResponse>> GetGainfosByGroupAsync(Guid code);
Task AssignGainfosAsync(GainfoAssignRequest request);
}

View File

@@ -13,13 +13,15 @@ public interface IGainfoService : IScopeDependency
Task UpdateAsync(GainfoSaveRequest request); Task UpdateAsync(GainfoSaveRequest request);
Task DimissionAsync(GainfoDImissionRequest request); Task DimissionAsync(GainfoDimissionRequest request);
Task OnboardingAsync(GainfoDImissionRequest request); Task OnboardingAsync(GainfoDimissionRequest request);
Task<GainfoCurrentResponse> CurrentUserInfoAsync(); Task<GainfoCurrentResponse> CurrentUserInfoAsync();
Task UploadFaceAsync(GainfoUploadFaceRequest request); Task UploadFaceAsync(GainfoUploadFaceRequest request);
Task<IActionResult> GetFaceAsync(string token); Task<IActionResult> GetFaceAsync(string token);
Task<string> GetFaceByUserCodeAsync(string userCode);
} }

View File

@@ -0,0 +1,101 @@
using Dlhis.Basic.Organization.Request;
using Dlhis.Basic.Organization.Response;
using Dlhis.Entity.Basic.Entity;
using Kurisu.AspNetCore.Utils.Extensions;
using Kurisu.Core.DataAccess.Dto;
using Kurisu.SqlSugar.Extensions;
using Kurisu.SqlSugar.Services;
using Mapster;
namespace Dlhis.Basic.Organization.Services.Implements;
public class GainfoGroupService : IGainfoGroupService
{
private readonly IDbContext _dbContext;
public GainfoGroupService(IDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task<Pagination<GainfoGroupResponse>> GetPageAsync(GainfoGroupPageRequest request)
{
return await _dbContext.Queryable<GainfoGroupEntity>()
.Select<GainfoGroupResponse>()
.ToPageListAsync(request);
}
public async Task<List<GainfoGroupResponse>> GetListAsync()
{
return await _dbContext.Queryable<GainfoGroupEntity>()
.Select<GainfoGroupResponse>()
.ToListAsync();
}
public async Task SaveAsync(GainfoGroupSaveRequest request)
{
await CheckDuplicateNameAsync(request);
if (!request.Id.HasValue)
{
var entity = request.Adapt<GainfoGroupEntity>();
entity.Code = Guid.NewGuid();
await _dbContext.InsertAsync(entity);
}
else
{
var entity = await _dbContext.Queryable<GainfoGroupEntity>().Where(x => x.Id == request.Id).SingleAsync();
request.Adapt(entity);
await _dbContext.UpdateAsync(entity);
}
}
public async Task<List<GainfoPageResponse>> GetGainfosByGroupAsync(Guid code)
{
var userNos = await _dbContext.Queryable<GainfoGroupRelationshipEntity>()
.Where(x => x.GroupCode == code)
.Select(x => x.UserNo)
.ToListAsync();
var list = await _dbContext.Queryable<GainfoEntity>()
.Where(x => userNos.Contains(x.No))
.Select<GainfoPageResponse>()
.ToListAsync();
return list;
}
public async Task AssignGainfosAsync(GainfoAssignRequest request)
{
var relations = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().Where(x => x.GroupCode == request.GroupCode).ToListAsync();
await _dbContext.DeleteReallyAsync(relations);
var entities = request.UserNos.Select(x => new GainfoGroupRelationshipEntity
{
GroupCode = request.GroupCode,
UserNo = x
}).ToList();
await _dbContext.InsertAsync(entities);
}
//******************************************************* help methods ***********************************************************
/// <summary>
/// 检查重名
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private async Task CheckDuplicateNameAsync(GainfoGroupSaveRequest request)
{
var exists = await _dbContext.Queryable<GainfoGroupEntity>()
.Where(x => x.Name == request.Name)
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
.AnyAsync();
exists.ThrowIfTrue($"重复组名{request.Name}");
}
}

View File

@@ -1,4 +1,5 @@
using Dlhis.Basic.Organization.Request; using System.Threading.Tasks;
using Dlhis.Basic.Organization.Request;
using Dlhis.Basic.Organization.Response; using Dlhis.Basic.Organization.Response;
using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Basic.Enums; using Dlhis.Entity.Basic.Enums;
@@ -13,6 +14,8 @@ using Kurisu.SqlSugar.Services;
using Mapster; using Mapster;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using NetTaste;
namespace Dlhis.Basic.Organization.Services.Implements; namespace Dlhis.Basic.Organization.Services.Implements;
@@ -87,7 +90,7 @@ public class GainfoService : IGainfoService
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
[Transactional] [Transactional]
public async Task DimissionAsync(GainfoDImissionRequest request) public async Task DimissionAsync(GainfoDimissionRequest request)
{ {
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working) var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
.Where(x => x.No == request.UserNo) .Where(x => x.No == request.UserNo)
@@ -107,7 +110,7 @@ public class GainfoService : IGainfoService
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
public async Task OnboardingAsync(GainfoDImissionRequest request) public async Task OnboardingAsync(GainfoDimissionRequest request)
{ {
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External) var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External)
.Where(x => x.No == request.UserNo) .Where(x => x.No == request.UserNo)
@@ -266,4 +269,44 @@ public class GainfoService : IGainfoService
} }
}); });
} }
public async Task<string> GetFaceByUserCodeAsync(string userCode)
{
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == userCode).SingleAsync();
gainfo.ThrowIfNull("人员信息不存在");
return await Scoped.Request.Value.CreateAsync<string>(async (sp) =>
{
var configuration = sp.GetService<IConfiguration>();
var faceConnectionString = configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value;
if (faceConnectionString.IsEmpty())
{
throw new UserFriendlyException("暂不支持获取人脸");
}
var dbContext = sp.GetService<IDbContext>();
//todo 切换连接字符串
dbContext.Client.CurrentConnectionConfig.ConnectionString = faceConnectionString;
var face = await dbContext.Queryable<GainfoFaceEntity>()
.Where(x => x.UserCode == userCode)
.SingleAsync();
face.ThrowIfNull("人脸照片尚未录入");
var timeLimitedDataProtector = sp.GetService<IDataProtectionProvider>()
.CreateProtector("down:face")
.ToTimeLimitedDataProtector();
var faceUrl = configuration.GetSection("FaceUrlOptions:Url").Value;
var limit = configuration.GetSection("FaceUrlOptions:Limit").Get<int>();
var dataProtectionProvider = sp.GetService<IDataProtectionProvider>();
var key = $"face:{userCode}";
var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit));
return faceUrl + token;
});
}
} }

View File

@@ -10,6 +10,10 @@
"CommonRequestUrl": "http://common", "CommonRequestUrl": "http://common",
"UserRequestUrl": "http://user" "UserRequestUrl": "http://user"
}, },
"FaceUrlOptions": {
"Url": "https://yikatong.isawesome.cn/api/basic/gainfos/face?token=",
"Limit": 7200
},
"SqlSugarOptions": { "SqlSugarOptions": {
"DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;", "DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;",
"SlaveConnectionString": [], "SlaveConnectionString": [],

View File

@@ -24,7 +24,7 @@ public class BalancesController : ControllerBase
} }
/// <summary> /// <summary>
/// 获取消费记录 /// 获取记录分页
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="request"></param>
/// <returns></returns> /// <returns></returns>

View File

@@ -381,7 +381,7 @@ public class BalanceService : IBalanceService
{ {
now = request.SearchDate.Value; now = request.SearchDate.Value;
start = new DateTime(now.Year, now.Month, now.Day); start = new DateTime(now.Year, now.Month, now.Day);
end = new DateTime(now.Year, now.Month, now.Day + 1); end = new DateTime(now.Year, now.Month, now.Day, 23, 59, 59);
} }
var device = await _dbContext.Queryable<DeviceEntity>() var device = await _dbContext.Queryable<DeviceEntity>()
@@ -433,8 +433,14 @@ public class BalanceService : IBalanceService
CostDateTime = record.CostDateTime CostDateTime = record.CostDateTime
}).ToPageListAsync(request); }).ToPageListAsync(request);
//消费总金额
var sum = await _dbContext.Queryable<BalanceRecordEntity>()
.WhereIF(request.SearchDate.HasValue, record => record.CostDate >= start)
.WhereIF(request.SearchDate.HasValue, record => record.CostDate <= end)
.Where(record => record.TenantId == device.TenantId || (record.DeviceInfo == device.Code.ToString() || record.DeviceInfo == device.UniqueNo))
.Where(record => record.Type == BalanceRecordTypeEnumType.Out && record.Status == BalanceRecordStatusEnumType.Valid)
.SumAsync(record => SqlFunc.Abs(SqlFunc.IsNull(record.Amount, 0)));
var sum = page.Data.Sum(x => Math.Abs(x.Amount));
page.Data.ForEach(x => x.Sum = sum); page.Data.ForEach(x => x.Sum = sum);
return page; return page;

View File

@@ -77,19 +77,6 @@ public class DeviceEntity : SugarBaseEntity, ITenantId
[SugarColumn(ColumnDescription = "连接信息")] [SugarColumn(ColumnDescription = "连接信息")]
public string ConnectionInfo { get; set; } public string ConnectionInfo { get; set; }
/// <summary>
/// 最后使用人
/// </summary>
[SugarColumn(IsNullable = true, ColumnDescription = "最后使用人")]
public DateTime? LastLogId { get; set; }
/// <summary>
/// 最后使用日期
/// </summary>
[SugarColumn(IsNullable = true, ColumnDescription = "最后使用日期")]
public DateTime? LastLogDateTime { get; set; }
/// <summary> /// <summary>
/// 是否启用 /// 是否启用
/// </summary> /// </summary>

View File

@@ -0,0 +1,29 @@
using Kurisu.SqlSugar;
using SqlSugar;
namespace Dlhis.Entity.Basic.Entity;
/// <summary>
/// 档案组
/// </summary>
[SugarTable(TableName = "GainfoGroup", TableDescription = "档案组")]
public class GainfoGroupEntity : SugarBaseEntity
{
/// <summary>
/// 分组code
/// </summary>
[SugarColumn(ColumnDescription = "分组code")]
public Guid Code { get; set; }
/// <summary>
/// 名称
/// </summary>
[SugarColumn(ColumnDescription = "名称")]
public string Name { get; set; }
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注")]
public string Remark { get; set; }
}

View File

@@ -0,0 +1,22 @@
using Kurisu.SqlSugar;
using SqlSugar;
namespace Dlhis.Entity.Basic.Entity;
/// <summary>
/// 档案人员组关系
/// </summary>
[SugarTable(TableName = "GainfoGroupRelationship", TableDescription = "档案人员组关系")]
public class GainfoGroupRelationshipEntity : SugarBaseEntity
{
/// <summary>
/// 分组code
/// </summary>
public Guid GroupCode { get; set; }
/// <summary>
/// 人员档案号
/// </summary>
[SugarColumn(ColumnDescription = "人员档案号")]
public string UserNo { get; set; }
}

View File

@@ -3,9 +3,9 @@
namespace Dlhis.Entity.Device.Enums; namespace Dlhis.Entity.Device.Enums;
/// <summary> /// <summary>
/// 机器设备功能 /// 设备功能
/// </summary> /// </summary>
[Description("机器设备功能")] [Description("设备功能")]
public enum DeviceFuncEnumType public enum DeviceFuncEnumType
{ {
/// <summary> /// <summary>
@@ -26,14 +26,12 @@ public enum DeviceFuncEnumType
[Description("人脸")] [Description("人脸")]
Face, Face,
/// <summary> /// <summary>
/// 刷卡 /// 刷卡
/// </summary> /// </summary>
[Description("刷卡")] [Description("刷卡")]
Card, Card,
/// <summary> /// <summary>
/// 二维码 /// 二维码
/// </summary> /// </summary>
@@ -46,4 +44,10 @@ public enum DeviceFuncEnumType
/// </summary> /// </summary>
[Description("布控")] [Description("布控")]
Control, Control,
/// <summary>
/// 考勤
/// </summary>
[Description("考勤")]
Attendance,
} }

View File

@@ -13,10 +13,17 @@ namespace Dlhis.Entity.Sys.Entities;
public class DevicePermissionEntity : SugarBaseEntity, ITenantId, ISoftDeleted public class DevicePermissionEntity : SugarBaseEntity, ITenantId, ISoftDeleted
{ {
/// <summary> /// <summary>
/// 人员档案 /// 分配权限类型
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "人员档案")] [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "分配权限类型", SqlParameterDbType = typeof(EnumToStringConvert))]
public string UserNo { get; set; } public AssignTypeEnumType AssignType { get; set; }
/// <summary>
/// 分配值
/// </summary>
[SugarColumn(ColumnDescription = "分配值")]
public string AssignValue { get; set; }
/// <summary> /// <summary>
/// 设备权限类型 /// 设备权限类型

View File

@@ -16,7 +16,7 @@ public class MenuPermissionEntity : SugarBaseEntity, ITenantId, ISoftDeleted
/// 权限分配类型 /// 权限分配类型
/// </summary> /// </summary>
[SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "权限分配类型", SqlParameterDbType = typeof(EnumToStringConvert))] [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "权限分配类型", SqlParameterDbType = typeof(EnumToStringConvert))]
public MenuAssignmentTypeEnumType UniqueType { get; set; } public AssignTypeEnumType UniqueType { get; set; }
/// <summary> /// <summary>
/// 类型值 /// 类型值

View File

@@ -5,8 +5,8 @@ namespace Dlhis.Entity.Sys.Enums;
/// <summary> /// <summary>
/// 权限类型 /// 权限类型
/// </summary> /// </summary>
[Description("权限分配类型")] [Description("分配类型")]
public enum MenuAssignmentTypeEnumType public enum AssignTypeEnumType
{ {
/// <summary> /// <summary>
/// 用户 /// 用户
@@ -30,5 +30,11 @@ public enum MenuAssignmentTypeEnumType
/// 部门 /// 部门
/// </summary> /// </summary>
[Description("部门")] [Description("部门")]
Department = 4 Department = 4,
/// <summary>
/// 租户/基地
/// </summary>
[Description("租户/基地")]
Tenant = 5,
} }

View File

@@ -169,7 +169,7 @@ public class AssignmentService : IAssignmentService
return Scoped.Request.Value.Create((sp) => return Scoped.Request.Value.Create((sp) =>
{ {
FaceUrlOptions faceUrlOptions = sp.GetService<IOptions<FaceUrlOptions>>().Value; var faceUrlOptions = sp.GetService<IOptions<FaceUrlOptions>>().Value;
var dataProtectionProvider = sp.GetService<IDataProtectionProvider>(); var dataProtectionProvider = sp.GetService<IDataProtectionProvider>();
var timeLimitedDataProtector = dataProtectionProvider var timeLimitedDataProtector = dataProtectionProvider