Merge branch 'development' of https://git.dlhis.com/liguoyang/jinko.yikatong into development
This commit is contained in:
@@ -29,7 +29,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Canteen", "Src\Dlhis.
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys.Api", "Src\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj", "{85A345C7-913E-4C1B-BE1C-600DE408A02F}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys.Api", "Src\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj", "{85A345C7-913E-4C1B-BE1C-600DE408A02F}"
|
||||||
EndProject
|
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
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class DeviceGroupSaveRequest
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上级分组
|
/// 上级分组
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid? PCode { get; set; }
|
public Guid PCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备组名称
|
/// 设备组名称
|
||||||
@@ -23,4 +23,9 @@ public class DeviceGroupSaveRequest
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[EnumDataType(typeof(DeviceTypeEnumType))]
|
[EnumDataType(typeof(DeviceTypeEnumType))]
|
||||||
public DeviceTypeEnumType? Type { get; set; }
|
public DeviceTypeEnumType? Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备注
|
||||||
|
/// </summary>
|
||||||
|
public string Remark { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Dlhis.Entity.Device.Enums;
|
using Dlhis.Entity.Device.Enums;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Server.IISIntegration;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Response;
|
namespace Dlhis.Basic.Device.Response;
|
||||||
@@ -29,6 +30,11 @@ public class DeviceGroupTreeResponse
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DeviceTypeEnumType? Type { get; set; }
|
public DeviceTypeEnumType? Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备注
|
||||||
|
/// </summary>
|
||||||
|
public string Remark { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分组类型描述
|
/// 分组类型描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -45,6 +51,15 @@ public class DeviceGroupTreeResponse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Editable { get; set; }
|
||||||
|
|
||||||
|
public bool IsDefault { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否允许设置下级
|
||||||
|
/// </summary>
|
||||||
|
public bool AbleSetNext => IsDefault;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string TenantId { get; set; }
|
public string TenantId { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -85,10 +85,32 @@ public class DevicePageResponse
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enable { get; set; }
|
public bool Enable { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
//*********************************************************附加信息**************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最后心跳时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? LastHeartbeatTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否在线
|
/// 是否在线
|
||||||
/// </summary>
|
/// </summary>
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 消费总额
|
/// 消费总额
|
||||||
@@ -103,7 +125,7 @@ public class DevicePageResponse
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 营业点code
|
/// 营业点code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BusinessPlaceCode { get; set; }
|
public Guid? BusinessPlaceCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 营业点名称
|
/// 营业点名称
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ 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 Dlhis.Entity.Device.Enums;
|
||||||
using Kurisu.AspNetCore.UnifyResultAndValidation;
|
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.User.Abstractions;
|
using Kurisu.Core.User.Abstractions;
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
@@ -46,19 +45,13 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
//检查父级节点
|
//检查父级节点
|
||||||
await CheckPCodeExistsDeviceAsync(request.PCode);
|
await CheckPCodeExistsDeviceAsync(request.PCode);
|
||||||
|
|
||||||
|
var pGrp = await _dbContext.Queryable<DeviceGroupEntity>().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.Id.HasValue)
|
||||||
{
|
{
|
||||||
if (request.PCode.HasValue)
|
|
||||||
{
|
|
||||||
var pGrp = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Code == request.PCode).FirstAsync();
|
|
||||||
if (pGrp != null && pGrp.Type != request.Type)
|
|
||||||
{
|
|
||||||
throw new UserFriendlyException("分组类型必须与上级类型保持一致");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var entity = request.Adapt<DeviceGroupEntity>();
|
var entity = request.Adapt<DeviceGroupEntity>();
|
||||||
entity.Editable = true;
|
|
||||||
entity.Code = Guid.NewGuid();
|
entity.Code = Guid.NewGuid();
|
||||||
|
|
||||||
await _dbContext.InsertAsync(entity);
|
await _dbContext.InsertAsync(entity);
|
||||||
@@ -69,31 +62,18 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
entity.ThrowIfNull("设备组不存在,无法更新");
|
entity.ThrowIfNull("设备组不存在,无法更新");
|
||||||
entity.Editable.ThrowIfFalse("不可编辑当前组");
|
entity.Editable.ThrowIfFalse("不可编辑当前组");
|
||||||
|
|
||||||
if (entity.PCode.HasValue)
|
if (request.Type != entity.Type)
|
||||||
{
|
{
|
||||||
var pGrp = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Code == request.PCode).FirstAsync();
|
//检查下级分组type不一致
|
||||||
if (pGrp != null && pGrp.Type != request.Type)
|
var existsDiffNextGroups = await _dbContext.Queryable<DeviceGroupEntity>()
|
||||||
{
|
.Where(x => x.PCode == entity.Code)
|
||||||
throw new UserFriendlyException("分组类型必须与上级类型保持一致");
|
.Where(x => x.Type != request.Type)
|
||||||
}
|
.AnyAsync();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var nGrp = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.PCode == entity.Code).FirstAsync();
|
|
||||||
if (nGrp != null && nGrp.Type != request.Type)
|
|
||||||
{
|
|
||||||
throw new UserFriendlyException("存在下级分组类型不一致,无法修改");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var nextDevices = await GetDevicesAsync(entity.Code);
|
existsDiffNextGroups.ThrowIfTrue("存在下级分组类型不一致,无法修改");
|
||||||
if (!entity.Type.HasValue)
|
|
||||||
{
|
var nextDevices = await GetDevicesAsync(entity.Code);
|
||||||
(request.Type.HasValue && nextDevices.Any(x => x.Type != request.Type)).ThrowIfTrue($"分组设备存在非{request.Type.Value.GetDescription()}类型的设备设备");
|
nextDevices.Any(x => x.Type != request.Type).ThrowIfTrue("分组设备类型不匹配,无法修改类型");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(request.Type.HasValue && request.Type != entity.Type && nextDevices.Any()).ThrowIfTrue("分组设备类型不匹配,无法修改类型");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Adapt(entity);
|
request.Adapt(entity);
|
||||||
@@ -185,10 +165,7 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
{
|
{
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => request.DeviceCodes.Contains(x.Code)).ToListAsync();
|
var devices = await _dbContext.Queryable<DeviceEntity>().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();
|
request.DeviceCodes = devices.Select(x => x.Code).ToList();
|
||||||
|
|||||||
@@ -11,11 +11,9 @@ using Kurisu.Core.DataAccess.Dto;
|
|||||||
using Kurisu.SqlSugar.Extensions;
|
using Kurisu.SqlSugar.Extensions;
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using MySqlX.XDevAPI.Relational;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Services.Implements;
|
namespace Dlhis.Basic.Device.Services.Implements;
|
||||||
|
|
||||||
@@ -32,73 +30,35 @@ public class DeviceService : IDeviceService
|
|||||||
{
|
{
|
||||||
var page = await _dbContext.Queryable<DeviceEntity>()
|
var page = await _dbContext.Queryable<DeviceEntity>()
|
||||||
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
|
.LeftJoin<DeviceRegistryEntity>((d, dt, dr) => d.UniqueNo == dr.DeviceUniqueNo)
|
||||||
|
.LeftJoin<BusinessPlaceEntity>((d, dt, dr, bp) => dr.BusinessPlaceCode == bp.Code)
|
||||||
.WhereIF(request.Type.HasValue, (d, dt) => d.Type == request.Type)
|
.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(),
|
FuncsStr = d.Funcs.ToString(),
|
||||||
Brand = dt.Brand,
|
Brand = dt.Brand,
|
||||||
Type = d.Type,
|
Type = d.Type,
|
||||||
|
BusinessPlaceCode = bp.Code,
|
||||||
|
BusinessPlaceName = bp.Name,
|
||||||
|
LastHeartbeatTime = dr.LastHeartbeatTime
|
||||||
}, true)
|
}, true)
|
||||||
.ToPageListAsync(request);
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
var now = DateTime.Now;
|
|
||||||
var deviceUniqueNos = page.Data.Select(x => x.UniqueNo).ToList();
|
var deviceUniqueNos = page.Data.Select(x => x.UniqueNo).ToList();
|
||||||
|
|
||||||
var balanceRecords = await _dbContext.Queryable<BalanceRecordEntity>().Where(x => x.Type == BalanceRecordTypeEnumType.Out)
|
var balanceRecords = await _dbContext.Queryable<BalanceRecordEntity>().Where(x => x.Type == BalanceRecordTypeEnumType.Out)
|
||||||
.Where(x => deviceUniqueNos.Contains(x.DeviceInfo))
|
.Where(x => deviceUniqueNos.Contains(x.DeviceInfo))
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.Amount,
|
||||||
|
x.UserCode
|
||||||
|
})
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var deviceRegistries = await _dbContext.Queryable<DeviceRegistryEntity>()
|
|
||||||
.LeftJoin<DeviceEntity>((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<DeviceRegistryEntity>()
|
|
||||||
.ToListAsync();
|
|
||||||
var BusinessPlaces = await _dbContext.Queryable<BusinessPlaceEntity>()
|
|
||||||
.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 =>
|
page.Data.ForEach(device =>
|
||||||
{
|
{
|
||||||
device.Amount = balanceRecords.Sum(x => x.Amount);
|
device.Amount = balanceRecords.Sum(x => x.Amount);
|
||||||
device.UserCount = balanceRecords.DistinctBy(x => x.UserCode).Count();
|
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;
|
return page;
|
||||||
@@ -290,7 +250,7 @@ public class DeviceService : IDeviceService
|
|||||||
public async Task<DeviceNumberResponse> GetDeviceNumberAsync()
|
public async Task<DeviceNumberResponse> GetDeviceNumberAsync()
|
||||||
{
|
{
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync();
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync();
|
||||||
|
|
||||||
var offlineNumber = await GetOfflineDevicesCount(devices);
|
var offlineNumber = await GetOfflineDevicesCount(devices);
|
||||||
|
|
||||||
var res = new DeviceNumberResponse
|
var res = new DeviceNumberResponse
|
||||||
@@ -333,7 +293,7 @@ public class DeviceService : IDeviceService
|
|||||||
return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now;
|
return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now;
|
||||||
|
|
||||||
})
|
})
|
||||||
.Select(x => new
|
.Select(x => new
|
||||||
{
|
{
|
||||||
UniqueNo = x.UniqueNo,
|
UniqueNo = x.UniqueNo,
|
||||||
})
|
})
|
||||||
@@ -345,7 +305,7 @@ public class DeviceService : IDeviceService
|
|||||||
var list = devices.Where(x => offUniqueNos.Contains(x.UniqueNo)).ToList();
|
var list = devices.Where(x => offUniqueNos.Contains(x.UniqueNo)).ToList();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<Pagination<DevicePageResponse>> GetAttendanceTotalAsync(AttendanceTotalRequest request)
|
public async Task<Pagination<DevicePageResponse>> GetAttendanceTotalAsync(AttendanceTotalRequest request)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Kurisu.AspNetCore" Version="0.6.0" />
|
<PackageReference Include="Kurisu.AspNetCore" Version="0.6.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -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 Dlhis.Basic.Organization.Services;
|
||||||
using Kurisu.AspNetCore.MVC;
|
using Kurisu.AspNetCore.MVC;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
@@ -33,14 +31,4 @@ public class DepartmentsController : ControllerBase
|
|||||||
{
|
{
|
||||||
return await _departmentService.GetTreeAsync();
|
return await _departmentService.GetTreeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取部门树分页
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("treepage")]
|
|
||||||
public async Task<Pagination<DepartmentTreeResponse>> GetTreePageAsync([FromQuery]DepartmentPageRequest request)
|
|
||||||
{
|
|
||||||
return await _departmentService.GetTreePageAsync(request);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Dlhis.Basic.Organization.Response;
|
using Dlhis.Basic.Organization.Services;
|
||||||
using Dlhis.Basic.Organization.Services;
|
using Dlhis.Sys.Api.Response;
|
||||||
using Dlhis.User.Api.Response;
|
|
||||||
using Kurisu.AspNetCore.MVC;
|
using Kurisu.AspNetCore.MVC;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Request
|
|
||||||
{
|
|
||||||
public class DepartmentPageRequest : PageDto
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
public class DepartmentTreeResponse
|
public class DepartmentTreeResponse
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 上级
|
||||||
|
/// </summary>
|
||||||
|
public string PNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 部门号
|
/// 部门号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -23,6 +23,21 @@ public class GainfoGroupTreeResponse
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Remark { get; set; }
|
public string Remark { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否可编辑
|
||||||
|
/// </summary>
|
||||||
|
public bool Editable { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为业务默认分组
|
||||||
|
/// </summary>
|
||||||
|
public bool IsDefault { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否允许设置下级
|
||||||
|
/// </summary>
|
||||||
|
public bool AbleSetNext => IsDefault;
|
||||||
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string TenantId { get; set; }
|
public string TenantId { get; set; }
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
using Dlhis.Basic.Organization.Request;
|
using Dlhis.Basic.Organization.Response;
|
||||||
using Dlhis.Basic.Organization.Response;
|
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Services;
|
namespace Dlhis.Basic.Organization.Services;
|
||||||
|
|
||||||
public interface IDepartmentService : IScopeDependency
|
public interface IDepartmentService : IScopeDependency
|
||||||
{
|
{
|
||||||
Task<List<DepartmentTreeResponse>> GetTreeAsync();
|
Task<List<DepartmentTreeResponse>> GetTreeAsync();
|
||||||
|
|
||||||
Task<Pagination<DepartmentTreeResponse>> GetTreePageAsync(DepartmentPageRequest request);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Dlhis.User.Api.Response;
|
using Dlhis.Sys.Api.Response;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Services;
|
namespace Dlhis.Basic.Organization.Services;
|
||||||
|
|
||||||
|
|||||||
@@ -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 Dlhis.Entity.Basic.Entity;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.Core.User.Abstractions;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Services.Implements;
|
namespace Dlhis.Basic.Organization.Services.Implements;
|
||||||
|
|
||||||
public class DepartmentService : IDepartmentService
|
public class DepartmentService : IDepartmentService
|
||||||
{
|
{
|
||||||
private readonly IDbContext _dbContext;
|
private readonly IDbContext _dbContext;
|
||||||
|
private readonly ICurrentUser _currentUser;
|
||||||
|
|
||||||
public DepartmentService(IDbContext dbContext)
|
public DepartmentService(IDbContext dbContext, ICurrentUser currentUser)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
|
_currentUser = currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<DepartmentTreeResponse>> GetTreeAsync()
|
public async Task<List<DepartmentTreeResponse>> GetTreeAsync()
|
||||||
{
|
{
|
||||||
var departments = await _dbContext.Queryable<DepartmentEntity>().ToListAsync();
|
var myTenants = _currentUser.GetUserClaim("tenants").Split(',').ToList();
|
||||||
|
|
||||||
|
var departments = await _dbContext.Queryable<DepartmentEntity>().Select<DepartmentTreeResponse>().ToListAsync();
|
||||||
//00001000 一定是这个开头的
|
//00001000 一定是这个开头的
|
||||||
var tops = departments.Where(x => x.PNo == "00001000").Adapt<List<DepartmentTreeResponse>>();
|
var tops = departments.Where(x => x.PNo == "00001000").ToList();
|
||||||
|
|
||||||
tops.ForEach(x =>
|
tops.ForEach(x =>
|
||||||
{
|
{
|
||||||
@@ -32,42 +32,13 @@ public class DepartmentService : IDepartmentService
|
|||||||
return tops;
|
return tops;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Pagination<DepartmentTreeResponse>> GetTreePageAsync(DepartmentPageRequest request)
|
private void RecursionGetNext(DepartmentTreeResponse current, List<DepartmentTreeResponse> data)
|
||||||
{
|
{
|
||||||
var departments = await _dbContext
|
var next = data.Where(x => x.PNo == current.No).ToList();
|
||||||
.Queryable<DepartmentEntity>()
|
current.Next = next;
|
||||||
.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<List<DepartmentTreeResponse>>();
|
|
||||||
|
|
||||||
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<DepartmentTreeResponse>
|
|
||||||
{
|
|
||||||
PageIndex = request.PageIndex,
|
|
||||||
PageSize = request.PageSize,
|
|
||||||
Total = tops.Count, // 使用原始列表的总数进行分页
|
|
||||||
Data = pagedData
|
|
||||||
};
|
|
||||||
|
|
||||||
return pagination;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RecursionGetNext(DepartmentTreeResponse current, List<DepartmentEntity> departments)
|
|
||||||
{
|
|
||||||
var next = departments.Where(x => x.PNo == current.No).ToList();
|
|
||||||
current.Next = next.Adapt<List<DepartmentTreeResponse>>();
|
|
||||||
foreach (var item in next)
|
foreach (var item in next)
|
||||||
{
|
{
|
||||||
RecursionGetNext(item.Adapt<DepartmentTreeResponse>(), departments);
|
RecursionGetNext(item, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ public class GainfoGroupService : IGainfoGroupService
|
|||||||
|
|
||||||
public async Task<List<GainfoGroupTreeResponse>> GetTreeAsync()
|
public async Task<List<GainfoGroupTreeResponse>> GetTreeAsync()
|
||||||
{
|
{
|
||||||
var deviceGroups = await _dbContext.Queryable<GainfoGroupEntity>()
|
var gainfoGroups = await _dbContext.Queryable<GainfoGroupEntity>()
|
||||||
.Select<GainfoGroupTreeResponse>()
|
.Select<GainfoGroupTreeResponse>()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList();
|
var tops = gainfoGroups.Where(x => !x.PCode.HasValue).ToList();
|
||||||
tops.ForEach(x =>
|
tops.ForEach(x =>
|
||||||
{
|
{
|
||||||
RecursionGetNext(x, deviceGroups);
|
RecursionGetNext(x, gainfoGroups);
|
||||||
});
|
});
|
||||||
|
|
||||||
return tops;
|
return tops;
|
||||||
@@ -59,14 +59,12 @@ public class GainfoGroupService : IGainfoGroupService
|
|||||||
{
|
{
|
||||||
var entity = request.Adapt<GainfoGroupEntity>();
|
var entity = request.Adapt<GainfoGroupEntity>();
|
||||||
entity.Code = Guid.NewGuid();
|
entity.Code = Guid.NewGuid();
|
||||||
entity.Editable = true;
|
|
||||||
await _dbContext.InsertAsync(entity);
|
await _dbContext.InsertAsync(entity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var entity = await _dbContext.Queryable<GainfoGroupEntity>().Where(x => x.Id == request.Id).SingleAsync();
|
var entity = await _dbContext.Queryable<GainfoGroupEntity>().Where(x => x.Id == request.Id).SingleAsync();
|
||||||
request.Adapt(entity);
|
request.Adapt(entity);
|
||||||
entity.Editable = true;
|
|
||||||
await _dbContext.UpdateAsync(entity);
|
await _dbContext.UpdateAsync(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,10 @@ public class GainfoService : IGainfoService
|
|||||||
.WhereIF(request.DepartmentNos.IsPresent(), gainfo => request.DepartmentNos.Contains(gainfo.DepartmentNo))
|
.WhereIF(request.DepartmentNos.IsPresent(), gainfo => request.DepartmentNos.Contains(gainfo.DepartmentNo))
|
||||||
.WhereIF(request.Search.IsPresent(), gainfo =>
|
.WhereIF(request.Search.IsPresent(), gainfo =>
|
||||||
gainfo.Name.Contains(request.Search)
|
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<GainfoPageResponse>()
|
.Select<GainfoPageResponse>()
|
||||||
.ToPageListAsync(request);
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using Dlhis.Sys.Api;
|
using Dlhis.Sys.Api;
|
||||||
using Dlhis.User.Api.Response;
|
using Dlhis.Sys.Api.Response;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.Result;
|
using Kurisu.Core.Result;
|
||||||
using Kurisu.Core.User.Abstractions;
|
using Kurisu.Core.User.Abstractions;
|
||||||
|
|||||||
@@ -36,11 +36,15 @@ public class BalanceService : IBalanceService
|
|||||||
.LeftJoin<DepartmentEntity>((record, ga, department) => ga.DepartmentNo == department.No)
|
.LeftJoin<DepartmentEntity>((record, ga, department) => ga.DepartmentNo == department.No)
|
||||||
.LeftJoin<BusinessPlaceEntity>((record, ga, department, bplace) => record.BusinessPlaceCode == bplace.Code)
|
.LeftJoin<BusinessPlaceEntity>((record, ga, department, bplace) => record.BusinessPlaceCode == bplace.Code)
|
||||||
.LeftJoin<BusinessShiftEntity>((record, ga, department, bplace, bshift) => record.BusinessShiftCode == bshift.Code)
|
.LeftJoin<BusinessShiftEntity>((record, ga, department, bplace, bshift) => record.BusinessShiftCode == bshift.Code)
|
||||||
.LeftJoin<BasicTypeEntity>((record, ga, department, bplace, bshift, type) => record.BusinessShiftCode.ToString() == type.Code)
|
.LeftJoin<BasicTypeEntity>((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?.Start.HasValue == true, record => record.CostDate >= request.SearchDateTimePeriod.Start)
|
||||||
.WhereIF(request.SearchDateTimePeriod?.End.HasValue == true, record => record.CostDate <= request.SearchDateTimePeriod.End)
|
.WhereIF(request.SearchDateTimePeriod?.End.HasValue == true, record => record.CostDate <= request.SearchDateTimePeriod.End)
|
||||||
.WhereIF(request.BusinessplaceCodes.IsPresent(), record => request.BusinessplaceCodes.Contains(record.BusinessPlaceCode))
|
.WhereIF(request.BusinessplaceCodes.IsPresent(), record => request.BusinessplaceCodes.Contains(record.BusinessPlaceCode))
|
||||||
.WhereIF(request.ShiftTypes.IsPresent(), record => request.ShiftTypes.Contains(record.ShiftType))
|
.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)
|
.OrderBy(record => record.CreateTime, OrderByType.Desc)
|
||||||
.Select((record, ga, department, bplace, bshift, type) => new BalanceRecordResponse
|
.Select((record, ga, department, bplace, bshift, type) => new BalanceRecordResponse
|
||||||
{
|
{
|
||||||
@@ -66,7 +70,7 @@ public class BalanceService : IBalanceService
|
|||||||
DepartmentName = department.Name,
|
DepartmentName = department.Name,
|
||||||
BusinessPlaceName = bplace.Name,
|
BusinessPlaceName = bplace.Name,
|
||||||
BusinessShiftName = type.Display,
|
BusinessShiftName = type.Display,
|
||||||
CostDateTime = record.CreateTime // todo
|
CostDateTime = record.CostDateTime
|
||||||
})
|
})
|
||||||
.ToPageListAsync(request);
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ public class DeviceGroupEntity : SugarBaseEntity, ITenantId, ISoftDeleted
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备组功能类型
|
/// 设备组功能类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(IsNullable = true, ColumnDescription = "设备组功能类型", ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))]
|
[SugarColumn(IsNullable = false, ColumnDescription = "设备组功能类型", ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))]
|
||||||
public DeviceTypeEnumType? Type { get; set; }
|
public DeviceTypeEnumType Type { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上级设备组code
|
/// 上级设备组code
|
||||||
@@ -40,9 +40,21 @@ public class DeviceGroupEntity : SugarBaseEntity, ITenantId, ISoftDeleted
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否可编辑
|
/// 是否可编辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(ColumnDescription = "是否可编辑")]
|
[SugarColumn(ColumnDataType = "bit", DefaultValue = "1", ColumnDescription = "是否可编辑")]
|
||||||
public bool Editable { get; set; }
|
public bool Editable { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可设置下级
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDataType = "bit", DefaultValue = "1")]
|
||||||
|
public bool AbleSetNext { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备注
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public string Remark { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string TenantId { get; set; }
|
public string TenantId { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class DeviceRegistryEntity : SugarBaseEntity, ITenantId
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备唯一号
|
/// 设备唯一号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(ColumnDescription = "设备唯一号")]
|
[SugarColumn(ColumnDescription = "设备唯一号", UniqueGroupNameList = new[] { "idx_DeviceRegistry_DeviceUniqueNo" })]
|
||||||
public string DeviceUniqueNo { get; set; }
|
public string DeviceUniqueNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using Dlhis.Entity.Device.Entities;
|
using Dlhis.Entity.Device.Entities;
|
||||||
using Dlhis.Entity.Device.Enums;
|
using Dlhis.Entity.Device.Enums;
|
||||||
using Dlhis.Sys.Api;
|
using Dlhis.Sys.Api;
|
||||||
using Dlhis.User.Api.Response;
|
using Dlhis.Sys.Api.Response;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.DataAccess.Entity;
|
using Kurisu.Core.DataAccess.Entity;
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
@@ -29,6 +29,8 @@ public class CreateDefinitelyGroupJob
|
|||||||
sqlSugarOptionsService.IgnoreTenant = true;
|
sqlSugarOptionsService.IgnoreTenant = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly string _remark = "系统自动生成";
|
||||||
|
|
||||||
public async Task RunAsync()
|
public async Task RunAsync()
|
||||||
{
|
{
|
||||||
_dbContext.Client.QueryFilter.ClearAndBackup<ITenantId>();
|
_dbContext.Client.QueryFilter.ClearAndBackup<ITenantId>();
|
||||||
@@ -77,6 +79,7 @@ public class CreateDefinitelyGroupJob
|
|||||||
Name = grp,
|
Name = grp,
|
||||||
IsDefault = grp.Equals("*自定义人员分组"),
|
IsDefault = grp.Equals("*自定义人员分组"),
|
||||||
Editable = false,
|
Editable = false,
|
||||||
|
Remark = _remark,
|
||||||
|
|
||||||
CreatedBy = 1,
|
CreatedBy = 1,
|
||||||
CreateTime = DateTime.Now,
|
CreateTime = DateTime.Now,
|
||||||
@@ -103,6 +106,8 @@ public class CreateDefinitelyGroupJob
|
|||||||
Type = type,
|
Type = type,
|
||||||
Name = grp,
|
Name = grp,
|
||||||
Editable = false,
|
Editable = false,
|
||||||
|
AbleSetNext = false,
|
||||||
|
Remark = _remark,
|
||||||
|
|
||||||
CreatedBy = 1,
|
CreatedBy = 1,
|
||||||
CreateTime = DateTime.Now,
|
CreateTime = DateTime.Now,
|
||||||
@@ -126,6 +131,8 @@ public class CreateDefinitelyGroupJob
|
|||||||
Type = type,
|
Type = type,
|
||||||
Name = workplaceName,
|
Name = workplaceName,
|
||||||
Editable = false,
|
Editable = false,
|
||||||
|
AbleSetNext = false,
|
||||||
|
Remark = _remark,
|
||||||
|
|
||||||
CreatedBy = 1,
|
CreatedBy = 1,
|
||||||
CreateTime = DateTime.Now,
|
CreateTime = DateTime.Now,
|
||||||
@@ -148,6 +155,8 @@ public class CreateDefinitelyGroupJob
|
|||||||
Type = type,
|
Type = type,
|
||||||
Name = factoryName,
|
Name = factoryName,
|
||||||
Editable = false,
|
Editable = false,
|
||||||
|
AbleSetNext = true,
|
||||||
|
Remark = _remark,
|
||||||
|
|
||||||
CreatedBy = 1,
|
CreatedBy = 1,
|
||||||
CreateTime = DateTime.Now,
|
CreateTime = DateTime.Now,
|
||||||
|
|||||||
@@ -32,4 +32,14 @@ public class DeviceTaskAssignmentsController : ControllerBase
|
|||||||
{
|
{
|
||||||
return await _deviceTaskAssignmentService.GetPageAsync(request);
|
return await _deviceTaskAssignmentService.GetPageAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置任务
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("reset")]
|
||||||
|
public async Task ResetAsync(DeviceTaskResetRequest request)
|
||||||
|
{
|
||||||
|
await _deviceTaskAssignmentService.ResetAsync(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Dlhis.ScheduledTask.TaskAssignment.Request;
|
||||||
|
|
||||||
|
public class DeviceTaskResetRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 任务ids
|
||||||
|
/// </summary>
|
||||||
|
[MinLength(1, ErrorMessage = "请选择任务进行重置")]
|
||||||
|
public List<long> Ids { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否强制重置
|
||||||
|
/// </summary>
|
||||||
|
public bool Force { get; set; }
|
||||||
|
}
|
||||||
@@ -57,6 +57,11 @@ public class DeviceTaskAssignmentResponse
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string ResultMessage { get; set; }
|
public string ResultMessage { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 任务创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 数据状态最新修改时间
|
/// 数据状态最新修改时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ public interface IDeviceTaskAssignmentService : IScopeDependency
|
|||||||
{
|
{
|
||||||
Task<Pagination<DeviceTaskAssignmentResponse>> GetPageAsync(DeviceTaskAssignmentRequest request);
|
Task<Pagination<DeviceTaskAssignmentResponse>> GetPageAsync(DeviceTaskAssignmentRequest request);
|
||||||
|
|
||||||
|
Task ResetAsync(DeviceTaskResetRequest request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
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 Dlhis.ScheduledTask.TaskAssignment.Request;
|
using Dlhis.ScheduledTask.TaskAssignment.Request;
|
||||||
using Dlhis.ScheduledTask.TaskAssignment.Response;
|
using Dlhis.ScheduledTask.TaskAssignment.Response;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
@@ -38,12 +39,35 @@ public class DeviceTaskAssignmentService : IDeviceTaskAssignmentService
|
|||||||
UserName = ga.Name,
|
UserName = ga.Name,
|
||||||
UserCode = ga.Code,
|
UserCode = ga.Code,
|
||||||
Type = deviceTask.Type,
|
Type = deviceTask.Type,
|
||||||
|
CreateTime = deviceTask.CreateTime,
|
||||||
LastUpdateTime = deviceTask.ModifiedTime
|
LastUpdateTime = deviceTask.ModifiedTime
|
||||||
})
|
})
|
||||||
.ToPageListAsync(request);
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ResetAsync(DeviceTaskResetRequest request)
|
||||||
|
{
|
||||||
|
var tasks = await _dbContext.Queryable<DeviceTaskEntity>()
|
||||||
|
.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<DeviceTaskEntity>()
|
||||||
|
.SetColumns(x => x.Status == DeviceTaskStatusEnumType.Wait)
|
||||||
|
.Where(x => request.Ids.Contains(x.Id))
|
||||||
|
.Where(x => x.Status == DeviceTaskStatusEnumType.Process || x.Status == DeviceTaskStatusEnumType.Error)
|
||||||
|
.ExecuteCommandAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Dlhis.User.Api.Response;
|
using Dlhis.Sys.Api.Response;
|
||||||
using Kurisu.Core.Result;
|
using Kurisu.Core.Result;
|
||||||
using Kurisu.RemoteCall.Attributes;
|
using Kurisu.RemoteCall.Attributes;
|
||||||
|
|
||||||
@@ -18,6 +18,11 @@ public interface ITenantApi
|
|||||||
[Get("/api/tenants/list")]
|
[Get("/api/tenants/list")]
|
||||||
Task<DefaultApiResult<List<TenantResponse>>> GetTenantsAsync();
|
Task<DefaultApiResult<List<TenantResponse>>> GetTenantsAsync();
|
||||||
|
|
||||||
|
|
||||||
|
[Auth]
|
||||||
|
[Get("/api/tenants/tree")]
|
||||||
|
Task<DefaultApiResult<List<TenantTreeResponse>>> GetTenantTreeAsync();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取所有租户(内部使用)
|
/// 获取所有租户(内部使用)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Dlhis.User.Api.Response;
|
namespace Dlhis.Sys.Api.Response;
|
||||||
|
|
||||||
public class TenantResponse
|
public class TenantResponse
|
||||||
{
|
{
|
||||||
|
|||||||
12
Src/Dlhis.Sys.Api/Response/TenantTreeResponse.cs
Normal file
12
Src/Dlhis.Sys.Api/Response/TenantTreeResponse.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Dlhis.Sys.Api.Response;
|
||||||
|
|
||||||
|
public class TenantTreeResponse : TenantResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 下级
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(Order = 99)]
|
||||||
|
public List<TenantTreeResponse> Next { get; set; }
|
||||||
|
}
|
||||||
@@ -51,6 +51,16 @@ public class TenantsController : ControllerBase
|
|||||||
return await _tenantService.GetListAsync();
|
return await _tenantService.GetListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 租户树
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("tree")]
|
||||||
|
public async Task<List<TenantTreeResponse>> GetTreeAsync()
|
||||||
|
{
|
||||||
|
return await _tenantService.GetTreeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取租户
|
/// 获取租户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ public class TenantSaveRequest
|
|||||||
{
|
{
|
||||||
public int? Id { get; set; }
|
public int? Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上级
|
||||||
|
/// </summary>
|
||||||
|
public string PCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 代码
|
/// 代码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
12
Src/Dlhis.Sys/Identity/Response/TenantTreeResponse.cs
Normal file
12
Src/Dlhis.Sys/Identity/Response/TenantTreeResponse.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Dlhis.Sys.Identity.Response;
|
||||||
|
|
||||||
|
public class TenantTreeResponse : TenantResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 下级
|
||||||
|
/// </summary>
|
||||||
|
[JsonProperty(Order = 99)]
|
||||||
|
public List<TenantTreeResponse> Next { get; set; }
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ public interface ITenantService : IScopeDependency
|
|||||||
|
|
||||||
Task<List<TenantResponse>> GetListAsync();
|
Task<List<TenantResponse>> GetListAsync();
|
||||||
|
|
||||||
|
Task<List<TenantTreeResponse>> GetTreeAsync();
|
||||||
|
|
||||||
Task<TenantResponse> GetTenantByCode(string code);
|
Task<TenantResponse> GetTenantByCode(string code);
|
||||||
|
|
||||||
Task<List<TenantResponse>> GetMyTenantsAsync();
|
Task<List<TenantResponse>> GetMyTenantsAsync();
|
||||||
|
|||||||
@@ -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.Request;
|
||||||
using Dlhis.Sys.Identity.Response;
|
using Dlhis.Sys.Identity.Response;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
@@ -14,11 +15,9 @@ public class TenantService : ITenantService
|
|||||||
private readonly IDbContext _dbContext;
|
private readonly IDbContext _dbContext;
|
||||||
private readonly ICurrentUser _currentUser;
|
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 = dbContext.ChangeDb("identity");
|
||||||
dbContext.Client.CurrentConnectionConfig.ConnectionString = identityConnection;
|
|
||||||
_dbContext = dbContext;
|
|
||||||
_currentUser = currentUser;
|
_currentUser = currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,6 +51,7 @@ public class TenantService : ITenantService
|
|||||||
{
|
{
|
||||||
await _dbContext.InsertAsync(new TenantEntity
|
await _dbContext.InsertAsync(new TenantEntity
|
||||||
{
|
{
|
||||||
|
PCode = request.PCode,
|
||||||
Code = request.Code,
|
Code = request.Code,
|
||||||
Name = request.Name,
|
Name = request.Name,
|
||||||
});
|
});
|
||||||
@@ -89,4 +89,29 @@ public class TenantService : ITenantService
|
|||||||
|
|
||||||
return myTenants;
|
return myTenants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<TenantTreeResponse>> GetTreeAsync()
|
||||||
|
{
|
||||||
|
var tenants = await _dbContext.Queryable<TenantEntity>()
|
||||||
|
.Select<TenantTreeResponse>()
|
||||||
|
.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<TenantTreeResponse> data)
|
||||||
|
{
|
||||||
|
var next = data.Where(x => x.PCode == current.Code).ToList();
|
||||||
|
current.Next = next;
|
||||||
|
foreach (var item in next)
|
||||||
|
{
|
||||||
|
RecursionGetNext(item, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Dlhis.Sys.Menu.Services;
|
|||||||
using Dlhis.Sys.Menu.Response;
|
using Dlhis.Sys.Menu.Response;
|
||||||
using Dlhis.Sys.Menu.Request;
|
using Dlhis.Sys.Menu.Request;
|
||||||
using Dlhis.Entity.Sys.Enums;
|
using Dlhis.Entity.Sys.Enums;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
|
|
||||||
namespace Dlhis.Sys.Menu.Controllers;
|
namespace Dlhis.Sys.Menu.Controllers;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using Kurisu.AspNetCore.Startup;
|
using Kurisu.AspNetCore.Startup;
|
||||||
using Kurisu.Core.DataAccess.Entity;
|
|
||||||
using Kurisu.SqlSugar.Extensions;
|
using Kurisu.SqlSugar.Extensions;
|
||||||
using Kurisu.SqlSugar.Services;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
|
|
||||||
namespace Dlhis.Sys;
|
namespace Dlhis.Sys;
|
||||||
@@ -36,103 +33,4 @@ public class SqlSugarPack : BaseAppPack
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 日志
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
|
||||||
public class LogAttribute : Attribute, IAsyncActionFilter
|
|
||||||
{
|
|
||||||
public LogAttribute(string title)
|
|
||||||
{
|
|
||||||
Title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否处理差异
|
|
||||||
/// </summary>
|
|
||||||
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<ISqlSugarOptionsService>();
|
|
||||||
|
|
||||||
options.Title = Title;
|
|
||||||
options.Diff = Diff;
|
|
||||||
options.BatchNo = Guid.NewGuid();
|
|
||||||
options.RoutePath = httpContext.Request.Path.Value;
|
|
||||||
options.RaiseTime = DateTime.Now;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 事务
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
|
||||||
public class TransactionalAttribute : Attribute, IAsyncActionFilter
|
|
||||||
{
|
|
||||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
|
||||||
{
|
|
||||||
var dbContext = context.HttpContext.RequestServices.GetRequiredService<ISqlSugarClient>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 忽略租户
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
|
||||||
public class IgnoreTenantAttribute : Attribute, IAsyncActionFilter
|
|
||||||
{
|
|
||||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
|
||||||
{
|
|
||||||
var dbContext = context.HttpContext.RequestServices.GetRequiredService<ISqlSugarClient>();
|
|
||||||
var options = context.HttpContext!.RequestServices.GetService<ISqlSugarOptionsService>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
dbContext.QueryFilter.ClearAndBackup<ITenantId>();
|
|
||||||
options.IgnoreTenant = true;
|
|
||||||
await next();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
options.IgnoreTenant = false;
|
|
||||||
dbContext.QueryFilter.Restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user