diff --git a/Dlhis.Jinko.Face.sln b/Dlhis.Jinko.Face.sln index ff1fecaa..0f893f5a 100644 --- a/Dlhis.Jinko.Face.sln +++ b/Dlhis.Jinko.Face.sln @@ -29,7 +29,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys.Api", "Src\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj", "{85A345C7-913E-4C1B-BE1C-600DE408A02F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dlhis.Basic.Api", "Src\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj", "{1F337648-8A22-4601-A842-0F634FBA2825}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Basic.Api", "Src\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj", "{1F337648-8A22-4601-A842-0F634FBA2825}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Src/Dlhis.Basic/Device/Request/DeviceGroupSaveRequest.cs b/Src/Dlhis.Basic/Device/Request/DeviceGroupSaveRequest.cs index 9cbf1ee9..73bf5281 100644 --- a/Src/Dlhis.Basic/Device/Request/DeviceGroupSaveRequest.cs +++ b/Src/Dlhis.Basic/Device/Request/DeviceGroupSaveRequest.cs @@ -10,7 +10,7 @@ public class DeviceGroupSaveRequest /// /// 上级分组 /// - public Guid? PCode { get; set; } + public Guid PCode { get; set; } /// /// 设备组名称 @@ -23,4 +23,9 @@ public class DeviceGroupSaveRequest /// [EnumDataType(typeof(DeviceTypeEnumType))] public DeviceTypeEnumType? Type { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } } diff --git a/Src/Dlhis.Basic/Device/Response/DeviceGroupTreeResponse.cs b/Src/Dlhis.Basic/Device/Response/DeviceGroupTreeResponse.cs index 31b5f3f3..a1e7456a 100644 --- a/Src/Dlhis.Basic/Device/Response/DeviceGroupTreeResponse.cs +++ b/Src/Dlhis.Basic/Device/Response/DeviceGroupTreeResponse.cs @@ -1,5 +1,6 @@ using Dlhis.Entity.Device.Enums; using Kurisu.AspNetCore.Utils.Extensions; +using Microsoft.AspNetCore.Server.IISIntegration; using Newtonsoft.Json; namespace Dlhis.Basic.Device.Response; @@ -29,6 +30,11 @@ public class DeviceGroupTreeResponse /// public DeviceTypeEnumType? Type { get; set; } + /// + /// 备注 + /// + public string Remark { get; set; } + /// /// 分组类型描述 /// @@ -45,6 +51,15 @@ public class DeviceGroupTreeResponse } } + public bool Editable { get; set; } + + public bool IsDefault { get; set; } + + /// + /// 是否允许设置下级 + /// + public bool AbleSetNext => IsDefault; + [JsonIgnore] public string TenantId { get; set; } diff --git a/Src/Dlhis.Basic/Device/Response/DevicePageResponse.cs b/Src/Dlhis.Basic/Device/Response/DevicePageResponse.cs index ab586f63..5543715e 100644 --- a/Src/Dlhis.Basic/Device/Response/DevicePageResponse.cs +++ b/Src/Dlhis.Basic/Device/Response/DevicePageResponse.cs @@ -85,10 +85,32 @@ public class DevicePageResponse /// public bool Enable { get; set; } + + //*********************************************************附加信息**************************************************************/ + + /// + /// 最后心跳时间 + /// + public DateTime? LastHeartbeatTime { get; set; } + /// /// 是否在线 /// - public bool IsOnline { get; set; } + public bool IsOnline + { + get + { + if (!LastHeartbeatTime.HasValue) + return false; + else + { + if (HeartbeatInterval <= 0) + return true; + else + return LastHeartbeatTime.Value.AddSeconds(HeartbeatInterval * 3) >= DateTime.Now; + } + } + } /// /// 消费总额 @@ -103,7 +125,7 @@ public class DevicePageResponse /// /// 营业点code /// - public string BusinessPlaceCode { get; set; } + public Guid? BusinessPlaceCode { get; set; } /// /// 营业点名称 diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs index 361d6289..23cc9137 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceGroupService.cs @@ -3,7 +3,6 @@ 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.User.Abstractions; using Kurisu.SqlSugar.Services; @@ -46,19 +45,13 @@ public class DeviceGroupService : IDeviceGroupService //检查父级节点 await CheckPCodeExistsDeviceAsync(request.PCode); + var pGrp = await _dbContext.Queryable().Where(x => x.Code == request.PCode).FirstAsync(); + pGrp.AbleSetNext.ThrowIfFalse($"分组{pGrp.Name}不可添加下级"); + (pGrp != null && pGrp.Type != request.Type).ThrowIfTrue("分组类型必须与上级类型保持一致"); + if (!request.Id.HasValue) { - if (request.PCode.HasValue) - { - var pGrp = await _dbContext.Queryable().Where(x => x.Code == request.PCode).FirstAsync(); - if (pGrp != null && pGrp.Type != request.Type) - { - throw new UserFriendlyException("分组类型必须与上级类型保持一致"); - } - } - var entity = request.Adapt(); - entity.Editable = true; entity.Code = Guid.NewGuid(); await _dbContext.InsertAsync(entity); @@ -69,31 +62,18 @@ public class DeviceGroupService : IDeviceGroupService entity.ThrowIfNull("设备组不存在,无法更新"); entity.Editable.ThrowIfFalse("不可编辑当前组"); - if (entity.PCode.HasValue) + if (request.Type != entity.Type) { - var pGrp = await _dbContext.Queryable().Where(x => x.Code == request.PCode).FirstAsync(); - if (pGrp != null && pGrp.Type != request.Type) - { - throw new UserFriendlyException("分组类型必须与上级类型保持一致"); - } - } - else - { - var nGrp = await _dbContext.Queryable().Where(x => x.PCode == entity.Code).FirstAsync(); - if (nGrp != null && nGrp.Type != request.Type) - { - throw new UserFriendlyException("存在下级分组类型不一致,无法修改"); - } - } + //检查下级分组type不一致 + var existsDiffNextGroups = await _dbContext.Queryable() + .Where(x => x.PCode == entity.Code) + .Where(x => x.Type != request.Type) + .AnyAsync(); - var nextDevices = await GetDevicesAsync(entity.Code); - if (!entity.Type.HasValue) - { - (request.Type.HasValue && nextDevices.Any(x => x.Type != request.Type)).ThrowIfTrue($"分组设备存在非{request.Type.Value.GetDescription()}类型的设备设备"); - } - else - { - (request.Type.HasValue && request.Type != entity.Type && nextDevices.Any()).ThrowIfTrue("分组设备类型不匹配,无法修改类型"); + existsDiffNextGroups.ThrowIfTrue("存在下级分组类型不一致,无法修改"); + + var nextDevices = await GetDevicesAsync(entity.Code); + nextDevices.Any(x => x.Type != request.Type).ThrowIfTrue("分组设备类型不匹配,无法修改类型"); } request.Adapt(entity); @@ -185,10 +165,7 @@ public class DeviceGroupService : IDeviceGroupService { var devices = await _dbContext.Queryable().Where(x => request.DeviceCodes.Contains(x.Code)).ToListAsync(); //检查分组的分类控制 - if (group.Type.HasValue) - { - devices.Any(x => x.Type != group.Type).ThrowIfTrue("存在设备类型有误,无法分配到当前分组"); - } + devices.Any(x => x.Type != group.Type).ThrowIfTrue("存在设备类型有误,无法分配到当前分组"); //重新赋值到请求参数中 request.DeviceCodes = devices.Select(x => x.Code).ToList(); diff --git a/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs b/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs index dc9409e9..7632b1b6 100644 --- a/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs +++ b/Src/Dlhis.Basic/Device/Services/Implements/DeviceService.cs @@ -11,11 +11,9 @@ using Kurisu.Core.DataAccess.Dto; using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; using Mapster; -using MySqlX.XDevAPI.Relational; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SqlSugar; -using System.Collections.Generic; namespace Dlhis.Basic.Device.Services.Implements; @@ -32,73 +30,35 @@ public class DeviceService : IDeviceService { var page = await _dbContext.Queryable() .LeftJoin((d, dt) => d.TemplateCode == dt.Code) + .LeftJoin((d, dt, dr) => d.UniqueNo == dr.DeviceUniqueNo) + .LeftJoin((d, dt, dr, bp) => dr.BusinessPlaceCode == bp.Code) .WhereIF(request.Type.HasValue, (d, dt) => d.Type == request.Type) - .Select((d, dt) => new DevicePageResponse + .Select((d, dt, dr, bp) => new DevicePageResponse { FuncsStr = d.Funcs.ToString(), Brand = dt.Brand, Type = d.Type, + BusinessPlaceCode = bp.Code, + BusinessPlaceName = bp.Name, + LastHeartbeatTime = dr.LastHeartbeatTime }, true) .ToPageListAsync(request); - var now = DateTime.Now; var deviceUniqueNos = page.Data.Select(x => x.UniqueNo).ToList(); var balanceRecords = await _dbContext.Queryable().Where(x => x.Type == BalanceRecordTypeEnumType.Out) .Where(x => deviceUniqueNos.Contains(x.DeviceInfo)) + .Select(x => new + { + x.Amount, + x.UserCode + }) .ToListAsync(); - var deviceRegistries = await _dbContext.Queryable() - .LeftJoin((x, d) => x.DeviceUniqueNo == d.UniqueNo) - .Where(x => deviceUniqueNos.Contains(x.DeviceUniqueNo)) - .Select((x, d) => new - { - d.HeartbeatInterval, - x.LastHeartbeatTime, - x.DeviceUniqueNo, - }) - .ToListAsync(); - - var Registries = await _dbContext.Queryable() - .ToListAsync(); - var BusinessPlaces = await _dbContext.Queryable() - .ToListAsync(); - - foreach (var res in page.Data) - { - var regis = Registries.Where(x => x.DeviceUniqueNo == res.UniqueNo).FirstOrDefault(); - if (regis != null) - { - var place = BusinessPlaces.Where(x => x.Code == regis.BusinessPlaceCode).FirstOrDefault(); - if (place != null) - { - res.BusinessPlaceCode = regis.BusinessPlaceCode.ToString(); - res.BusinessPlaceName = place.Name; - } - } - - } page.Data.ForEach(device => { device.Amount = balanceRecords.Sum(x => x.Amount); device.UserCount = balanceRecords.DistinctBy(x => x.UserCode).Count(); - - var r = deviceRegistries.FirstOrDefault(x => x.DeviceUniqueNo == device.UniqueNo); - if (r == null) - { - device.IsOnline = false; - } - else - { - if (r.HeartbeatInterval <= 0) - { - device.IsOnline = true; - } - else - { - device.IsOnline = r.LastHeartbeatTime.AddSeconds(r.HeartbeatInterval * 3) >= now; - } - } }); return page; @@ -290,7 +250,7 @@ public class DeviceService : IDeviceService public async Task GetDeviceNumberAsync() { var devices = await _dbContext.Queryable().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync(); - + var offlineNumber = await GetOfflineDevicesCount(devices); var res = new DeviceNumberResponse @@ -333,7 +293,7 @@ public class DeviceService : IDeviceService return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now; }) - .Select(x => new + .Select(x => new { UniqueNo = x.UniqueNo, }) @@ -345,7 +305,7 @@ public class DeviceService : IDeviceService var list = devices.Where(x => offUniqueNos.Contains(x.UniqueNo)).ToList(); return list; } - + public async Task> GetAttendanceTotalAsync(AttendanceTotalRequest request) { diff --git a/Src/Dlhis.Basic/Dlhis.Basic.csproj b/Src/Dlhis.Basic/Dlhis.Basic.csproj index 43b23333..ffe86e4d 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/DepartmentsController.cs b/Src/Dlhis.Basic/Organization/Controllers/DepartmentsController.cs index 678e2e0a..55fa4c2b 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/DepartmentsController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/DepartmentsController.cs @@ -1,8 +1,6 @@ -using Dlhis.Basic.Organization.Request; -using Dlhis.Basic.Organization.Response; +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; @@ -33,14 +31,4 @@ public class DepartmentsController : ControllerBase { return await _departmentService.GetTreeAsync(); } - - /// - /// 获取部门树分页 - /// - /// - [HttpGet("treepage")] - public async Task> GetTreePageAsync([FromQuery]DepartmentPageRequest request) - { - return await _departmentService.GetTreePageAsync(request); - } } diff --git a/Src/Dlhis.Basic/Organization/Controllers/WerksController.cs b/Src/Dlhis.Basic/Organization/Controllers/WerksController.cs index 5f7522dd..bbbb7904 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/WerksController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/WerksController.cs @@ -1,6 +1,5 @@ -using Dlhis.Basic.Organization.Response; -using Dlhis.Basic.Organization.Services; -using Dlhis.User.Api.Response; +using Dlhis.Basic.Organization.Services; +using Dlhis.Sys.Api.Response; using Kurisu.AspNetCore.MVC; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; diff --git a/Src/Dlhis.Basic/Organization/Request/DepartmentPageRequest.cs b/Src/Dlhis.Basic/Organization/Request/DepartmentPageRequest.cs deleted file mode 100644 index cdba378c..00000000 --- a/Src/Dlhis.Basic/Organization/Request/DepartmentPageRequest.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Kurisu.Core.DataAccess.Dto; - -namespace Dlhis.Basic.Organization.Request -{ - public class DepartmentPageRequest : PageDto - { - } -} diff --git a/Src/Dlhis.Basic/Organization/Response/DepartmentTreeResponse.cs b/Src/Dlhis.Basic/Organization/Response/DepartmentTreeResponse.cs index c30d68b1..309e6d58 100644 --- a/Src/Dlhis.Basic/Organization/Response/DepartmentTreeResponse.cs +++ b/Src/Dlhis.Basic/Organization/Response/DepartmentTreeResponse.cs @@ -2,6 +2,11 @@ public class DepartmentTreeResponse { + /// + /// 上级 + /// + public string PNo { get; set; } + /// /// 部门号 /// diff --git a/Src/Dlhis.Basic/Organization/Response/GainfoGroupTreeResponse.cs b/Src/Dlhis.Basic/Organization/Response/GainfoGroupTreeResponse.cs index 3fb4ca63..5b5000fd 100644 --- a/Src/Dlhis.Basic/Organization/Response/GainfoGroupTreeResponse.cs +++ b/Src/Dlhis.Basic/Organization/Response/GainfoGroupTreeResponse.cs @@ -23,6 +23,21 @@ public class GainfoGroupTreeResponse /// public string Remark { get; set; } + /// + /// 是否可编辑 + /// + public bool Editable { get; set; } + + /// + /// 是否为业务默认分组 + /// + public bool IsDefault { get; set; } + + /// + /// 是否允许设置下级 + /// + public bool AbleSetNext => IsDefault; + [JsonIgnore] public string TenantId { get; set; } diff --git a/Src/Dlhis.Basic/Organization/Services/IDepartmentService.cs b/Src/Dlhis.Basic/Organization/Services/IDepartmentService.cs index cfd0b9d2..5e3784c1 100644 --- a/Src/Dlhis.Basic/Organization/Services/IDepartmentService.cs +++ b/Src/Dlhis.Basic/Organization/Services/IDepartmentService.cs @@ -1,12 +1,8 @@ -using Dlhis.Basic.Organization.Request; -using Dlhis.Basic.Organization.Response; -using Kurisu.Core.DataAccess.Dto; +using Dlhis.Basic.Organization.Response; namespace Dlhis.Basic.Organization.Services; public interface IDepartmentService : IScopeDependency { Task> GetTreeAsync(); - - Task> GetTreePageAsync(DepartmentPageRequest request); } diff --git a/Src/Dlhis.Basic/Organization/Services/IWerkService.cs b/Src/Dlhis.Basic/Organization/Services/IWerkService.cs index 8f8ecc4b..42b1a90e 100644 --- a/Src/Dlhis.Basic/Organization/Services/IWerkService.cs +++ b/Src/Dlhis.Basic/Organization/Services/IWerkService.cs @@ -1,4 +1,4 @@ -using Dlhis.User.Api.Response; +using Dlhis.Sys.Api.Response; namespace Dlhis.Basic.Organization.Services; diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/DepartmentService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/DepartmentService.cs index 77f42f9a..9800dc40 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/DepartmentService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/DepartmentService.cs @@ -1,28 +1,28 @@ -using Dlhis.Basic.Organization.Request; -using Dlhis.Basic.Organization.Response; +using Dlhis.Basic.Organization.Response; using Dlhis.Entity.Basic.Entity; -using Kurisu.AspNetCore.Utils.Extensions; -using Kurisu.Core.DataAccess.Dto; +using Kurisu.Core.User.Abstractions; using Kurisu.SqlSugar.Services; -using Mapster; -using System.Collections.Generic; namespace Dlhis.Basic.Organization.Services.Implements; public class DepartmentService : IDepartmentService { private readonly IDbContext _dbContext; + private readonly ICurrentUser _currentUser; - public DepartmentService(IDbContext dbContext) + public DepartmentService(IDbContext dbContext, ICurrentUser currentUser) { _dbContext = dbContext; + _currentUser = currentUser; } public async Task> GetTreeAsync() { - var departments = await _dbContext.Queryable().ToListAsync(); + var myTenants = _currentUser.GetUserClaim("tenants").Split(',').ToList(); + + var departments = await _dbContext.Queryable().Select().ToListAsync(); //00001000 一定是这个开头的 - var tops = departments.Where(x => x.PNo == "00001000").Adapt>(); + var tops = departments.Where(x => x.PNo == "00001000").ToList(); tops.ForEach(x => { @@ -32,42 +32,13 @@ public class DepartmentService : IDepartmentService return tops; } - public async Task> GetTreePageAsync(DepartmentPageRequest request) + private void RecursionGetNext(DepartmentTreeResponse current, List data) { - var departments = await _dbContext - .Queryable() - .WhereIF(!request.Search.IsEmpty(), x => x.Name.Contains(request.Search) || x.No.Contains(request.Search)).ToListAsync(); - - var tops = departments.Where(x => x.PNo.IsEmpty()).Adapt>(); - - tops.ForEach(x => - { - RecursionGetNext(x, departments); - }); - - // 分页操作 - var startIndex = (request.PageIndex - 1) * request.PageSize; - var pagedData = tops.Skip(startIndex).Take(request.PageSize).ToList(); - - var pagination = new Pagination - { - PageIndex = request.PageIndex, - PageSize = request.PageSize, - Total = tops.Count, // 使用原始列表的总数进行分页 - Data = pagedData - }; - - return pagination; - - } - - private void RecursionGetNext(DepartmentTreeResponse current, List departments) - { - var next = departments.Where(x => x.PNo == current.No).ToList(); - current.Next = next.Adapt>(); + var next = data.Where(x => x.PNo == current.No).ToList(); + current.Next = next; foreach (var item in next) { - RecursionGetNext(item.Adapt(), departments); + RecursionGetNext(item, data); } } } diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs index 2a4390ef..ea35ff11 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoGroupService.cs @@ -22,14 +22,14 @@ public class GainfoGroupService : IGainfoGroupService public async Task> GetTreeAsync() { - var deviceGroups = await _dbContext.Queryable() + var gainfoGroups = await _dbContext.Queryable() .Select() .ToListAsync(); - var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList(); + var tops = gainfoGroups.Where(x => !x.PCode.HasValue).ToList(); tops.ForEach(x => { - RecursionGetNext(x, deviceGroups); + RecursionGetNext(x, gainfoGroups); }); return tops; @@ -59,14 +59,12 @@ public class GainfoGroupService : IGainfoGroupService { var entity = request.Adapt(); entity.Code = Guid.NewGuid(); - entity.Editable = true; await _dbContext.InsertAsync(entity); } else { var entity = await _dbContext.Queryable().Where(x => x.Id == request.Id).SingleAsync(); request.Adapt(entity); - entity.Editable = true; await _dbContext.UpdateAsync(entity); } } diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs index f500ad8c..7997ceb8 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs @@ -63,7 +63,10 @@ public class GainfoService : IGainfoService .WhereIF(request.DepartmentNos.IsPresent(), gainfo => request.DepartmentNos.Contains(gainfo.DepartmentNo)) .WhereIF(request.Search.IsPresent(), gainfo => gainfo.Name.Contains(request.Search) - || gainfo.Code.Contains(request.Search)) + || gainfo.Code.Contains(request.Search) + || gainfo.IdNo.Contains(request.Search) + || gainfo.Werks.Contains(request.Search) + ) .Select() .ToPageListAsync(request); diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/WerkService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/WerkService.cs index 718bd6c1..99517d8a 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/WerkService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/WerkService.cs @@ -1,5 +1,5 @@ using Dlhis.Sys.Api; -using Dlhis.User.Api.Response; +using Dlhis.Sys.Api.Response; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.Result; using Kurisu.Core.User.Abstractions; diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs index 1a7c47f4..f8e57a1f 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs @@ -36,11 +36,15 @@ public class BalanceService : IBalanceService .LeftJoin((record, ga, department) => ga.DepartmentNo == department.No) .LeftJoin((record, ga, department, bplace) => record.BusinessPlaceCode == bplace.Code) .LeftJoin((record, ga, department, bplace, bshift) => record.BusinessShiftCode == bshift.Code) - .LeftJoin((record, ga, department, bplace, bshift, type) => record.BusinessShiftCode.ToString() == type.Code) + .LeftJoin((record, ga, department, bplace, bshift, type) => record.ShiftType == type.Code && type.Type == "mealshift") .WhereIF(request.SearchDateTimePeriod?.Start.HasValue == true, record => record.CostDate >= request.SearchDateTimePeriod.Start) .WhereIF(request.SearchDateTimePeriod?.End.HasValue == true, record => record.CostDate <= request.SearchDateTimePeriod.End) .WhereIF(request.BusinessplaceCodes.IsPresent(), record => request.BusinessplaceCodes.Contains(record.BusinessPlaceCode)) .WhereIF(request.ShiftTypes.IsPresent(), record => request.ShiftTypes.Contains(record.ShiftType)) + .WhereIF(request.Search.IsPresent(), (record, ga) => + ga.Name.Contains(request.Search) + || ga.Code.Contains(request.Search) + ) .OrderBy(record => record.CreateTime, OrderByType.Desc) .Select((record, ga, department, bplace, bshift, type) => new BalanceRecordResponse { @@ -66,7 +70,7 @@ public class BalanceService : IBalanceService DepartmentName = department.Name, BusinessPlaceName = bplace.Name, BusinessShiftName = type.Display, - CostDateTime = record.CreateTime // todo + CostDateTime = record.CostDateTime }) .ToPageListAsync(request); diff --git a/Src/Dlhis.Entity/Device/Entities/DeviceGroupEntity.cs b/Src/Dlhis.Entity/Device/Entities/DeviceGroupEntity.cs index b3f44bb9..a56c8c97 100644 --- a/Src/Dlhis.Entity/Device/Entities/DeviceGroupEntity.cs +++ b/Src/Dlhis.Entity/Device/Entities/DeviceGroupEntity.cs @@ -15,8 +15,8 @@ public class DeviceGroupEntity : SugarBaseEntity, ITenantId, ISoftDeleted /// /// 设备组功能类型 /// - [SugarColumn(IsNullable = true, ColumnDescription = "设备组功能类型", ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))] - public DeviceTypeEnumType? Type { get; set; } + [SugarColumn(IsNullable = false, ColumnDescription = "设备组功能类型", ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))] + public DeviceTypeEnumType Type { get; set; } /// /// 上级设备组code @@ -40,9 +40,21 @@ public class DeviceGroupEntity : SugarBaseEntity, ITenantId, ISoftDeleted /// /// 是否可编辑 /// - [SugarColumn(ColumnDescription = "是否可编辑")] + [SugarColumn(ColumnDataType = "bit", DefaultValue = "1", ColumnDescription = "是否可编辑")] public bool Editable { get; set; } + /// + /// 可设置下级 + /// + [SugarColumn(ColumnDataType = "bit", DefaultValue = "1")] + public bool AbleSetNext { get; set; } + + /// + /// 备注 + /// + [SugarColumn(IsNullable = true)] + public string Remark { get; set; } + public string TenantId { get; set; } diff --git a/Src/Dlhis.Entity/Device/Entities/DeviceRegistryEntity.cs b/Src/Dlhis.Entity/Device/Entities/DeviceRegistryEntity.cs index aa88393e..4d45f3ef 100644 --- a/Src/Dlhis.Entity/Device/Entities/DeviceRegistryEntity.cs +++ b/Src/Dlhis.Entity/Device/Entities/DeviceRegistryEntity.cs @@ -13,7 +13,7 @@ public class DeviceRegistryEntity : SugarBaseEntity, ITenantId /// /// 设备唯一号 /// - [SugarColumn(ColumnDescription = "设备唯一号")] + [SugarColumn(ColumnDescription = "设备唯一号", UniqueGroupNameList = new[] { "idx_DeviceRegistry_DeviceUniqueNo" })] public string DeviceUniqueNo { get; set; } /// diff --git a/Src/Dlhis.ScheduledTask/CommonJobs/CreateDefinitelyGroupJob.cs b/Src/Dlhis.ScheduledTask/CommonJobs/CreateDefinitelyGroupJob.cs index af824291..9daadce1 100644 --- a/Src/Dlhis.ScheduledTask/CommonJobs/CreateDefinitelyGroupJob.cs +++ b/Src/Dlhis.ScheduledTask/CommonJobs/CreateDefinitelyGroupJob.cs @@ -2,7 +2,7 @@ using Dlhis.Entity.Device.Entities; using Dlhis.Entity.Device.Enums; using Dlhis.Sys.Api; -using Dlhis.User.Api.Response; +using Dlhis.Sys.Api.Response; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Entity; using Kurisu.SqlSugar.Services; @@ -29,6 +29,8 @@ public class CreateDefinitelyGroupJob sqlSugarOptionsService.IgnoreTenant = true; } + private static readonly string _remark = "系统自动生成"; + public async Task RunAsync() { _dbContext.Client.QueryFilter.ClearAndBackup(); @@ -77,6 +79,7 @@ public class CreateDefinitelyGroupJob Name = grp, IsDefault = grp.Equals("*自定义人员分组"), Editable = false, + Remark = _remark, CreatedBy = 1, CreateTime = DateTime.Now, @@ -103,6 +106,8 @@ public class CreateDefinitelyGroupJob Type = type, Name = grp, Editable = false, + AbleSetNext = false, + Remark = _remark, CreatedBy = 1, CreateTime = DateTime.Now, @@ -126,6 +131,8 @@ public class CreateDefinitelyGroupJob Type = type, Name = workplaceName, Editable = false, + AbleSetNext = false, + Remark = _remark, CreatedBy = 1, CreateTime = DateTime.Now, @@ -148,6 +155,8 @@ public class CreateDefinitelyGroupJob Type = type, Name = factoryName, Editable = false, + AbleSetNext = true, + Remark = _remark, CreatedBy = 1, CreateTime = DateTime.Now, diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Controllers/DeviceTaskAssignmentsController.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Controllers/DeviceTaskAssignmentsController.cs index 6b72836c..52822708 100644 --- a/Src/Dlhis.ScheduledTask/TaskAssignment/Controllers/DeviceTaskAssignmentsController.cs +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Controllers/DeviceTaskAssignmentsController.cs @@ -32,4 +32,14 @@ public class DeviceTaskAssignmentsController : ControllerBase { return await _deviceTaskAssignmentService.GetPageAsync(request); } + + /// + /// 重置任务 + /// + /// + [HttpPost("reset")] + public async Task ResetAsync(DeviceTaskResetRequest request) + { + await _deviceTaskAssignmentService.ResetAsync(request); + } } diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Request/DeviceTaskResetRequest.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Request/DeviceTaskResetRequest.cs new file mode 100644 index 00000000..516be624 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Request/DeviceTaskResetRequest.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace Dlhis.ScheduledTask.TaskAssignment.Request; + +public class DeviceTaskResetRequest +{ + /// + /// 任务ids + /// + [MinLength(1, ErrorMessage = "请选择任务进行重置")] + public List Ids { get; set; } + + /// + /// 是否强制重置 + /// + public bool Force { get; set; } +} diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Response/DeviceTaskAssignmentResponse.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Response/DeviceTaskAssignmentResponse.cs index 96ae9243..7eb69334 100644 --- a/Src/Dlhis.ScheduledTask/TaskAssignment/Response/DeviceTaskAssignmentResponse.cs +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Response/DeviceTaskAssignmentResponse.cs @@ -57,6 +57,11 @@ public class DeviceTaskAssignmentResponse /// public string ResultMessage { get; set; } + /// + /// 任务创建时间 + /// + public DateTime CreateTime { get; set; } + /// /// 数据状态最新修改时间 /// diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/IDeviceTaskAssignmentService.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/IDeviceTaskAssignmentService.cs index e5bc005c..67c172dd 100644 --- a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/IDeviceTaskAssignmentService.cs +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/IDeviceTaskAssignmentService.cs @@ -8,4 +8,6 @@ public interface IDeviceTaskAssignmentService : IScopeDependency { Task> GetPageAsync(DeviceTaskAssignmentRequest request); + Task ResetAsync(DeviceTaskResetRequest request); + } diff --git a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/DeviceTaskAssignmentService.cs b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/DeviceTaskAssignmentService.cs index 40f2386a..f2cff78a 100644 --- a/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/DeviceTaskAssignmentService.cs +++ b/Src/Dlhis.ScheduledTask/TaskAssignment/Services/Implements/DeviceTaskAssignmentService.cs @@ -1,5 +1,6 @@ using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Device.Entities; +using Dlhis.Entity.Device.Enums; using Dlhis.ScheduledTask.TaskAssignment.Request; using Dlhis.ScheduledTask.TaskAssignment.Response; using Kurisu.AspNetCore.Utils.Extensions; @@ -38,12 +39,35 @@ public class DeviceTaskAssignmentService : IDeviceTaskAssignmentService UserName = ga.Name, UserCode = ga.Code, Type = deviceTask.Type, + CreateTime = deviceTask.CreateTime, LastUpdateTime = deviceTask.ModifiedTime }) .ToPageListAsync(request); return page; } + + public async Task ResetAsync(DeviceTaskResetRequest request) + { + var tasks = await _dbContext.Queryable() + .Where(x => request.Ids.Contains(x.Id)) + .Where(x => x.Status == DeviceTaskStatusEnumType.Process || x.Status == DeviceTaskStatusEnumType.Error) + .ToListAsync(); + + //判断process任务时间 + if (!request.Force) + { + var now = DateTime.Now; + tasks.Any(x => x.ModifiedTime.AddMinutes(10) < now && x.Status == DeviceTaskStatusEnumType.Process).ThrowIfTrue("请等待任务处理完成"); + } + + //更新任务状态 + await _dbContext.Updateable() + .SetColumns(x => x.Status == DeviceTaskStatusEnumType.Wait) + .Where(x => request.Ids.Contains(x.Id)) + .Where(x => x.Status == DeviceTaskStatusEnumType.Process || x.Status == DeviceTaskStatusEnumType.Error) + .ExecuteCommandAsync(); + } } diff --git a/Src/Dlhis.Sys.Api/ITenantApi.cs b/Src/Dlhis.Sys.Api/ITenantApi.cs index efa3634f..72feba3b 100644 --- a/Src/Dlhis.Sys.Api/ITenantApi.cs +++ b/Src/Dlhis.Sys.Api/ITenantApi.cs @@ -1,4 +1,4 @@ -using Dlhis.User.Api.Response; +using Dlhis.Sys.Api.Response; using Kurisu.Core.Result; using Kurisu.RemoteCall.Attributes; @@ -18,6 +18,11 @@ public interface ITenantApi [Get("/api/tenants/list")] Task>> GetTenantsAsync(); + + [Auth] + [Get("/api/tenants/tree")] + Task>> GetTenantTreeAsync(); + /// /// 获取所有租户(内部使用) /// diff --git a/Src/Dlhis.Sys.Api/Response/TenantResponse.cs b/Src/Dlhis.Sys.Api/Response/TenantResponse.cs index e20f2110..329c0b98 100644 --- a/Src/Dlhis.Sys.Api/Response/TenantResponse.cs +++ b/Src/Dlhis.Sys.Api/Response/TenantResponse.cs @@ -1,4 +1,4 @@ -namespace Dlhis.User.Api.Response; +namespace Dlhis.Sys.Api.Response; public class TenantResponse { diff --git a/Src/Dlhis.Sys.Api/Response/TenantTreeResponse.cs b/Src/Dlhis.Sys.Api/Response/TenantTreeResponse.cs new file mode 100644 index 00000000..a81ba190 --- /dev/null +++ b/Src/Dlhis.Sys.Api/Response/TenantTreeResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Dlhis.Sys.Api.Response; + +public class TenantTreeResponse : TenantResponse +{ + /// + /// 下级 + /// + [JsonProperty(Order = 99)] + public List Next { get; set; } +} diff --git a/Src/Dlhis.Sys/Identity/Controllers/TenantsController.cs b/Src/Dlhis.Sys/Identity/Controllers/TenantsController.cs index f34fb7ab..4018d12d 100644 --- a/Src/Dlhis.Sys/Identity/Controllers/TenantsController.cs +++ b/Src/Dlhis.Sys/Identity/Controllers/TenantsController.cs @@ -51,6 +51,16 @@ public class TenantsController : ControllerBase return await _tenantService.GetListAsync(); } + /// + /// 租户树 + /// + /// + [HttpGet("tree")] + public async Task> GetTreeAsync() + { + return await _tenantService.GetTreeAsync(); + } + /// /// 获取租户 /// diff --git a/Src/Dlhis.Sys/Identity/Request/TenantSaveRequest.cs b/Src/Dlhis.Sys/Identity/Request/TenantSaveRequest.cs index a065d331..700c3ba0 100644 --- a/Src/Dlhis.Sys/Identity/Request/TenantSaveRequest.cs +++ b/Src/Dlhis.Sys/Identity/Request/TenantSaveRequest.cs @@ -6,6 +6,11 @@ public class TenantSaveRequest { public int? Id { get; set; } + /// + /// 上级 + /// + public string PCode { get; set; } + /// /// 代码 /// diff --git a/Src/Dlhis.Sys/Identity/Response/TenantTreeResponse.cs b/Src/Dlhis.Sys/Identity/Response/TenantTreeResponse.cs new file mode 100644 index 00000000..dc940ba0 --- /dev/null +++ b/Src/Dlhis.Sys/Identity/Response/TenantTreeResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Dlhis.Sys.Identity.Response; + +public class TenantTreeResponse : TenantResponse +{ + /// + /// 下级 + /// + [JsonProperty(Order = 99)] + public List Next { get; set; } +} diff --git a/Src/Dlhis.Sys/Identity/Services/ITenantService.cs b/Src/Dlhis.Sys/Identity/Services/ITenantService.cs index 4c58ad63..c7fb53d8 100644 --- a/Src/Dlhis.Sys/Identity/Services/ITenantService.cs +++ b/Src/Dlhis.Sys/Identity/Services/ITenantService.cs @@ -10,6 +10,8 @@ public interface ITenantService : IScopeDependency Task> GetListAsync(); + Task> GetTreeAsync(); + Task GetTenantByCode(string code); Task> GetMyTenantsAsync(); diff --git a/Src/Dlhis.Sys/Identity/Services/Implements/TenantService.cs b/Src/Dlhis.Sys/Identity/Services/Implements/TenantService.cs index 7dfbbff8..9302cc6e 100644 --- a/Src/Dlhis.Sys/Identity/Services/Implements/TenantService.cs +++ b/Src/Dlhis.Sys/Identity/Services/Implements/TenantService.cs @@ -1,4 +1,5 @@ -using Dlhis.Entity.Sys.Entities; +using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Sys.Entities; using Dlhis.Sys.Identity.Request; using Dlhis.Sys.Identity.Response; using Kurisu.AspNetCore.Utils.Extensions; @@ -14,11 +15,9 @@ public class TenantService : ITenantService private readonly IDbContext _dbContext; private readonly ICurrentUser _currentUser; - public TenantService(IDbContext dbContext, IConfiguration configuration, ICurrentUser currentUser) + public TenantService(IDbContext dbContext, ICurrentUser currentUser) { - var identityConnection = configuration.GetSection("SqlSugarOptions:IdentityConnectionString").Value; - dbContext.Client.CurrentConnectionConfig.ConnectionString = identityConnection; - _dbContext = dbContext; + _dbContext = dbContext.ChangeDb("identity"); _currentUser = currentUser; } @@ -52,6 +51,7 @@ public class TenantService : ITenantService { await _dbContext.InsertAsync(new TenantEntity { + PCode = request.PCode, Code = request.Code, Name = request.Name, }); @@ -89,4 +89,29 @@ public class TenantService : ITenantService return myTenants; } + + public async Task> GetTreeAsync() + { + var tenants = await _dbContext.Queryable() + .Select() + .ToListAsync(); + + var tops = tenants.Where(x => x.PCode.IsEmpty()).ToList(); + foreach (var item in tops) + { + RecursionGetNext(item, tenants); + } + return tops; + } + + + private void RecursionGetNext(TenantTreeResponse current, List data) + { + var next = data.Where(x => x.PCode == current.Code).ToList(); + current.Next = next; + foreach (var item in next) + { + RecursionGetNext(item, data); + } + } } diff --git a/Src/Dlhis.Sys/Menu/Controllers/MenusController.cs b/Src/Dlhis.Sys/Menu/Controllers/MenusController.cs index 97808ff2..cf0247f4 100644 --- a/Src/Dlhis.Sys/Menu/Controllers/MenusController.cs +++ b/Src/Dlhis.Sys/Menu/Controllers/MenusController.cs @@ -5,6 +5,7 @@ using Dlhis.Sys.Menu.Services; using Dlhis.Sys.Menu.Response; using Dlhis.Sys.Menu.Request; using Dlhis.Entity.Sys.Enums; +using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; namespace Dlhis.Sys.Menu.Controllers; diff --git a/Src/Dlhis.Sys/SqlSugarPack.cs b/Src/Dlhis.Sys/SqlSugarPack.cs index 3c58cc41..9458f466 100644 --- a/Src/Dlhis.Sys/SqlSugarPack.cs +++ b/Src/Dlhis.Sys/SqlSugarPack.cs @@ -1,8 +1,5 @@ using Kurisu.AspNetCore.Startup; -using Kurisu.Core.DataAccess.Entity; using Kurisu.SqlSugar.Extensions; -using Kurisu.SqlSugar.Services; -using Microsoft.AspNetCore.Mvc.Filters; using SqlSugar; namespace Dlhis.Sys; @@ -36,103 +33,4 @@ public class SqlSugarPack : BaseAppPack }; }); } -} - - - - -/// -/// 日志 -/// -[AttributeUsage(AttributeTargets.Method)] -public class LogAttribute : Attribute, IAsyncActionFilter -{ - public LogAttribute(string title) - { - Title = title; - } - - /// - /// - /// - public string Title { get; set; } - - /// - /// 是否处理差异 - /// - public bool Diff { get; set; } - - - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) - { - PreSetting(context.HttpContext); - await next(); - } - - private void PreSetting(HttpContext httpContext) - { - var options = httpContext.RequestServices.GetService(); - - options.Title = Title; - options.Diff = Diff; - options.BatchNo = Guid.NewGuid(); - options.RoutePath = httpContext.Request.Path.Value; - options.RaiseTime = DateTime.Now; - } -} - -/// -/// 事务 -/// -[AttributeUsage(AttributeTargets.Method)] -public class TransactionalAttribute : Attribute, IAsyncActionFilter -{ - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) - { - var dbContext = context.HttpContext.RequestServices.GetRequiredService(); - await dbContext.Ado.BeginTranAsync(); - try - { - var result = await next(); - if (result.Exception != null) - { - throw result.Exception; - } - else - { - await dbContext.Ado.CommitTranAsync(); - } - } - catch (Exception) - { - await dbContext.Ado.RollbackTranAsync(); - throw; - } - } -} - -/// -/// 忽略租户 -/// -[AttributeUsage(AttributeTargets.Method)] -public class IgnoreTenantAttribute : Attribute, IAsyncActionFilter -{ - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) - { - var dbContext = context.HttpContext.RequestServices.GetRequiredService(); - var options = context.HttpContext!.RequestServices.GetService(); - try - { - dbContext.QueryFilter.ClearAndBackup(); - options.IgnoreTenant = true; - await next(); - } - finally - { - options.IgnoreTenant = false; - dbContext.QueryFilter.Restore(); - } - } -} - - +} \ No newline at end of file