diff --git a/Src/Dlhis.Basic/Device/Controllers/DevicePermissionsController.cs b/Src/Dlhis.Basic/Device/Controllers/DevicePermissionsController.cs index 0efd2afc..aedb02e5 100644 --- a/Src/Dlhis.Basic/Device/Controllers/DevicePermissionsController.cs +++ b/Src/Dlhis.Basic/Device/Controllers/DevicePermissionsController.cs @@ -20,12 +20,12 @@ public class DevicePermissionsController : ControllerBase /// /// 分配权限 /// - /// + /// /// [HttpPost("assign")] - public async Task AssignmentAsync(List requests) + public async Task AssignAsync(DevicePermissionSaveReuqest request) { - await _devicePermissionService.AssignmentAsync(requests); + await _devicePermissionService.AssignAsync(request); } /// @@ -36,18 +36,6 @@ public class DevicePermissionsController : ControllerBase [HttpGet("assignments")] public async Task> GetAssignmentsAsync([FromQuery] DeviceGetAssignmentsRequest request) { - return await _devicePermissionService.GetAssignmentsAsync(request.UserNo, request.UniqueType); - } - - - /// - /// 重置 - /// - /// - /// - [HttpPost("reset")] - public async Task ResetAssignmentsAsync(DeviceResetAssignmentsRequest request) - { - await _devicePermissionService.ResetAssignmentsAsync(request); + return await _devicePermissionService.GetAssignmentsAsync(request.UniqueType, request.AssignType, request.AssignValue); } } diff --git a/Src/Dlhis.Basic/Device/Controllers/DevicesController.cs b/Src/Dlhis.Basic/Device/Controllers/DevicesController.cs index 610f6768..19d92f35 100644 --- a/Src/Dlhis.Basic/Device/Controllers/DevicesController.cs +++ b/Src/Dlhis.Basic/Device/Controllers/DevicesController.cs @@ -145,8 +145,18 @@ public class DevicesController : ControllerBase /// /// [HttpGet] - public async Task> GetDeviceByNoAsync([FromQuery]DevicePageRequest request) + public async Task> GetDeviceByNoAsync([FromQuery] DevicePageRequest request) { return await _deviceService.GetDeviceByNoAsync(request); } + + /// + /// 获取考勤设备 + /// + /// + [HttpGet("attendances")] + public async Task> GetAttendanceDevicesAsync() + { + return await _deviceService.GetAttendanceDevicesAsync(); + } } diff --git a/Src/Dlhis.Basic/Device/Request/DeviceGetAssignmentsRequest.cs b/Src/Dlhis.Basic/Device/Request/DeviceGetAssignmentsRequest.cs index f4974b17..9d4f4114 100644 --- a/Src/Dlhis.Basic/Device/Request/DeviceGetAssignmentsRequest.cs +++ b/Src/Dlhis.Basic/Device/Request/DeviceGetAssignmentsRequest.cs @@ -6,14 +6,19 @@ namespace Dlhis.Basic.Device.Request; public class DeviceGetAssignmentsRequest { /// - /// 用户档案号 - /// - [Required] - public string UserNo { get; set; } - - /// - /// 权限分配类型 MenuAssignmentTypeEnumType + /// 权限分配类型 DeviceAssignmentTypeEnumType /// [EnumDataType(typeof(DeviceAssignmentTypeEnumType))] public DeviceAssignmentTypeEnumType UniqueType { get; set; } + + /// + /// 分配类型 AssignTypeEnumType + /// + [EnumDataType(typeof(AssignTypeEnumType))] + public AssignTypeEnumType AssignType { get; set; } + + /// + /// 分配值 + /// + public string AssignValue { get; set; } } diff --git a/Src/Dlhis.Basic/Device/Request/DevicePermissionSaveReuqest.cs b/Src/Dlhis.Basic/Device/Request/DevicePermissionSaveReuqest.cs index e115b57d..5bca130a 100644 --- a/Src/Dlhis.Basic/Device/Request/DevicePermissionSaveReuqest.cs +++ b/Src/Dlhis.Basic/Device/Request/DevicePermissionSaveReuqest.cs @@ -5,14 +5,20 @@ namespace Dlhis.Basic.Device.Request; public class DevicePermissionSaveReuqest { + /// + /// 分配类型 AssignTypeEnumType + /// + [EnumDataType(typeof(AssignTypeEnumType), ErrorMessage = "枚举类型错误")] + public AssignTypeEnumType AssignType { get; set; } + /// /// 人员档案号 /// [Required(ErrorMessage = "人员档案号不能为空")] - public string UserNo { get; set; } + public string AssignValue { get; set; } /// - /// 分配权限类型 DevicePermissionTypeEnumType + /// 来源分配权限类型 DevicePermissionTypeEnumType /// [EnumDataType(typeof(DeviceAssignmentTypeEnumType), ErrorMessage = "枚举类型错误")] public DeviceAssignmentTypeEnumType UniqueType { get; set; } @@ -20,6 +26,5 @@ public class DevicePermissionSaveReuqest /// /// 分配权限值不能为空 /// - [Required(ErrorMessage = "分配权限值不能为空")] - public Guid UniqueValue { get; set; } + public List Codes { get; set; } = new List(); } diff --git a/Src/Dlhis.Basic/Device/Response/DeviceResponse.cs b/Src/Dlhis.Basic/Device/Response/DeviceResponse.cs index a36e18c7..628a35b4 100644 --- a/Src/Dlhis.Basic/Device/Response/DeviceResponse.cs +++ b/Src/Dlhis.Basic/Device/Response/DeviceResponse.cs @@ -74,17 +74,6 @@ public class DeviceResponse /// public string ConnectionInfo { get; set; } - /// - /// 最后使用人 - /// - public DateTime LastLogId { get; set; } - - /// - /// 最后使用日期 - /// - public DateTime LastLogDateTime { get; set; } - - /// /// 是否启用 /// diff --git a/Src/Dlhis.Basic/Device/Services/IDevicePermissionService.cs b/Src/Dlhis.Basic/Device/Services/IDevicePermissionService.cs index 8c75e764..9b35637b 100644 --- a/Src/Dlhis.Basic/Device/Services/IDevicePermissionService.cs +++ b/Src/Dlhis.Basic/Device/Services/IDevicePermissionService.cs @@ -8,24 +8,18 @@ public interface IDevicePermissionService : IScopeDependency /// /// 保存设备权限 /// - /// + /// /// - Task AssignmentAsync(List reuqests); + Task AssignAsync(DevicePermissionSaveReuqest reuqest); /// /// 获取分配的权限 /// - /// /// + /// + /// /// - Task> GetAssignmentsAsync(string userNo, DeviceAssignmentTypeEnumType? uniqueType); - - - /// - /// 重置分配 - /// - /// - Task ResetAssignmentsAsync(DeviceResetAssignmentsRequest request); + Task> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue); /// @@ -35,4 +29,12 @@ public interface IDevicePermissionService : IScopeDependency /// /// Task GenerateDeviceTasksAsync(Func func, List userNos); + + + /// + /// 获取用户所有设备权限 + /// + /// + /// + Task> GetAssignDeviceCodesAsync(string userNo); } diff --git a/Src/Dlhis.Basic/Device/Services/IDeviceService.cs b/Src/Dlhis.Basic/Device/Services/IDeviceService.cs index d13e5dcb..930db433 100644 --- a/Src/Dlhis.Basic/Device/Services/IDeviceService.cs +++ b/Src/Dlhis.Basic/Device/Services/IDeviceService.cs @@ -13,4 +13,6 @@ public interface IDeviceService : IScopeDependency Task CheckExistsAsync(string deviceUniqueNo); Task> GetDeviceByNoAsync(DevicePageRequest request); + + Task> GetAttendanceDevicesAsync(); } diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs index 3798ede7..99c0f409 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DevicePermissionService.cs @@ -20,81 +20,66 @@ public class DevicePermissionService : IDevicePermissionService } [Transactional] - public async Task AssignmentAsync(List reuqests) + public async Task AssignAsync(DevicePermissionSaveReuqest reuqest) { - foreach (var grp in reuqests.GroupBy(x => x.UserNo)) + await GenerateDeviceTasksAsync(async () => { - var userNo = grp.Key; - var data = grp.AsEnumerable().DistinctBy(x => x.UniqueValue).ToList(); + await _dbContext.Client.Deleteable() + .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() - .Where(x => x.UserNo == userNo) - .ExecuteCommandAsync(); + AssignType = reuqest.AssignType, + AssignValue = reuqest.AssignValue, + UniqueType = reuqest.UniqueType, + UniqueValue = x, + }).ToList(); - var devicePermissions = data.Select(x => new DevicePermissionEntity - { - UserNo = x.UserNo, - UniqueType = x.UniqueType, - UniqueValue = x.UniqueValue, + await _dbContext.InsertAsync(devicePermissions); - }).ToList(); - - await _dbContext.InsertAsync(devicePermissions); - - }, new List { userNo }); - }; + }, null); } - public async Task> GetAssignmentsAsync(string userNo, DeviceAssignmentTypeEnumType? uniqueType) + public async Task> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue) { - var assignments = await _dbContext.Queryable() - .WhereIF(uniqueType.HasValue, x => x.UniqueType == uniqueType) - .Where(x => x.UserNo == userNo) + var devicePermissions = await _dbContext.Queryable() + .Where(x => x.UniqueType == uniqueType) + .Where(x => x.AssignType == assignType) + .Where(x => x.AssignValue == assignValue) .Select(x => x.UniqueValue) .ToListAsync(); - if (uniqueType.HasValue && uniqueType == DeviceAssignmentTypeEnumType.Group) + if (uniqueType == DeviceAssignmentTypeEnumType.Group) { var deviceGroups = await _dbContext.Queryable().ToListAsync(); var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList(); 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 deviceGroups, List result, bool add) { var next = deviceGroups.Where(x => x.PCode == current.Code).ToList(); foreach (var item in next) { - if (add) assignments.Add(item.Code); - RecursionGetNext(item, deviceGroups, result, assignments.Contains(item.Code)); + if (add) result.Add(item.Code); + RecursionGetNext(item, deviceGroups, result, result.Contains(item.Code)); } } } - public async Task ResetAssignmentsAsync(DeviceResetAssignmentsRequest request) - { - await GenerateDeviceTasksAsync(async () => - { - await _dbContext.Client.Deleteable() - .Where(x => x.UserNo == request.UserNo) - .ExecuteCommandAsync(); - - }, new List { request.UserNo }); - } - public async Task GenerateDeviceTasksAsync(Func func, List userNos) { if (userNos.IsEmpty()) { - userNos = await _dbContext.Queryable().Select(x => x.UserNo).Distinct().ToListAsync(); + userNos = await GetPermissionUserNosAsync(); } var beforeDic = new Dictionary>(userNos.Count); @@ -108,6 +93,7 @@ public class DevicePermissionService : IDevicePermissionService //获取当前的权限code var currentDic = new Dictionary>(userNos.Count); + userNos = await GetPermissionUserNosAsync(); foreach (var userNo in userNos) { currentDic.TryAdd(userNo, await GetAssignDeviceCodesAsync(userNo)); @@ -115,8 +101,11 @@ public class DevicePermissionService : IDevicePermissionService foreach (var userNo in userNos) { - var beforeCodes = beforeDic[userNo]; - var currentCodes = currentDic[userNo]; + beforeDic.TryGetValue(userNo, out var beforeCodes); + if (beforeCodes == null) beforeCodes = new List(); + + currentDic.TryGetValue(userNo, out var currentCodes); + if (currentCodes == null) currentCodes = new List(); //被删除 var deletedItems = beforeCodes.Where(x => !currentCodes.Contains(x)).ToList(); @@ -169,27 +158,78 @@ public class DevicePermissionService : IDevicePermissionService } - //************************************************ help methods ******************************************************* - /// /// 获取用户所有设备权限 /// /// /// - private async Task> GetAssignDeviceCodesAsync(string userNo) + public async Task> GetAssignDeviceCodesAsync(string userNo) { - var deviceCodes = await GetAssignmentsAsync(userNo, DeviceAssignmentTypeEnumType.Device); + var gainfo = await _dbContext.Queryable().Where(x => x.No == userNo).SingleAsync(); + var gainfoGroups = await _dbContext.Queryable().Where(x => x.UserNo == userNo).Select(x => x.GroupCode).ToListAsync(); - var groupCodes = await GetAssignmentsAsync(userNo, DeviceAssignmentTypeEnumType.Group); - var deviceCodeUnderGroups = await _dbContext.Queryable() - .Where(x => groupCodes.Contains(x.GroupCode)) - .Select(x => x.DeviceCode) - .Distinct() - .ToListAsync(); + var deviceCodes = new List(); + var deviceGroupCodes = new List(); - 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().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync(); + deviceCodes.AddRange(deveiceCodesByGroup); return deviceCodes.Distinct().ToList(); } + + + //************************************************ 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).ToList(); + } + } diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs index dc5f4e37..92d90627 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs @@ -2,6 +2,7 @@ using Dlhis.Basic.Device.Response; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Device.Entities; +using Dlhis.Entity.Device.Enums; using Kurisu.AspNetCore.UnifyResultAndValidation; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Dto; @@ -154,7 +155,7 @@ public class DeviceService : IDeviceService public async Task> GetDeviceByNoAsync(DevicePageRequest request) { var page = await _dbContext.Queryable() - .Where(x=>x.UniqueNo == request.UniqueNo) + .Where(x => x.UniqueNo == request.UniqueNo) .Select(device => new DeviceResponse { FuncsStr = device.Funcs.ToString() @@ -164,5 +165,18 @@ public class DeviceService : IDeviceService return page; } + + public async Task> GetAttendanceDevicesAsync() + { + var devices = await _dbContext.Queryable() + .Where(x => x.Enable) + .Select(x => new DeviceResponse + { + FuncsStr = x.Funcs.ToString() + }, true) + .ToListAsync(); + + return devices.Where(x => x.Funcs.Contains(DeviceFuncEnumType.Attendance)).ToList(); + } } diff --git a/Src/Dlhis.Basic/Dlhis.Basic.csproj b/Src/Dlhis.Basic/Dlhis.Basic.csproj index 2d3bb2ea..ddf7fbde 100644 --- a/Src/Dlhis.Basic/Dlhis.Basic.csproj +++ b/Src/Dlhis.Basic/Dlhis.Basic.csproj @@ -17,7 +17,7 @@ - + diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfoGroupsController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfoGroupsController.cs new file mode 100644 index 00000000..b578cf1a --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Controllers/GainfoGroupsController.cs @@ -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; + +/// +/// 档案分组 +/// +[Authorize] +[ApiDefinition("SAP", Description = "晶科sap组织架构信息")] +[Route("api/[controller]")] +[ApiController] +public class GainfoGroupsController : ControllerBase +{ + private readonly IGainfoGroupService _gainfoGroupService; + + public GainfoGroupsController(IGainfoGroupService gainfoGroupService) + { + _gainfoGroupService = gainfoGroupService; + } + + /// + /// 获取档案组分页 + /// + /// + /// + [HttpGet("page")] + public async Task> GetPageAsync([FromQuery] GainfoGroupPageRequest request) + { + return await _gainfoGroupService.GetPageAsync(request); + } + + /// + /// 获取所有档案组 + /// + /// + [HttpGet("list")] + public async Task> GetListAsync() + { + return await _gainfoGroupService.GetListAsync(); + } + + /// + /// 保存档案组 + /// + /// + /// + [HttpPost] + public async Task SaveAsync(GainfoGroupSaveRequest request) + { + await _gainfoGroupService.SaveAsync(request); + } + + /// + /// 根据分组code获取人员档案 + /// + /// + /// + [HttpGet("gainfos")] + public async Task> GetGainfosByGroupAsync(Guid code) + { + return await _gainfoGroupService.GetGainfosByGroupAsync(code); + } + + /// + /// 分配人员 + /// + /// + /// + [HttpPost("assign")] + public async Task AssignGainfosAsync(GainfoAssignRequest request) + { + await _gainfoGroupService.AssignGainfosAsync(request); + } +} diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs index c18beb24..56b26d43 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs @@ -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.Response; using Dlhis.Basic.Organization.Services; @@ -65,7 +64,7 @@ public class GainfosController : ControllerBase /// /// [HttpPost("dimission")] - public async Task DimissionAsync(GainfoDImissionRequest request) + public async Task DimissionAsync(GainfoDimissionRequest request) { await _gainfoService.DimissionAsync(request); } @@ -76,7 +75,7 @@ public class GainfosController : ControllerBase /// /// [HttpPost("onboarding")] - public async Task OnboardingAsync(GainfoDImissionRequest request) + public async Task OnboardingAsync(GainfoDimissionRequest request) { await _gainfoService.OnboardingAsync(request); } @@ -113,5 +112,16 @@ public class GainfosController : ControllerBase { return await _gainfoService.GetFaceAsync(token); } + + /// + /// 获取人脸照片 + /// + /// + /// + [HttpGet("face/{userCode}")] + public async Task GetFaceByUserCodeAsync(string userCode) + { + return await _gainfoService.GetFaceByUserCodeAsync(userCode); + } } diff --git a/Src/Dlhis.Basic/Organization/Request/GainfoAssignRequest.cs b/Src/Dlhis.Basic/Organization/Request/GainfoAssignRequest.cs new file mode 100644 index 00000000..6741f83a --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Request/GainfoAssignRequest.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace Dlhis.Basic.Organization.Request; + +public class GainfoAssignRequest +{ + /// + /// 分组code + /// + [Required(ErrorMessage = "档案组code")] + public Guid GroupCode { get; set; } + + /// + /// 档案号 + /// + public List UserNos { get; set; } = new List(); +} diff --git a/Src/Dlhis.Basic/Organization/Request/GainfoDImissionRequest.cs b/Src/Dlhis.Basic/Organization/Request/GainfoDImissionRequest.cs index 6d56fcd7..320420f8 100644 --- a/Src/Dlhis.Basic/Organization/Request/GainfoDImissionRequest.cs +++ b/Src/Dlhis.Basic/Organization/Request/GainfoDImissionRequest.cs @@ -1,13 +1,12 @@ using System.ComponentModel.DataAnnotations; -namespace Dlhis.Basic.Organization.Request +namespace Dlhis.Basic.Organization.Request; + +public class GainfoDimissionRequest { - public class GainfoDImissionRequest - { - /// - /// 档案号 - /// - [Required(ErrorMessage = "档案号不能为空")] - public string UserNo { get; set; } - } + /// + /// 档案号 + /// + [Required(ErrorMessage = "档案号不能为空")] + public string UserNo { get; set; } } diff --git a/Src/Dlhis.Basic/Organization/Request/GainfoGroupPageRequest.cs b/Src/Dlhis.Basic/Organization/Request/GainfoGroupPageRequest.cs new file mode 100644 index 00000000..b38a161d --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Request/GainfoGroupPageRequest.cs @@ -0,0 +1,7 @@ +using Kurisu.Core.DataAccess.Dto; + +namespace Dlhis.Basic.Organization.Request; + +public class GainfoGroupPageRequest: PageDto +{ +} diff --git a/Src/Dlhis.Basic/Organization/Request/GainfoGroupSaveRequest.cs b/Src/Dlhis.Basic/Organization/Request/GainfoGroupSaveRequest.cs new file mode 100644 index 00000000..bb5173e4 --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Request/GainfoGroupSaveRequest.cs @@ -0,0 +1,16 @@ +namespace Dlhis.Basic.Organization.Request; + +public class GainfoGroupSaveRequest +{ + public long? Id { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Basic/Organization/Request/GainfoUploadFaceRequest.cs b/Src/Dlhis.Basic/Organization/Request/GainfoUploadFaceRequest.cs index 495a329e..5f403df8 100644 --- a/Src/Dlhis.Basic/Organization/Request/GainfoUploadFaceRequest.cs +++ b/Src/Dlhis.Basic/Organization/Request/GainfoUploadFaceRequest.cs @@ -2,7 +2,7 @@ namespace Dlhis.Basic.Organization.Request; -public class GainfoUploadFaceRequest +public class GainfoUploadFaceRequest : IValidatableObject { /// /// 用户档案号 @@ -15,4 +15,22 @@ public class GainfoUploadFaceRequest /// [Required(ErrorMessage = "人脸照片不能为空")] public string Face { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) + { + bool v = true; + try + { + Convert.FromBase64String(Face); + } + catch (Exception) + { + v = false; + } + + if (!v) + { + yield return new ValidationResult("人脸照片需要为Base64格式", new[] { nameof(Face) }); + } + } } diff --git a/Src/Dlhis.Basic/Organization/Response/GainfoGroupResponse.cs b/Src/Dlhis.Basic/Organization/Response/GainfoGroupResponse.cs new file mode 100644 index 00000000..f7f397b4 --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Response/GainfoGroupResponse.cs @@ -0,0 +1,21 @@ +namespace Dlhis.Basic.Organization.Response; + +public class GainfoGroupResponse +{ + public long Id { get; set; } + + /// + /// 分组code + /// + public Guid Code { get; set; } + + /// + /// 名称 + /// + public string Name { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Basic/Organization/Services/IGainfoGroupService.cs b/Src/Dlhis.Basic/Organization/Services/IGainfoGroupService.cs new file mode 100644 index 00000000..344f4dd1 --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Services/IGainfoGroupService.cs @@ -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> GetPageAsync(GainfoGroupPageRequest request); + + Task> GetListAsync(); + + Task SaveAsync(GainfoGroupSaveRequest request); + + Task> GetGainfosByGroupAsync(Guid code); + + Task AssignGainfosAsync(GainfoAssignRequest request); +} diff --git a/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs b/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs index eff29b50..77e812c1 100644 --- a/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/IGainfoService.cs @@ -13,13 +13,15 @@ public interface IGainfoService : IScopeDependency Task UpdateAsync(GainfoSaveRequest request); - Task DimissionAsync(GainfoDImissionRequest request); + Task DimissionAsync(GainfoDimissionRequest request); - Task OnboardingAsync(GainfoDImissionRequest request); + Task OnboardingAsync(GainfoDimissionRequest request); Task CurrentUserInfoAsync(); Task UploadFaceAsync(GainfoUploadFaceRequest request); Task GetFaceAsync(string token); + + Task GetFaceByUserCodeAsync(string userCode); } diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs new file mode 100644 index 00000000..a82c11f6 --- /dev/null +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs @@ -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> GetPageAsync(GainfoGroupPageRequest request) + { + return await _dbContext.Queryable() + .Select() + .ToPageListAsync(request); + } + + + public async Task> GetListAsync() + { + return await _dbContext.Queryable() + .Select() + .ToListAsync(); + } + + public async Task SaveAsync(GainfoGroupSaveRequest request) + { + await CheckDuplicateNameAsync(request); + + if (!request.Id.HasValue) + { + var entity = request.Adapt(); + entity.Code = Guid.NewGuid(); + await _dbContext.InsertAsync(entity); + } + else + { + var entity = await _dbContext.Queryable().Where(x => x.Id == request.Id).SingleAsync(); + request.Adapt(entity); + + await _dbContext.UpdateAsync(entity); + } + } + + public async Task> GetGainfosByGroupAsync(Guid code) + { + var userNos = await _dbContext.Queryable() + .Where(x => x.GroupCode == code) + .Select(x => x.UserNo) + .ToListAsync(); + + var list = await _dbContext.Queryable() + .Where(x => userNos.Contains(x.No)) + .Select() + .ToListAsync(); + + return list; + } + + public async Task AssignGainfosAsync(GainfoAssignRequest request) + { + var relations = await _dbContext.Queryable().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 *********************************************************** + + /// + /// 检查重名 + /// + /// + /// + private async Task CheckDuplicateNameAsync(GainfoGroupSaveRequest request) + { + var exists = await _dbContext.Queryable() + .Where(x => x.Name == request.Name) + .WhereIF(request.Id.HasValue, x => x.Id != request.Id) + .AnyAsync(); + + exists.ThrowIfTrue($"重复组名{request.Name}"); + } +} diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs index 16c3c30a..2c67f1e6 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs @@ -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.Entity.Basic.Entity; using Dlhis.Entity.Basic.Enums; @@ -13,6 +14,8 @@ using Kurisu.SqlSugar.Services; using Mapster; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using NetTaste; namespace Dlhis.Basic.Organization.Services.Implements; @@ -87,7 +90,7 @@ public class GainfoService : IGainfoService /// /// [Transactional] - public async Task DimissionAsync(GainfoDImissionRequest request) + public async Task DimissionAsync(GainfoDimissionRequest request) { var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working) .Where(x => x.No == request.UserNo) @@ -107,7 +110,7 @@ public class GainfoService : IGainfoService /// /// /// - public async Task OnboardingAsync(GainfoDImissionRequest request) + public async Task OnboardingAsync(GainfoDimissionRequest request) { var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.External) .Where(x => x.No == request.UserNo) @@ -266,4 +269,44 @@ public class GainfoService : IGainfoService } }); } + + public async Task GetFaceByUserCodeAsync(string userCode) + { + var gainfo = await _dbContext.Queryable().Where(x => x.Code == userCode).SingleAsync(); + gainfo.ThrowIfNull("人员信息不存在"); + + return await Scoped.Request.Value.CreateAsync(async (sp) => + { + var configuration = sp.GetService(); + + var faceConnectionString = configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value; + if (faceConnectionString.IsEmpty()) + { + throw new UserFriendlyException("暂不支持获取人脸"); + } + + var dbContext = sp.GetService(); + //todo 切换连接字符串 + dbContext.Client.CurrentConnectionConfig.ConnectionString = faceConnectionString; + + var face = await dbContext.Queryable() + .Where(x => x.UserCode == userCode) + .SingleAsync(); + + face.ThrowIfNull("人脸照片尚未录入"); + + var timeLimitedDataProtector = sp.GetService() + .CreateProtector("down:face") + .ToTimeLimitedDataProtector(); + + var faceUrl = configuration.GetSection("FaceUrlOptions:Url").Value; + var limit = configuration.GetSection("FaceUrlOptions:Limit").Get(); + var dataProtectionProvider = sp.GetService(); + + var key = $"face:{userCode}"; + var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit)); + + return faceUrl + token; + }); + } } diff --git a/Src/Dlhis.Basic/appsettings.json b/Src/Dlhis.Basic/appsettings.json index 75960c44..d48a4890 100644 --- a/Src/Dlhis.Basic/appsettings.json +++ b/Src/Dlhis.Basic/appsettings.json @@ -10,6 +10,10 @@ "CommonRequestUrl": "http://common", "UserRequestUrl": "http://user" }, + "FaceUrlOptions": { + "Url": "https://yikatong.isawesome.cn/api/basic/gainfos/face?token=", + "Limit": 7200 + }, "SqlSugarOptions": { "DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;", "SlaveConnectionString": [], diff --git a/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs b/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs index 4e0f7964..511c6741 100644 --- a/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs +++ b/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs @@ -24,7 +24,7 @@ public class BalancesController : ControllerBase } /// - /// 获取消费记录 + /// 获取记录分页 /// /// /// diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs index 5da6da22..9e957ce0 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs @@ -381,7 +381,7 @@ public class BalanceService : IBalanceService { now = request.SearchDate.Value; 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() @@ -433,8 +433,14 @@ public class BalanceService : IBalanceService CostDateTime = record.CostDateTime }).ToPageListAsync(request); + //消费总金额 + var sum = await _dbContext.Queryable() + .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); return page; diff --git a/Src/Dlhis.Entity/Basic/Entity/DeviceEntity.cs b/Src/Dlhis.Entity/Basic/Entity/DeviceEntity.cs index 529fdb59..90e508fe 100644 --- a/Src/Dlhis.Entity/Basic/Entity/DeviceEntity.cs +++ b/Src/Dlhis.Entity/Basic/Entity/DeviceEntity.cs @@ -77,19 +77,6 @@ public class DeviceEntity : SugarBaseEntity, ITenantId [SugarColumn(ColumnDescription = "连接信息")] public string ConnectionInfo { get; set; } - /// - /// 最后使用人 - /// - [SugarColumn(IsNullable = true, ColumnDescription = "最后使用人")] - public DateTime? LastLogId { get; set; } - - /// - /// 最后使用日期 - /// - [SugarColumn(IsNullable = true, ColumnDescription = "最后使用日期")] - public DateTime? LastLogDateTime { get; set; } - - /// /// 是否启用 /// diff --git a/Src/Dlhis.Entity/Basic/Entity/GainfoGroupEntity.cs b/Src/Dlhis.Entity/Basic/Entity/GainfoGroupEntity.cs new file mode 100644 index 00000000..2243b9e5 --- /dev/null +++ b/Src/Dlhis.Entity/Basic/Entity/GainfoGroupEntity.cs @@ -0,0 +1,29 @@ +using Kurisu.SqlSugar; +using SqlSugar; + +namespace Dlhis.Entity.Basic.Entity; + +/// +/// 档案组 +/// +[SugarTable(TableName = "GainfoGroup", TableDescription = "档案组")] +public class GainfoGroupEntity : SugarBaseEntity +{ + /// + /// 分组code + /// + [SugarColumn(ColumnDescription = "分组code")] + public Guid Code { get; set; } + + /// + /// 名称 + /// + [SugarColumn(ColumnDescription = "名称")] + public string Name { get; set; } + + /// + /// 备注 + /// + [SugarColumn(ColumnDescription = "备注")] + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Entity/Basic/Entity/GainfoGroupRelationshipEntity.cs b/Src/Dlhis.Entity/Basic/Entity/GainfoGroupRelationshipEntity.cs new file mode 100644 index 00000000..a8747085 --- /dev/null +++ b/Src/Dlhis.Entity/Basic/Entity/GainfoGroupRelationshipEntity.cs @@ -0,0 +1,22 @@ +using Kurisu.SqlSugar; +using SqlSugar; + +namespace Dlhis.Entity.Basic.Entity; + +/// +/// 档案人员组关系 +/// +[SugarTable(TableName = "GainfoGroupRelationship", TableDescription = "档案人员组关系")] +public class GainfoGroupRelationshipEntity : SugarBaseEntity +{ + /// + /// 分组code + /// + public Guid GroupCode { get; set; } + + /// + /// 人员档案号 + /// + [SugarColumn(ColumnDescription = "人员档案号")] + public string UserNo { get; set; } +} diff --git a/Src/Dlhis.Entity/Device/Enums/DeviceFuncEnumType.cs b/Src/Dlhis.Entity/Device/Enums/DeviceFuncEnumType.cs index 2d6a2f10..ac475816 100644 --- a/Src/Dlhis.Entity/Device/Enums/DeviceFuncEnumType.cs +++ b/Src/Dlhis.Entity/Device/Enums/DeviceFuncEnumType.cs @@ -3,9 +3,9 @@ namespace Dlhis.Entity.Device.Enums; /// -/// 机器设备功能 +/// 设备功能 /// -[Description("机器设备功能")] +[Description("设备功能")] public enum DeviceFuncEnumType { /// @@ -26,14 +26,12 @@ public enum DeviceFuncEnumType [Description("人脸")] Face, - /// /// 刷卡 /// [Description("刷卡")] Card, - /// /// 二维码 /// @@ -46,4 +44,10 @@ public enum DeviceFuncEnumType /// [Description("布控")] Control, + + /// + /// 考勤 + /// + [Description("考勤")] + Attendance, } diff --git a/Src/Dlhis.Entity/Sys/Entities/DevicePermissionEntity.cs b/Src/Dlhis.Entity/Sys/Entities/DevicePermissionEntity.cs index c6f98596..cb4e2e0f 100644 --- a/Src/Dlhis.Entity/Sys/Entities/DevicePermissionEntity.cs +++ b/Src/Dlhis.Entity/Sys/Entities/DevicePermissionEntity.cs @@ -13,10 +13,17 @@ namespace Dlhis.Entity.Sys.Entities; public class DevicePermissionEntity : SugarBaseEntity, ITenantId, ISoftDeleted { /// - /// 人员档案 + /// 分配权限类型 /// - [SugarColumn(ColumnDescription = "人员档案")] - public string UserNo { get; set; } + [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "分配权限类型", SqlParameterDbType = typeof(EnumToStringConvert))] + public AssignTypeEnumType AssignType { get; set; } + + /// + /// 分配值 + /// + [SugarColumn(ColumnDescription = "分配值")] + public string AssignValue { get; set; } + /// /// 设备权限类型 diff --git a/Src/Dlhis.Entity/Sys/Entities/MenuPermissionEntity.cs b/Src/Dlhis.Entity/Sys/Entities/MenuPermissionEntity.cs index 33133cf2..67d38089 100644 --- a/Src/Dlhis.Entity/Sys/Entities/MenuPermissionEntity.cs +++ b/Src/Dlhis.Entity/Sys/Entities/MenuPermissionEntity.cs @@ -16,7 +16,7 @@ public class MenuPermissionEntity : SugarBaseEntity, ITenantId, ISoftDeleted /// 权限分配类型 /// [SugarColumn(ColumnDataType = "varchar(50)", ColumnDescription = "权限分配类型", SqlParameterDbType = typeof(EnumToStringConvert))] - public MenuAssignmentTypeEnumType UniqueType { get; set; } + public AssignTypeEnumType UniqueType { get; set; } /// /// 类型值 diff --git a/Src/Dlhis.Entity/Sys/Enums/MenuAssignmentTypeEnumType.cs b/Src/Dlhis.Entity/Sys/Enums/AssignTypeEnumType.cs similarity index 71% rename from Src/Dlhis.Entity/Sys/Enums/MenuAssignmentTypeEnumType.cs rename to Src/Dlhis.Entity/Sys/Enums/AssignTypeEnumType.cs index 0d70d4b4..f41385d5 100644 --- a/Src/Dlhis.Entity/Sys/Enums/MenuAssignmentTypeEnumType.cs +++ b/Src/Dlhis.Entity/Sys/Enums/AssignTypeEnumType.cs @@ -5,8 +5,8 @@ namespace Dlhis.Entity.Sys.Enums; /// /// 权限类型 /// -[Description("权限分配类型")] -public enum MenuAssignmentTypeEnumType +[Description("分配类型")] +public enum AssignTypeEnumType { /// /// 用户 @@ -30,5 +30,11 @@ public enum MenuAssignmentTypeEnumType /// 部门 /// [Description("部门")] - Department = 4 + Department = 4, + + /// + /// 租户/基地 + /// + [Description("租户/基地")] + Tenant = 5, } diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs index 8b8bd91d..e49d24f0 100644 --- a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/AssignmentService.cs @@ -169,7 +169,7 @@ public class AssignmentService : IAssignmentService return Scoped.Request.Value.Create((sp) => { - FaceUrlOptions faceUrlOptions = sp.GetService>().Value; + var faceUrlOptions = sp.GetService>().Value; var dataProtectionProvider = sp.GetService(); var timeLimitedDataProtector = dataProtectionProvider