Merge branch 'development'
This commit is contained in:
@@ -29,6 +29,8 @@ 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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Basic.Api", "Src\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj", "{1F337648-8A22-4601-A842-0F634FBA2825}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -71,6 +73,10 @@ Global
|
|||||||
{85A345C7-913E-4C1B-BE1C-600DE408A02F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{85A345C7-913E-4C1B-BE1C-600DE408A02F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{85A345C7-913E-4C1B-BE1C-600DE408A02F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{85A345C7-913E-4C1B-BE1C-600DE408A02F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{85A345C7-913E-4C1B-BE1C-600DE408A02F}.Release|Any CPU.Build.0 = Release|Any CPU
|
{85A345C7-913E-4C1B-BE1C-600DE408A02F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{1F337648-8A22-4601-A842-0F634FBA2825}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1F337648-8A22-4601-A842-0F634FBA2825}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1F337648-8A22-4601-A842-0F634FBA2825}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1F337648-8A22-4601-A842-0F634FBA2825}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -84,6 +90,7 @@ Global
|
|||||||
{925048C9-5940-4B51-8480-4DC908C754A1} = {57074FD8-1A2F-40C7-8476-001778A3F65D}
|
{925048C9-5940-4B51-8480-4DC908C754A1} = {57074FD8-1A2F-40C7-8476-001778A3F65D}
|
||||||
{8317C526-3523-4195-9B19-2F17CFD71927} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B}
|
{8317C526-3523-4195-9B19-2F17CFD71927} = {3D8A98C1-83C9-4375-AEAB-4F72AFAF365B}
|
||||||
{85A345C7-913E-4C1B-BE1C-600DE408A02F} = {57074FD8-1A2F-40C7-8476-001778A3F65D}
|
{85A345C7-913E-4C1B-BE1C-600DE408A02F} = {57074FD8-1A2F-40C7-8476-001778A3F65D}
|
||||||
|
{1F337648-8A22-4601-A842-0F634FBA2825} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0}
|
SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0}
|
||||||
13
Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj
Normal file
13
Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Kurisu.RemoteCall" Version="0.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
12
Src/Dlhis.Basic.Api/IDevicePermissionApi.cs
Normal file
12
Src/Dlhis.Basic.Api/IDevicePermissionApi.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Kurisu.Core.Result;
|
||||||
|
using Kurisu.RemoteCall.Attributes;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Api;
|
||||||
|
|
||||||
|
[EnableRemoteClient(Name = "basic-service", BaseUrl = "${InternalRequest:BasicRequestUrl}")]
|
||||||
|
public interface IDevicePermissionApi
|
||||||
|
{
|
||||||
|
[Auth]
|
||||||
|
[Get("/api/devicepermissions/canteen/uniqueNos")]
|
||||||
|
Task<DefaultApiResult<List<string>>> GetCanteenDeviceUniqueNosByUserNoAsync(string userNo);
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using Dlhis.Basic.BusinessPlace.Response;
|
using Dlhis.Basic.BusinessPlace.Response;
|
||||||
using Dlhis.Basic.BusinessPlace.Services;
|
using Dlhis.Basic.BusinessPlace.Services;
|
||||||
using Dlhis.Basic.BusinessShift.Services;
|
using Dlhis.Basic.BusinessShift.Services;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -58,12 +59,24 @@ public class BusinessPlacesController : ControllerBase
|
|||||||
await _businessPlaceService.SaveAsync(request);
|
await _businessPlaceService.SaveAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点保存餐次
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("shift/save")]
|
||||||
|
public async Task SaveShiftAsync(BusinessPlaceSaveShiftRequest request)
|
||||||
|
{
|
||||||
|
await _businessPlaceService.SaveShiftAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据手工号获取餐别
|
/// 根据手工号获取餐别
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("shifts")]
|
[HttpPost("shifts")]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeHttpPostAsync(BusinessPlaceGetShiftsRequest request)
|
public async Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeHttpPostAsync(BusinessPlaceGetShiftsRequest request)
|
||||||
{
|
{
|
||||||
return await _businessPlaceShiftService.GetShiftsByPlaceCustomCodeAsync(request.CustomCode);
|
return await _businessPlaceShiftService.GetShiftsByPlaceCustomCodeAsync(request.CustomCode);
|
||||||
@@ -75,8 +88,20 @@ public class BusinessPlacesController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("shifts")]
|
[HttpGet("shifts")]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeHttpGetAsync([FromQuery] BusinessPlaceGetShiftsRequest request)
|
public async Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeHttpGetAsync([FromQuery] BusinessPlaceGetShiftsRequest request)
|
||||||
{
|
{
|
||||||
return await _businessPlaceShiftService.GetShiftsByPlaceCustomCodeAsync(request.CustomCode);
|
return await _businessPlaceShiftService.GetShiftsByPlaceCustomCodeAsync(request.CustomCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据营业点获取下面的设备
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("devicenos")]
|
||||||
|
public async Task<Pagination<DeviceCodeNameDetail>> GetDevicesByCode([FromQuery]BusinessPlaceGetByCodeRequest request)
|
||||||
|
{
|
||||||
|
return await _businessPlaceShiftService.GetDevicesByCode(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.BusinessPlace.Request
|
||||||
|
{
|
||||||
|
public class BusinessPlaceGetByCodeRequest : PageDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点号
|
||||||
|
/// </summary>
|
||||||
|
[Required(ErrorMessage = "营业点号不能为空")]
|
||||||
|
public string Code { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Dlhis.Basic.BusinessPlace.Request;
|
||||||
|
|
||||||
|
public class BusinessPlaceSaveShiftRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点id
|
||||||
|
/// </summary>
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 餐次code
|
||||||
|
/// </summary>
|
||||||
|
public Guid ShiftCode { get; set; }
|
||||||
|
}
|
||||||
@@ -35,9 +35,21 @@ public class BusinessPlaceResponse
|
|||||||
public CanteenBusinessPlaceSourceEnumType Source { get; set; }
|
public CanteenBusinessPlaceSourceEnumType Source { get; set; }
|
||||||
public string SourceDesc => Source.GetDescription();
|
public string SourceDesc => Source.GetDescription();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分类,超市/餐厅/食堂
|
/// 分类,超市/餐厅/食堂
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CanteenBusinessPlaceCatalogEnumType Catalog { get; set; }
|
public CanteenBusinessPlaceCatalogEnumType Catalog { get; set; }
|
||||||
public string CatalogDesc => Catalog.GetDescription();
|
public string CatalogDesc => Catalog.GetDescription();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 餐次code
|
||||||
|
/// </summary>
|
||||||
|
public Guid? ShiftCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 餐次名称
|
||||||
|
/// </summary>
|
||||||
|
public string ShiftName { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Dlhis.Basic.BusinessPlace.Response
|
||||||
|
{
|
||||||
|
public class DeviceCodeNameDetail
|
||||||
|
{
|
||||||
|
public string UniqueNo { get; set; }
|
||||||
|
public string UniqueName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
using Dlhis.Basic.BusinessPlace.Request;
|
using Dlhis.Basic.BusinessPlace.Request;
|
||||||
using Dlhis.Basic.BusinessPlace.Response;
|
using Dlhis.Basic.BusinessPlace.Response;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Kurisu.SqlSugar.Attributes;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.BusinessPlace.Services;
|
namespace Dlhis.Basic.BusinessPlace.Services;
|
||||||
|
|
||||||
public interface IBusinessPlaceService : IScopeDependency
|
public interface IBusinessPlaceService : IScopeDependency
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点分页
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
Task<Pagination<BusinessPlaceResponse>> GetPageAsync(BusinessPlacePageRequest request);
|
Task<Pagination<BusinessPlaceResponse>> GetPageAsync(BusinessPlacePageRequest request);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -15,6 +19,17 @@ public interface IBusinessPlaceService : IScopeDependency
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<List<BusinessPlaceResponse>> GetOpenedListAsync();
|
Task<List<BusinessPlaceResponse>> GetOpenedListAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存营业点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
Task SaveAsync(BusinessPlaceSaveRequest request);
|
Task SaveAsync(BusinessPlaceSaveRequest request);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点保存餐次
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task SaveShiftAsync(BusinessPlaceSaveShiftRequest request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,46 +22,83 @@ public class BusinessPlaceService : IBusinessPlaceService
|
|||||||
|
|
||||||
public async Task<Pagination<BusinessPlaceResponse>> GetPageAsync(BusinessPlacePageRequest request)
|
public async Task<Pagination<BusinessPlaceResponse>> GetPageAsync(BusinessPlacePageRequest request)
|
||||||
{
|
{
|
||||||
var page = await _dbContext.Queryable<CanteenBusinessPlaceEntity>()
|
var page = await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||||
.WhereIF(request.Search.IsPresent(), x => x.CustomCode.Contains(request.Search))
|
.LeftJoin<BusinessPlaceShiftRelationshipEntity>((x, ps) => x.Code == ps.PlaceCode)
|
||||||
|
.LeftJoin<BusinessShiftEntity>((x, ps, s) => s.Code == ps.ShiftCode)
|
||||||
|
.WhereIF(request.Search.IsPresent(), x => x.CustomCode.Contains(request.Search)
|
||||||
|
|| x.Code.ToString().Contains(request.Search) || x.Name.Contains(request.Search))
|
||||||
.WhereIF(request.Catalog.HasValue, x => x.Catalog == request.Catalog)
|
.WhereIF(request.Catalog.HasValue, x => x.Catalog == request.Catalog)
|
||||||
.WhereIF(request.Status.HasValue, x => x.Status == request.Status)
|
.WhereIF(request.Status.HasValue, x => x.Status == request.Status)
|
||||||
.WhereIF(request.Source.HasValue, x => x.Source == request.Source)
|
.WhereIF(request.Source.HasValue, x => x.Source == request.Source)
|
||||||
.Select<BusinessPlaceResponse>()
|
.Select((x, ps, s) => new BusinessPlaceResponse
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
Code = x.Code,
|
||||||
|
Status = x.Status,
|
||||||
|
Name = x.Name,
|
||||||
|
Catalog = x.Catalog,
|
||||||
|
CustomCode = x.CustomCode,
|
||||||
|
Source = x.Source,
|
||||||
|
|
||||||
|
ShiftCode = s.Code,
|
||||||
|
ShiftName = s.Name
|
||||||
|
})
|
||||||
.ToPageListAsync(request);
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<List<BusinessPlaceResponse>> GetOpenedListAsync()
|
public async Task<List<BusinessPlaceResponse>> GetOpenedListAsync()
|
||||||
{
|
{
|
||||||
return await _dbContext.Queryable<CanteenBusinessPlaceEntity>()
|
return await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||||
.Where(x => x.Status == CanteenBusinessPlaceStatusEnumType.Opened)
|
.Where(x => x.Status == CanteenBusinessPlaceStatusEnumType.Opened)
|
||||||
.Select<BusinessPlaceResponse>()
|
.Select<BusinessPlaceResponse>()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task SaveAsync(BusinessPlaceSaveRequest request)
|
public async Task SaveAsync(BusinessPlaceSaveRequest request)
|
||||||
{
|
{
|
||||||
await CheckExistsCustomCodeAsync(request);
|
await CheckExistsCustomCodeAsync(request);
|
||||||
|
|
||||||
if (!request.Id.HasValue)
|
if (!request.Id.HasValue)
|
||||||
{
|
{
|
||||||
var entity = request.Adapt<CanteenBusinessPlaceEntity>();
|
var entity = request.Adapt<BusinessPlaceEntity>();
|
||||||
entity.Code = Guid.NewGuid();
|
entity.Code = Guid.NewGuid();
|
||||||
await _dbContext.InsertAsync(entity);
|
await _dbContext.InsertAsync(entity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var entity = await _dbContext.Queryable<CanteenBusinessPlaceEntity>().FirstAsync(x => x.Id == request.Id);
|
var entity = await _dbContext.Queryable<BusinessPlaceEntity>().FirstAsync(x => x.Id == request.Id);
|
||||||
request.Adapt(entity);
|
request.Adapt(entity);
|
||||||
|
|
||||||
await _dbContext.UpdateAsync(entity);
|
await _dbContext.UpdateAsync(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task SaveShiftAsync(BusinessPlaceSaveShiftRequest request)
|
||||||
|
{
|
||||||
|
var place = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.Id == request.Id).FirstAsync();
|
||||||
|
place.ThrowIfNull("营业点不存在");
|
||||||
|
|
||||||
|
var relationship = await _dbContext.Queryable<BusinessPlaceShiftRelationshipEntity>().Where(x => x.PlaceCode == place.Code).FirstAsync();
|
||||||
|
if (relationship == null)
|
||||||
|
{
|
||||||
|
await _dbContext.InsertAsync(new BusinessPlaceShiftRelationshipEntity
|
||||||
|
{
|
||||||
|
PlaceCode = place.Code,
|
||||||
|
ShiftCode = request.ShiftCode,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
relationship.ShiftCode = request.ShiftCode;
|
||||||
|
await _dbContext.UpdateAsync(relationship);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//*********************************************** help methods ***************************************************//
|
//*********************************************** help methods ***************************************************//
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -71,7 +108,7 @@ public class BusinessPlaceService : IBusinessPlaceService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task CheckExistsCustomCodeAsync(BusinessPlaceSaveRequest request)
|
private async Task CheckExistsCustomCodeAsync(BusinessPlaceSaveRequest request)
|
||||||
{
|
{
|
||||||
var existsSameCustomCode = await _dbContext.Queryable<CanteenBusinessPlaceEntity>()
|
var existsSameCustomCode = await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||||
.Where(x => x.CustomCode == request.CustomCode)
|
.Where(x => x.CustomCode == request.CustomCode)
|
||||||
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
||||||
.AnyAsync();
|
.AnyAsync();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Dlhis.Basic.BusinessShift.Request;
|
using Dlhis.Basic.BusinessShift.Request;
|
||||||
using Dlhis.Basic.BusinessShift.Response;
|
using Dlhis.Basic.BusinessShift.Response;
|
||||||
using Dlhis.Basic.BusinessShift.Services;
|
using Dlhis.Basic.BusinessShift.Services;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -33,14 +34,36 @@ public class BusinessShiftsController : ControllerBase
|
|||||||
return await _businessPlaceShiftService.GetPageAsync(request);
|
return await _businessPlaceShiftService.GetPageAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 餐次列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("list")]
|
||||||
|
public async Task<List<BusinessPlaceShiftResponse>> GetListAsync()
|
||||||
|
{
|
||||||
|
return await _businessPlaceShiftService.GetListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 餐次保存
|
/// 餐次保存
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("save")]
|
[HttpPost("save")]
|
||||||
public async Task SaveAsync(BusinessPlaceShiftSaveRequest request)
|
public async Task<Guid> SaveAsync(BusinessPlaceShiftSaveRequest request)
|
||||||
{
|
{
|
||||||
await _businessPlaceShiftService.SaveAsync(request);
|
return await _businessPlaceShiftService.SaveAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存餐次段
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="requests"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("meal/save")]
|
||||||
|
[Transactional]
|
||||||
|
public async Task SaveMealShiftsAsync(List<BusinessPlaceShiftSaveMealShiftRequest> requests)
|
||||||
|
{
|
||||||
|
await _businessPlaceShiftService.SaveMealShiftsAsync(requests);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ namespace Dlhis.Basic.BusinessShift.Request;
|
|||||||
|
|
||||||
public class BusinessPlaceShiftPageRequest : PageDto
|
public class BusinessPlaceShiftPageRequest : PageDto
|
||||||
{
|
{
|
||||||
public Guid? BusinessPlaceCode { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Kurisu.Core.CustomClass;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.BusinessShift.Request;
|
||||||
|
|
||||||
|
public class BusinessPlaceShiftSaveMealShiftRequest : IValidatableObject
|
||||||
|
{
|
||||||
|
public long? Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 餐次Code
|
||||||
|
/// </summary>
|
||||||
|
public Guid ShiftCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// mealshift
|
||||||
|
/// </summary>
|
||||||
|
public string ShiftType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 序号
|
||||||
|
/// </summary>
|
||||||
|
public int Sequence { get; set; } = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 时间段
|
||||||
|
/// </summary>
|
||||||
|
public TimePeriod TimePeriod { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
if (TimePeriod.Start == TimePeriod.End)
|
||||||
|
{
|
||||||
|
yield return new ValidationResult("时间段设置区间有误,开始时段不能等于结束时段.", new[] { nameof(TimePeriod) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,39 +1,20 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Kurisu.Core.CustomClass;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.BusinessShift.Request;
|
namespace Dlhis.Basic.BusinessShift.Request;
|
||||||
|
|
||||||
public class BusinessPlaceShiftSaveRequest : IValidatableObject
|
public class BusinessPlaceShiftSaveRequest
|
||||||
{
|
{
|
||||||
public long? Id { get; set; }
|
public long? Id { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 营业点代号
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "营业点不能为空")]
|
|
||||||
public Guid BusinessPlaceCode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义代号 mealshift
|
/// 自定义代号 mealshift
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "餐次编号不能为空")]
|
[Required(ErrorMessage = "餐次手工号不能为空")]
|
||||||
public string CustomCode { get; set; }
|
public string CustomCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 序号
|
/// 餐次名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Sequence { get; set; } = 100;
|
[Required(ErrorMessage = "餐次名称")]
|
||||||
|
public string Name { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// 时间段
|
|
||||||
/// </summary>
|
|
||||||
public TimePeriod TimePeriod { get; set; }
|
|
||||||
|
|
||||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
|
||||||
{
|
|
||||||
if (TimePeriod.Start == TimePeriod.End)
|
|
||||||
{
|
|
||||||
yield return new ValidationResult("时间段设置区间有误,开始时段不能等于结束时段.", new[] { nameof(TimePeriod) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,21 +4,6 @@ public class BusinessPlaceShiftResponse
|
|||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 营业点代号
|
|
||||||
/// </summary>
|
|
||||||
public Guid BusinessPlaceCode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 营业点手工号
|
|
||||||
/// </summary>
|
|
||||||
public string BusinessPlaceCustomCode { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 营业点
|
|
||||||
/// </summary>
|
|
||||||
public string BusinessPlace { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 代号
|
/// 代号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -35,12 +20,7 @@ public class BusinessPlaceShiftResponse
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 经营开始时间
|
/// 就餐时间段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TimeOnly Start { get; set; }
|
public List<MealShiftResponse> MealShifts { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 经营结束时间
|
|
||||||
/// </summary>
|
|
||||||
public TimeOnly End { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
public class BusinessPlaceShiftTinyResponse
|
public class BusinessPlaceShiftTinyResponse
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 自定义代号
|
/// 无用字段,暂时不删除 //todo
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CustomCode { get; set; }
|
public string CustomCode { get; set; }
|
||||||
|
|
||||||
|
|||||||
17
Src/Dlhis.Basic/BusinessShift/Response/MealShiftResponse.cs
Normal file
17
Src/Dlhis.Basic/BusinessShift/Response/MealShiftResponse.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
namespace Dlhis.Basic.BusinessShift.Response
|
||||||
|
{
|
||||||
|
public class MealShiftResponse
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
public Guid ShiftCode { get; set; }
|
||||||
|
|
||||||
|
public string ShiftType { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public TimeOnly Start { get; set; }
|
||||||
|
|
||||||
|
public TimeOnly End { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dlhis.Basic.BusinessPlace.Response;
|
using Dlhis.Basic.BusinessPlace.Request;
|
||||||
|
using Dlhis.Basic.BusinessPlace.Response;
|
||||||
using Dlhis.Basic.BusinessShift.Request;
|
using Dlhis.Basic.BusinessShift.Request;
|
||||||
using Dlhis.Basic.BusinessShift.Response;
|
using Dlhis.Basic.BusinessShift.Response;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
@@ -9,7 +10,13 @@ public interface IBusinessPlaceShiftService : IScopeDependency
|
|||||||
{
|
{
|
||||||
Task<Pagination<BusinessPlaceShiftResponse>> GetPageAsync(BusinessPlaceShiftPageRequest request);
|
Task<Pagination<BusinessPlaceShiftResponse>> GetPageAsync(BusinessPlaceShiftPageRequest request);
|
||||||
|
|
||||||
Task SaveAsync(BusinessPlaceShiftSaveRequest request);
|
Task<List<BusinessPlaceShiftResponse>> GetListAsync();
|
||||||
|
|
||||||
|
Task<Guid> SaveAsync(BusinessPlaceShiftSaveRequest request);
|
||||||
|
|
||||||
|
Task SaveMealShiftsAsync(List<BusinessPlaceShiftSaveMealShiftRequest> requests);
|
||||||
|
|
||||||
Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeAsync(string placeCustomCode);
|
Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeAsync(string placeCustomCode);
|
||||||
|
|
||||||
|
Task<Pagination<DeviceCodeNameDetail>> GetDevicesByCode(BusinessPlaceGetByCodeRequest request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
using Dlhis.Basic.BusinessPlace.Response;
|
using Dlhis.Basic.BusinessPlace.Request;
|
||||||
|
using Dlhis.Basic.BusinessPlace.Response;
|
||||||
using Dlhis.Basic.BusinessShift.Request;
|
using Dlhis.Basic.BusinessShift.Request;
|
||||||
using Dlhis.Basic.BusinessShift.Response;
|
using Dlhis.Basic.BusinessShift.Response;
|
||||||
using Dlhis.Entity.Basic.Entity;
|
using Dlhis.Entity.Basic.Entity;
|
||||||
|
using Dlhis.Entity.Device.Entities;
|
||||||
using Dlhis.Sys.Api;
|
using Dlhis.Sys.Api;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.CustomClass;
|
using Kurisu.Core.CustomClass;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Kurisu.Core.Result;
|
using Kurisu.Core.Result;
|
||||||
using Kurisu.SqlSugar.Attributes;
|
|
||||||
using Kurisu.SqlSugar.Extensions;
|
using Kurisu.SqlSugar.Extensions;
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Dlhis.Basic.BusinessShift.Services.Implements;
|
namespace Dlhis.Basic.BusinessShift.Services.Implements;
|
||||||
|
|
||||||
@@ -27,58 +29,109 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
|
|||||||
|
|
||||||
public async Task<Pagination<BusinessPlaceShiftResponse>> GetPageAsync(BusinessPlaceShiftPageRequest request)
|
public async Task<Pagination<BusinessPlaceShiftResponse>> GetPageAsync(BusinessPlaceShiftPageRequest request)
|
||||||
{
|
{
|
||||||
var page = await _dbContext.Queryable<CanteenBusinessShiftEntity>()
|
var page = await _dbContext.Queryable<BusinessShiftEntity>()
|
||||||
.LeftJoin<CanteenBusinessPlaceEntity>((shift, place) => shift.BusinessPlaceCode == place.Code)
|
.WhereIF(request.Search.IsPresent(), (shift) => shift.CustomCode.Contains(request.Search) || shift.Name.Contains(request.Search))
|
||||||
.LeftJoin<BasicTypeEntity>((shift, place, type) => shift.Code.ToString() == type.Code)
|
.Select<BusinessPlaceShiftResponse>()
|
||||||
.WhereIF(request.Search.IsPresent(), (shift, place) => shift.CustomCode.Contains(request.Search))
|
|
||||||
.WhereIF(request.BusinessPlaceCode.HasValue, (shift, place) => shift.BusinessPlaceCode == request.BusinessPlaceCode)
|
|
||||||
.Select((shift, place, type) => new BusinessPlaceShiftResponse
|
|
||||||
{
|
|
||||||
Id = shift.Id,
|
|
||||||
BusinessPlaceCode = place.Code,
|
|
||||||
BusinessPlaceCustomCode = place.CustomCode,
|
|
||||||
BusinessPlace = place.Name,
|
|
||||||
Code = shift.Code,
|
|
||||||
CustomCode = shift.CustomCode,
|
|
||||||
Name = type.Display,
|
|
||||||
Start = shift.Start,
|
|
||||||
End = shift.End
|
|
||||||
})
|
|
||||||
.ToPageListAsync(request);
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
|
var shiftCodes = page.Data.Select(x => x.Code).ToList();
|
||||||
|
|
||||||
|
//下级就餐时间段
|
||||||
|
var mealShifts = await _dbContext.Queryable<BusinessShiftMealRelationshipEntity>()
|
||||||
|
.LeftJoin<BasicTypeEntity>((x, bt) => x.ShiftType == bt.Code)
|
||||||
|
.Where(x => shiftCodes.Contains(x.ShiftCode))
|
||||||
|
.Select((x, bt) => new MealShiftResponse
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
ShiftCode = x.ShiftCode,
|
||||||
|
ShiftType = bt.Code,
|
||||||
|
Name = bt.Display,
|
||||||
|
Start = x.Start,
|
||||||
|
End = x.End,
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
page.Data.ForEach(x =>
|
||||||
|
{
|
||||||
|
x.MealShifts = mealShifts.Where(item => item.ShiftCode == x.Code).ToList();
|
||||||
|
});
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveAsync(BusinessPlaceShiftSaveRequest request)
|
public async Task<List<BusinessPlaceShiftResponse>> GetListAsync()
|
||||||
{
|
{
|
||||||
await CheckExistsCustomCodeAsync(request);
|
var result = await _dbContext.Queryable<BusinessShiftEntity>()
|
||||||
await DuplicateTimePeriodAsync(request);
|
.Select<BusinessPlaceShiftResponse>().ToListAsync();
|
||||||
await CheckPlaceExistsAsync(request.BusinessPlaceCode);
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Guid> SaveAsync(BusinessPlaceShiftSaveRequest request)
|
||||||
|
{
|
||||||
|
await CheckExistsAsync(request);
|
||||||
|
|
||||||
|
Guid code = Guid.Empty;
|
||||||
if (!request.Id.HasValue)
|
if (!request.Id.HasValue)
|
||||||
{
|
{
|
||||||
var entity = request.Adapt<CanteenBusinessShiftEntity>();
|
var entity = request.Adapt<BusinessShiftEntity>();
|
||||||
|
|
||||||
entity.Code = Guid.NewGuid();
|
entity.Code = Guid.NewGuid();
|
||||||
entity.Start = request.TimePeriod.Start.Value;
|
|
||||||
entity.End = request.TimePeriod.End.Value;
|
|
||||||
|
|
||||||
await _dbContext.InsertAsync(entity);
|
await _dbContext.InsertAsync(entity);
|
||||||
|
|
||||||
|
code = entity.Code;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var entity = await _dbContext.Queryable<CanteenBusinessShiftEntity>().FirstAsync(x => x.Id == request.Id);
|
var entity = await _dbContext.Queryable<BusinessShiftEntity>().FirstAsync(x => x.Id == request.Id);
|
||||||
entity.Adapt(request);
|
entity.ThrowIfNull("餐次不存在");
|
||||||
|
|
||||||
|
request.Adapt(entity);
|
||||||
await _dbContext.UpdateAsync(entity);
|
await _dbContext.UpdateAsync(entity);
|
||||||
|
|
||||||
|
code = entity.Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveMealShiftsAsync(List<BusinessPlaceShiftSaveMealShiftRequest> requests)
|
||||||
|
{
|
||||||
|
var mealShifts = await GetMealShiftAsync();
|
||||||
|
|
||||||
|
foreach (var request in requests)
|
||||||
|
{
|
||||||
|
var shift = await CheckExistsShiftAsync(request.ShiftCode);
|
||||||
|
await CheckExistsMealShiftAsync(request);
|
||||||
|
await DuplicateTimePeriodAsync(request);
|
||||||
|
mealShifts.Contains(request.ShiftType).ThrowIfFalse($"{request.ShiftType}不存在");
|
||||||
|
|
||||||
|
if (!request.Id.HasValue)
|
||||||
|
{
|
||||||
|
var entity = request.Adapt<BusinessShiftMealRelationshipEntity>();
|
||||||
|
|
||||||
|
entity.ShiftCode = shift.Code;
|
||||||
|
entity.ShiftCustomCode = shift.CustomCode;
|
||||||
|
entity.Start = request.TimePeriod.Start.Value;
|
||||||
|
entity.End = request.TimePeriod.End.Value;
|
||||||
|
|
||||||
|
await _dbContext.InsertAsync(entity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var entity = await _dbContext.Queryable<BusinessShiftMealRelationshipEntity>().FirstAsync(x => x.Id == request.Id);
|
||||||
|
entity.ThrowIfNull("餐次段不存在");
|
||||||
|
|
||||||
|
request.Adapt(entity);
|
||||||
|
await _dbContext.UpdateAsync(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreTenant]
|
|
||||||
public async Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeAsync(string placeCustomCode)
|
public async Task<BusinessPlaceWithShiftResponse> GetShiftsByPlaceCustomCodeAsync(string placeCustomCode)
|
||||||
{
|
{
|
||||||
var place = await _dbContext.Queryable<CanteenBusinessPlaceEntity>().Where(x => x.CustomCode == placeCustomCode).FirstAsync();
|
var place = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.CustomCode == placeCustomCode).FirstAsync();
|
||||||
if (place == null)
|
if (place == null)
|
||||||
{
|
{
|
||||||
return new BusinessPlaceWithShiftResponse()
|
return new BusinessPlaceWithShiftResponse()
|
||||||
@@ -87,29 +140,45 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var shifts = await _dbContext.Queryable<CanteenBusinessShiftEntity>()
|
|
||||||
.Where(x => x.BusinessPlaceCode == place.Code)
|
|
||||||
.OrderBy(x => x.Sequence) //排序
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
var tenantResult = await _tenantApi.GetTenantByCodeAsync(place.TenantId);
|
var tenantResult = await _tenantApi.GetTenantByCodeAsync(place.TenantId);
|
||||||
(tenantResult.Code == ApiStateCode.Success).ThrowIfFalse(tenantResult.Msg);
|
(tenantResult.Code == ApiStateCode.Success).ThrowIfFalse(tenantResult.Msg);
|
||||||
var tenantInfo = tenantResult.Data;
|
var tenantInfo = tenantResult.Data;
|
||||||
|
|
||||||
|
var relationship = await _dbContext.Queryable<BusinessPlaceShiftRelationshipEntity>().Where(x => x.PlaceCode == place.Code).FirstAsync();
|
||||||
|
if (relationship == null)
|
||||||
|
{
|
||||||
|
return new BusinessPlaceWithShiftResponse()
|
||||||
|
{
|
||||||
|
CustomCode = placeCustomCode,
|
||||||
|
Name = place.Name,
|
||||||
|
TenantCode = tenantInfo.Code,
|
||||||
|
TenantName = tenantInfo.Name,
|
||||||
|
Shifts = new List<BusinessPlaceShiftTinyResponse>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var shifts = await _dbContext.Queryable<BusinessShiftMealRelationshipEntity>()
|
||||||
|
.Where(x => x.ShiftCode == relationship.ShiftCode)
|
||||||
|
.OrderBy(x => x.Sequence) //排序
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
var list = new List<BusinessPlaceShiftTinyResponse>();
|
var list = new List<BusinessPlaceShiftTinyResponse>();
|
||||||
foreach (CanteenBusinessShiftEntity shiftinfo in shifts)
|
|
||||||
|
foreach (BusinessShiftMealRelationshipEntity shiftinfo in shifts)
|
||||||
{
|
{
|
||||||
var name = _dbContext.Queryable<BasicTypeEntity>()
|
var name = _dbContext.Queryable<BasicTypeEntity>()
|
||||||
.Where(x => x.Code == shiftinfo.CustomCode.ToString())
|
.Where(x => x.Code == shiftinfo.ShiftType.ToString())
|
||||||
.Select(x => x.Display)
|
.Select(x => x.Display)
|
||||||
.First();
|
.First();
|
||||||
|
|
||||||
var shift = new BusinessPlaceShiftTinyResponse
|
var shift = new BusinessPlaceShiftTinyResponse
|
||||||
{
|
{
|
||||||
CustomCode = shiftinfo.CustomCode,
|
CustomCode = shiftinfo.Id.ToString(),
|
||||||
Name = name,
|
Name = name,
|
||||||
Start = shiftinfo.Start,
|
Start = shiftinfo.Start,
|
||||||
End = shiftinfo.End
|
End = shiftinfo.End
|
||||||
};
|
};
|
||||||
|
|
||||||
list.Add(shift);
|
list.Add(shift);
|
||||||
}
|
}
|
||||||
return new BusinessPlaceWithShiftResponse
|
return new BusinessPlaceWithShiftResponse
|
||||||
@@ -122,24 +191,58 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
//*********************************************** help methods ***************************************************//
|
public async Task<Pagination<DeviceCodeNameDetail>> GetDevicesByCode(BusinessPlaceGetByCodeRequest request)
|
||||||
|
|
||||||
|
|
||||||
private async Task CheckPlaceExistsAsync(Guid code)
|
|
||||||
{
|
{
|
||||||
var existsPlace = await _dbContext.Queryable<CanteenBusinessPlaceEntity>().AnyAsync(x => x.Code == code);
|
var regiss = await _dbContext.Queryable<DeviceRegistryEntity>()
|
||||||
existsPlace.ThrowIfFalse("营业点不存在,请检查.");
|
.Where(x => x.BusinessPlaceCode.ToString() == request.Code)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var devices = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
|
||||||
|
|
||||||
|
var list = new List<DeviceCodeNameDetail>();
|
||||||
|
if (regiss.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var regis in regiss)
|
||||||
|
{
|
||||||
|
var device = devices.Where(x => x.UniqueNo == regis.DeviceUniqueNo)
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (device != null)
|
||||||
|
{
|
||||||
|
var detail = new DeviceCodeNameDetail
|
||||||
|
{
|
||||||
|
UniqueNo = regis.DeviceUniqueNo,
|
||||||
|
UniqueName = device.Supplier
|
||||||
|
};
|
||||||
|
list.Add(detail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//分页
|
||||||
|
var startIndex = (request.PageIndex - 1) * request.PageSize;
|
||||||
|
var pagedData = list.Skip(startIndex).Take(request.PageSize).ToList();
|
||||||
|
|
||||||
|
var pagination = new Pagination<DeviceCodeNameDetail>
|
||||||
|
{
|
||||||
|
PageIndex = request.PageIndex,
|
||||||
|
PageSize = request.PageSize,
|
||||||
|
Total = list.Count, // 使用原始列表的总数进行分页
|
||||||
|
Data = pagedData
|
||||||
|
};
|
||||||
|
|
||||||
|
return pagination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*********************************************** help methods ***************************************************//
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 时间段重合检查
|
/// 时间段重合检查
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task DuplicateTimePeriodAsync(BusinessPlaceShiftSaveRequest request)
|
private async Task DuplicateTimePeriodAsync(BusinessPlaceShiftSaveMealShiftRequest request)
|
||||||
{
|
{
|
||||||
var periods = await _dbContext.Queryable<CanteenBusinessShiftEntity>()
|
var periods = await _dbContext.Queryable<BusinessShiftMealRelationshipEntity>()
|
||||||
.Where(x => x.BusinessPlaceCode == request.BusinessPlaceCode)
|
.Where(x => x.ShiftCode == request.ShiftCode)
|
||||||
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
||||||
.Select(x => new TimePeriod
|
.Select(x => new TimePeriod
|
||||||
{
|
{
|
||||||
@@ -150,24 +253,47 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
|
|||||||
|
|
||||||
foreach (var period in periods)
|
foreach (var period in periods)
|
||||||
{
|
{
|
||||||
period.IsDuplicate(request.TimePeriod).ThrowIfTrue($"存在时间段重合[{period.Start}-{period.End}]");
|
period.IsDuplicate1(request.TimePeriod).ThrowIfTrue($"存在时间段重合[{period.Start}-{period.End}]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检查重复手工号
|
/// 检查重复
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task CheckExistsCustomCodeAsync(BusinessPlaceShiftSaveRequest request)
|
private async Task CheckExistsAsync(BusinessPlaceShiftSaveRequest request)
|
||||||
{
|
{
|
||||||
var existsSameCustomCode = await _dbContext.Queryable<CanteenBusinessShiftEntity>()
|
var existsSameCustomCode = await _dbContext.Queryable<BusinessShiftEntity>()
|
||||||
.Where(x => x.CustomCode == request.CustomCode)
|
.Where(x => x.CustomCode == request.CustomCode || x.Name == request.Name)
|
||||||
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
||||||
.AnyAsync();
|
.AnyAsync();
|
||||||
|
|
||||||
existsSameCustomCode.ThrowIfTrue($"自定义手工号[{request.CustomCode}]存在重复,请检查.");
|
existsSameCustomCode.ThrowIfTrue($"自定义手工号或者名称存在重复,请检查.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<BusinessShiftEntity> CheckExistsShiftAsync(Guid shiftCode)
|
||||||
|
{
|
||||||
|
var shift = await _dbContext.Queryable<BusinessShiftEntity>().Where(x => x.Code == shiftCode).FirstAsync();
|
||||||
|
shift.ThrowIfNull("餐次不存在");
|
||||||
|
|
||||||
|
return shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<List<string>> GetMealShiftAsync()
|
||||||
|
{
|
||||||
|
return await _dbContext.Queryable<BasicTypeEntity>().Where(x => x.Type == "mealshift").Select(x => x.Code).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task CheckExistsMealShiftAsync(BusinessPlaceShiftSaveMealShiftRequest request)
|
||||||
|
{
|
||||||
|
var exists = await _dbContext.Queryable<BusinessShiftMealRelationshipEntity>()
|
||||||
|
.Where(x => x.ShiftCode == request.ShiftCode)
|
||||||
|
.Where(x => x.ShiftType == request.ShiftType)
|
||||||
|
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
||||||
|
.AnyAsync();
|
||||||
|
|
||||||
|
exists.ThrowIfTrue("重复设置!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
73
Src/Dlhis.Basic/BusinessShift/TimePeriodExtensions.cs
Normal file
73
Src/Dlhis.Basic/BusinessShift/TimePeriodExtensions.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using Kurisu.Core.CustomClass;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.BusinessShift;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 临时的扩展类 todo: 嵌入框架
|
||||||
|
/// </summary>
|
||||||
|
public static class TimePeriodExtensions
|
||||||
|
{
|
||||||
|
public static bool IsDuplicate1(this TimePeriod current, TimePeriod period)
|
||||||
|
{
|
||||||
|
return !Check();
|
||||||
|
|
||||||
|
bool Check()
|
||||||
|
{
|
||||||
|
if (current.IsCrossDay())
|
||||||
|
{
|
||||||
|
if (period.IsCrossDay())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return period.Start > current.End && period.End < current.Start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (period.IsCrossDay())
|
||||||
|
{
|
||||||
|
return period.Start > current.End && period.End < current.Start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return period.Start > current.End || period.End < current.Start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static bool IsPresent1(this TimePeriod period, DateTime dateTime)
|
||||||
|
{
|
||||||
|
DateTime start;
|
||||||
|
DateTime end;
|
||||||
|
|
||||||
|
if (period.IsCrossDay())
|
||||||
|
{
|
||||||
|
var currentStart = DateTime.Today.Add(period.Start.Value.ToTimeSpan());
|
||||||
|
var endOfDay = DateTime.Today.AddHours(23).AddMinutes(59).AddSeconds(59);
|
||||||
|
|
||||||
|
if (dateTime >= currentStart && dateTime <= endOfDay)
|
||||||
|
{
|
||||||
|
start = DateTime.Today.Add(period.Start.Value.ToTimeSpan());
|
||||||
|
end = DateTime.Today.AddDays(1).Add(period.End.Value.ToTimeSpan());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//第二天
|
||||||
|
start = DateTime.Today.AddDays(-1).Add(period.Start.Value.ToTimeSpan());
|
||||||
|
end = DateTime.Today.Add(period.End.Value.ToTimeSpan());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start = DateTime.Today.Add(period.Start.Value.ToTimeSpan());
|
||||||
|
end = DateTime.Today.Add(period.End.Value.ToTimeSpan());
|
||||||
|
}
|
||||||
|
|
||||||
|
return dateTime >= start && dateTime <= end;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using Dlhis.Basic.Device.Request;
|
using Dlhis.Basic.Device.Request;
|
||||||
using Dlhis.Basic.Device.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
using Dlhis.Basic.Device.Services;
|
using Dlhis.Basic.Device.Services;
|
||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -22,26 +24,17 @@ public class DeviceGroupsController : ControllerBase
|
|||||||
_deviceGroupService = deviceGroupService;
|
_deviceGroupService = deviceGroupService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设备组分页
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpPost("page")]
|
|
||||||
public async Task<Pagination<DeviceGroupPageResponse>> GetPageAsync([FromQuery] DeviceGroupPageRequest request)
|
|
||||||
{
|
|
||||||
return await _deviceGroupService.GetPageAsync(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取设备组树
|
/// 获取设备组树
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="showDevices">是否显示设备</param>
|
/// <param name="showDevices">是否显示设备</param>
|
||||||
|
/// <param name="type">分组类型</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("tree")]
|
[HttpGet("tree")]
|
||||||
public async Task<List<DeviceGroupTreeResponse>> GetTreeAsync(bool showDevices)
|
[IgnoreTenant]
|
||||||
|
public async Task<List<DeviceGroupTreeResponse>> GetTreeAsync(bool showDevices, DeviceTypeEnumType? type)
|
||||||
{
|
{
|
||||||
return await _deviceGroupService.GetTreeAsync(showDevices);
|
return await _deviceGroupService.GetTreeAsync(showDevices, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -50,6 +43,7 @@ public class DeviceGroupsController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("save")]
|
[HttpPost("save")]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task SaveAsync(DeviceGroupSaveRequest request)
|
public async Task SaveAsync(DeviceGroupSaveRequest request)
|
||||||
{
|
{
|
||||||
await _deviceGroupService.SaveAsync(request);
|
await _deviceGroupService.SaveAsync(request);
|
||||||
@@ -72,6 +66,8 @@ public class DeviceGroupsController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("assign")]
|
[HttpPost("assign")]
|
||||||
|
[IgnoreTenant]
|
||||||
|
[Transactional]
|
||||||
public async Task AssignDevicesAsync(DeviceAssignRequest request)
|
public async Task AssignDevicesAsync(DeviceAssignRequest request)
|
||||||
{
|
{
|
||||||
await _deviceGroupService.AssignDevicesAsync(request);
|
await _deviceGroupService.AssignDevicesAsync(request);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Dlhis.Basic.Device.Request;
|
using Dlhis.Basic.Device.Request;
|
||||||
using Dlhis.Basic.Device.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
using Dlhis.Basic.Device.Services;
|
using Dlhis.Basic.Device.Services;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -25,6 +26,8 @@ public class DevicePermissionsController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("assign")]
|
[HttpPost("assign")]
|
||||||
|
[Transactional]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task AssignAsync(DevicePermissionSaveReuqest request)
|
public async Task AssignAsync(DevicePermissionSaveReuqest request)
|
||||||
{
|
{
|
||||||
await _devicePermissionService.AssignAsync(request);
|
await _devicePermissionService.AssignAsync(request);
|
||||||
@@ -51,4 +54,17 @@ public class DevicePermissionsController : ControllerBase
|
|||||||
{
|
{
|
||||||
return await _devicePermissionService.GetAssigmentByCodeAsync(request);
|
return await _devicePermissionService.GetAssigmentByCodeAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 就餐设备唯一号权限
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userNo"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("canteen/uniqueNos")]
|
||||||
|
[IgnoreTenant]
|
||||||
|
public async Task<List<string>> GetCanteenDeviceUniqueNosByUserNoAsync(string userNo)
|
||||||
|
{
|
||||||
|
return await _devicePermissionService.GetCanteenDeviceUniqueNosByUserNoAsync(userNo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Dlhis.Basic.Device.Request;
|
using Dlhis.Basic.Device.Request;
|
||||||
using Dlhis.Basic.Device.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
using Dlhis.Basic.Device.Services;
|
using Dlhis.Basic.Device.Services;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -70,6 +71,7 @@ public class DevicesController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("save")]
|
[HttpPost("save")]
|
||||||
|
[Transactional]
|
||||||
public async Task SaveAsync(DeviceSaveRequest request)
|
public async Task SaveAsync(DeviceSaveRequest request)
|
||||||
{
|
{
|
||||||
await _deviceService.SaveAsync(request);
|
await _deviceService.SaveAsync(request);
|
||||||
@@ -81,6 +83,7 @@ public class DevicesController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("resigter")]
|
[HttpPost("resigter")]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task<string> ResigterAsync(DeviceResigterRequest request)
|
public async Task<string> ResigterAsync(DeviceResigterRequest request)
|
||||||
{
|
{
|
||||||
return await _deviceConnectService.ResigterAsync(request);
|
return await _deviceConnectService.ResigterAsync(request);
|
||||||
@@ -128,6 +131,7 @@ public class DevicesController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("heartbeat")]
|
[HttpPost("heartbeat")]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task HeartbeatAsync(DeviceHeartbeatRequest request)
|
public async Task HeartbeatAsync(DeviceHeartbeatRequest request)
|
||||||
{
|
{
|
||||||
await _deviceConnectService.HeartbeatAsync(request);
|
await _deviceConnectService.HeartbeatAsync(request);
|
||||||
@@ -142,6 +146,7 @@ public class DevicesController : ControllerBase
|
|||||||
{
|
{
|
||||||
return await _deviceService.CheckExistsAsync(deviceUniqueNo);
|
return await _deviceService.CheckExistsAsync(deviceUniqueNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取设备
|
/// 获取设备
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -194,12 +199,34 @@ public class DevicesController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取近期30天新增设备数
|
/// 获取门禁在线/离线设备详情列表
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("dooroffline")]
|
||||||
|
public async Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync([FromQuery] GetDoorOfflineRequest request)
|
||||||
|
{
|
||||||
|
return await _deviceService.GetDoorOfflineAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取近期30天考勤新增设备数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("recentnumbers")]
|
[HttpGet("recentnumbers")]
|
||||||
public async Task<Dictionary<string, int>> GetRecentNumbersAsync()
|
public async Task<List<RecentNumberResponse>> GetRecentNumbersAsync()
|
||||||
{
|
{
|
||||||
return await _deviceService.GetRecentNumbersAsync();
|
return await _deviceService.GetRecentNumbersAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量导入设备信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("bulkUploads")]
|
||||||
|
public async Task BulkUploadsAsync([FromForm] BulkUploadsRequest request)
|
||||||
|
{
|
||||||
|
await _deviceService.BulkUploadsAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
14
Src/Dlhis.Basic/Device/Dtos/UserTenantDeviceCodeDto.cs
Normal file
14
Src/Dlhis.Basic/Device/Dtos/UserTenantDeviceCodeDto.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Dlhis.Basic.Device.Dtos;
|
||||||
|
|
||||||
|
public class UserTenantDeviceCodeDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 租户
|
||||||
|
/// </summary>
|
||||||
|
public string Tenant { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备权限
|
||||||
|
/// </summary>
|
||||||
|
public List<Guid> Codes { get; set; }
|
||||||
|
}
|
||||||
10
Src/Dlhis.Basic/Device/Request/BulkUploadsRequest.cs
Normal file
10
Src/Dlhis.Basic/Device/Request/BulkUploadsRequest.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace Dlhis.Basic.Device.Request
|
||||||
|
{
|
||||||
|
public class BulkUploadsRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 设备信息文件
|
||||||
|
/// </summary>
|
||||||
|
public IFormFile FormFile { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Request;
|
|
||||||
|
|
||||||
public class DeviceGroupPageRequest : PageDto
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@ public class DeviceGroupSaveRequest
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上级分组
|
/// 上级分组
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid? PCode { get; set; }
|
public Guid PCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设备组名称
|
/// 设备组名称
|
||||||
@@ -21,7 +21,11 @@ public class DeviceGroupSaveRequest
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分类类型 DeviceTypeEnumType
|
/// 分类类型 DeviceTypeEnumType
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "分类不能为空")]
|
|
||||||
[EnumDataType(typeof(DeviceTypeEnumType))]
|
[EnumDataType(typeof(DeviceTypeEnumType))]
|
||||||
public DeviceTypeEnumType Type { get; set; }
|
public DeviceTypeEnumType? Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备注
|
||||||
|
/// </summary>
|
||||||
|
public string Remark { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Dlhis.Basic.Device.Request
|
namespace Dlhis.Basic.Device.Request
|
||||||
{
|
{
|
||||||
public class DeviceOnlineAndofflineRequest :PageDto
|
public class DeviceOnlineAndofflineRequest : PageDto
|
||||||
{
|
{
|
||||||
public bool IsOnAndOff { get; set; }
|
public bool IsOnAndOff { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Dlhis.Entity.Sys.Enums;
|
using Dlhis.Entity.Sys.Enums;
|
||||||
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Request;
|
namespace Dlhis.Basic.Device.Request;
|
||||||
|
|
||||||
public class DevicePermissionSaveReuqest
|
public class DevicePermissionSaveReuqest : IValidatableObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分配类型 AssignTypeEnumType
|
/// 分配类型 AssignTypeEnumType
|
||||||
@@ -12,9 +13,12 @@ public class DevicePermissionSaveReuqest
|
|||||||
public AssignTypeEnumType AssignType { get; set; }
|
public AssignTypeEnumType AssignType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 人员档案号
|
/// 分配值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "人员档案号不能为空")]
|
/// <remarks>
|
||||||
|
/// 如果<see cref="AssignTypeEnumType"/>为用户,那么AssignValue=UserNo
|
||||||
|
/// </remarks>
|
||||||
|
[Required(ErrorMessage = "分配值不能为空")]
|
||||||
public string AssignValue { get; set; }
|
public string AssignValue { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -24,7 +28,23 @@ public class DevicePermissionSaveReuqest
|
|||||||
public DeviceAssignmentTypeEnumType UniqueType { get; set; }
|
public DeviceAssignmentTypeEnumType UniqueType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 分配权限值不能为空
|
/// 分配权限值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<Guid> Codes { get; set; } = new List<Guid>();
|
public List<Guid> Codes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// AssignType == AssignTypeEnumType.Department 需要传入
|
||||||
|
/// </summary>
|
||||||
|
public string TenantId { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
if (AssignType == AssignTypeEnumType.Department)
|
||||||
|
{
|
||||||
|
if (TenantId.IsEmpty())
|
||||||
|
{
|
||||||
|
yield return new ValidationResult("请明确具体的厂区", new[] { nameof(TenantId) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Dlhis.Entity.Device.Enums;
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Request;
|
namespace Dlhis.Basic.Device.Request;
|
||||||
|
|
||||||
public class DeviceSaveRequest
|
public class DeviceSaveRequest : IValidatableObject
|
||||||
{
|
{
|
||||||
public long? Id { get; set; }
|
public long? Id { get; set; }
|
||||||
|
|
||||||
@@ -42,7 +43,6 @@ public class DeviceSaveRequest
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 心跳间隔
|
/// 心跳间隔
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Range(0, int.MaxValue)]
|
|
||||||
public int HeartbeatInterval { get; set; }
|
public int HeartbeatInterval { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -70,4 +70,22 @@ public class DeviceSaveRequest
|
|||||||
/// 是否启用
|
/// 是否启用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enable { get; set; }
|
public bool Enable { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否作为考勤设备
|
||||||
|
/// </summary>
|
||||||
|
public bool AsAttendance { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
if (Type != DeviceTypeEnumType.Door && AsAttendance)
|
||||||
|
{
|
||||||
|
yield return new ValidationResult($"{DeviceTypeEnumType.Door.GetDescription()}才可设置作为考勤设备", new[] { nameof(AsAttendance) });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HeartbeatInterval != 0 && HeartbeatInterval < 30)
|
||||||
|
{
|
||||||
|
yield return new ValidationResult($"心跳间隔需要设置>=30秒", new[] { nameof(HeartbeatInterval) });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,6 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 营业点
|
/// 营业点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid BusinessPlaceCode { get; set; }
|
public Guid? BusinessPlaceCode { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
76
Src/Dlhis.Basic/Device/Request/ImportDeviceSaveRequest.cs
Normal file
76
Src/Dlhis.Basic/Device/Request/ImportDeviceSaveRequest.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Device.Request
|
||||||
|
{
|
||||||
|
public class ImportDeviceSaveRequest
|
||||||
|
{
|
||||||
|
|
||||||
|
public long? Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备唯一号
|
||||||
|
/// </summary>
|
||||||
|
public string UniqueNo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 模板code
|
||||||
|
/// </summary>
|
||||||
|
public Guid TemplateCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 供应商信息
|
||||||
|
/// </summary>
|
||||||
|
public string Supplier { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备功能
|
||||||
|
/// </summary>
|
||||||
|
public List<DeviceFuncEnumType> Funcs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备类型 DeviceTypeEnumType
|
||||||
|
/// </summary>
|
||||||
|
public DeviceTypeEnumType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 心跳间隔
|
||||||
|
/// </summary>
|
||||||
|
public int HeartbeatInterval { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部署点
|
||||||
|
/// </summary>
|
||||||
|
public string DeployPlace { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部署坐标
|
||||||
|
/// </summary>
|
||||||
|
public string DeployPosition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部署方向
|
||||||
|
/// </summary>
|
||||||
|
public string DeployDirection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接信息
|
||||||
|
/// </summary>
|
||||||
|
public string ConnectionInfo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否启用
|
||||||
|
/// </summary>
|
||||||
|
public bool Enable { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否作为考勤设备
|
||||||
|
/// </summary>
|
||||||
|
public bool AsAttendance { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点code
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PlaceeCode { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
namespace Dlhis.Basic.Device.Response;
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Device.Response;
|
||||||
|
|
||||||
public class DeviceGroupPageResponse
|
public class DeviceGroupPageResponse
|
||||||
{
|
{
|
||||||
@@ -11,4 +14,30 @@ public class DeviceGroupPageResponse
|
|||||||
/// 设备组名称
|
/// 设备组名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分组类型
|
||||||
|
/// </summary>
|
||||||
|
public DeviceTypeEnumType? Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否可编辑
|
||||||
|
/// </summary>
|
||||||
|
public bool Editable { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分组类型描述
|
||||||
|
/// </summary>
|
||||||
|
public string TypeDesc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!Type.HasValue)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Type.Value.GetDescription();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
namespace Dlhis.Basic.Device.Response;
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Device.Response;
|
||||||
|
|
||||||
public class DeviceGroupTreeResponse
|
public class DeviceGroupTreeResponse
|
||||||
{
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上级分组code
|
/// 上级分组code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -17,6 +24,42 @@ public class DeviceGroupTreeResponse
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备组类型
|
||||||
|
/// </summary>
|
||||||
|
public DeviceTypeEnumType? Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备注
|
||||||
|
/// </summary>
|
||||||
|
public string Remark { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分组类型描述
|
||||||
|
/// </summary>
|
||||||
|
public string TypeDesc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!Type.HasValue)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Type.Value.GetDescription();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Editable { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否允许设置下级
|
||||||
|
/// </summary>
|
||||||
|
public bool AbleSetNext { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string TenantId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下级
|
/// 下级
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -84,4 +84,51 @@ public class DevicePageResponse
|
|||||||
/// 是否启用
|
/// 是否启用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enable { get; set; }
|
public bool Enable { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
//*********************************************************附加信息**************************************************************/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最后心跳时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? LastHeartbeatTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否在线
|
||||||
|
/// </summary>
|
||||||
|
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>
|
||||||
|
public decimal Amount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消费人次
|
||||||
|
/// </summary>
|
||||||
|
public int UserCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点code
|
||||||
|
/// </summary>
|
||||||
|
public Guid? BusinessPlaceCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点名称
|
||||||
|
/// </summary>
|
||||||
|
public string BusinessPlaceName { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,9 @@ public class DeviceResponse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DeviceTypeEnumType Type { get; set; }
|
||||||
|
public string TypeDesc => Type.GetDescription();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 连接信息
|
/// 连接信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace Dlhis.Basic.Device.Response;
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Device.Response;
|
||||||
|
|
||||||
public class DeviceUnderGroupResponse
|
public class DeviceUnderGroupResponse
|
||||||
{
|
{
|
||||||
@@ -14,6 +16,12 @@ public class DeviceUnderGroupResponse
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Brand { get; set; }
|
public string Brand { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设备类型
|
||||||
|
/// </summary>
|
||||||
|
public DeviceTypeEnumType Type { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否启用
|
/// 是否启用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
9
Src/Dlhis.Basic/Device/Response/GetDoorOfflineRequest.cs
Normal file
9
Src/Dlhis.Basic/Device/Response/GetDoorOfflineRequest.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Device.Response
|
||||||
|
{
|
||||||
|
public class GetDoorOfflineRequest : PageDto
|
||||||
|
{
|
||||||
|
public bool IsOnAndOff { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
9
Src/Dlhis.Basic/Device/Response/RecentNumberResponse.cs
Normal file
9
Src/Dlhis.Basic/Device/Response/RecentNumberResponse.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Dlhis.Basic.Device.Response
|
||||||
|
{
|
||||||
|
public class RecentNumberResponse
|
||||||
|
{
|
||||||
|
public string Date { get; set; }
|
||||||
|
|
||||||
|
public int Num { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
using Dlhis.Basic.Device.Request;
|
using Dlhis.Basic.Device.Request;
|
||||||
using Dlhis.Basic.Device.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Services;
|
namespace Dlhis.Basic.Device.Services;
|
||||||
|
|
||||||
public interface IDeviceGroupService : IScopeDependency
|
public interface IDeviceGroupService : IScopeDependency
|
||||||
{
|
{
|
||||||
Task<Pagination<DeviceGroupPageResponse>> GetPageAsync(DeviceGroupPageRequest request);
|
Task<List<DeviceGroupTreeResponse>> GetTreeAsync(bool showDevices, DeviceTypeEnumType? type);
|
||||||
|
|
||||||
Task<List<DeviceGroupTreeResponse>> GetTreeAsync(bool showDevices);
|
|
||||||
|
|
||||||
Task SaveAsync(DeviceGroupSaveRequest request);
|
Task SaveAsync(DeviceGroupSaveRequest request);
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,14 @@ public interface IDevicePermissionService : IScopeDependency
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo);
|
Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取就餐权限唯一号
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userNo"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<List<string>> GetCanteenDeviceUniqueNosByUserNoAsync(string userNo);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取用户权限设备
|
/// 获取用户权限设备
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -23,5 +23,11 @@ public interface IDeviceService : IScopeDependency
|
|||||||
|
|
||||||
Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync(DeviceOnlineAndofflineRequest request);
|
Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync(DeviceOnlineAndofflineRequest request);
|
||||||
|
|
||||||
Task<Dictionary<string, int>> GetRecentNumbersAsync();
|
Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync(GetDoorOfflineRequest request);
|
||||||
|
|
||||||
|
Task<List<RecentNumberResponse>> GetRecentNumbersAsync();
|
||||||
|
|
||||||
|
Task BulkUploadsAsync(BulkUploadsRequest request);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ 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.SqlSugar.Attributes;
|
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
|
|
||||||
@@ -20,10 +18,10 @@ public class DeviceConnectService : IDeviceConnectService
|
|||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreTenant]
|
|
||||||
public async Task<string> ResigterAsync(DeviceResigterRequest request)
|
public async Task<string> ResigterAsync(DeviceResigterRequest request)
|
||||||
{
|
{
|
||||||
var businessPlace = await _dbContext.Queryable<CanteenBusinessPlaceEntity>().Where(x => x.CustomCode == request.BusinessCustomCode).FirstAsync();
|
var businessPlace = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.CustomCode == request.BusinessCustomCode).FirstAsync();
|
||||||
businessPlace.ThrowIfNull("营业点不存在");
|
businessPlace.ThrowIfNull("营业点不存在");
|
||||||
|
|
||||||
var device = await GetEnableDeviceAsync(request.UniqueNo, false, request.DeployPlace, businessPlace.TenantId);
|
var device = await GetEnableDeviceAsync(request.UniqueNo, false, request.DeployPlace, businessPlace.TenantId);
|
||||||
@@ -55,7 +53,7 @@ public class DeviceConnectService : IDeviceConnectService
|
|||||||
public async Task<List<DeviceNotSetBusinessPlaceResponse>> GetNotSetBusinessPlaceDevicesAsync()
|
public async Task<List<DeviceNotSetBusinessPlaceResponse>> GetNotSetBusinessPlaceDevicesAsync()
|
||||||
{
|
{
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Enable).ToListAsync();
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Enable).ToListAsync();
|
||||||
devices = devices.Where(x => x.Funcs.Any(item => item == DeviceFuncEnumType.Meal)).ToList();
|
devices = devices.Where(x => x.Type == DeviceTypeEnumType.Meal).ToList();
|
||||||
|
|
||||||
return devices.Adapt<List<DeviceNotSetBusinessPlaceResponse>>();
|
return devices.Adapt<List<DeviceNotSetBusinessPlaceResponse>>();
|
||||||
}
|
}
|
||||||
@@ -63,26 +61,31 @@ public class DeviceConnectService : IDeviceConnectService
|
|||||||
public async Task SetResigterBusinessPlaceAsync(DeviceSetResigterBusinessPlaceRequest request)
|
public async Task SetResigterBusinessPlaceAsync(DeviceSetResigterBusinessPlaceRequest request)
|
||||||
{
|
{
|
||||||
var device = await GetEnableDeviceAsync(request.UniqueNo);
|
var device = await GetEnableDeviceAsync(request.UniqueNo);
|
||||||
if (device.Funcs?.Any(x => x == DeviceFuncEnumType.Meal) != true)
|
(device.Type != DeviceTypeEnumType.Meal).ThrowIfTrue("非就餐类型设备,无法设置");
|
||||||
{
|
|
||||||
throw new UserFriendlyException("当前设备无用餐功能,无法设置");
|
|
||||||
}
|
|
||||||
|
|
||||||
var registry = await _dbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync();
|
var registry = await _dbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync();
|
||||||
registry.ThrowIfNull($"{request.UniqueNo}的设备注册信息不存在,无法设置营业点");
|
registry.ThrowIfNull($"{request.UniqueNo}的设备注册信息不存在,无法设置营业点");
|
||||||
|
|
||||||
var businessPlace = await _dbContext.Queryable<CanteenBusinessPlaceEntity>().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync();
|
if (request.BusinessPlaceCode.HasValue)
|
||||||
businessPlace.ThrowIfNull("营业点不存在,无法设置到设备注册信息中");
|
{
|
||||||
|
var businessPlace = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync();
|
||||||
|
businessPlace.ThrowIfNull("营业点不存在,无法设置到设备注册信息中");
|
||||||
|
|
||||||
//更新营业点信息
|
//更新营业点信息
|
||||||
registry.BusinessPlaceCode = businessPlace.Code;
|
registry.BusinessPlaceCode = businessPlace.Code;
|
||||||
registry.BusinessPlaceCustomCode = businessPlace.CustomCode;
|
registry.BusinessPlaceCustomCode = businessPlace.CustomCode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//更新营业点信息
|
||||||
|
registry.BusinessPlaceCode = null;
|
||||||
|
registry.BusinessPlaceCustomCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
await _dbContext.UpdateAsync(registry);
|
await _dbContext.UpdateAsync(registry);
|
||||||
//todo 通知设备重新获取
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreTenant]
|
|
||||||
public async Task HeartbeatAsync(DeviceHeartbeatRequest request)
|
public async Task HeartbeatAsync(DeviceHeartbeatRequest request)
|
||||||
{
|
{
|
||||||
var registry = await _dbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync();
|
var registry = await _dbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.UniqueNo).FirstAsync();
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
using Dlhis.Basic.Device.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
using Dlhis.Entity.Basic.Entity;
|
using Dlhis.Entity.Basic.Entity;
|
||||||
using Dlhis.Entity.Device.Entities;
|
using Dlhis.Entity.Device.Entities;
|
||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.User.Abstractions;
|
||||||
using Kurisu.SqlSugar.Attributes;
|
|
||||||
using Kurisu.SqlSugar.Extensions;
|
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
|
|
||||||
@@ -15,24 +14,20 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
{
|
{
|
||||||
private readonly IDbContext _dbContext;
|
private readonly IDbContext _dbContext;
|
||||||
private readonly IDevicePermissionService _devicePermissionService;
|
private readonly IDevicePermissionService _devicePermissionService;
|
||||||
|
private readonly ICurrentUser _currentUser;
|
||||||
|
|
||||||
public DeviceGroupService(IDbContext dbContext, IDevicePermissionService devicePermissionService)
|
public DeviceGroupService(IDbContext dbContext, IDevicePermissionService devicePermissionService, ICurrentUser currentUser)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
_devicePermissionService = devicePermissionService;
|
_devicePermissionService = devicePermissionService;
|
||||||
|
_currentUser = currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Pagination<DeviceGroupPageResponse>> GetPageAsync(DeviceGroupPageRequest request)
|
|
||||||
{
|
|
||||||
return await _dbContext.Queryable<DeviceGroupEntity>()
|
|
||||||
.WhereIF(request.Search.IsPresent(), x => x.Name.Contains(request.Search))
|
|
||||||
.Select<DeviceGroupPageResponse>()
|
|
||||||
.ToPageListAsync(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<DeviceGroupTreeResponse>> GetTreeAsync(bool showDevices)
|
public async Task<List<DeviceGroupTreeResponse>> GetTreeAsync(bool showDevices, DeviceTypeEnumType? type)
|
||||||
{
|
{
|
||||||
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>()
|
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>()
|
||||||
|
.WhereIF(type.HasValue, x => x.Type == type)
|
||||||
.Select<DeviceGroupTreeResponse>()
|
.Select<DeviceGroupTreeResponse>()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@@ -48,19 +43,37 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
public async Task SaveAsync(DeviceGroupSaveRequest request)
|
public async Task SaveAsync(DeviceGroupSaveRequest request)
|
||||||
{
|
{
|
||||||
//检查父级节点
|
//检查父级节点
|
||||||
await CheckPCodeExistsDeviceAsync(request.PCode);
|
var pGrp = await CheckPCodeAsync(request);
|
||||||
|
|
||||||
if (!request.Id.HasValue)
|
if (!request.Id.HasValue)
|
||||||
{
|
{
|
||||||
var entity = request.Adapt<DeviceGroupEntity>();
|
var entity = request.Adapt<DeviceGroupEntity>();
|
||||||
|
|
||||||
entity.Code = Guid.NewGuid();
|
entity.Code = Guid.NewGuid();
|
||||||
|
entity.TenantId = _currentUser.GetStringTenantId();
|
||||||
|
|
||||||
await _dbContext.InsertAsync(entity);
|
await _dbContext.InsertAsync(entity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var entity = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Id == request.Id).FirstAsync();
|
var entity = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Id == request.Id).FirstAsync();
|
||||||
entity.ThrowIfNull("设备组不存在,无法更新");
|
entity.ThrowIfNull("设备分组不存在,无法更新");
|
||||||
|
entity.Editable.ThrowIfFalse("不可编辑当前分组");
|
||||||
|
|
||||||
|
if (request.Type != entity.Type)
|
||||||
|
{
|
||||||
|
//检查下级分组type不一致
|
||||||
|
var existsDiffNextGroups = await _dbContext.Queryable<DeviceGroupEntity>()
|
||||||
|
.Where(x => x.PCode == entity.Code)
|
||||||
|
.Where(x => x.Type != request.Type)
|
||||||
|
.AnyAsync();
|
||||||
|
|
||||||
|
existsDiffNextGroups.ThrowIfTrue("存在下级分组类型不一致,无法修改");
|
||||||
|
|
||||||
|
var nextDevices = await GetDevicesAsync(entity.Code);
|
||||||
|
nextDevices.Any(x => x.Type != request.Type).ThrowIfTrue("分组设备类型不匹配,无法修改类型");
|
||||||
|
}
|
||||||
|
|
||||||
|
request.Adapt(entity);
|
||||||
await _dbContext.UpdateAsync(entity);
|
await _dbContext.UpdateAsync(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,16 +81,16 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
public async Task DeleteAsync(long id)
|
public async Task DeleteAsync(long id)
|
||||||
{
|
{
|
||||||
var deviceGroup = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Id == id).FirstAsync();
|
var deviceGroup = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Id == id).FirstAsync();
|
||||||
deviceGroup.ThrowIfNull("设备组不存在,无需删除");
|
deviceGroup.ThrowIfNull("设备分组不存在,无需删除");
|
||||||
|
|
||||||
await _dbContext.DeleteAsync(deviceGroup);
|
await _dbContext.DeleteAsync(deviceGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Transactional]
|
|
||||||
public async Task AssignDevicesAsync(DeviceAssignRequest request)
|
public async Task AssignDevicesAsync(DeviceAssignRequest request)
|
||||||
{
|
{
|
||||||
var group = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Code == request.GroupCode).FirstAsync();
|
var group = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Code == request.GroupCode).FirstAsync();
|
||||||
group.ThrowIfNull("设备组不存在");
|
group.ThrowIfNull("设备分组不存在,无法进行分配");
|
||||||
|
|
||||||
await CheckNoNextGroupAsync(group.Code);
|
await CheckNoNextGroupAsync(group.Code);
|
||||||
await CheckGroupTypeMatchAsync(request, group);
|
await CheckGroupTypeMatchAsync(request, group);
|
||||||
@@ -86,13 +99,14 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
await _devicePermissionService.GenerateDeviceTasksAsync(async () =>
|
await _devicePermissionService.GenerateDeviceTasksAsync(async () =>
|
||||||
{
|
{
|
||||||
var relationships = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => x.GroupCode == request.GroupCode).ToListAsync();
|
var relationships = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => x.GroupCode == request.GroupCode).ToListAsync();
|
||||||
await _dbContext.DeleteAsync(relationships);
|
await _dbContext.DeleteReallyAsync(relationships);
|
||||||
|
|
||||||
|
|
||||||
var entities = request.DeviceCodes.Select(x => new DeviceGroupRelationshipEntity
|
var entities = request.DeviceCodes.Select(x => new DeviceGroupRelationshipEntity
|
||||||
{
|
{
|
||||||
GroupCode = request.GroupCode,
|
GroupCode = request.GroupCode,
|
||||||
DeviceCode = x
|
DeviceCode = x,
|
||||||
|
|
||||||
|
TenantId = _currentUser.GetStringTenantId(),
|
||||||
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
@@ -116,28 +130,33 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
/****************************************************** help methods *********************************************************/
|
/****************************************************** help methods *********************************************************/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检查父级分组存在设备
|
/// 检查父级分组
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pCode"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task CheckPCodeExistsDeviceAsync(Guid? pCode)
|
private async Task<DeviceGroupEntity> CheckPCodeAsync(DeviceGroupSaveRequest request)
|
||||||
{
|
{
|
||||||
if (pCode.HasValue)
|
var pGrp = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.Code == request.PCode).FirstAsync();
|
||||||
|
if (pGrp != null)
|
||||||
{
|
{
|
||||||
var exists = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => x.GroupCode == pCode).AnyAsync();
|
(!pGrp.AbleSetNext && !request.Id.HasValue).ThrowIfTrue($"{pGrp.Name}不可添加下级");
|
||||||
exists.ThrowIfTrue("父级分组存在设备");
|
var exists = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => x.GroupCode == request.PCode).AnyAsync();
|
||||||
|
exists.ThrowIfTrue("上级分组存在设备");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(pGrp != null && pGrp.Type != request.Type).ThrowIfTrue("分组类型必须与上级类型保持一致");
|
||||||
|
return pGrp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// 检查分组是否存在下级
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="currentCode"></param>
|
/// <param name="currentCode"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task CheckNoNextGroupAsync(Guid currentCode)
|
private async Task CheckNoNextGroupAsync(Guid currentCode)
|
||||||
{
|
{
|
||||||
var exists = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.PCode == currentCode).AnyAsync();
|
var exists = await _dbContext.Queryable<DeviceGroupEntity>().Where(x => x.PCode == currentCode).AnyAsync();
|
||||||
exists.ThrowIfTrue("存在下级设备分组");
|
exists.ThrowIfTrue("存在下级设备分组,无法分配设备");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -150,10 +169,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($"存在设备类型不一致,无法分配到当前{group.Type.GetDescription()}分组");
|
||||||
{
|
|
||||||
devices.Any(x => x.Type != group.Type).ThrowIfTrue("存在设备类型有误,无法分配到当前分组");
|
|
||||||
}
|
|
||||||
|
|
||||||
//重新赋值到请求参数中
|
//重新赋值到请求参数中
|
||||||
request.DeviceCodes = devices.Select(x => x.Code).ToList();
|
request.DeviceCodes = devices.Select(x => x.Code).ToList();
|
||||||
@@ -164,15 +180,32 @@ public class DeviceGroupService : IDeviceGroupService
|
|||||||
/// 递归获取树
|
/// 递归获取树
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="current"></param>
|
/// <param name="current"></param>
|
||||||
/// <param name="departments"></param>
|
/// <param name="deviceGroups"></param>
|
||||||
/// <param name="showDevices"></param>
|
/// <param name="showDevices"></param>
|
||||||
private void RecursionGetNext(DeviceGroupTreeResponse current, List<DeviceGroupTreeResponse> departments, bool showDevices)
|
private void RecursionGetNext(DeviceGroupTreeResponse current, List<DeviceGroupTreeResponse> deviceGroups, bool showDevices)
|
||||||
{
|
{
|
||||||
var next = departments.Where(x => x.PCode == current.Code).ToList();
|
var currentTenantId = _currentUser.GetStringTenantId();
|
||||||
|
var next = deviceGroups.Where(x =>
|
||||||
|
{
|
||||||
|
if (x.PCode == current.Code)
|
||||||
|
{
|
||||||
|
if (x.TenantId.IsEmpty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return x.TenantId == currentTenantId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}).ToList();
|
||||||
current.Next = next;
|
current.Next = next;
|
||||||
foreach (var item in next)
|
foreach (var item in next)
|
||||||
{
|
{
|
||||||
RecursionGetNext(item, departments, showDevices);
|
RecursionGetNext(item, deviceGroups, showDevices);
|
||||||
}
|
}
|
||||||
|
|
||||||
//最后层级附加设备信息
|
//最后层级附加设备信息
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Dlhis.Basic.Device.Request;
|
using Dlhis.Basic.Device.Dtos;
|
||||||
|
using Dlhis.Basic.Device.Request;
|
||||||
using Dlhis.Basic.Device.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
using Dlhis.Entity.Basic.Entity;
|
using Dlhis.Entity.Basic.Entity;
|
||||||
using Dlhis.Entity.Device.Entities;
|
using Dlhis.Entity.Device.Entities;
|
||||||
@@ -7,159 +8,156 @@ using Dlhis.Entity.Sys.Entities;
|
|||||||
using Dlhis.Entity.Sys.Enums;
|
using Dlhis.Entity.Sys.Enums;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Kurisu.SqlSugar.Attributes;
|
using Kurisu.Core.DataAccess.Entity;
|
||||||
|
using Kurisu.Core.User.Abstractions;
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Services.Implements;
|
namespace Dlhis.Basic.Device.Services.Implements;
|
||||||
|
|
||||||
public class DevicePermissionService : IDevicePermissionService
|
public class DevicePermissionService : IDevicePermissionService
|
||||||
{
|
{
|
||||||
private readonly IDbContext _dbContext;
|
private readonly IDbContext _dbContext;
|
||||||
|
private readonly ICurrentUser _currentUser;
|
||||||
|
|
||||||
public DevicePermissionService(IDbContext dbContext)
|
public DevicePermissionService(IDbContext dbContext, ICurrentUser currentUser)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
|
_currentUser = currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Transactional]
|
|
||||||
public async Task AssignAsync(DevicePermissionSaveReuqest reuqest)
|
public async Task AssignAsync(DevicePermissionSaveReuqest reuqest)
|
||||||
{
|
{
|
||||||
|
var tenantId = reuqest.AssignType == AssignTypeEnumType.Department ? reuqest.TenantId : _currentUser.GetStringTenantId();
|
||||||
|
|
||||||
|
//删除当前匹配的基地权限
|
||||||
|
var p = await _dbContext.Queryable<DevicePermissionEntity>()
|
||||||
|
.Where(x => x.AssignType == reuqest.AssignType)
|
||||||
|
.Where(x => x.AssignValue == reuqest.AssignValue)
|
||||||
|
.Where(x => x.UniqueType == reuqest.UniqueType)
|
||||||
|
.Where(x => x.TenantId == tenantId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
await _dbContext.DeleteReallyAsync(p);
|
||||||
|
|
||||||
await GenerateDeviceTasksAsync(async () =>
|
await GenerateDeviceTasksAsync(async () =>
|
||||||
{
|
{
|
||||||
|
//保存配置的权限
|
||||||
var p = await _dbContext.Queryable<DevicePermissionEntity>()
|
if (reuqest.Codes.IsPresent())
|
||||||
.Where(x => x.AssignType == reuqest.AssignType)
|
|
||||||
.Where(x => x.AssignValue == reuqest.AssignValue)
|
|
||||||
.Where(x => x.UniqueType == reuqest.UniqueType)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
await _dbContext.DeleteReallyAsync(p);
|
|
||||||
|
|
||||||
var devicePermissions = reuqest.Codes.Select(x => new DevicePermissionEntity
|
|
||||||
{
|
{
|
||||||
AssignType = reuqest.AssignType,
|
var devicePermissions = reuqest.Codes.Select(code => new DevicePermissionEntity
|
||||||
AssignValue = reuqest.AssignValue,
|
{
|
||||||
UniqueType = reuqest.UniqueType,
|
AssignType = reuqest.AssignType,
|
||||||
UniqueValue = x,
|
AssignValue = reuqest.AssignValue,
|
||||||
|
UniqueType = reuqest.UniqueType,
|
||||||
|
UniqueValue = code,
|
||||||
|
TenantId = tenantId
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
}).ToList();
|
await _dbContext.InsertAsync(devicePermissions);
|
||||||
|
}
|
||||||
await _dbContext.InsertAsync(devicePermissions);
|
|
||||||
|
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Guid>> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue)
|
public async Task<List<Guid>> GetAssignmentsAsync(DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue)
|
||||||
{
|
{
|
||||||
var devicePermissions = await _dbContext.Queryable<DevicePermissionEntity>()
|
var devicePermissions = await _dbContext.Queryable<DevicePermissionEntity>().ToListAsync();
|
||||||
.Where(x => x.UniqueType == uniqueType)
|
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
|
||||||
.Where(x => x.AssignType == assignType)
|
|
||||||
.Where(x => x.AssignValue == assignValue)
|
|
||||||
.Select(x => x.UniqueValue)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (uniqueType == DeviceAssignmentTypeEnumType.Group)
|
var result = GetAssignCodesInternal(devicePermissions, deviceGroups, uniqueType, assignType, assignValue);
|
||||||
{
|
return result.FirstOrDefault(x => x.Tenant == _currentUser.GetStringTenantId())?.Codes;
|
||||||
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
|
|
||||||
var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList();
|
|
||||||
tops.ForEach(x =>
|
|
||||||
{
|
|
||||||
RecursionGetNext(x, deviceGroups, devicePermissions, devicePermissions.Contains(x.Code));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return devicePermissions.Distinct().ToList();
|
|
||||||
|
|
||||||
void RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups, List<Guid> result, bool add)
|
|
||||||
{
|
|
||||||
var next = deviceGroups.Where(x => x.PCode == current.Code).ToList();
|
|
||||||
foreach (var item in next)
|
|
||||||
{
|
|
||||||
if (add) result.Add(item.Code);
|
|
||||||
RecursionGetNext(item, deviceGroups, result, result.Contains(item.Code));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task GenerateDeviceTasksAsync(Func<Task> func, List<string> userNos)
|
public async Task GenerateDeviceTasksAsync(Func<Task> func, List<string> userNos)
|
||||||
{
|
{
|
||||||
if (userNos.IsEmpty())
|
_dbContext.Client.QueryFilter.ClearAndBackup<ITenantId>();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
userNos = await GetPermissionUserNosAsync();
|
//获取所有人的权限
|
||||||
}
|
if (userNos.IsEmpty())
|
||||||
|
userNos = await GetPermissionUserNosAsync();
|
||||||
|
|
||||||
var beforeDic = await GetAssignDeviceCodesAsync(userNos);
|
var before = await GetAssignDeviceCodesInternalAsync(userNos);
|
||||||
|
|
||||||
//获取处理
|
_dbContext.Client.QueryFilter.Restore();
|
||||||
await func();
|
//业务处理
|
||||||
|
await func();
|
||||||
|
_dbContext.Client.QueryFilter.ClearAndBackup<ITenantId>();
|
||||||
|
|
||||||
//获取当前的权限code
|
//获取业务处理后所有人的权限
|
||||||
|
var nextUserNos = await GetPermissionUserNosAsync();
|
||||||
|
if (nextUserNos.Any())
|
||||||
|
userNos = userNos.Concat(nextUserNos).Distinct().ToList();
|
||||||
|
|
||||||
var nextUserNos = await GetPermissionUserNosAsync();
|
var current = await GetAssignDeviceCodesInternalAsync(userNos);
|
||||||
if (nextUserNos.Any())
|
|
||||||
{
|
|
||||||
userNos = nextUserNos;
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentDic = await GetAssignDeviceCodesAsync(userNos);
|
var deivces = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
|
||||||
|
var waitTasks = new List<DeviceTaskEntity>();
|
||||||
|
|
||||||
var deivces = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
|
foreach (var userNo in userNos)
|
||||||
foreach (var userNo in userNos)
|
|
||||||
{
|
|
||||||
beforeDic.TryGetValue(userNo, out var beforeCodes);
|
|
||||||
beforeCodes ??= new List<Guid>();
|
|
||||||
|
|
||||||
currentDic.TryGetValue(userNo, out var currentCodes);
|
|
||||||
currentCodes ??= new List<Guid>();
|
|
||||||
|
|
||||||
//被删除
|
|
||||||
var deletedItems = beforeCodes.Where(x => !currentCodes.Contains(x)).ToList();
|
|
||||||
//新增
|
|
||||||
var addItems = currentCodes.Where(x => !beforeCodes.Contains(x)).ToList();
|
|
||||||
|
|
||||||
if (!deletedItems.Any() && !addItems.Any())
|
|
||||||
{
|
{
|
||||||
continue;
|
before.TryGetValue(userNo, out var beforeTenantDeviceCodes);
|
||||||
|
beforeTenantDeviceCodes ??= new();
|
||||||
|
|
||||||
|
current.TryGetValue(userNo, out var currentTenantDeviceCodes);
|
||||||
|
currentTenantDeviceCodes ??= new();
|
||||||
|
|
||||||
|
var tenants = beforeTenantDeviceCodes.Select(x => x.Tenant).Concat(currentTenantDeviceCodes.Select(x => x.Tenant)).Distinct().ToList();
|
||||||
|
|
||||||
|
foreach (var tenant in tenants)
|
||||||
|
{
|
||||||
|
var currentCodes = currentTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes ?? new();
|
||||||
|
var beforeCodes = beforeTenantDeviceCodes.FirstOrDefault(x => x.Tenant == tenant)?.Codes ?? new();
|
||||||
|
|
||||||
|
//被删除
|
||||||
|
var deletedItems = beforeCodes.Where(x => !currentCodes.Contains(x)).ToList();
|
||||||
|
//新增
|
||||||
|
var addItems = currentCodes.Where(x => !beforeCodes.Contains(x)).ToList();
|
||||||
|
|
||||||
|
if (!deletedItems.Any() && !addItems.Any())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var deviceCodes = deivces.Where(x => deletedItems.Contains(x.Code) || addItems.Contains(x.Code)).Select(x => x.Code).ToList();
|
||||||
|
deletedItems = deletedItems.Where(x => deviceCodes.Contains(x)).ToList();
|
||||||
|
addItems = addItems.Where(x => deviceCodes.Contains(x)).ToList();
|
||||||
|
|
||||||
|
//下发任务创建
|
||||||
|
var toDeleted = deletedItems.Select(x => new DeviceTaskEntity
|
||||||
|
{
|
||||||
|
DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo,
|
||||||
|
Status = DeviceTaskStatusEnumType.Wait,
|
||||||
|
Type = DeviceTaskEnumType.Delete,
|
||||||
|
UserNo = userNo,
|
||||||
|
Version = 0,
|
||||||
|
TenantId = tenant,
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
var toAdd = addItems.Select(x => new DeviceTaskEntity
|
||||||
|
{
|
||||||
|
DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo,
|
||||||
|
Status = DeviceTaskStatusEnumType.Wait,
|
||||||
|
Type = DeviceTaskEnumType.Add,
|
||||||
|
UserNo = userNo,
|
||||||
|
Version = 0,
|
||||||
|
TenantId = tenant,
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
waitTasks.AddRange(toDeleted.Concat(toAdd).ToList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var deviceCodes = deivces.Where(x => deletedItems.Contains(x.Code) || addItems.Contains(x.Code)).Select(x => x.Code).ToList();
|
if (waitTasks.Any())
|
||||||
deletedItems = deletedItems.Where(x => deviceCodes.Contains(x)).ToList();
|
|
||||||
addItems = addItems.Where(x => deviceCodes.Contains(x)).ToList();
|
|
||||||
|
|
||||||
var userInfo = await _dbContext.Queryable<GainfoEntity>()
|
|
||||||
.LeftJoin<DepartmentEntity>((ga, department) => department.No == ga.DepartmentNo)
|
|
||||||
.Where(ga => ga.No == userNo)
|
|
||||||
.Select(ga => new
|
|
||||||
{
|
|
||||||
ga.Code
|
|
||||||
})
|
|
||||||
.SingleAsync();
|
|
||||||
|
|
||||||
//下发任务创建
|
|
||||||
var toDeleted = deletedItems.Select(x => new DeviceTaskEntity
|
|
||||||
{
|
{
|
||||||
DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo,
|
await _dbContext.InsertAsync(waitTasks);
|
||||||
Status = DeviceTaskStatusEnumType.Wait,
|
}
|
||||||
Type = DeviceTaskEnumType.Delete,
|
}
|
||||||
UserNo = userNo,
|
finally
|
||||||
Version = 0,
|
{
|
||||||
UserCode = userInfo.Code,
|
_dbContext.Client.QueryFilter.Restore();
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
var toAdd = addItems.Select(x => new DeviceTaskEntity
|
|
||||||
{
|
|
||||||
DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo,
|
|
||||||
Status = DeviceTaskStatusEnumType.Wait,
|
|
||||||
Type = DeviceTaskEnumType.Add,
|
|
||||||
UserNo = userNo,
|
|
||||||
Version = 0,
|
|
||||||
UserCode = userInfo.Code,
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
var tasks = toDeleted.Concat(toAdd).ToList();
|
|
||||||
await _dbContext.InsertAsync(tasks);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +181,6 @@ public class DevicePermissionService : IDevicePermissionService
|
|||||||
})
|
})
|
||||||
.SingleAsync();
|
.SingleAsync();
|
||||||
|
|
||||||
|
|
||||||
var tasks = deviceCodes.Select(x => new DeviceTaskEntity
|
var tasks = deviceCodes.Select(x => new DeviceTaskEntity
|
||||||
{
|
{
|
||||||
DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo,
|
DeviceUniqueNo = deivces.First(item => item.Code == x).UniqueNo,
|
||||||
@@ -191,13 +188,23 @@ public class DevicePermissionService : IDevicePermissionService
|
|||||||
Type = taskType,
|
Type = taskType,
|
||||||
UserNo = userNo,
|
UserNo = userNo,
|
||||||
Version = 0,
|
Version = 0,
|
||||||
UserCode = userInfo.Code,
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
await _dbContext.InsertAsync(tasks);
|
await _dbContext.InsertAsync(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<List<string>> GetCanteenDeviceUniqueNosByUserNoAsync(string userNo)
|
||||||
|
{
|
||||||
|
var all = await GetAssignDeviceCodesAsync(userNo);
|
||||||
|
|
||||||
|
return await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Meal)
|
||||||
|
.Where(x => all.Contains(x.Code))
|
||||||
|
.Select(x => x.UniqueNo)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取用户所有设备权限
|
/// 获取用户所有设备权限
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -206,125 +213,17 @@ public class DevicePermissionService : IDevicePermissionService
|
|||||||
public async Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo)
|
public async Task<List<Guid>> GetAssignDeviceCodesAsync(string userNo)
|
||||||
{
|
{
|
||||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.No == userNo).SingleAsync();
|
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.No == userNo).SingleAsync();
|
||||||
var gainfoGroups = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().Where(x => x.UserNo == userNo).Select(x => x.GroupCode).ToListAsync();
|
var gainfoGroups = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().ToListAsync();
|
||||||
|
|
||||||
var deviceCodes = new List<Guid>();
|
|
||||||
var deviceGroupCodes = new List<Guid>();
|
|
||||||
|
|
||||||
var du = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, userNo);
|
|
||||||
var gu = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo);
|
|
||||||
deviceCodes.AddRange(du);
|
|
||||||
deviceGroupCodes.AddRange(gu);
|
|
||||||
|
|
||||||
foreach (var group in gainfoGroups)
|
|
||||||
{
|
|
||||||
var dg = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, group.ToString());
|
|
||||||
var gg = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, group.ToString());
|
|
||||||
deviceCodes.AddRange(dg);
|
|
||||||
deviceGroupCodes.AddRange(gg);
|
|
||||||
}
|
|
||||||
|
|
||||||
var dd = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, gainfo.DepartmentNo);
|
|
||||||
var gd = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, gainfo.DepartmentNo);
|
|
||||||
deviceCodes.AddRange(dd);
|
|
||||||
deviceGroupCodes.AddRange(gd);
|
|
||||||
|
|
||||||
var dt = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Werks);
|
|
||||||
var gt = await GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Werks);
|
|
||||||
deviceCodes.AddRange(du);
|
|
||||||
deviceGroupCodes.AddRange(gu);
|
|
||||||
|
|
||||||
var deveiceCodesByGroup = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync();
|
|
||||||
deviceCodes.AddRange(deveiceCodesByGroup);
|
|
||||||
|
|
||||||
return deviceCodes.Distinct().ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<Dictionary<string, List<Guid>>> GetAssignDeviceCodesAsync(List<string> userNos)
|
|
||||||
{
|
|
||||||
var gainfos = await _dbContext.Queryable<GainfoEntity>().Where(x => userNos.Contains(x.No)).ToListAsync();
|
|
||||||
if (!gainfos.Any())
|
|
||||||
{
|
|
||||||
return new Dictionary<string, List<Guid>>();
|
|
||||||
}
|
|
||||||
var gainfoGroupRelationships = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().ToListAsync();
|
|
||||||
var devicePermissions = await _dbContext.Queryable<DevicePermissionEntity>().ToListAsync();
|
var devicePermissions = await _dbContext.Queryable<DevicePermissionEntity>().ToListAsync();
|
||||||
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
|
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
|
||||||
|
var deviceRelationships = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().ToListAsync();
|
||||||
|
|
||||||
var result = new Dictionary<string, List<Guid>>();
|
var result = GetAssignDeviceCodesInternal(gainfo, gainfoGroups, devicePermissions, deviceGroups, deviceRelationships);
|
||||||
|
return result.SelectMany(x => x.Codes).ToList();
|
||||||
foreach (var gainfo in gainfos)
|
|
||||||
{
|
|
||||||
var userNo = gainfo.No;
|
|
||||||
|
|
||||||
var gainfoGroups = gainfoGroupRelationships.Where(x => x.UserNo == userNo).ToList();
|
|
||||||
|
|
||||||
var deviceCodes = new List<Guid>();
|
|
||||||
var deviceGroupCodes = new List<Guid>();
|
|
||||||
|
|
||||||
var du = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, userNo);
|
|
||||||
var gu = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo);
|
|
||||||
deviceCodes.AddRange(du);
|
|
||||||
deviceGroupCodes.AddRange(gu);
|
|
||||||
|
|
||||||
foreach (var group in gainfoGroups)
|
|
||||||
{
|
|
||||||
var dg = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, group.ToString());
|
|
||||||
var gg = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, group.ToString());
|
|
||||||
deviceCodes.AddRange(dg);
|
|
||||||
deviceGroupCodes.AddRange(gg);
|
|
||||||
}
|
|
||||||
|
|
||||||
var dd = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, gainfo.DepartmentNo);
|
|
||||||
var gd = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, gainfo.DepartmentNo);
|
|
||||||
deviceCodes.AddRange(dd);
|
|
||||||
deviceGroupCodes.AddRange(gd);
|
|
||||||
|
|
||||||
var dt = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Werks);
|
|
||||||
var gt = GetAssignmentsInternal(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Werks);
|
|
||||||
deviceCodes.AddRange(du);
|
|
||||||
deviceGroupCodes.AddRange(gu);
|
|
||||||
|
|
||||||
var deveiceCodesByGroup = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().Where(x => deviceGroupCodes.Contains(x.GroupCode)).Select(x => x.DeviceCode).ToListAsync();
|
|
||||||
deviceCodes.AddRange(deveiceCodesByGroup);
|
|
||||||
|
|
||||||
result.Add(userNo, deviceCodes.Distinct().ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
|
|
||||||
|
|
||||||
List<Guid> GetAssignmentsInternal(DeviceAssignmentTypeEnumType uniqueTypeInternal, AssignTypeEnumType assignTypeInternal, string assignValueInternal)
|
|
||||||
{
|
|
||||||
var devicePermissionsInternal = devicePermissions.Where(x => x.UniqueType == uniqueTypeInternal)
|
|
||||||
.Where(x => x.AssignType == assignTypeInternal)
|
|
||||||
.Where(x => x.AssignValue == assignValueInternal)
|
|
||||||
.Select(x => x.UniqueValue)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (uniqueTypeInternal == DeviceAssignmentTypeEnumType.Group)
|
|
||||||
{
|
|
||||||
var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList();
|
|
||||||
tops.ForEach(x =>
|
|
||||||
{
|
|
||||||
RecursionGetNext(x, deviceGroups, devicePermissionsInternal, devicePermissionsInternal.Contains(x.Code));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return devicePermissionsInternal.Distinct().ToList();
|
|
||||||
|
|
||||||
void RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups, List<Guid> result, bool add)
|
|
||||||
{
|
|
||||||
var next = deviceGroups.Where(x => x.PCode == current.Code).ToList();
|
|
||||||
foreach (var item in next)
|
|
||||||
{
|
|
||||||
if (add) result.Add(item.Code);
|
|
||||||
RecursionGetNext(item, deviceGroups, result, result.Contains(item.Code));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取用户权限设备
|
/// 获取用户权限设备
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -340,7 +239,7 @@ public class DevicePermissionService : IDevicePermissionService
|
|||||||
|
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
|
var devices = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
|
||||||
|
|
||||||
if(ggs != null && ggs.Count > 0)
|
if (ggs != null && ggs.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (var gid in ggs)
|
foreach (var gid in ggs)
|
||||||
{
|
{
|
||||||
@@ -351,7 +250,7 @@ public class DevicePermissionService : IDevicePermissionService
|
|||||||
gds.AddRange(ds);
|
gds.AddRange(ds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var dds = gds.Distinct().ToList();
|
var dds = gds.Distinct().ToList();
|
||||||
var lst = devices.Where(x => dds.Contains(x.Code))
|
var lst = devices.Where(x => dds.Contains(x.Code))
|
||||||
.Select(x => new AssigmentByCodeResponse
|
.Select(x => new AssigmentByCodeResponse
|
||||||
@@ -403,8 +302,169 @@ public class DevicePermissionService : IDevicePermissionService
|
|||||||
var tenants = permissions.Where(x => x.AssignType == AssignTypeEnumType.Tenant).Select(x => x.AssignValue).ToList();
|
var tenants = permissions.Where(x => x.AssignType == AssignTypeEnumType.Tenant).Select(x => x.AssignValue).ToList();
|
||||||
var userNosByWerk = await _dbContext.Queryable<GainfoEntity>().Where(x => tenants.Contains(x.Werks)).Select(x => x.No).ToListAsync();
|
var userNosByWerk = await _dbContext.Queryable<GainfoEntity>().Where(x => tenants.Contains(x.Werks)).Select(x => x.No).ToListAsync();
|
||||||
|
|
||||||
|
return userNos.Concat(userNosByGroup).Concat(userNosByDepartment).Concat(userNosByWerk).Distinct().ToList();
|
||||||
return userNos.Concat(userNosByGroup).Concat(userNosByDepartment).Concat(userNosByWerk).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static List<Guid> GetAssignmentsInternal(
|
||||||
|
List<DevicePermissionEntity> devicePermissions, List<DeviceGroupEntity> deviceGroups,
|
||||||
|
DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue)
|
||||||
|
{
|
||||||
|
var devicePermissionCodes = devicePermissions
|
||||||
|
.Where(x => x.UniqueType == uniqueType)
|
||||||
|
.Where(x => x.AssignType == assignType)
|
||||||
|
.Where(x => x.AssignValue == assignValue)
|
||||||
|
.Select(x => x.UniqueValue).ToList();
|
||||||
|
|
||||||
|
//处理获取设备组的情况,递归到最下级获取设备code
|
||||||
|
if (uniqueType == DeviceAssignmentTypeEnumType.Group)
|
||||||
|
{
|
||||||
|
var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList();
|
||||||
|
tops.ForEach(x =>
|
||||||
|
{
|
||||||
|
RecursionGetNext(x, deviceGroups, devicePermissionCodes, devicePermissionCodes.Contains(x.Code));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return devicePermissionCodes.Distinct().ToList();
|
||||||
|
|
||||||
|
void RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups, List<Guid> result, bool add)
|
||||||
|
{
|
||||||
|
var next = deviceGroups.Where(x => x.PCode == current.Code).ToList();
|
||||||
|
foreach (var item in next)
|
||||||
|
{
|
||||||
|
if (add) result.Add(item.Code);
|
||||||
|
RecursionGetNext(item, deviceGroups, result, result.Contains(item.Code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<UserTenantDeviceCodeDto> GetAssignCodesInternal(
|
||||||
|
List<DevicePermissionEntity> devicePermissions, List<DeviceGroupEntity> deviceGroups,
|
||||||
|
DeviceAssignmentTypeEnumType uniqueType, AssignTypeEnumType assignType, string assignValue)
|
||||||
|
{
|
||||||
|
var tenantDevicePermissions = devicePermissions
|
||||||
|
.Where(x => x.UniqueType == uniqueType)
|
||||||
|
.Where(x => x.AssignType == assignType)
|
||||||
|
.Where(x => x.AssignValue == assignValue)
|
||||||
|
.GroupBy(x => x.TenantId)
|
||||||
|
.Select(x => new UserTenantDeviceCodeDto { Tenant = x.Key, Codes = x.Select(x => x.UniqueValue).ToList() })
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
//处理获取设备分组的情况
|
||||||
|
if (uniqueType == DeviceAssignmentTypeEnumType.Group)
|
||||||
|
{
|
||||||
|
//开始递归处理
|
||||||
|
var tops = deviceGroups.Where(x => !x.PCode.HasValue).ToList();
|
||||||
|
tops.ForEach(x =>
|
||||||
|
{
|
||||||
|
RecursionGetNext(x, deviceGroups, tenantDevicePermissions, tenantDevicePermissions.SelectMany(x => x.Codes).Contains(x.Code));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return tenantDevicePermissions.GroupBy(x => x.Tenant).Select(x =>
|
||||||
|
{
|
||||||
|
var tenant = x.Key;
|
||||||
|
|
||||||
|
return new UserTenantDeviceCodeDto
|
||||||
|
{
|
||||||
|
Tenant = tenant,
|
||||||
|
Codes = x.SelectMany(item => item.Codes).ToList()
|
||||||
|
};
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
void RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups, List<UserTenantDeviceCodeDto> result, bool add)
|
||||||
|
{
|
||||||
|
var next = deviceGroups.Where(x => x.PCode == current.Code).ToList();
|
||||||
|
foreach (var item in next)
|
||||||
|
{
|
||||||
|
if (add)
|
||||||
|
{
|
||||||
|
result.Add(new UserTenantDeviceCodeDto { Tenant = item.TenantId, Codes = new List<Guid> { item.Code } });
|
||||||
|
}
|
||||||
|
RecursionGetNext(item, deviceGroups, result, result.SelectMany(x => x.Codes).Contains(item.Code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Dictionary<string, List<UserTenantDeviceCodeDto>>> GetAssignDeviceCodesInternalAsync(List<string> userNos)
|
||||||
|
{
|
||||||
|
var gainfos = await _dbContext.Queryable<GainfoEntity>().Where(x => userNos.Contains(x.No)).ToListAsync();
|
||||||
|
if (!gainfos.Any())
|
||||||
|
{
|
||||||
|
return new Dictionary<string, List<UserTenantDeviceCodeDto>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var gainfoGroupRelationships = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().Where(x => userNos.Contains(x.UserNo)).ToListAsync();
|
||||||
|
var devicePermissions = await _dbContext.Queryable<DevicePermissionEntity>().ToListAsync();
|
||||||
|
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
|
||||||
|
var deviceRelationships = await _dbContext.Queryable<DeviceGroupRelationshipEntity>().ToListAsync();
|
||||||
|
|
||||||
|
var result = new Dictionary<string, List<UserTenantDeviceCodeDto>>(gainfos.Count);
|
||||||
|
|
||||||
|
foreach (var gainfo in gainfos)
|
||||||
|
{
|
||||||
|
var codes = GetAssignDeviceCodesInternal(gainfo, gainfoGroupRelationships, devicePermissions, deviceGroups, deviceRelationships);
|
||||||
|
result.Add(gainfo.No, codes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<UserTenantDeviceCodeDto> GetAssignDeviceCodesInternal(
|
||||||
|
GainfoEntity gainfo,
|
||||||
|
List<GainfoGroupRelationshipEntity> gainfoGroupRelationships,
|
||||||
|
List<DevicePermissionEntity> devicePermissions,
|
||||||
|
List<DeviceGroupEntity> deviceGroups,
|
||||||
|
List<DeviceGroupRelationshipEntity> deviceGroupRelationships)
|
||||||
|
{
|
||||||
|
var userNo = gainfo.No;
|
||||||
|
var deviceCodes = new List<UserTenantDeviceCodeDto>();
|
||||||
|
var deviceGroupCodes = new List<UserTenantDeviceCodeDto>();
|
||||||
|
|
||||||
|
//获取人员的分组,跨基地
|
||||||
|
var gainfoGroups = gainfoGroupRelationships.Where(x => x.UserNo == userNo).Select(x => x.GroupCode).ToList();
|
||||||
|
|
||||||
|
//按User获取权限
|
||||||
|
var du = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.User, userNo);
|
||||||
|
var gu = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo);
|
||||||
|
deviceCodes.AddRange(du);
|
||||||
|
deviceGroupCodes.AddRange(gu);
|
||||||
|
|
||||||
|
foreach (var groupCode in gainfoGroups)
|
||||||
|
{
|
||||||
|
var dg = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Group, groupCode.ToString());
|
||||||
|
var gg = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Group, groupCode.ToString());
|
||||||
|
deviceCodes.AddRange(dg);
|
||||||
|
deviceGroupCodes.AddRange(gg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var gainfoFactoryDevicePermissions = devicePermissions.Where(x => x.TenantId == gainfo.Factory).ToList();
|
||||||
|
var dd = GetAssignCodesInternal(gainfoFactoryDevicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Department, gainfo.DepartmentNo);
|
||||||
|
var gd = GetAssignCodesInternal(gainfoFactoryDevicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Department, gainfo.DepartmentNo);
|
||||||
|
deviceCodes.AddRange(dd);
|
||||||
|
deviceGroupCodes.AddRange(gd);
|
||||||
|
|
||||||
|
var dt = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Device, AssignTypeEnumType.Tenant, gainfo.Factory);
|
||||||
|
var gt = GetAssignCodesInternal(devicePermissions, deviceGroups, DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.Tenant, gainfo.Factory);
|
||||||
|
deviceCodes.AddRange(du);
|
||||||
|
deviceGroupCodes.AddRange(gu);
|
||||||
|
|
||||||
|
var groupCodes = deviceGroupCodes.SelectMany(x => x.Codes).Distinct().ToList();
|
||||||
|
var deveiceCodesByGroup = deviceGroupRelationships.Where(x => groupCodes.Contains(x.GroupCode)).GroupBy(x => x.TenantId)
|
||||||
|
.Select(x => new UserTenantDeviceCodeDto
|
||||||
|
{
|
||||||
|
Tenant = x.Key,
|
||||||
|
Codes = x.Select(item => item.DeviceCode).Distinct().ToList()
|
||||||
|
});
|
||||||
|
|
||||||
|
deviceCodes.AddRange(deveiceCodesByGroup);
|
||||||
|
|
||||||
|
return deviceCodes.GroupBy(x => x.Tenant).Select(x => new UserTenantDeviceCodeDto
|
||||||
|
{
|
||||||
|
Tenant = x.Key,
|
||||||
|
Codes = x.SelectMany(item => item.Codes).Distinct().ToList()
|
||||||
|
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
using Dlhis.Basic.Device.Request;
|
using Dlhis.Basic.Device.Request;
|
||||||
using Dlhis.Basic.Device.Response;
|
using Dlhis.Basic.Device.Response;
|
||||||
using Dlhis.Entity.Basic.Entity;
|
using Dlhis.Entity.Basic.Entity;
|
||||||
|
using Dlhis.Entity.Canteen.Entities;
|
||||||
|
using Dlhis.Entity.Canteen.Enums;
|
||||||
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.UnifyResultAndValidation;
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Kurisu.SqlSugar.Attributes;
|
|
||||||
using Kurisu.SqlSugar.Extensions;
|
using Kurisu.SqlSugar.Extensions;
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MySqlX.XDevAPI.Relational;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using NPOI.OpenXmlFormats;
|
||||||
|
using NPOI.SS.UserModel;
|
||||||
|
using NPOI.XSSF.UserModel;
|
||||||
|
using SqlSugar;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Device.Services.Implements;
|
namespace Dlhis.Basic.Device.Services.Implements;
|
||||||
|
|
||||||
@@ -29,29 +35,57 @@ 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 deviceUniqueNos = page.Data.Select(x => x.UniqueNo).ToList();
|
||||||
|
|
||||||
|
var balanceInfos = await _dbContext.Queryable<BalanceRecordEntity>().Where(x => x.Type == BalanceRecordTypeEnumType.Out)
|
||||||
|
.Where(x => deviceUniqueNos.Contains(x.DeviceInfo))
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
x.DeviceInfo,
|
||||||
|
Amount = SqlFunc.AggregateSum(x.Amount),
|
||||||
|
UserCount = SqlFunc.AggregateDistinctCount(x.UserCode)
|
||||||
|
})
|
||||||
|
.GroupBy(x => x.DeviceInfo)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
page.Data.ForEach(device =>
|
||||||
|
{
|
||||||
|
var info = balanceInfos.FirstOrDefault(x => x.DeviceInfo == device.UniqueNo);
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
device.Amount = info.Amount;
|
||||||
|
device.UserCount = info.UserCount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Transactional]
|
|
||||||
public async Task SaveAsync(DeviceSaveRequest request)
|
public async Task SaveAsync(DeviceSaveRequest request)
|
||||||
{
|
{
|
||||||
await CheckUniqueNoExistsAsync(request);
|
await CheckUniqueNoExistsAsync(request);
|
||||||
var template = await CheckTemplateExistsAsync(request.TemplateCode);
|
var template = await CheckTemplateExistsAsync(request.TemplateCode);
|
||||||
await CheckTemplateFieldAsync(request.TemplateCode, request.ConnectionInfo);
|
await CheckTemplateFieldAsync(request.TemplateCode, request.ConnectionInfo);
|
||||||
|
|
||||||
|
DeviceEntity entity = null;
|
||||||
if (!request.Id.HasValue)
|
if (!request.Id.HasValue)
|
||||||
{
|
{
|
||||||
var entity = request.Adapt<DeviceEntity>();
|
entity = request.Adapt<DeviceEntity>();
|
||||||
entity.Code = Guid.NewGuid();
|
entity.Code = Guid.NewGuid();
|
||||||
await _dbContext.InsertAsync(entity);
|
await _dbContext.InsertAsync(entity);
|
||||||
//同时保存注册信息
|
//同时保存注册信息
|
||||||
@@ -72,7 +106,7 @@ public class DeviceService : IDeviceService
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var entity = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Id == request.Id).FirstAsync();
|
entity = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Id == request.Id).FirstAsync();
|
||||||
entity.ThrowIfNull("设备不存在,无法更新");
|
entity.ThrowIfNull("设备不存在,无法更新");
|
||||||
|
|
||||||
//分类发生变化,检查是否存在分组
|
//分类发生变化,检查是否存在分组
|
||||||
@@ -81,21 +115,94 @@ public class DeviceService : IDeviceService
|
|||||||
var existsG = await _dbContext.Queryable<DeviceGroupRelationshipEntity>()
|
var existsG = await _dbContext.Queryable<DeviceGroupRelationshipEntity>()
|
||||||
.LeftJoin<DeviceGroupEntity>((dgr, dg) => dgr.GroupCode == dg.Code)
|
.LeftJoin<DeviceGroupEntity>((dgr, dg) => dgr.GroupCode == dg.Code)
|
||||||
.Where((dgr, dg) => dgr.DeviceCode == entity.Code)
|
.Where((dgr, dg) => dgr.DeviceCode == entity.Code)
|
||||||
.Where((dgr, dg) => dg.Type != null)
|
|
||||||
.AnyAsync();
|
.AnyAsync();
|
||||||
|
|
||||||
existsG.ThrowIfTrue("存在设备分组,不可修改设备分类");
|
existsG.ThrowIfTrue("存在设备分组,不可修改设备分类");
|
||||||
}
|
}
|
||||||
|
|
||||||
var uniqueNo = entity.UniqueNo;
|
request.Adapt(entity);
|
||||||
request.Adapt(entity).UniqueNo = uniqueNo;
|
|
||||||
|
|
||||||
await _dbContext.UpdateAsync(entity);
|
await _dbContext.UpdateAsync(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await GenerateUploadRecordLogForBeginTimeAsync(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量导入
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task BulkUploadsAsync(BulkUploadsRequest request)
|
||||||
|
{
|
||||||
|
var lst = ImportFromExcel(request.FormFile);
|
||||||
|
var places = await _dbContext.Queryable<BusinessPlaceEntity>().ToListAsync();
|
||||||
|
|
||||||
|
foreach (var form in lst)
|
||||||
|
{
|
||||||
|
if (form.PlaceeCode != null)
|
||||||
|
{
|
||||||
|
var place = places.Where(x => x.Code == form.PlaceeCode).FirstOrDefault();
|
||||||
|
place.ThrowIfNull($"该设备{form.UniqueNo}配置的营业点营业点不存在!");
|
||||||
|
}
|
||||||
|
//插入
|
||||||
|
var exists = await _dbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == form.UniqueNo)
|
||||||
|
.AnyAsync();
|
||||||
|
exists.ThrowIfTrue("唯一号已经存在");
|
||||||
|
var template = await CheckTemplateExistsAsync(form.TemplateCode);
|
||||||
|
await CheckTemplateFieldAsync(form.TemplateCode, form.ConnectionInfo);
|
||||||
|
|
||||||
|
var saveEntity = form.Adapt<DeviceEntity>();
|
||||||
|
saveEntity.Code = Guid.NewGuid();
|
||||||
|
await _dbContext.InsertAsync(saveEntity);
|
||||||
|
//保存注册信息
|
||||||
|
var regis = await _dbContext.Queryable<DeviceRegistryEntity>()
|
||||||
|
.Where(x => x.DeviceUniqueNo == form.UniqueNo)
|
||||||
|
.FirstAsync();
|
||||||
|
if(regis == null)
|
||||||
|
{
|
||||||
|
var custCode = places.Where(x => x.Code == form.PlaceeCode).Select(x => x.CustomCode).FirstOrDefault();
|
||||||
|
regis = new DeviceRegistryEntity
|
||||||
|
{
|
||||||
|
DeviceUniqueNo = form.UniqueNo,
|
||||||
|
LastHeartbeatTime = DateTime.Now,
|
||||||
|
RegisterTime = DateTime.Now,
|
||||||
|
BusinessPlaceCode = form.PlaceeCode,
|
||||||
|
BusinessPlaceCustomCode = custCode
|
||||||
|
};
|
||||||
|
await _dbContext.InsertAsync(regis);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************** help methods **********************************************************
|
//******************************************************** help methods **********************************************************
|
||||||
|
|
||||||
|
private async Task GenerateUploadRecordLogForBeginTimeAsync(DeviceEntity entity)
|
||||||
|
{
|
||||||
|
if (entity.Type == DeviceTypeEnumType.Door || entity.Type == DeviceTypeEnumType.Attendance)
|
||||||
|
{
|
||||||
|
var exists = await _dbContext.Queryable<DeviceUploadLogEntity>()
|
||||||
|
.Where(x => x.DeviceUniqueNo == entity.UniqueNo)
|
||||||
|
.Where(x => x.Type == DeviceUploadLogTypeEnumType.Raise)
|
||||||
|
.AnyAsync();
|
||||||
|
|
||||||
|
if (!exists)
|
||||||
|
{
|
||||||
|
await _dbContext.InsertAsync(new DeviceUploadLogEntity
|
||||||
|
{
|
||||||
|
DeviceUniqueNo = entity.UniqueNo,
|
||||||
|
Type = DeviceUploadLogTypeEnumType.Raise,
|
||||||
|
UserUniqueNo = string.Empty,
|
||||||
|
RaiseDateTime = entity.CreateTime,
|
||||||
|
|
||||||
|
CreatedBy = 1,
|
||||||
|
CreateTime = DateTime.Now,
|
||||||
|
ModifiedBy = 1,
|
||||||
|
ModifiedTime = DateTime.Now,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检查设备模板是否存在
|
/// 检查设备模板是否存在
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -148,14 +255,15 @@ public class DeviceService : IDeviceService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task CheckUniqueNoExistsAsync(DeviceSaveRequest request)
|
private async Task CheckUniqueNoExistsAsync(DeviceSaveRequest request)
|
||||||
{
|
{
|
||||||
var exists = await _dbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == request.UniqueNo)
|
var exists = await _dbContext.Queryable<DeviceEntity>()
|
||||||
|
.Where(x => x.UniqueNo == request.UniqueNo)
|
||||||
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
.WhereIF(request.Id.HasValue, x => x.Id != request.Id)
|
||||||
.AnyAsync();
|
.AnyAsync();
|
||||||
|
|
||||||
exists.ThrowIfTrue("唯一号已经存在");
|
exists.ThrowIfTrue("唯一号已经存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
[IgnoreTenant]
|
|
||||||
public async Task<bool> CheckExistsAsync(string deviceUniqueNo)
|
public async Task<bool> CheckExistsAsync(string deviceUniqueNo)
|
||||||
{
|
{
|
||||||
return await _dbContext.Queryable<DeviceEntity>()
|
return await _dbContext.Queryable<DeviceEntity>()
|
||||||
@@ -187,36 +295,81 @@ public class DeviceService : IDeviceService
|
|||||||
{
|
{
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>()
|
var devices = await _dbContext.Queryable<DeviceEntity>()
|
||||||
.Where(x => x.Enable)
|
.Where(x => x.Enable)
|
||||||
|
.Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance))
|
||||||
.Select(x => new DeviceResponse
|
.Select(x => new DeviceResponse
|
||||||
{
|
{
|
||||||
FuncsStr = x.Funcs.ToString()
|
FuncsStr = x.Funcs.ToString()
|
||||||
}, true)
|
}, true)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
return devices.Where(x => x.Funcs.Contains(DeviceFuncEnumType.Attendance)).ToList();
|
return devices.Where(x => x.Type == DeviceTypeEnumType.Attendance).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<DeviceNumberResponse> GetDeviceNumberAsync()
|
public async Task<DeviceNumberResponse> GetDeviceNumberAsync()
|
||||||
{
|
{
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>()
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync();
|
||||||
.Where(x => x.Type == DeviceTypeEnumType.Attendance)
|
|
||||||
.ToListAsync();
|
var offlineNumber = await GetOfflineDevicesCount(devices);
|
||||||
var onlineNumber = devices.Where(x => x.Enable).Count();
|
|
||||||
var offlineNumber = devices.Where(x => x.Enable == false).Count();
|
|
||||||
var res = new DeviceNumberResponse
|
var res = new DeviceNumberResponse
|
||||||
{
|
{
|
||||||
OnlineNumber = onlineNumber,
|
OfflineNumber = offlineNumber.Count,
|
||||||
OfflineNumber = offlineNumber,
|
TotalNumber = devices.Count,
|
||||||
TotalNumber = devices.Count()
|
OnlineNumber = devices.Count - offlineNumber.Count
|
||||||
};
|
};
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取离线设备
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task<List<DeviceEntity>> GetOfflineDevicesCount(List<DeviceEntity> devices)
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
|
||||||
|
var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
|
||||||
|
|
||||||
|
var deviceRegistries = await _dbContext.Queryable<DeviceRegistryEntity>()
|
||||||
|
.LeftJoin<DeviceEntity>((x, d) => x.DeviceUniqueNo == d.UniqueNo)
|
||||||
|
.Where(x => deviceUniqueNos.Contains(x.DeviceUniqueNo))
|
||||||
|
.Select((x, d) => new
|
||||||
|
{
|
||||||
|
UniqueNo = d.UniqueNo,
|
||||||
|
d.HeartbeatInterval,
|
||||||
|
x.LastHeartbeatTime
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var OnlineDevices = deviceRegistries
|
||||||
|
.Where(x =>
|
||||||
|
{
|
||||||
|
if (x.HeartbeatInterval <= 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now;
|
||||||
|
|
||||||
|
})
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
UniqueNo = x.UniqueNo,
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
var onlineUniqueNos = new List<string>();
|
||||||
|
OnlineDevices.ForEach(x => onlineUniqueNos.Add(x.UniqueNo));
|
||||||
|
|
||||||
|
var offUniqueNos = deviceUniqueNos.Except(onlineUniqueNos).ToList();
|
||||||
|
var list = devices.Where(x => offUniqueNos.Contains(x.UniqueNo)).ToList();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<Pagination<DevicePageResponse>> GetAttendanceTotalAsync(AttendanceTotalRequest request)
|
public async Task<Pagination<DevicePageResponse>> GetAttendanceTotalAsync(AttendanceTotalRequest request)
|
||||||
{
|
{
|
||||||
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)
|
||||||
.Where(d => d.Type == DeviceTypeEnumType.Attendance)
|
.Where(d => d.Type == DeviceTypeEnumType.Attendance || (d.Type == DeviceTypeEnumType.Door && d.AsAttendance))
|
||||||
.Select((d, dt) => new DevicePageResponse
|
.Select((d, dt) => new DevicePageResponse
|
||||||
{
|
{
|
||||||
FuncsStr = d.Funcs.ToString(),
|
FuncsStr = d.Funcs.ToString(),
|
||||||
@@ -231,9 +384,37 @@ public class DeviceService : IDeviceService
|
|||||||
|
|
||||||
public async Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync(DeviceOnlineAndofflineRequest request)
|
public async Task<Pagination<DevicePageResponse>> GetAttendanceOfflineAsync(DeviceOnlineAndofflineRequest request)
|
||||||
{
|
{
|
||||||
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync();
|
||||||
|
|
||||||
|
//离线
|
||||||
|
var offDevices = await GetOfflineDevicesCount(devices);
|
||||||
|
var offids = offDevices.Select(x => x.Id).ToList();
|
||||||
|
|
||||||
|
if (request.IsOnAndOff)
|
||||||
|
{
|
||||||
|
//离线
|
||||||
|
var offpage = await _dbContext.Queryable<DeviceEntity>()
|
||||||
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
|
.Where(d => d.Type == DeviceTypeEnumType.Attendance)
|
||||||
|
.Where(d => offids.Contains(d.Id))
|
||||||
|
.Select((d, dt) => new DevicePageResponse
|
||||||
|
{
|
||||||
|
FuncsStr = d.Funcs.ToString(),
|
||||||
|
Brand = dt.Brand,
|
||||||
|
Type = d.Type,
|
||||||
|
|
||||||
|
}, true)
|
||||||
|
.ToPageListAsync(request);
|
||||||
|
return offpage;
|
||||||
|
}
|
||||||
|
//在线
|
||||||
|
var ids = devices.Select(x => x.Id).ToList();
|
||||||
|
List<long> onids = ids.Except(offids).ToList();
|
||||||
|
|
||||||
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)
|
||||||
.Where(d => d.Type == DeviceTypeEnumType.Attendance && d.Enable == request.IsOnAndOff)
|
.Where(d => d.Type == DeviceTypeEnumType.Attendance)
|
||||||
|
.Where(d => onids.Contains(d.Id))
|
||||||
.Select((d, dt) => new DevicePageResponse
|
.Select((d, dt) => new DevicePageResponse
|
||||||
{
|
{
|
||||||
FuncsStr = d.Funcs.ToString(),
|
FuncsStr = d.Funcs.ToString(),
|
||||||
@@ -246,7 +427,52 @@ public class DeviceService : IDeviceService
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<string, int>> GetRecentNumbersAsync()
|
public async Task<Pagination<DevicePageResponse>> GetDoorOfflineAsync(GetDoorOfflineRequest request)
|
||||||
|
{
|
||||||
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Door).ToListAsync();
|
||||||
|
|
||||||
|
var offDevices = await GetOfflineDevicesCount(devices);
|
||||||
|
var offids = offDevices.Select(x => x.Id).ToList();
|
||||||
|
|
||||||
|
if (request.IsOnAndOff)
|
||||||
|
{
|
||||||
|
//离线
|
||||||
|
var offpage = await _dbContext.Queryable<DeviceEntity>()
|
||||||
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
|
.Where(d => d.Type == DeviceTypeEnumType.Door)
|
||||||
|
.Where(d => offids.Contains(d.Id))
|
||||||
|
.Select((d, dt) => new DevicePageResponse
|
||||||
|
{
|
||||||
|
FuncsStr = d.Funcs.ToString(),
|
||||||
|
Brand = dt.Brand,
|
||||||
|
Type = d.Type,
|
||||||
|
|
||||||
|
}, true)
|
||||||
|
.ToPageListAsync(request);
|
||||||
|
return offpage;
|
||||||
|
}
|
||||||
|
//在线
|
||||||
|
var ids = devices.Select(x => x.Id).ToList();
|
||||||
|
List<long> onids = ids.Except(offids).ToList();
|
||||||
|
|
||||||
|
var page = await _dbContext.Queryable<DeviceEntity>()
|
||||||
|
.LeftJoin<DeviceTemplateEntity>((d, dt) => d.TemplateCode == dt.Code)
|
||||||
|
.Where(d => d.Type == DeviceTypeEnumType.Door)
|
||||||
|
.Where(d => onids.Contains(d.Id))
|
||||||
|
.Select((d, dt) => new DevicePageResponse
|
||||||
|
{
|
||||||
|
FuncsStr = d.Funcs.ToString(),
|
||||||
|
Brand = dt.Brand,
|
||||||
|
Type = d.Type,
|
||||||
|
|
||||||
|
}, true)
|
||||||
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<RecentNumberResponse>> GetRecentNumbersAsync()
|
||||||
{
|
{
|
||||||
//获取近30天并转化为"yyyy-MM-dd"集合
|
//获取近30天并转化为"yyyy-MM-dd"集合
|
||||||
DateTime currentDate = DateTime.Now;
|
DateTime currentDate = DateTime.Now;
|
||||||
@@ -258,15 +484,84 @@ public class DeviceService : IDeviceService
|
|||||||
times.Add(dateString);
|
times.Add(dateString);
|
||||||
}
|
}
|
||||||
|
|
||||||
var devices = await _dbContext.Queryable<DeviceEntity>().ToListAsync();
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync();
|
||||||
|
|
||||||
var dic = new Dictionary<string, int>();
|
var list = new List<RecentNumberResponse>();
|
||||||
times.ForEach(time =>
|
times.ForEach(time =>
|
||||||
{
|
{
|
||||||
var count = devices.Where(x => x.CreateTime.ToString("yyyy-MM-dd") == time).Count();
|
var count = devices.Where(x => x.CreateTime.ToString("yyyy-MM-dd") == time).Count();
|
||||||
dic[time] = count;
|
var res = new RecentNumberResponse
|
||||||
|
{
|
||||||
|
Date = time,
|
||||||
|
Num = count,
|
||||||
|
};
|
||||||
|
list.Add(res);
|
||||||
});
|
});
|
||||||
return dic;
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
private List<ImportDeviceSaveRequest> ImportFromExcel(IFormFile formFile)
|
||||||
|
{
|
||||||
|
var requests = new List<ImportDeviceSaveRequest>();
|
||||||
|
|
||||||
|
using (var stream = formFile.OpenReadStream())
|
||||||
|
{
|
||||||
|
XSSFWorkbook workbook = new XSSFWorkbook(stream);
|
||||||
|
ISheet sheet = workbook.GetSheetAt(0);
|
||||||
|
|
||||||
|
for (int rowIdx = 1; rowIdx <= sheet.LastRowNum; rowIdx++)
|
||||||
|
{
|
||||||
|
IRow row = sheet.GetRow(rowIdx);
|
||||||
|
if (row == null) continue;
|
||||||
|
|
||||||
|
var request = new ImportDeviceSaveRequest();
|
||||||
|
|
||||||
|
request.UniqueNo = row.GetCell(0).ToString();
|
||||||
|
request.TemplateCode = Guid.Parse(row.GetCell(1).ToString());
|
||||||
|
request.Supplier = row.GetCell(2).ToString();
|
||||||
|
|
||||||
|
var funs = new List<DeviceFuncEnumType>();
|
||||||
|
var fs = row.GetCell(3).ToString().Split(',');
|
||||||
|
foreach (string str in fs)
|
||||||
|
{
|
||||||
|
switch (str)
|
||||||
|
{
|
||||||
|
case "1":
|
||||||
|
funs.Add(DeviceFuncEnumType.Face);
|
||||||
|
break;
|
||||||
|
case "2":
|
||||||
|
funs.Add(DeviceFuncEnumType.Card);
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
funs.Add(DeviceFuncEnumType.QrCode);
|
||||||
|
break;
|
||||||
|
case "4":
|
||||||
|
funs.Add(DeviceFuncEnumType.Control);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.Funcs = funs;
|
||||||
|
request.Type = (DeviceTypeEnumType)Enum.Parse(typeof(DeviceTypeEnumType), row.GetCell(4).ToString());
|
||||||
|
request.HeartbeatInterval = int.Parse(row.GetCell(5).ToString());
|
||||||
|
request.DeployPlace = row.GetCell(6).ToString();
|
||||||
|
request.DeployPosition = row.GetCell(7).ToString();
|
||||||
|
request.DeployDirection = row.GetCell(8).ToString();
|
||||||
|
request.ConnectionInfo = row.GetCell(9).ToString();
|
||||||
|
request.Enable = Convert.ToBoolean(Convert.ToInt32(row.GetCell(10).ToString()));
|
||||||
|
request.AsAttendance = Convert.ToBoolean(Convert.ToInt32(row.GetCell(11).ToString()));
|
||||||
|
if (row.GetCell(12) != null)
|
||||||
|
{
|
||||||
|
request.PlaceeCode = Guid.Parse(row.GetCell(12)?.ToString());
|
||||||
|
}
|
||||||
|
requests.Add(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return requests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class DeviceTemplateService : IDeviceTemplateService
|
|||||||
{
|
{
|
||||||
var entity = await _dbContext.Queryable<DeviceTemplateEntity>().Where(x => x.Id == request.Id).FirstAsync();
|
var entity = await _dbContext.Queryable<DeviceTemplateEntity>().Where(x => x.Id == request.Id).FirstAsync();
|
||||||
await ExistsDeviceUsingTemplateAsync(entity.Code);
|
await ExistsDeviceUsingTemplateAsync(entity.Code);
|
||||||
|
request.Adapt(entity);
|
||||||
await _dbContext.UpdateAsync(entity);
|
await _dbContext.UpdateAsync(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Kurisu.AspNetCore" Version="0.5.2" />
|
<PackageReference Include="Kurisu.AspNetCore" Version="0.6.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="6.0.26" />
|
<PackageReference Include="NPOI" Version="2.6.2" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -28,4 +27,8 @@
|
|||||||
<ProjectReference Include="..\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj" />
|
<ProjectReference Include="..\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Summary\Request\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using Dlhis.Basic.Organization.Request;
|
||||||
|
using Dlhis.Basic.Organization.Response;
|
||||||
|
using Dlhis.Basic.Organization.Services;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Organization.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 档案卡记录
|
||||||
|
/// </summary>
|
||||||
|
[Authorize]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class GainfoCardsController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IGainfoCardService _gainfoCardService;
|
||||||
|
|
||||||
|
public GainfoCardsController(IGainfoCardService gainfoCardService)
|
||||||
|
{
|
||||||
|
_gainfoCardService = gainfoCardService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 换卡
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("change")]
|
||||||
|
[Transactional]
|
||||||
|
public async Task ChangeCardAsync(ChangeCardRequest request)
|
||||||
|
{
|
||||||
|
await _gainfoCardService.ChangeCardAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 换卡记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userNo"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("records")]
|
||||||
|
public async Task<List<ChangeCardResponse>> GetChangeRecordsAsync(string userNo)
|
||||||
|
{
|
||||||
|
return await _gainfoCardService.GetChangeRecordsAsync(userNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using Dlhis.Basic.Organization.Request;
|
using Dlhis.Basic.Organization.Request;
|
||||||
using Dlhis.Basic.Organization.Response;
|
using Dlhis.Basic.Organization.Response;
|
||||||
using Dlhis.Basic.Organization.Services;
|
using Dlhis.Basic.Organization.Services;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
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;
|
||||||
|
|
||||||
@@ -25,24 +25,14 @@ public class GainfoGroupsController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取档案组分页
|
/// 获取档案分组树
|
||||||
/// </summary>
|
|
||||||
/// <param name="request"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("page")]
|
|
||||||
public async Task<Pagination<GainfoGroupResponse>> GetPageAsync([FromQuery] GainfoGroupPageRequest request)
|
|
||||||
{
|
|
||||||
return await _gainfoGroupService.GetPageAsync(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取所有档案组
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("list")]
|
[HttpGet("tree")]
|
||||||
public async Task<List<GainfoGroupResponse>> GetListAsync()
|
[IgnoreTenant]
|
||||||
|
public async Task<List<GainfoGroupTreeResponse>> GetTreeAsync()
|
||||||
{
|
{
|
||||||
return await _gainfoGroupService.GetListAsync();
|
return await _gainfoGroupService.GetTreeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -50,7 +40,7 @@ public class GainfoGroupsController : ControllerBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost("save")]
|
||||||
public async Task SaveAsync(GainfoGroupSaveRequest request)
|
public async Task SaveAsync(GainfoGroupSaveRequest request)
|
||||||
{
|
{
|
||||||
await _gainfoGroupService.SaveAsync(request);
|
await _gainfoGroupService.SaveAsync(request);
|
||||||
@@ -73,6 +63,8 @@ public class GainfoGroupsController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("assign")]
|
[HttpPost("assign")]
|
||||||
|
[IgnoreTenant]
|
||||||
|
[Transactional]
|
||||||
public async Task AssignGainfosAsync(GainfoAssignRequest request)
|
public async Task AssignGainfosAsync(GainfoAssignRequest request)
|
||||||
{
|
{
|
||||||
await _gainfoGroupService.AssignGainfosAsync(request);
|
await _gainfoGroupService.AssignGainfosAsync(request);
|
||||||
|
|||||||
@@ -2,12 +2,10 @@
|
|||||||
using Dlhis.Basic.Organization.Request;
|
using Dlhis.Basic.Organization.Request;
|
||||||
using Dlhis.Basic.Organization.Response;
|
using Dlhis.Basic.Organization.Response;
|
||||||
using Dlhis.Basic.Organization.Services;
|
using Dlhis.Basic.Organization.Services;
|
||||||
using Dlhis.Entity.Basic.Entity;
|
|
||||||
using Kurisu.AspNetCore.MVC;
|
using Kurisu.AspNetCore.MVC;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Org.BouncyCastle.Asn1.Ocsp;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.MealUser.Controllers;
|
namespace Dlhis.Basic.MealUser.Controllers;
|
||||||
|
|
||||||
@@ -43,8 +41,8 @@ public class GainfosController : ControllerBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("page")]
|
[HttpPost("page")]
|
||||||
public async Task<Pagination<GainfoPageResponse>> GetPageAsync([FromQuery] GainfoPageRequest request)
|
public async Task<Pagination<GainfoPageResponse>> GetPageAsync(GainfoPageRequest request)
|
||||||
{
|
{
|
||||||
return await _gainfoService.GetPageAsync(request);
|
return await _gainfoService.GetPageAsync(request);
|
||||||
}
|
}
|
||||||
@@ -102,6 +100,17 @@ public class GainfosController : ControllerBase
|
|||||||
await _gainfoService.UploadFaceAsync(request);
|
await _gainfoService.UploadFaceAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量上传人脸照片
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("batchface")]
|
||||||
|
public async Task UploadFaceAsync(List<GainfoUploadFaceRequest> request)
|
||||||
|
{
|
||||||
|
await _gainfoService.UploadFacesAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 通过token获取人脸照片,失效或者找不到返回HttpStatus404状态码
|
/// 通过token获取人脸照片,失效或者找不到返回HttpStatus404状态码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -142,72 +151,21 @@ public class GainfosController : ControllerBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("gainfolist")]
|
[HttpGet("list")]
|
||||||
public async Task<Pagination<GainfoListResponse>> GetGainfoListTaskAsync([FromQuery]GainfoListRequest request)
|
public async Task<Pagination<GainfoListResponse>> GetGainfoListTaskAsync([FromQuery] GainfoListRequest request)
|
||||||
{
|
{
|
||||||
return await _gainfoService.GetGainfoListTaskAsync(request);
|
return await _gainfoService.GetGainfoListAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 档案详情
|
/// 档案详情
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("gainfodetail")]
|
[HttpGet("detail")]
|
||||||
public async Task<GainfoDetailResponse> GetGainfoDetailTaskAsync([FromQuery] GainfoDetailRequest request)
|
public async Task<GainfoDetailResponse> GetGainfoDetailAsync([FromQuery] GainfoDetailRequest request)
|
||||||
{
|
{
|
||||||
return await _gainfoService.GetGainfoDetailTaskAsync(request);
|
return await _gainfoService.GetGainfoDetailAsync(request);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取近七天入职人数及列表
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("weeknumber")]
|
|
||||||
public async Task<Dictionary<string, Pagination<GainfoDetailResponse>>> GetWeekNumberAsync([FromQuery] WeekNumberRequest request)
|
|
||||||
{
|
|
||||||
// 从请求头中获取 Token
|
|
||||||
string token = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
|
||||||
|
|
||||||
return await _gainfoService.GetWeekNumberAsync(request,token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取近七天离职人数及列表
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("weeknumberdimission")]
|
|
||||||
public async Task<Dictionary<string, Pagination<GainfoDetailResponse>>> GetDimissionWeekNumberAsync([FromQuery] WeekNumberRequest request)
|
|
||||||
{
|
|
||||||
// 从请求头中获取 Token
|
|
||||||
string token = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
|
||||||
|
|
||||||
return await _gainfoService.GetDimissionWeekNumberAsync(request,token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取基地在职、离职、考勤数
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("gainfonumbers")]
|
|
||||||
public async Task<GainfoGainfoNumbersResponse> GetGainfoNumbersAsync()
|
|
||||||
{
|
|
||||||
// 从请求头中获取 Token
|
|
||||||
string token = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
|
||||||
|
|
||||||
return await _gainfoService.GetGainfoNumbersAsync(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取本基地管理员列表
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("administrator")]
|
|
||||||
public async Task<Pagination<GainfoDetailResponse>> GetAdministratorAsync([FromQuery] WeekNumberRequest request)
|
|
||||||
{
|
|
||||||
// 从请求头中获取 Token
|
|
||||||
string token = HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
|
||||||
return await _gainfoService.GetAdministratorAsync(request,token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
17
Src/Dlhis.Basic/Organization/Request/ChangeCardRequest.cs
Normal file
17
Src/Dlhis.Basic/Organization/Request/ChangeCardRequest.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Organization.Request;
|
||||||
|
|
||||||
|
public class ChangeCardRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string UserNo { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string CardNo { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string Reason { get; set; }
|
||||||
|
|
||||||
|
public string Remark { get; set; }
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Request
|
|
||||||
{
|
|
||||||
public class DepartmentPageRequest : PageDto
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,25 @@
|
|||||||
using Dlhis.Entity.Basic.Enums;
|
using Dlhis.Entity.Basic.Enums;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
using SqlSugar;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Request
|
namespace Dlhis.Basic.Organization.Request;
|
||||||
{
|
|
||||||
public class GainfoDetailRequest : PageDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 档案类型
|
|
||||||
/// </summary>
|
|
||||||
[Required]
|
|
||||||
[EnumDataType(typeof(GainfoStatusEnumType))]
|
|
||||||
public GainfoStatusEnumType Status { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
public class GainfoDetailRequest
|
||||||
/// 档案号
|
{
|
||||||
/// </summary>
|
/// <summary>
|
||||||
[Required]
|
/// 档案类型
|
||||||
public string No { get; set; }
|
/// </summary>
|
||||||
}
|
[Required]
|
||||||
|
[EnumDataType(typeof(GainfoStatusEnumType))]
|
||||||
|
public GainfoStatusEnumType Status { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 档案号
|
||||||
|
/// </summary>
|
||||||
|
[Required]
|
||||||
|
public string No { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否需要人脸信息
|
||||||
|
/// </summary>
|
||||||
|
public bool WithFace { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Request;
|
|
||||||
|
|
||||||
public class GainfoGroupPageRequest: PageDto
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,11 @@ public class GainfoGroupSaveRequest
|
|||||||
{
|
{
|
||||||
public long? Id { get; set; }
|
public long? Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上级
|
||||||
|
/// </summary>
|
||||||
|
public Guid? PCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 名称
|
/// 名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ public class GainfoPageRequest : PageDto
|
|||||||
/// 档案类型
|
/// 档案类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[EnumDataType(typeof(GainfoStatusEnumType))]
|
[EnumDataType(typeof(GainfoStatusEnumType))]
|
||||||
public GainfoStatusEnumType Status { get; set; } = GainfoStatusEnumType.Working;
|
public GainfoStatusEnumType? Status { get; set; } = GainfoStatusEnumType.Working;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 部门号(部门树传入)
|
/// 部门选择
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> DepartmentNos { get; set; }
|
public List<TenantDepartmentRequest> DepartmentSelections { get; set; } = new List<TenantDepartmentRequest>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,11 +110,6 @@ public class GainfoSaveRequest : IValidatableObject
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Werks { get; set; }
|
public string Werks { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在职状态
|
|
||||||
/// </summary>
|
|
||||||
public string Employed { get; set; }
|
|
||||||
|
|
||||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||||
{
|
{
|
||||||
if (GainfoStatus.HasValue && GainfoStatus == GainfoStatusEnumType.Leave)
|
if (GainfoStatus.HasValue && GainfoStatus == GainfoStatusEnumType.Leave)
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Organization.Request;
|
||||||
|
|
||||||
|
public class TenantDepartmentRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string Tenant { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 部门号(部门树传入)
|
||||||
|
/// </summary>
|
||||||
|
public List<string> DepartmentNos { get; set; }
|
||||||
|
}
|
||||||
15
Src/Dlhis.Basic/Organization/Response/ChangeCardResponse.cs
Normal file
15
Src/Dlhis.Basic/Organization/Response/ChangeCardResponse.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Dlhis.Basic.Organization.Response;
|
||||||
|
|
||||||
|
public class ChangeCardResponse
|
||||||
|
{
|
||||||
|
public string UserNo { get; set; }
|
||||||
|
public string UserCode { get; set; }
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public string CardNo { get; set; }
|
||||||
|
|
||||||
|
public string Reason { get; set; }
|
||||||
|
|
||||||
|
public string Remark { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
}
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
namespace Dlhis.Basic.Organization.Response;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Organization.Response;
|
||||||
|
|
||||||
public class DepartmentTreeResponse
|
public class DepartmentTreeResponse
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 上级
|
||||||
|
/// </summary>
|
||||||
|
public string PNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 部门号
|
/// 部门号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -12,8 +19,24 @@ public class DepartmentTreeResponse
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public string Tenant { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下级部门
|
/// 下级部门
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<DepartmentTreeResponse> Next { get; set; } = new List<DepartmentTreeResponse>();
|
[JsonIgnore]
|
||||||
|
public List<DepartmentTreeResponse> _Next { get; set; } = new List<DepartmentTreeResponse>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下级部门
|
||||||
|
/// </summary>
|
||||||
|
public List<DepartmentTreeResponse> Next
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
_Next.ForEach(x => x.Tenant = Tenant);
|
||||||
|
return _Next;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,114 +1,125 @@
|
|||||||
using Dlhis.Entity.Basic.Enums;
|
using Dlhis.Entity.Basic.Enums;
|
||||||
using SqlSugar;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using SqlSugar.DbConvert;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Response
|
namespace Dlhis.Basic.Organization.Response;
|
||||||
|
|
||||||
|
public class GainfoDetailResponse
|
||||||
{
|
{
|
||||||
public class GainfoDetailResponse
|
/// <summary>
|
||||||
{
|
/// 档案号
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// 档案号
|
public string No { get; set; }
|
||||||
/// </summary>
|
|
||||||
public string No { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SAP内部编号
|
/// SAP内部编号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SapNo { get; set; }
|
public string SapNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 姓名
|
/// 姓名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 学工号
|
/// 学工号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Code { get; set; }
|
public string Code { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 部门名称
|
/// 部门名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DepartmentName { get; set; }
|
public string DepartmentName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 证件类型代码
|
/// 证件类型代码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string IdClass { get; set; }
|
public string IdClass { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 身份证号
|
/// 证件类型名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string IdNo { get; set; }
|
public string ClassName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 性别
|
/// 身份证号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GenderEnumType Gender { get; set; }
|
public string IdNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 身份证籍贯
|
/// 性别
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string NativeName { get; set; }
|
public GenderEnumType Gender { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 身份证地址
|
/// 性别描述
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Address { get; set; }
|
public string GenderCN => Gender.GetDescription();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生日
|
/// 身份证籍贯
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime Birthday { get; set; }
|
public string NativeName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 手机号码
|
/// 身份证地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Phone { get; set; }
|
public string Address { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 岗位
|
/// 生日
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Position { get; set; }
|
public DateTime Birthday { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 职等
|
/// 手机号码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Grade { get; set; }
|
public string Phone { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 学历
|
/// 岗位
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Degree { get; set; }
|
public string Position { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 人事范围
|
/// 职等
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Werks { get; set; }
|
public string Grade { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 成本中心
|
/// 学历
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CostId { get; set; }
|
public string Degree { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 已婚/未婚
|
/// 人事范围
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Marital { get; set; }
|
public string Werks { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 国家
|
/// 成本中心
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CountryName { get; set; }
|
public string CostId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 已婚/未婚
|
||||||
|
/// </summary>
|
||||||
|
public string Marital { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 国家
|
||||||
|
/// </summary>
|
||||||
|
public string CountryName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 民族代码
|
||||||
|
/// </summary>
|
||||||
|
public string NationName { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 人脸base64
|
||||||
|
/// </summary>
|
||||||
|
public string Face { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 民族代码
|
|
||||||
/// </summary>
|
|
||||||
public string NationName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否在职
|
|
||||||
/// </summary>
|
|
||||||
public bool IsActive { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
namespace Dlhis.Basic.Organization.Response;
|
|
||||||
|
|
||||||
public class GainfoGroupResponse
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 分组code
|
|
||||||
/// </summary>
|
|
||||||
public Guid Code { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 名称
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 备注
|
|
||||||
/// </summary>
|
|
||||||
public string Remark { get; set; }
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Organization.Response;
|
||||||
|
|
||||||
|
public class GainfoGroupTreeResponse
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
public Guid? PCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分组code
|
||||||
|
/// </summary>
|
||||||
|
public Guid Code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 备注
|
||||||
|
/// </summary>
|
||||||
|
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]
|
||||||
|
public string TenantId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下级数据
|
||||||
|
/// </summary>
|
||||||
|
public List<GainfoGroupTreeResponse> Next { get; set; }
|
||||||
|
}
|
||||||
@@ -1,60 +1,51 @@
|
|||||||
using Dlhis.Entity.Basic.Enums;
|
using Dlhis.Entity.Basic.Enums;
|
||||||
using SqlSugar;
|
|
||||||
using SqlSugar.DbConvert;
|
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Response
|
namespace Dlhis.Basic.Organization.Response;
|
||||||
|
|
||||||
|
public class GainfoListResponse
|
||||||
{
|
{
|
||||||
public class GainfoListResponse
|
/// <summary>
|
||||||
{
|
/// 档案号
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// 档案号
|
public string No { get; set; }
|
||||||
/// </summary>
|
|
||||||
public string No { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 姓名
|
/// 姓名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 学工号
|
/// 学工号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Code { get; set; }
|
public string Code { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 身份证号
|
/// 身份证号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string IdNo { get; set; }
|
public string IdNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 性别
|
/// 性别
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GenderEnumType Gender { get; set; }
|
public GenderEnumType Gender { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 手机号码
|
/// 手机号码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Phone { get; set; }
|
public string Phone { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 部门编码
|
/// 部门编码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DepartmentNo { get; set; }
|
public string DepartmentNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 部门名称
|
/// 部门名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DepartmentName { get; set; }
|
public string DepartmentName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 身份证地址
|
/// 身份证地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Address { get; set; }
|
public string Address { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在职状态
|
|
||||||
/// </summary>
|
|
||||||
public string Employed { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
namespace Dlhis.Basic.Organization.Response;
|
using Dlhis.Entity.Basic.Enums;
|
||||||
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Organization.Response;
|
||||||
|
|
||||||
public class GainfoPageResponse
|
public class GainfoPageResponse
|
||||||
{
|
{
|
||||||
@@ -52,7 +55,8 @@ public class GainfoPageResponse
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 性别
|
/// 性别
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Gender { get; set; }
|
public GenderEnumType Gender { get; set; }
|
||||||
|
public string GenderDesc => Gender.GetDescription();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生日
|
/// 生日
|
||||||
@@ -108,9 +112,4 @@ public class GainfoPageResponse
|
|||||||
/// 人事范围
|
/// 人事范围
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Werks { get; set; }
|
public string Werks { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在职状态
|
|
||||||
/// </summary>
|
|
||||||
public string Employed { 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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
Src/Dlhis.Basic/Organization/Services/IGainfoCardService.cs
Normal file
11
Src/Dlhis.Basic/Organization/Services/IGainfoCardService.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Dlhis.Basic.Organization.Request;
|
||||||
|
using Dlhis.Basic.Organization.Response;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Organization.Services;
|
||||||
|
|
||||||
|
public interface IGainfoCardService
|
||||||
|
{
|
||||||
|
Task ChangeCardAsync(ChangeCardRequest request);
|
||||||
|
|
||||||
|
Task<List<ChangeCardResponse>> GetChangeRecordsAsync(string userNo);
|
||||||
|
}
|
||||||
@@ -1,14 +1,11 @@
|
|||||||
using Dlhis.Basic.Organization.Request;
|
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 IGainfoGroupService : IScopeDependency
|
public interface IGainfoGroupService : IScopeDependency
|
||||||
{
|
{
|
||||||
Task<Pagination<GainfoGroupResponse>> GetPageAsync(GainfoGroupPageRequest request);
|
Task<List<GainfoGroupTreeResponse>> GetTreeAsync();
|
||||||
|
|
||||||
Task<List<GainfoGroupResponse>> GetListAsync();
|
|
||||||
|
|
||||||
Task SaveAsync(GainfoGroupSaveRequest request);
|
Task SaveAsync(GainfoGroupSaveRequest request);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Dlhis.Basic.Organization.Request;
|
using Dlhis.Basic.Organization.Request;
|
||||||
using Dlhis.Basic.Organization.Response;
|
using Dlhis.Basic.Organization.Response;
|
||||||
using Dlhis.Entity.Basic.Entity;
|
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
@@ -22,21 +21,15 @@ public interface IGainfoService : IScopeDependency
|
|||||||
|
|
||||||
Task UploadFaceAsync(GainfoUploadFaceRequest request);
|
Task UploadFaceAsync(GainfoUploadFaceRequest request);
|
||||||
|
|
||||||
|
Task UploadFacesAsync(List<GainfoUploadFaceRequest> request);
|
||||||
|
|
||||||
Task<IActionResult> GetFaceAsync(string token);
|
Task<IActionResult> GetFaceAsync(string token);
|
||||||
|
|
||||||
Task<string> GetFaceByUserCodeAsync(string userCode);
|
Task<string> GetFaceByUserCodeAsync(string userCode);
|
||||||
|
|
||||||
Task<Dictionary<string, string>> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request);
|
Task<Dictionary<string, string>> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request);
|
||||||
|
|
||||||
Task<Pagination<GainfoListResponse>> GetGainfoListTaskAsync(GainfoListRequest request);
|
Task<Pagination<GainfoListResponse>> GetGainfoListAsync(GainfoListRequest request);
|
||||||
|
|
||||||
Task<GainfoDetailResponse> GetGainfoDetailTaskAsync(GainfoDetailRequest request);
|
Task<GainfoDetailResponse> GetGainfoDetailAsync(GainfoDetailRequest request);
|
||||||
|
|
||||||
Task<Dictionary<string, Pagination<GainfoDetailResponse>>> GetWeekNumberAsync(WeekNumberRequest request, string token);
|
|
||||||
|
|
||||||
Task<Dictionary<string, Pagination<GainfoDetailResponse>>> GetDimissionWeekNumberAsync([FromQuery] WeekNumberRequest request, string token);
|
|
||||||
|
|
||||||
Task<GainfoGainfoNumbersResponse> GetGainfoNumbersAsync(string token);
|
|
||||||
|
|
||||||
Task<Pagination<GainfoDetailResponse>> GetAdministratorAsync(WeekNumberRequest request,string token);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Dlhis.Basic.Organization.Services;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IGainfoStore : IScopeDependency
|
public interface IGainfoStore : IScopeDependency
|
||||||
{
|
{
|
||||||
ISugarQueryable<GainfoEntity> Queryable(GainfoStatusEnumType? gainfoStatus);
|
ISugarQueryable<GainfoEntity> Queryable(GainfoStatusEnumType? gainfoStatus = null);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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,73 +1,60 @@
|
|||||||
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 Dlhis.Sys.Api;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
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 ITenantApi _tenantApi;
|
||||||
|
|
||||||
public DepartmentService(IDbContext dbContext)
|
public DepartmentService(IDbContext dbContext, ITenantApi tenantApi)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
|
_tenantApi = tenantApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<DepartmentTreeResponse>> GetTreeAsync()
|
public async Task<List<DepartmentTreeResponse>> GetTreeAsync()
|
||||||
{
|
{
|
||||||
var departments = await _dbContext.Queryable<DepartmentEntity>().ToListAsync();
|
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 =>
|
||||||
{
|
{
|
||||||
RecursionGetNext(x, departments);
|
RecursionGetNext(x, departments);
|
||||||
});
|
});
|
||||||
|
|
||||||
return tops;
|
var myTenantResult = await _tenantApi.GetMyTenantsAsync();
|
||||||
|
var tenants = myTenantResult.Data;
|
||||||
|
|
||||||
|
return tenants.Select(x => new DepartmentTreeResponse
|
||||||
|
{
|
||||||
|
Name = x.Name,
|
||||||
|
No = x.Code,
|
||||||
|
PNo = x.PCode,
|
||||||
|
Tenant = x.Code,
|
||||||
|
_Next = tops.Select(item =>
|
||||||
|
{
|
||||||
|
var i = item.Adapt<DepartmentTreeResponse>();
|
||||||
|
i.PNo = x.Code;
|
||||||
|
return i;
|
||||||
|
|
||||||
|
}).ToList()
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using Dlhis.Basic.Organization.Request;
|
||||||
|
using Dlhis.Basic.Organization.Response;
|
||||||
|
using Dlhis.Entity.Basic.Entity;
|
||||||
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
|
using Kurisu.SqlSugar.Services;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Organization.Services.Implements;
|
||||||
|
|
||||||
|
public class GainfoCardService : IGainfoCardService
|
||||||
|
{
|
||||||
|
private readonly IDbContext _dbContext;
|
||||||
|
private readonly IGainfoStore _gainfoStore;
|
||||||
|
|
||||||
|
public GainfoCardService(IDbContext dbContext, IGainfoStore gainfoStore)
|
||||||
|
{
|
||||||
|
_dbContext = dbContext;
|
||||||
|
_gainfoStore = gainfoStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ChangeCardAsync(ChangeCardRequest request)
|
||||||
|
{
|
||||||
|
var gainfo = await _gainfoStore.Queryable().Where(x => x.No == request.UserNo).FirstAsync();
|
||||||
|
gainfo.ThrowIfNull("档案不存在");
|
||||||
|
|
||||||
|
gainfo.CardNo = request.CardNo;
|
||||||
|
|
||||||
|
await _gainfoStore.UpdateAsync(gainfo);
|
||||||
|
await _dbContext.InsertAsync(new GainfoCardRecordEntity
|
||||||
|
{
|
||||||
|
UserNo = request.UserNo,
|
||||||
|
CardNo = request.CardNo,
|
||||||
|
Reason = request.Reason,
|
||||||
|
Remark = request.Remark,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<ChangeCardResponse>> GetChangeRecordsAsync(string userNo)
|
||||||
|
{
|
||||||
|
return await _dbContext.Queryable<GainfoCardRecordEntity>()
|
||||||
|
.LeftJoin<GainfoEntity>((x, ga) => x.UserNo == ga.No)
|
||||||
|
.Where(x => x.UserNo == userNo)
|
||||||
|
.Select((x, ga) => new ChangeCardResponse
|
||||||
|
{
|
||||||
|
UserNo = x.UserNo,
|
||||||
|
UserCode = ga.Code,
|
||||||
|
UserName = ga.Name,
|
||||||
|
CardNo = x.CardNo,
|
||||||
|
Reason = x.Reason,
|
||||||
|
Remark = x.Remark,
|
||||||
|
CreateTime = x.CreateTime,
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
using Dlhis.Basic.Organization.Request;
|
using Dlhis.Basic.Device.Services;
|
||||||
|
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.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Entity;
|
||||||
using Kurisu.SqlSugar.Extensions;
|
using Kurisu.Core.User.Abstractions;
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
|
|
||||||
@@ -12,30 +13,50 @@ namespace Dlhis.Basic.Organization.Services.Implements;
|
|||||||
public class GainfoGroupService : IGainfoGroupService
|
public class GainfoGroupService : IGainfoGroupService
|
||||||
{
|
{
|
||||||
private readonly IDbContext _dbContext;
|
private readonly IDbContext _dbContext;
|
||||||
|
private readonly ICurrentUser _currentUser;
|
||||||
|
private readonly IDevicePermissionService _devicePermissionService;
|
||||||
|
|
||||||
public GainfoGroupService(IDbContext dbContext)
|
public GainfoGroupService(IDbContext dbContext, ICurrentUser currentUser, IDevicePermissionService devicePermissionService)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
|
_currentUser = currentUser;
|
||||||
|
_devicePermissionService = devicePermissionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Pagination<GainfoGroupResponse>> GetPageAsync(GainfoGroupPageRequest request)
|
public async Task<List<GainfoGroupTreeResponse>> GetTreeAsync()
|
||||||
{
|
{
|
||||||
return await _dbContext.Queryable<GainfoGroupEntity>()
|
var gainfoGroups = await _dbContext.Queryable<GainfoGroupEntity>()
|
||||||
.Select<GainfoGroupResponse>()
|
.Select<GainfoGroupTreeResponse>()
|
||||||
.ToPageListAsync(request);
|
.ToListAsync();
|
||||||
}
|
|
||||||
|
|
||||||
|
var tops = gainfoGroups.Where(x => !x.PCode.HasValue).ToList();
|
||||||
|
tops.ForEach(x =>
|
||||||
|
{
|
||||||
|
RecursionGetNext(x, gainfoGroups);
|
||||||
|
});
|
||||||
|
|
||||||
public async Task<List<GainfoGroupResponse>> GetListAsync()
|
return tops;
|
||||||
{
|
|
||||||
return await _dbContext.Queryable<GainfoGroupEntity>()
|
|
||||||
.Select<GainfoGroupResponse>()
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveAsync(GainfoGroupSaveRequest request)
|
public async Task SaveAsync(GainfoGroupSaveRequest request)
|
||||||
{
|
{
|
||||||
await CheckDuplicateNameAsync(request);
|
await CheckDuplicateNameAsync(request);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//todo
|
||||||
|
_dbContext.Client.QueryFilter.ClearAndBackup<ITenantId>();
|
||||||
|
var defaultGroup = await _dbContext.Queryable<GainfoGroupEntity>().Where(x => x.IsDefault).FirstAsync();
|
||||||
|
|
||||||
|
if (!request.PCode.HasValue)
|
||||||
|
{
|
||||||
|
request.PCode = defaultGroup.Code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_dbContext.Client.QueryFilter.Restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!request.Id.HasValue)
|
if (!request.Id.HasValue)
|
||||||
{
|
{
|
||||||
@@ -47,7 +68,6 @@ public class GainfoGroupService : IGainfoGroupService
|
|||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
await _dbContext.UpdateAsync(entity);
|
await _dbContext.UpdateAsync(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,18 +89,32 @@ public class GainfoGroupService : IGainfoGroupService
|
|||||||
|
|
||||||
public async Task AssignGainfosAsync(GainfoAssignRequest request)
|
public async Task AssignGainfosAsync(GainfoAssignRequest request)
|
||||||
{
|
{
|
||||||
var relations = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().Where(x => x.GroupCode == request.GroupCode).ToListAsync();
|
if (request.UserNos.IsPresent())
|
||||||
await _dbContext.DeleteReallyAsync(relations);
|
|
||||||
|
|
||||||
request.UserNos = await _dbContext.Queryable<GainfoEntity>().Where(x => request.UserNos.Contains(x.No)).Select(x => x.No).ToListAsync();
|
|
||||||
var entities = request.UserNos.Select(x => new GainfoGroupRelationshipEntity
|
|
||||||
{
|
{
|
||||||
GroupCode = request.GroupCode,
|
var pGrp = await _dbContext.Queryable<GainfoGroupEntity>().Where(x => x.Code == request.GroupCode).FirstAsync();
|
||||||
UserNo = x
|
(pGrp?.Editable == false && pGrp?.IsDefault == true).ThrowIfTrue("不可分配人员到当前分组");
|
||||||
|
}
|
||||||
|
|
||||||
}).ToList();
|
var existsNextGroup = await _dbContext.Queryable<GainfoGroupEntity>().Where(x => x.PCode == request.GroupCode).AnyAsync();
|
||||||
|
existsNextGroup.ThrowIfTrue("存在下级分组,无法分配人员");
|
||||||
|
|
||||||
await _dbContext.InsertAsync(entities);
|
await _devicePermissionService.GenerateDeviceTasksAsync(async () =>
|
||||||
|
{
|
||||||
|
var relations = await _dbContext.Queryable<GainfoGroupRelationshipEntity>().Where(x => x.GroupCode == request.GroupCode).ToListAsync();
|
||||||
|
await _dbContext.DeleteReallyAsync(relations);
|
||||||
|
|
||||||
|
request.UserNos = await _dbContext.Queryable<GainfoEntity>().Where(x => request.UserNos.Contains(x.No)).Select(x => x.No).ToListAsync();
|
||||||
|
var entities = request.UserNos.Select(x => new GainfoGroupRelationshipEntity
|
||||||
|
{
|
||||||
|
GroupCode = request.GroupCode,
|
||||||
|
UserNo = x,
|
||||||
|
|
||||||
|
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
await _dbContext.InsertAsync(entities);
|
||||||
|
|
||||||
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************* help methods ***********************************************************
|
//******************************************************* help methods ***********************************************************
|
||||||
@@ -99,4 +133,32 @@ public class GainfoGroupService : IGainfoGroupService
|
|||||||
|
|
||||||
exists.ThrowIfTrue($"重复组名{request.Name}");
|
exists.ThrowIfTrue($"重复组名{request.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void RecursionGetNext(GainfoGroupTreeResponse current, List<GainfoGroupTreeResponse> gainfoGroups)
|
||||||
|
{
|
||||||
|
var currentTenantId = _currentUser.GetStringTenantId();
|
||||||
|
var next = gainfoGroups.Where(x =>
|
||||||
|
{
|
||||||
|
if (x.PCode == current.Code)
|
||||||
|
{
|
||||||
|
if (x.TenantId.IsEmpty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return x.TenantId == currentTenantId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}).ToList();
|
||||||
|
current.Next = next;
|
||||||
|
foreach (var item in next)
|
||||||
|
{
|
||||||
|
RecursionGetNext(item, gainfoGroups);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,19 +4,17 @@ using Dlhis.Basic.Organization.Response;
|
|||||||
using Dlhis.Entity.Basic.Entity;
|
using Dlhis.Entity.Basic.Entity;
|
||||||
using Dlhis.Entity.Basic.Enums;
|
using Dlhis.Entity.Basic.Enums;
|
||||||
using Dlhis.Entity.Device.Enums;
|
using Dlhis.Entity.Device.Enums;
|
||||||
using Kurisu.AspNetCore.Scope;
|
using Kurisu.AspNetCore.Utils;
|
||||||
using Kurisu.AspNetCore.UnifyResultAndValidation;
|
|
||||||
using Kurisu.AspNetCore.Utils.Extensions;
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Kurisu.Core.User.Abstractions;
|
using Kurisu.Core.User.Abstractions;
|
||||||
using Kurisu.SqlSugar.Attributes;
|
|
||||||
using Kurisu.SqlSugar.Extensions;
|
using Kurisu.SqlSugar.Extensions;
|
||||||
using Kurisu.SqlSugar.Options;
|
|
||||||
using Kurisu.SqlSugar.Services;
|
using Kurisu.SqlSugar.Services;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
namespace Dlhis.Basic.Organization.Services.Implements;
|
namespace Dlhis.Basic.Organization.Services.Implements;
|
||||||
|
|
||||||
@@ -26,18 +24,27 @@ public class GainfoService : IGainfoService
|
|||||||
private readonly IDbContext _dbContext;
|
private readonly IDbContext _dbContext;
|
||||||
private readonly ICurrentUser _currentUser;
|
private readonly ICurrentUser _currentUser;
|
||||||
private readonly IDevicePermissionService _devicePermissionService;
|
private readonly IDevicePermissionService _devicePermissionService;
|
||||||
|
private readonly RedisCache _redisCache;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
private readonly ILogger<GainfoService> _logger;
|
private readonly ILogger<GainfoService> _logger;
|
||||||
|
|
||||||
public GainfoService(IGainfoStore gainfoStore,
|
public GainfoService(IGainfoStore gainfoStore,
|
||||||
IDbContext dbContext,
|
IDbContext dbContext,
|
||||||
ICurrentUser currentUser,
|
ICurrentUser currentUser,
|
||||||
IDevicePermissionService devicePermissionService,
|
IDevicePermissionService devicePermissionService,
|
||||||
|
RedisCache redisCache,
|
||||||
|
IServiceProvider serviceProvider,
|
||||||
|
IConfiguration configuration,
|
||||||
ILogger<GainfoService> logger)
|
ILogger<GainfoService> logger)
|
||||||
{
|
{
|
||||||
_gainfoStore = gainfoStore;
|
_gainfoStore = gainfoStore;
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
_currentUser = currentUser;
|
_currentUser = currentUser;
|
||||||
_devicePermissionService = devicePermissionService;
|
_devicePermissionService = devicePermissionService;
|
||||||
|
_redisCache = redisCache;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
_configuration = configuration;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,16 +55,28 @@ public class GainfoService : IGainfoService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<Pagination<GainfoPageResponse>> GetPageAsync(GainfoPageRequest request)
|
public async Task<Pagination<GainfoPageResponse>> GetPageAsync(GainfoPageRequest request)
|
||||||
{
|
{
|
||||||
request.DepartmentNos = await GetRecursionDepartmentNosAsync(request.DepartmentNos);
|
var currentTenantId = _currentUser.GetStringTenantId();
|
||||||
|
|
||||||
var tenant = _currentUser.GetStringTenantId();
|
//根据组织架构搜索档案
|
||||||
|
Expression<Func<GainfoEntity, bool>> where = LinqExpressionExtension.False<GainfoEntity>();
|
||||||
|
foreach (var item in request.DepartmentSelections)
|
||||||
|
{
|
||||||
|
var depts = await GetRecursionDepartmentNosAsync(item.DepartmentNos);
|
||||||
|
if (depts.Any())
|
||||||
|
where = where.Or(gainfo => gainfo.Factory == item.Tenant && depts.Contains(gainfo.DepartmentNo));
|
||||||
|
else
|
||||||
|
where = where.Or(gainfo => gainfo.Factory == item.Tenant);
|
||||||
|
}
|
||||||
|
|
||||||
var page = await _gainfoStore.Queryable(request.Status)
|
var page = await _gainfoStore.Queryable(request.Status)
|
||||||
.WhereIF(request.DepartmentNos?.Any() == true, gainfo => request.DepartmentNos.Contains(gainfo.DepartmentNo))
|
.WhereIF(request.DepartmentSelections.IsPresent(), where)
|
||||||
|
.WhereIF(request.DepartmentSelections.IsEmpty(), gainfo => gainfo.Factory == currentTenantId)
|
||||||
.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)
|
||||||
.Where(gainfo => gainfo.Werks == tenant)
|
|| gainfo.IdNo.Contains(request.Search)
|
||||||
|
|| gainfo.Werks.Contains(request.Search)
|
||||||
|
)
|
||||||
.Select<GainfoPageResponse>()
|
.Select<GainfoPageResponse>()
|
||||||
.ToPageListAsync(request);
|
.ToPageListAsync(request);
|
||||||
|
|
||||||
@@ -104,7 +123,6 @@ public class GainfoService : IGainfoService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Transactional]
|
|
||||||
public async Task DimissionAsync(GainfoDimissionRequest request)
|
public async Task DimissionAsync(GainfoDimissionRequest request)
|
||||||
{
|
{
|
||||||
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
|
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
|
||||||
@@ -140,11 +158,19 @@ public class GainfoService : IGainfoService
|
|||||||
public async Task<GainfoCurrentResponse> CurrentUserInfoAsync()
|
public async Task<GainfoCurrentResponse> CurrentUserInfoAsync()
|
||||||
{
|
{
|
||||||
var identityId = _currentUser.GetIntSubjectId();
|
var identityId = _currentUser.GetIntSubjectId();
|
||||||
|
var code = _currentUser.GetUserClaim("jinko-code");
|
||||||
|
var gainfo = await _gainfoStore.Queryable().Where(x => x.Code == code).FirstAsync()
|
||||||
|
?? await _gainfoStore.Queryable().Where(x => x.IdentityUserId == identityId).FirstAsync();
|
||||||
|
|
||||||
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
|
if (gainfo == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
|
||||||
.LeftJoin<DepartmentEntity>((ga, department) => ga.DepartmentNo == department.No)
|
.LeftJoin<DepartmentEntity>((ga, department) => ga.DepartmentNo == department.No)
|
||||||
.LeftJoin<CanteenUserEntity>((ga, department, mealUser) => ga.No == mealUser.UserNo)
|
.LeftJoin<CanteenUserEntity>((ga, department, mealUser) => ga.No == mealUser.UserNo)
|
||||||
.Where((ga, department) => ga.IdentityUserId == identityId)
|
.Where((ga, department) => ga.Id == gainfo.Id)
|
||||||
.Select((ga, department, mealUser) => new GainfoCurrentResponse
|
.Select((ga, department, mealUser) => new GainfoCurrentResponse
|
||||||
{
|
{
|
||||||
UserNo = ga.No,
|
UserNo = ga.No,
|
||||||
@@ -161,49 +187,43 @@ public class GainfoService : IGainfoService
|
|||||||
})
|
})
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
|
|
||||||
return gainfo;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> GetFaceAsync(string token)
|
public async Task<IActionResult> GetFaceAsync(string token)
|
||||||
{
|
{
|
||||||
return await Scoped.Request.Value.CreateAsync<IActionResult>(async (sp) =>
|
var timeLimitedDataProtector = _serviceProvider.GetService<IDataProtectionProvider>()
|
||||||
|
.CreateProtector("down:face")
|
||||||
|
.ToTimeLimitedDataProtector();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var timeLimitedDataProtector = sp.GetService<IDataProtectionProvider>()
|
var password = timeLimitedDataProtector.Unprotect(token);
|
||||||
.CreateProtector("down:face")
|
var userCode = password.Split(':')[1];
|
||||||
.ToTimeLimitedDataProtector();
|
|
||||||
|
|
||||||
try
|
var faceCache = await _redisCache.HashGetAsync("faces", userCode);
|
||||||
|
if (faceCache.HasValue)
|
||||||
{
|
{
|
||||||
var password = timeLimitedDataProtector.Unprotect(token);
|
return new FileContentResult(Convert.FromBase64String(faceCache), "image/png");
|
||||||
var userCode = password.Split(':')[1];
|
|
||||||
|
|
||||||
var configuration = sp.GetService<IConfiguration>();
|
|
||||||
var faceConnectionString = configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value;
|
|
||||||
if (faceConnectionString.IsEmpty())
|
|
||||||
{
|
|
||||||
_logger.LogWarning("暂不支持获取人脸");
|
|
||||||
return new NotFoundResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo 切换连接字符串
|
|
||||||
var dbContext = sp.GetService<IDbContext>();
|
|
||||||
dbContext.Client.CurrentConnectionConfig.ConnectionString = faceConnectionString;
|
|
||||||
var face = await dbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == userCode).SingleAsync();
|
|
||||||
|
|
||||||
if (face == null)
|
|
||||||
{
|
|
||||||
_logger.LogWarning("学工号:{userCode}不存在人脸照片", userCode);
|
|
||||||
return new NotFoundResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FileContentResult(Convert.FromBase64String(face.Face), "image/png");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
var dbContext = _dbContext.ChangeDb("face");
|
||||||
|
var face = await dbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == userCode).SingleAsync();
|
||||||
|
|
||||||
|
if (face == null)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "获取人脸失败:" + ex.Message);
|
_logger.LogWarning("学工号:{userCode}不存在人脸照片", userCode);
|
||||||
return new NotFoundResult();
|
return new NotFoundResult();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
await _redisCache.HashSetAsync("faces", userCode, face.Face);
|
||||||
|
return new FileContentResult(Convert.FromBase64String(face.Face), "image/png");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "获取人脸失败:{message}", ex.Message);
|
||||||
|
return new NotFoundResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UploadFaceAsync(GainfoUploadFaceRequest request)
|
public async Task UploadFaceAsync(GainfoUploadFaceRequest request)
|
||||||
@@ -213,21 +233,53 @@ public class GainfoService : IGainfoService
|
|||||||
|
|
||||||
gainfo.ThrowIfNull("人员档案信息不存在");
|
gainfo.ThrowIfNull("人员档案信息不存在");
|
||||||
|
|
||||||
await Scoped.Request.Value.CreateAsync(async (sp) =>
|
var dbContext = _dbContext.ChangeDb("face");
|
||||||
|
var face = await dbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
|
||||||
|
|
||||||
|
var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update;
|
||||||
|
|
||||||
|
await _redisCache.HashSetAsync("faces", gainfo.Code, request.Face);
|
||||||
|
if (face == null)
|
||||||
{
|
{
|
||||||
var configuration = sp.GetService<IConfiguration>();
|
face = new GainfoFaceEntity
|
||||||
var faceConnectionString = configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value;
|
|
||||||
if (faceConnectionString.IsEmpty())
|
|
||||||
{
|
{
|
||||||
throw new UserFriendlyException("暂不支持人脸上传");
|
UserCode = gainfo.Code,
|
||||||
|
Face = request.Face
|
||||||
|
};
|
||||||
|
|
||||||
|
await dbContext.InsertAsync(face);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (face.Face == request.Face)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("相同的人脸照片更新忽略");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dbContext = sp.GetService<IDbContext>();
|
face.Face = request.Face;
|
||||||
//todo 切换连接字符串
|
await dbContext.UpdateAsync(face);
|
||||||
dbContext.Client.CurrentConnectionConfig.ConnectionString = faceConnectionString;
|
}
|
||||||
|
|
||||||
|
//生成任务
|
||||||
|
await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UploadFacesAsync(List<GainfoUploadFaceRequest> requests)
|
||||||
|
{
|
||||||
|
foreach (var request in requests)
|
||||||
|
{
|
||||||
|
var gainfo = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).Where(x => x.No == request.UserNo).FirstAsync();
|
||||||
|
gainfo ??= await _gainfoStore.Queryable(GainfoStatusEnumType.External).Where(x => x.No == request.UserNo).FirstAsync();
|
||||||
|
|
||||||
|
gainfo.ThrowIfNull("人员档案信息不存在");
|
||||||
|
|
||||||
|
var dbContext = _dbContext.ChangeDb("face");
|
||||||
var face = await dbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
|
var face = await dbContext.Queryable<GainfoFaceEntity>().Where(x => x.UserCode == gainfo.Code).SingleAsync();
|
||||||
|
|
||||||
var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update;
|
var taskType = face == null ? DeviceTaskEnumType.Add : DeviceTaskEnumType.Update;
|
||||||
|
|
||||||
|
await _redisCache.HashSetAsync("faces", gainfo.Code, request.Face);
|
||||||
if (face == null)
|
if (face == null)
|
||||||
{
|
{
|
||||||
face = new GainfoFaceEntity
|
face = new GainfoFaceEntity
|
||||||
@@ -252,49 +304,33 @@ public class GainfoService : IGainfoService
|
|||||||
|
|
||||||
//生成任务
|
//生成任务
|
||||||
await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType);
|
await _devicePermissionService.GenerateDeviceTasksAsync(gainfo.No, taskType);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<string> GetFaceByUserCodeAsync(string userCode)
|
public async Task<string> GetFaceByUserCodeAsync(string userCode)
|
||||||
{
|
{
|
||||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == userCode).SingleAsync();
|
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == userCode).SingleAsync();
|
||||||
gainfo.ThrowIfNull($"{userCode}人员信息不存在");
|
gainfo.ThrowIfNull($"{userCode}人员信息不存在");
|
||||||
|
|
||||||
return await Scoped.Request.Value.CreateAsync<string>(async (sp) =>
|
var dbContext = _dbContext.ChangeDb("face");
|
||||||
{
|
|
||||||
var configuration = sp.GetService<IConfiguration>();
|
|
||||||
|
|
||||||
var faceConnectionString = configuration.GetSection($"{nameof(SqlSugarOptions)}:FaceConnectionString").Value;
|
var face = await dbContext.Queryable<GainfoFaceEntity>()
|
||||||
if (faceConnectionString.IsEmpty())
|
.Where(x => x.UserCode == userCode)
|
||||||
{
|
.SingleAsync();
|
||||||
throw new UserFriendlyException("暂不支持获取人脸");
|
|
||||||
}
|
|
||||||
|
|
||||||
var dbContext = sp.GetService<IDbContext>();
|
face.ThrowIfNull("人脸照片尚未录入");
|
||||||
//todo 切换连接字符串
|
|
||||||
dbContext.Client.CurrentConnectionConfig.ConnectionString = faceConnectionString;
|
|
||||||
|
|
||||||
var face = await dbContext.Queryable<GainfoFaceEntity>()
|
var timeLimitedDataProtector = _serviceProvider.GetService<IDataProtectionProvider>()
|
||||||
.Where(x => x.UserCode == userCode)
|
.CreateProtector("down:face")
|
||||||
.SingleAsync();
|
.ToTimeLimitedDataProtector();
|
||||||
|
|
||||||
face.ThrowIfNull("人脸照片尚未录入");
|
var faceUrl = _configuration.GetSection("FaceUrlOptions:Url").Value;
|
||||||
|
var limit = _configuration.GetSection("FaceUrlOptions:Limit").Get<int>();
|
||||||
|
|
||||||
var timeLimitedDataProtector = sp.GetService<IDataProtectionProvider>()
|
var key = $"face:{userCode}";
|
||||||
.CreateProtector("down:face")
|
var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit));
|
||||||
.ToTimeLimitedDataProtector();
|
|
||||||
|
|
||||||
var faceUrl = configuration.GetSection("FaceUrlOptions:Url").Value;
|
return faceUrl + token;
|
||||||
var limit = configuration.GetSection("FaceUrlOptions:Limit").Get<int>();
|
|
||||||
var dataProtectionProvider = sp.GetService<IDataProtectionProvider>();
|
|
||||||
|
|
||||||
var key = $"face:{userCode}";
|
|
||||||
var token = timeLimitedDataProtector.Protect(key, TimeSpan.FromSeconds(limit));
|
|
||||||
|
|
||||||
return faceUrl + token;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<string, string>> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request)
|
public async Task<Dictionary<string, string>> GetFaceByUserCodesAsync(GetFaceByUserCodesRequest request)
|
||||||
@@ -314,7 +350,7 @@ public class GainfoService : IGainfoService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<Pagination<GainfoListResponse>> GetGainfoListTaskAsync(GainfoListRequest request)
|
public async Task<Pagination<GainfoListResponse>> GetGainfoListAsync(GainfoListRequest request)
|
||||||
{
|
{
|
||||||
var page = await _gainfoStore.Queryable(request.Status)
|
var page = await _gainfoStore.Queryable(request.Status)
|
||||||
.LeftJoin<DepartmentEntity>((ga, de) => ga.DepartmentNo == de.No)
|
.LeftJoin<DepartmentEntity>((ga, de) => ga.DepartmentNo == de.No)
|
||||||
@@ -333,25 +369,26 @@ public class GainfoService : IGainfoService
|
|||||||
DepartmentNo = de.No,
|
DepartmentNo = de.No,
|
||||||
DepartmentName = de.Name,
|
DepartmentName = de.Name,
|
||||||
Address = ga.Address,
|
Address = ga.Address,
|
||||||
Employed = ga.Employed
|
|
||||||
}).ToPageListAsync(request);
|
}).ToPageListAsync(request);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 档案详情
|
/// 档案详情
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<GainfoDetailResponse> GetGainfoDetailTaskAsync(GainfoDetailRequest request)
|
public async Task<GainfoDetailResponse> GetGainfoDetailAsync(GainfoDetailRequest request)
|
||||||
{
|
{
|
||||||
var info = await _gainfoStore.Queryable(request.Status)
|
var info = await _gainfoStore.Queryable(request.Status)
|
||||||
.LeftJoin<DepartmentEntity>((ga, de) => ga.DepartmentNo == de.No)
|
.LeftJoin<DepartmentEntity>((ga, de) => ga.DepartmentNo == de.No)
|
||||||
.LeftJoin<BasicTypeEntity>((ga, de, type) => ga.Native == type.Code && type.Type == "native")
|
.LeftJoin<BasicTypeEntity>((ga, de, type) => ga.Native == type.Code && type.Type == "native")
|
||||||
.LeftJoin<PositionEntity>((ga, de, type, posi) => ga.Position == posi.Name)
|
.LeftJoin<PositionEntity>((ga, de, type, posi) => ga.Position == posi.Name)
|
||||||
.LeftJoin<BasicTypeEntity>((ga, de, type, posi, type2) => ga.CountryNo == type2.Code && type2.Type == "country")
|
.LeftJoin<BasicTypeEntity>((ga, de, type, posi, type2) => ga.CountryNo == type2.Code && type2.Type == "country")
|
||||||
.LeftJoin<BasicTypeEntity>((ga, de, type, posi, type2, type3) => ga.Nation == type3.Code && type3.Type == "nation")
|
.LeftJoin<BasicTypeEntity>((ga, de, type, posi, type2, type3) => ga.Nation == type3.Code && type3.Type == "nation")
|
||||||
|
.LeftJoin<BasicTypeEntity>((ga, de, type, posi, type2, type3, type4) => ga.IdClass == type4.Code && type4.Type == "cls")
|
||||||
.Where(ga => ga.No == request.No)
|
.Where(ga => ga.No == request.No)
|
||||||
.Select((ga, de, type, posi, type2, type3) => new GainfoDetailResponse
|
.Select((ga, de, type, posi, type2, type3, type4) => new GainfoDetailResponse
|
||||||
{
|
{
|
||||||
No = ga.No,
|
No = ga.No,
|
||||||
SapNo = ga.SapNo,
|
SapNo = ga.SapNo,
|
||||||
@@ -370,11 +407,21 @@ public class GainfoService : IGainfoService
|
|||||||
Degree = ga.Degree,
|
Degree = ga.Degree,
|
||||||
Werks = ga.Werks,
|
Werks = ga.Werks,
|
||||||
CostId = ga.CostId,
|
CostId = ga.CostId,
|
||||||
Marital = ga.Marital,
|
Marital = ga.Marital == "Single" ? "未婚" : "已婚",
|
||||||
CountryName = type2.Display,
|
CountryName = type2.Display,
|
||||||
NationName = type3.Display,
|
NationName = type3.Display,
|
||||||
IsActive = ga.Employed == "Active" ? true : false,
|
ClassName = type4.Display,
|
||||||
}).FirstAsync();
|
})
|
||||||
|
.FirstAsync();
|
||||||
|
|
||||||
|
if (info != null)
|
||||||
|
{
|
||||||
|
if (request.WithFace)
|
||||||
|
{
|
||||||
|
info.Face = await _dbContext.ChangeDb("face").Queryable<GainfoFaceEntity>().Where(x => x.UserCode == info.Code).Select(x => x.Face).SingleAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,11 +472,8 @@ public class GainfoService : IGainfoService
|
|||||||
Marital = ga.Marital,
|
Marital = ga.Marital,
|
||||||
CountryName = type2.Display,
|
CountryName = type2.Display,
|
||||||
NationName = type3.Display,
|
NationName = type3.Display,
|
||||||
IsActive = ga.Employed == "Active" ? true : false,
|
|
||||||
}).ToPageListAsync(request);
|
}).ToPageListAsync(request);
|
||||||
//var infos = await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
|
|
||||||
// .Where(ga => ga.CreateTime.ToString("yyyy-MM-dd") == time)
|
|
||||||
// .ToPageListAsync(request);
|
|
||||||
dic[time] = infos;
|
dic[time] = infos;
|
||||||
}
|
}
|
||||||
return dic;
|
return dic;
|
||||||
@@ -481,7 +525,6 @@ public class GainfoService : IGainfoService
|
|||||||
Marital = ga.Marital,
|
Marital = ga.Marital,
|
||||||
CountryName = type2.Display,
|
CountryName = type2.Display,
|
||||||
NationName = type3.Display,
|
NationName = type3.Display,
|
||||||
IsActive = ga.Employed == "Active" ? true : false,
|
|
||||||
}).ToPageListAsync(request);
|
}).ToPageListAsync(request);
|
||||||
dic[time] = infos;
|
dic[time] = infos;
|
||||||
}
|
}
|
||||||
@@ -514,44 +557,6 @@ public class GainfoService : IGainfoService
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Pagination<GainfoDetailResponse>> GetAdministratorAsync( WeekNumberRequest request, string token)
|
|
||||||
{
|
|
||||||
var werks = GetClaimValueFromToken(token, "tenant");
|
|
||||||
var info = await _gainfoStore.Queryable(GainfoStatusEnumType.Working)
|
|
||||||
.LeftJoin<DepartmentEntity>((ga, de) => ga.DepartmentNo == de.No)
|
|
||||||
.LeftJoin<BasicTypeEntity>((ga, de, type) => ga.Native == type.Code && type.Type == "native")
|
|
||||||
.LeftJoin<PositionEntity>((ga, de, type, posi) => ga.Position == posi.Name)
|
|
||||||
.LeftJoin<BasicTypeEntity>((ga, de, type, posi, type2) => ga.CountryNo == type2.Code && type2.Type == "country")
|
|
||||||
.LeftJoin<BasicTypeEntity>((ga, de, type, posi, type2, type3) => ga.Nation == type3.Code && type3.Type == "nation")
|
|
||||||
.Where(ga => ga.Werks == werks && ga.IdentityUserId != 0)
|
|
||||||
.Select((ga, de, type, posi, type2, type3) => new GainfoDetailResponse
|
|
||||||
{
|
|
||||||
No = ga.No,
|
|
||||||
SapNo = ga.SapNo,
|
|
||||||
Name = ga.Name,
|
|
||||||
Code = ga.Code,
|
|
||||||
DepartmentName = de.Name,
|
|
||||||
IdClass = ga.IdClass,
|
|
||||||
IdNo = ga.IdNo,
|
|
||||||
Gender = ga.Gender,
|
|
||||||
NativeName = type.Display,
|
|
||||||
Address = ga.Address,
|
|
||||||
Birthday = ga.Birthday,
|
|
||||||
Phone = ga.Phone,
|
|
||||||
Position = ga.Position,
|
|
||||||
Grade = posi.Grade,
|
|
||||||
Degree = ga.Degree,
|
|
||||||
Werks = ga.Werks,
|
|
||||||
CostId = ga.CostId,
|
|
||||||
Marital = ga.Marital,
|
|
||||||
CountryName = type2.Display,
|
|
||||||
NationName = type3.Display,
|
|
||||||
IsActive = ga.Employed == "Active" ? true : false,
|
|
||||||
}).ToPageListAsync(request);
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------help methods ------------------------------------------------
|
//-------------------------------------------help methods ------------------------------------------------
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -561,7 +566,7 @@ public class GainfoService : IGainfoService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<List<string>> GetRecursionDepartmentNosAsync(List<string> departmentNos)
|
private async Task<List<string>> GetRecursionDepartmentNosAsync(List<string> departmentNos)
|
||||||
{
|
{
|
||||||
if (departmentNos == null || departmentNos.Count == 0)
|
if (departmentNos.IsEmpty())
|
||||||
{
|
{
|
||||||
return new List<string>();
|
return new List<string>();
|
||||||
}
|
}
|
||||||
@@ -579,13 +584,10 @@ public class GainfoService : IGainfoService
|
|||||||
void RecursionGetNext(string currentCode, List<DepartmentEntity> departments, List<string> result)
|
void RecursionGetNext(string currentCode, List<DepartmentEntity> departments, List<string> result)
|
||||||
{
|
{
|
||||||
var next = departments.Where(x => x.PNo == currentCode).ToList();
|
var next = departments.Where(x => x.PNo == currentCode).ToList();
|
||||||
foreach (var item in next)
|
|
||||||
{
|
|
||||||
result.Add(item.No);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var item in next)
|
foreach (var item in next)
|
||||||
{
|
{
|
||||||
|
result.Add(item.No);
|
||||||
RecursionGetNext(item.No, departments, result);
|
RecursionGetNext(item.No, departments, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using Dlhis.Entity.Basic.Entity;
|
using Dlhis.Entity.Basic.Entity;
|
||||||
using Kurisu.AspNetCore;
|
using Kurisu.AspNetCore;
|
||||||
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.Basic.Packs;
|
namespace Dlhis.Basic.Packs;
|
||||||
@@ -12,25 +15,57 @@ public class SqlSugarPack : BaseAppPack
|
|||||||
|
|
||||||
public override void ConfigureServices(IServiceCollection services)
|
public override void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSqlSugar();
|
services.AddSqlSugar(sp =>
|
||||||
|
{
|
||||||
|
var configuration = sp.GetService<IConfiguration>();
|
||||||
|
|
||||||
|
return new List<ConnectionConfig>
|
||||||
|
{
|
||||||
|
new ConnectionConfig
|
||||||
|
{
|
||||||
|
ConfigId = "face",
|
||||||
|
|
||||||
|
ConnectionString = configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value,
|
||||||
|
DbType = DbType.MySql,
|
||||||
|
InitKeyType = InitKeyType.Attribute,
|
||||||
|
IsAutoCloseConnection = true,
|
||||||
|
|
||||||
|
MoreSettings = new ConnMoreSettings
|
||||||
|
{
|
||||||
|
DisableNvarchar = true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new ConnectionConfig
|
||||||
|
{
|
||||||
|
ConfigId = "log",
|
||||||
|
|
||||||
|
ConnectionString = configuration.GetSection("SqlSugarOptions:LogConnectionString").Value,
|
||||||
|
DbType = DbType.MySql,
|
||||||
|
InitKeyType = InitKeyType.Attribute,
|
||||||
|
IsAutoCloseConnection = true,
|
||||||
|
|
||||||
|
MoreSettings = new ConnMoreSettings
|
||||||
|
{
|
||||||
|
DisableNvarchar = true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
{
|
{
|
||||||
//using var scope = app.ApplicationServices.CreateScope();
|
using var scope = app.ApplicationServices.CreateScope();
|
||||||
//var db = scope.ServiceProvider.GetService<ISqlSugarClient>();
|
var db = scope.ServiceProvider.GetService<IDbContext>();
|
||||||
//var tables = App.ActiveTyps.Where(x => x.IsDefined(typeof(SugarTable), false))
|
var tables = App.ActiveTyps.Where(x => x.IsDefined(typeof(SugarTable), false))
|
||||||
// .Where(x => !x.IsDefined(typeof(SkipScanAttribute), false))
|
.Where(x => !x.IsDefined(typeof(SkipScanAttribute), false))
|
||||||
// .ToArray();
|
.ToArray();
|
||||||
|
|
||||||
//db.DbMaintenance.CreateDatabase();
|
db.Client.DbMaintenance.CreateDatabase();
|
||||||
//db.CodeFirst.InitTables(tables);
|
db.Client.CodeFirst.InitTables(tables);
|
||||||
|
|
||||||
//using var scopeFace = app.ApplicationServices.CreateScope();
|
var faceDb = db.ChangeDb("face");
|
||||||
//var dbFace = scopeFace.ServiceProvider.GetService<ISqlSugarClient>();
|
faceDb.Client.DbMaintenance.CreateDatabase();
|
||||||
//var faceConnectionString = Configuration.GetSection("SqlSugarOptions:FaceConnectionString").Value;
|
faceDb.Client.CodeFirst.InitTables<GainfoFaceEntity>();
|
||||||
//dbFace.CurrentConnectionConfig.ConnectionString = faceConnectionString;
|
|
||||||
//dbFace.DbMaintenance.CreateDatabase();
|
|
||||||
//dbFace.CodeFirst.InitTables<GainfoFaceEntity>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
using Kurisu.AspNetCore.Startup;
|
using Kurisu.AspNetCore.Startup;
|
||||||
|
using Kurisu.AspNetCore.Utils.Extensions;
|
||||||
using Kurisu.Startup;
|
using Kurisu.Startup;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
|
||||||
using Microsoft.IdentityModel.Logging;
|
using Microsoft.IdentityModel.Logging;
|
||||||
using StackExchange.Redis;
|
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
@@ -22,11 +21,6 @@ public class Startup : DefaultStartup
|
|||||||
public override void ConfigureServices(IServiceCollection services)
|
public override void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
base.ConfigureServices(services);
|
base.ConfigureServices(services);
|
||||||
|
services.AddRedis();
|
||||||
//todo
|
|
||||||
var redis = ConnectionMultiplexer.Connect($"10.27.21.15:30050,defaultDatabase:1,password=dlhis123");
|
|
||||||
services.AddDataProtection()
|
|
||||||
.SetApplicationName("basic")
|
|
||||||
.PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
40
Src/Dlhis.Basic/Summary/Controllers/SummariesController.cs
Normal file
40
Src/Dlhis.Basic/Summary/Controllers/SummariesController.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using Dlhis.Basic.Device.Response;
|
||||||
|
using Dlhis.Basic.Summary.Response;
|
||||||
|
using Dlhis.Basic.Summary.Services;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Summary.Controllers;
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class SummariesController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ISummaryService _summaryService;
|
||||||
|
|
||||||
|
public SummariesController(ISummaryService summaryService)
|
||||||
|
{
|
||||||
|
_summaryService = summaryService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 考勤首页
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("attendance-summary")]
|
||||||
|
public async Task<AttendanceSummaryResponse> GetKaoQingSummary()
|
||||||
|
{
|
||||||
|
return await _summaryService.GetAttendanceSummaryAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 门禁首页数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("door-summary")]
|
||||||
|
public async Task<DoorHomeDataResponse> GetDoorHomeDataAsync()
|
||||||
|
{
|
||||||
|
return await _summaryService.GetDoorHomeDataAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Src/Dlhis.Basic/Summary/Dto/TrendDto.cs
Normal file
8
Src/Dlhis.Basic/Summary/Dto/TrendDto.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Dlhis.Basic.Summary.Dto;
|
||||||
|
|
||||||
|
public class TrendDto
|
||||||
|
{
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
|
public int Count { get; set; }
|
||||||
|
}
|
||||||
24
Src/Dlhis.Basic/Summary/Response/AttendanceDetailSummary.cs
Normal file
24
Src/Dlhis.Basic/Summary/Response/AttendanceDetailSummary.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Dlhis.Basic.Summary.Response;
|
||||||
|
|
||||||
|
public class AttendanceDetailSummary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 考勤总人数
|
||||||
|
/// </summary>
|
||||||
|
public int Total => Employed + Unemployed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在职人数
|
||||||
|
/// </summary>
|
||||||
|
public int Employed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 非在职人数
|
||||||
|
/// </summary>
|
||||||
|
public int Unemployed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 人员趋势 7天
|
||||||
|
/// </summary>
|
||||||
|
public GainfoTrendResponse GainfoTrend { get; set; }
|
||||||
|
}
|
||||||
31
Src/Dlhis.Basic/Summary/Response/AttendanceDeviceSummary.cs
Normal file
31
Src/Dlhis.Basic/Summary/Response/AttendanceDeviceSummary.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using Dlhis.Basic.Summary.Dto;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Summary.Response;
|
||||||
|
|
||||||
|
public class AttendanceDeviceSummary
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 总数
|
||||||
|
/// </summary>
|
||||||
|
public int Total { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在线数
|
||||||
|
/// </summary>
|
||||||
|
public int OnlineCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启用数
|
||||||
|
/// </summary>
|
||||||
|
public int EnableCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 离线数
|
||||||
|
/// </summary>
|
||||||
|
public int OfflineCount => Total - OnlineCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 新增设备趋势 30天内
|
||||||
|
/// </summary>
|
||||||
|
public List<TrendDto> Trend { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Dlhis.Basic.Summary.Response
|
||||||
|
{
|
||||||
|
public class AttendanceSummaryResponse
|
||||||
|
{
|
||||||
|
public AttendanceDeviceSummary DeviceSummary { get; set; }
|
||||||
|
|
||||||
|
public AttendanceDetailSummary AttendanceDetailSummary { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Src/Dlhis.Basic/Summary/Response/DoorHomeDataResponse.cs
Normal file
11
Src/Dlhis.Basic/Summary/Response/DoorHomeDataResponse.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Dlhis.Basic.Summary.Dto;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Summary.Response
|
||||||
|
{
|
||||||
|
public class DoorHomeDataResponse
|
||||||
|
{
|
||||||
|
public int OffNum { get; set; }
|
||||||
|
public int TotalNum { get; set; }
|
||||||
|
public List<TrendDto> Trend { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
10
Src/Dlhis.Basic/Summary/Response/GainfoTrendResponse.cs
Normal file
10
Src/Dlhis.Basic/Summary/Response/GainfoTrendResponse.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
using Dlhis.Basic.Summary.Dto;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Summary.Response
|
||||||
|
{
|
||||||
|
public class GainfoTrendResponse
|
||||||
|
{
|
||||||
|
public List<TrendDto> EmployedTrend { get; set; }
|
||||||
|
public List<TrendDto> UnemployedTrend { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Src/Dlhis.Basic/Summary/Services/ISummaryService.cs
Normal file
11
Src/Dlhis.Basic/Summary/Services/ISummaryService.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Dlhis.Basic.Device.Response;
|
||||||
|
using Dlhis.Basic.Summary.Response;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Summary.Services;
|
||||||
|
|
||||||
|
public interface ISummaryService : IScopeDependency
|
||||||
|
{
|
||||||
|
Task<AttendanceSummaryResponse> GetAttendanceSummaryAsync();
|
||||||
|
|
||||||
|
Task<DoorHomeDataResponse> GetDoorHomeDataAsync();
|
||||||
|
}
|
||||||
189
Src/Dlhis.Basic/Summary/Services/Implements/SummaryService.cs
Normal file
189
Src/Dlhis.Basic/Summary/Services/Implements/SummaryService.cs
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
using Dlhis.Basic.Device.Response;
|
||||||
|
using Dlhis.Basic.Organization.Services;
|
||||||
|
using Dlhis.Basic.Summary.Dto;
|
||||||
|
using Dlhis.Basic.Summary.Response;
|
||||||
|
using Dlhis.Entity.Basic.Entity;
|
||||||
|
using Dlhis.Entity.Basic.Enums;
|
||||||
|
using Dlhis.Entity.Device.Entities;
|
||||||
|
using Dlhis.Entity.Device.Enums;
|
||||||
|
using Kurisu.SqlSugar.Services;
|
||||||
|
|
||||||
|
namespace Dlhis.Basic.Summary.Services.Implements;
|
||||||
|
|
||||||
|
public class SummaryService : ISummaryService
|
||||||
|
{
|
||||||
|
private readonly IDbContext _dbContext;
|
||||||
|
private readonly IGainfoStore _gainfoStore;
|
||||||
|
|
||||||
|
public SummaryService(IDbContext dbContext, IGainfoStore gainfoStore)
|
||||||
|
{
|
||||||
|
_dbContext = dbContext;
|
||||||
|
_gainfoStore = gainfoStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<AttendanceSummaryResponse> GetAttendanceSummaryAsync()
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
|
||||||
|
var currentDay = DateTime.Today.AddDays(1).AddSeconds(-1);
|
||||||
|
var before30Day = DateTime.Today.AddDays(-29);
|
||||||
|
var before7Day = DateTime.Today.AddDays(-6);
|
||||||
|
|
||||||
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Attendance || (x.Type == DeviceTypeEnumType.Door && x.AsAttendance)).ToListAsync();
|
||||||
|
var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
|
||||||
|
|
||||||
|
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
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var workingGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Working).ToListAsync();
|
||||||
|
var leaveGainfos = await _gainfoStore.Queryable(GainfoStatusEnumType.Leave).ToListAsync();
|
||||||
|
|
||||||
|
return new AttendanceSummaryResponse
|
||||||
|
{
|
||||||
|
DeviceSummary = new AttendanceDeviceSummary
|
||||||
|
{
|
||||||
|
Total = devices.Count,
|
||||||
|
EnableCount = devices.Where(x => x.Enable).Count(),
|
||||||
|
OnlineCount = deviceRegistries.Where(x =>
|
||||||
|
{
|
||||||
|
if (x.HeartbeatInterval <= 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now;
|
||||||
|
|
||||||
|
}).Count(),
|
||||||
|
Trend = FixTrend(devices.Where(x => x.CreateTime >= before30Day && x.CreateTime <= currentDay)
|
||||||
|
.GroupBy(x => x.CreateTime.Date)
|
||||||
|
.Select(x => new TrendDto { Date = x.Key, Count = x.Count() }), before30Day, currentDay)
|
||||||
|
},
|
||||||
|
AttendanceDetailSummary = new AttendanceDetailSummary
|
||||||
|
{
|
||||||
|
Employed = workingGainfos.Count,
|
||||||
|
Unemployed = leaveGainfos.Count,
|
||||||
|
GainfoTrend = new GainfoTrendResponse
|
||||||
|
{
|
||||||
|
EmployedTrend = FixTrend(workingGainfos.Where(x => x.CreateTime >= before7Day && x.CreateTime <= currentDay)
|
||||||
|
.GroupBy(x => x.CreateTime.Date)
|
||||||
|
.Select(x => new TrendDto { Date = x.Key, Count = x.Count() }), before7Day, currentDay),
|
||||||
|
UnemployedTrend = FixTrend(leaveGainfos.Where(x => x.CreateTime >= before7Day && x.CreateTime <= currentDay)
|
||||||
|
.GroupBy(x => x.CreateTime.Date)
|
||||||
|
.Select(x => new TrendDto { Date = x.Key, Count = x.Count() }), before7Day, currentDay),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<DoorHomeDataResponse> GetDoorHomeDataAsync()
|
||||||
|
{
|
||||||
|
var devices = await _dbContext.Queryable<DeviceEntity>().Where(x => x.Type == DeviceTypeEnumType.Door).ToListAsync();
|
||||||
|
|
||||||
|
var offDevices = await GetOfflineDevicesCount(devices);
|
||||||
|
|
||||||
|
//获取近30天并转化为"yyyy-MM-dd"集合
|
||||||
|
DateTime currentDate = DateTime.Now;
|
||||||
|
List<string> times = new List<string>();
|
||||||
|
for (int i = 0; i < 30; i++)
|
||||||
|
{
|
||||||
|
DateTime date = currentDate.AddDays(-i);
|
||||||
|
string dateString = date.ToString("yyyy-MM-dd");
|
||||||
|
times.Add(dateString);
|
||||||
|
}
|
||||||
|
|
||||||
|
var list = new List<TrendDto>();
|
||||||
|
times.ForEach(time =>
|
||||||
|
{
|
||||||
|
var count = devices.Where(x => x.CreateTime.ToString("yyyy-MM-dd") == time).Count();
|
||||||
|
var trend = new TrendDto
|
||||||
|
{
|
||||||
|
Date = DateTime.ParseExact(time, "yyyy-MM-dd", null),
|
||||||
|
Count = count,
|
||||||
|
};
|
||||||
|
list.Add(trend);
|
||||||
|
});
|
||||||
|
var res = new DoorHomeDataResponse
|
||||||
|
{
|
||||||
|
OffNum = offDevices.Count,
|
||||||
|
TotalNum = devices.Count,
|
||||||
|
Trend = list
|
||||||
|
};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<TrendDto> FixTrend(IEnumerable<TrendDto> dtos, DateTime start, DateTime end)
|
||||||
|
{
|
||||||
|
var result = dtos.ToList();
|
||||||
|
|
||||||
|
start = start.Date;
|
||||||
|
end = end.Date;
|
||||||
|
|
||||||
|
var currentDate = start;
|
||||||
|
while (currentDate <= end)
|
||||||
|
{
|
||||||
|
if (result.Any(x => x.Date == currentDate))
|
||||||
|
{
|
||||||
|
currentDate = currentDate.AddDays(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(new TrendDto { Date = currentDate, Count = 0 });
|
||||||
|
|
||||||
|
currentDate = currentDate.AddDays(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.OrderBy(x => x.Date).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取离线设备
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task<List<DeviceEntity>> GetOfflineDevicesCount(List<DeviceEntity> devices)
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
|
||||||
|
var deviceUniqueNos = devices.Select(x => x.UniqueNo).ToList();
|
||||||
|
|
||||||
|
var deviceRegistries = await _dbContext.Queryable<DeviceRegistryEntity>()
|
||||||
|
.LeftJoin<DeviceEntity>((x, d) => x.DeviceUniqueNo == d.UniqueNo)
|
||||||
|
.Where(x => deviceUniqueNos.Contains(x.DeviceUniqueNo))
|
||||||
|
.Select((x, d) => new
|
||||||
|
{
|
||||||
|
UniqueNo = d.UniqueNo,
|
||||||
|
d.HeartbeatInterval,
|
||||||
|
x.LastHeartbeatTime
|
||||||
|
})
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var OnlineDevices = deviceRegistries
|
||||||
|
.Where(x =>
|
||||||
|
{
|
||||||
|
if (x.HeartbeatInterval <= 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x.LastHeartbeatTime.AddSeconds(x.HeartbeatInterval * 3) >= now;
|
||||||
|
|
||||||
|
})
|
||||||
|
.Select(x => new
|
||||||
|
{
|
||||||
|
UniqueNo = x.UniqueNo,
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
var onlineUniqueNos = new List<string>();
|
||||||
|
OnlineDevices.ForEach(x => onlineUniqueNos.Add(x.UniqueNo));
|
||||||
|
|
||||||
|
var offUniqueNos = deviceUniqueNos.Except(onlineUniqueNos).ToList();
|
||||||
|
var list = devices.Where(x => offUniqueNos.Contains(x.UniqueNo)).ToList();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,10 @@
|
|||||||
"CommonRequestUrl": "http://localhost:5001",
|
"CommonRequestUrl": "http://localhost:5001",
|
||||||
"SysRequestUrl": "http://localhost:5003"
|
"SysRequestUrl": "http://localhost:5003"
|
||||||
},
|
},
|
||||||
|
"FaceUrlOptions": {
|
||||||
|
"Url": "http://localhost:5002/api/gainfos/face?token=",
|
||||||
|
"Limit": 7200
|
||||||
|
},
|
||||||
"SwaggerOptions": {
|
"SwaggerOptions": {
|
||||||
"Enable": true,
|
"Enable": true,
|
||||||
"Authority": "https://yikatong.isawesome.cn/oauth2",
|
"Authority": "https://yikatong.isawesome.cn/oauth2",
|
||||||
|
|||||||
@@ -11,13 +11,18 @@
|
|||||||
"SysRequestUrl": "http://sys"
|
"SysRequestUrl": "http://sys"
|
||||||
},
|
},
|
||||||
"FaceUrlOptions": {
|
"FaceUrlOptions": {
|
||||||
"Url": "https://face.jinkosolar.com/api/basic/gainfos/face?token=",
|
"Url": "https://yikatong.isawesome.cn/api/basic/gainfos/face?token=",
|
||||||
"Limit": 7200
|
"Limit": 7200
|
||||||
},
|
},
|
||||||
|
"DataProtectionOptions": {
|
||||||
|
"Enable": true,
|
||||||
|
"AppName": "yiliantong"
|
||||||
|
},
|
||||||
"SqlSugarOptions": {
|
"SqlSugarOptions": {
|
||||||
"DefaultConnectionString": "server=10.27.21.22;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;",
|
"DefaultConnectionString": "server=10.27.21.22;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;",
|
||||||
"SlaveConnectionString": [],
|
"SlaveConnectionString": [],
|
||||||
"FaceConnectionString": "server=10.27.21.20;port=3306;userid=root;password=dlhis123;database=face;charset=utf8mb4;",
|
"FaceConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=face;charset=utf8mb4;",
|
||||||
|
"LogConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=log;charset=utf8mb4;",
|
||||||
"Timeout": 30,
|
"Timeout": 30,
|
||||||
"SlowSqlTime": 1,
|
"SlowSqlTime": 1,
|
||||||
"EnableSqlLog": false
|
"EnableSqlLog": false
|
||||||
@@ -33,6 +38,9 @@
|
|||||||
"yikatong": "yikatong"
|
"yikatong": "yikatong"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"RedisOptions": {
|
||||||
|
"ConnectionString": "192.168.199.30:30115,defaultDatabase:1,password=dlhis123"
|
||||||
|
},
|
||||||
"IdentityServerOptions": {
|
"IdentityServerOptions": {
|
||||||
"Authority": "http://identity.oauth.svc.cluster.local",
|
"Authority": "http://identity.oauth.svc.cluster.local",
|
||||||
"RequireHttpsMetadata": false,
|
"RequireHttpsMetadata": false,
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Dlhis.Common.Api\Dlhis.Common.Api.csproj" />
|
<ProjectReference Include="..\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj" />
|
||||||
<ProjectReference Include="..\Dlhis.Entity\Dlhis.Entity.csproj" />
|
<ProjectReference Include="..\Dlhis.Entity\Dlhis.Entity.csproj" />
|
||||||
|
<ProjectReference Include="..\Dlhis.Sys.Api\Dlhis.Sys.Api.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -35,7 +36,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Kurisu.AspNetCore" Version="0.5.2" />
|
<PackageReference Include="Kurisu.AspNetCore" Version="0.7.0" />
|
||||||
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ EXPOSE 80
|
|||||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY ["Src/Dlhis.Canteen/Dlhis.Canteen.csproj", "Src/Dlhis.Canteen/"]
|
COPY ["Src/Dlhis.Canteen/Dlhis.Canteen.csproj", "Src/Dlhis.Canteen/"]
|
||||||
COPY ["Src/Dlhis.Common.Api/Dlhis.Common.Api.csproj", "Src/Dlhis.Common.Api/"]
|
COPY ["Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj", "Src/Dlhis.Basic.Api/"]
|
||||||
COPY ["Src/Dlhis.Entity/Dlhis.Entity.csproj", "Src/Dlhis.Entity/"]
|
COPY ["Src/Dlhis.Entity/Dlhis.Entity.csproj", "Src/Dlhis.Entity/"]
|
||||||
|
COPY ["Src/Dlhis.Sys.Api/Dlhis.Sys.Api.csproj", "Src/Dlhis.Sys.Api/"]
|
||||||
RUN dotnet restore "Src/Dlhis.Canteen/Dlhis.Canteen.csproj"
|
RUN dotnet restore "Src/Dlhis.Canteen/Dlhis.Canteen.csproj"
|
||||||
COPY . .
|
COPY . .
|
||||||
WORKDIR "/src/Src/Dlhis.Canteen"
|
WORKDIR "/src/Src/Dlhis.Canteen"
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Dlhis.Canteen.Order.Request;
|
using Dlhis.Canteen.Order.Request;
|
||||||
using Dlhis.Canteen.Order.Response;
|
using Dlhis.Canteen.Order.Response;
|
||||||
using Dlhis.Canteen.Order.Services;
|
using Dlhis.Canteen.Order.Services;
|
||||||
|
using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop;
|
||||||
using Kurisu.Core.DataAccess.Dto;
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Org.BouncyCastle.Asn1.Ocsp;
|
||||||
|
|
||||||
namespace Dlhis.Canteen.Order.Controllers;
|
namespace Dlhis.Canteen.Order.Controllers;
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ public class BalancesController : ControllerBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
[DataPermission]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<Pagination<BalanceRecordResponse>> GetPageAsync([FromQuery] BalanceRecordPageRequest request)
|
public async Task<Pagination<BalanceRecordResponse>> GetPageAsync([FromQuery] BalanceRecordPageRequest request)
|
||||||
{
|
{
|
||||||
@@ -39,6 +42,7 @@ public class BalancesController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("device/page")]
|
[HttpGet("device/page")]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task<Pagination<BalanceRecordResponse>> GetPageByDeviceUniqueNoGetAsync([FromQuery] BalanceRecordPageByDeviceUniqueNoRequest request)
|
public async Task<Pagination<BalanceRecordResponse>> GetPageByDeviceUniqueNoGetAsync([FromQuery] BalanceRecordPageByDeviceUniqueNoRequest request)
|
||||||
{
|
{
|
||||||
return await _balanceService.GetPageByDeviceUniqueNoAsync(request);
|
return await _balanceService.GetPageByDeviceUniqueNoAsync(request);
|
||||||
@@ -50,6 +54,7 @@ public class BalancesController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("device/page")]
|
[HttpPost("device/page")]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task<Pagination<BalanceRecordResponse>> GetPageByDeviceUniqueNoPostAsync(BalanceRecordPageByDeviceUniqueNoRequest request)
|
public async Task<Pagination<BalanceRecordResponse>> GetPageByDeviceUniqueNoPostAsync(BalanceRecordPageByDeviceUniqueNoRequest request)
|
||||||
{
|
{
|
||||||
return await _balanceService.GetPageByDeviceUniqueNoAsync(request);
|
return await _balanceService.GetPageByDeviceUniqueNoAsync(request);
|
||||||
@@ -72,6 +77,7 @@ public class BalancesController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("obsoluteOutRecord")]
|
[HttpPost("obsoluteOutRecord")]
|
||||||
|
[Transactional]
|
||||||
public async Task ObsoluteAsync(BalanceRecordObsoluteRequest request)
|
public async Task ObsoluteAsync(BalanceRecordObsoluteRequest request)
|
||||||
{
|
{
|
||||||
await _balanceService.ObsoluteAsync(request);
|
await _balanceService.ObsoluteAsync(request);
|
||||||
@@ -85,7 +91,7 @@ public class BalancesController : ControllerBase
|
|||||||
[HttpGet("recordByCostId")]
|
[HttpGet("recordByCostId")]
|
||||||
public async Task<Pagination<BalanceRecordCostIdResponse>> RecordByCostIdAsync([FromQuery] BalanceRecordPageByCostIdRequest request)
|
public async Task<Pagination<BalanceRecordCostIdResponse>> RecordByCostIdAsync([FromQuery] BalanceRecordPageByCostIdRequest request)
|
||||||
{
|
{
|
||||||
return await _balanceService.RecordByCostIdAsync(request);
|
return await _balanceService.RecordByCostIdAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -132,4 +138,81 @@ public class BalancesController : ControllerBase
|
|||||||
{
|
{
|
||||||
return await _balanceService.BalanceRecordAnalysisAsync(request);
|
return await _balanceService.BalanceRecordAnalysisAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取消费机总数、离线设备数量、营业点数量、可消费人数、人均日消费额
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("consumenumbers")]
|
||||||
|
public async Task<ConsumeNumberResponse> GetConsumeNumberAsync()
|
||||||
|
{
|
||||||
|
return await _balanceService.GetConsumeNumberAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消费人数详情
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("spendingDetails")]
|
||||||
|
public async Task<Pagination<SpendingDetailResponse>> GetSpendingDetailsAsync([FromQuery]SpendingDetailRequest request)
|
||||||
|
{
|
||||||
|
return await _balanceService.GetSpendingDetailsAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 日消费均额
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("averageDaily")]
|
||||||
|
public async Task<Pagination<AverageDailyResponse>> AverageDailyAsync([FromQuery] AverageDailyRequest request)
|
||||||
|
{
|
||||||
|
return await _balanceService.AverageDailyAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取消费机详情
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("consumeDevices")]
|
||||||
|
public async Task<Pagination<DevicePageResponse>> GetConsumeDeviceAsync([FromQuery] GetConsumeDeviceRequest request)
|
||||||
|
{
|
||||||
|
return await _balanceService.GetConsumeDeviceAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点增加配置设备接口
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("disposition")]
|
||||||
|
public async Task DispositionDeviceAsync([FromQuery] DispositionDeviceRequest request)
|
||||||
|
{
|
||||||
|
await _balanceService.DispositionDeviceAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 电子餐券申请记录查询
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("oaemealvoucher")]
|
||||||
|
public async Task<Pagination<OaEMealVoucherResponse>> GetOaEMealVoucherAsync([FromQuery] OaEMealVoucherRequest request)
|
||||||
|
{
|
||||||
|
return await _balanceService.GetOaEMealVoucherAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 电子餐券使用记录查询
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("oaemealvoucherdetail")]
|
||||||
|
public async Task<Pagination<OaEMealVoucherDetailResponse>> GetOaEMealVoucherDetailAsync([FromQuery] OaEMealVoucherDetailRequest request)
|
||||||
|
{
|
||||||
|
return await _balanceService.GetOaEMealVoucherDetailAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ public class OrdersController : ControllerBase
|
|||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
[IgnoreTenant]
|
||||||
public async Task<OrderResultResponse> AddAsync(OrderAddRequest request)
|
public async Task<OrderResultResponse> AddAsync(OrderAddRequest request)
|
||||||
{
|
{
|
||||||
return await _orderService.AddAsync(request);
|
return await _orderService.AddAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
8
Src/Dlhis.Canteen/Order/Request/AverageDailyRequest.cs
Normal file
8
Src/Dlhis.Canteen/Order/Request/AverageDailyRequest.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
using Kurisu.Core.DataAccess.Dto;
|
||||||
|
|
||||||
|
namespace Dlhis.Canteen.Order.Request
|
||||||
|
{
|
||||||
|
public class AverageDailyRequest : PageDto
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,17 @@ namespace Dlhis.Canteen.Order.Request;
|
|||||||
|
|
||||||
public class BalanceRecordPageRequest : PageDto, IValidatableObject
|
public class BalanceRecordPageRequest : PageDto, IValidatableObject
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 营业点codes
|
||||||
|
/// </summary>
|
||||||
|
public List<Guid?> BusinessplaceCodes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 餐次
|
||||||
|
/// </summary>
|
||||||
|
public List<string> ShiftTypes { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询日期范围类型 DateTimeSearchEnumType
|
/// 查询日期范围类型 DateTimeSearchEnumType
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
12
Src/Dlhis.Canteen/Order/Request/ConsumptionTrendRequest.cs
Normal file
12
Src/Dlhis.Canteen/Order/Request/ConsumptionTrendRequest.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Dlhis.Entity.Canteen.Enums;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Dlhis.Canteen.Order.Request
|
||||||
|
{
|
||||||
|
public class ConsumptionTrendRequest
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[EnumDataType(typeof(ConsumptionTrendEnumType))]
|
||||||
|
public ConsumptionTrendEnumType Type { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Dlhis.Canteen.Order.Request
|
||||||
|
{
|
||||||
|
public class DispositionDeviceRequest
|
||||||
|
{
|
||||||
|
public string PlaceCode { get; set; }
|
||||||
|
|
||||||
|
public List<string> UniqueNos { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user