Merge branch 'development'

This commit is contained in:
2024-03-15 13:59:18 +08:00
75 changed files with 2418 additions and 88 deletions

View File

@@ -31,7 +31,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Sys.Api", "Src\Dlhis.
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Basic.Api", "Src\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj", "{1F337648-8A22-4601-A842-0F634FBA2825}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.Basic.Api", "Src\Dlhis.Basic.Api\Dlhis.Basic.Api.csproj", "{1F337648-8A22-4601-A842-0F634FBA2825}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gateway", "Src\Gateway\Gateway.csproj", "{00DE1D49-8F1F-4EAA-B06F-CDE0EFAA03D3}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gateway", "Src\Gateway\Gateway.csproj", "{00DE1D49-8F1F-4EAA-B06F-CDE0EFAA03D3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{489252FB-A44B-46EE-B065-21CDCB724441}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dlhis.External", "Src\Dlhis.External\Dlhis.External.csproj", "{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -83,6 +87,10 @@ Global
{00DE1D49-8F1F-4EAA-B06F-CDE0EFAA03D3}.Debug|Any CPU.Build.0 = Debug|Any CPU {00DE1D49-8F1F-4EAA-B06F-CDE0EFAA03D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00DE1D49-8F1F-4EAA-B06F-CDE0EFAA03D3}.Release|Any CPU.ActiveCfg = Release|Any CPU {00DE1D49-8F1F-4EAA-B06F-CDE0EFAA03D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00DE1D49-8F1F-4EAA-B06F-CDE0EFAA03D3}.Release|Any CPU.Build.0 = Release|Any CPU {00DE1D49-8F1F-4EAA-B06F-CDE0EFAA03D3}.Release|Any CPU.Build.0 = Release|Any CPU
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -97,6 +105,7 @@ Global
{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} {1F337648-8A22-4601-A842-0F634FBA2825} = {4EBCE46B-CE3A-4A47-9432-82A1854CA58A}
{8472596E-0DE7-4A17-93D6-F0FC7D44FDF5} = {489252FB-A44B-46EE-B065-21CDCB724441}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0} SolutionGuid = {7439494A-E2FD-4FEA-8ABF-74AE57A4A5A0}

View File

@@ -25,6 +25,11 @@ public class BusinessPlaceSaveRequest
[Required(ErrorMessage = "营业点名称不能为空")] [Required(ErrorMessage = "营业点名称不能为空")]
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// 供应商
/// </summary>
public string Supplier { get; set; }
/// <summary> /// <summary>
/// 状态 CanteenBusinessPlaceStatusEnumType /// 状态 CanteenBusinessPlaceStatusEnumType
/// </summary> /// </summary>

View File

@@ -23,6 +23,12 @@ public class BusinessPlaceResponse
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// 供应商
/// </summary>
public string Supplier { get; set; }
/// <summary> /// <summary>
/// 状态,停用/启用 /// 状态,停用/启用
/// </summary> /// </summary>

View File

@@ -39,7 +39,7 @@ public class BusinessPlaceService : IBusinessPlaceService
Catalog = x.Catalog, Catalog = x.Catalog,
CustomCode = x.CustomCode, CustomCode = x.CustomCode,
Source = x.Source, Source = x.Source,
Supplier = x.Supplier,
ShiftCode = s.Code, ShiftCode = s.Code,
ShiftName = s.Name ShiftName = s.Name
}) })
@@ -65,6 +65,7 @@ public class BusinessPlaceService : IBusinessPlaceService
if (!request.Id.HasValue) if (!request.Id.HasValue)
{ {
var entity = request.Adapt<BusinessPlaceEntity>(); var entity = request.Adapt<BusinessPlaceEntity>();
entity.CustomCode = request.CustomCode;
entity.Code = Guid.NewGuid(); entity.Code = Guid.NewGuid();
await _dbContext.InsertAsync(entity); await _dbContext.InsertAsync(entity);
} }

View File

@@ -62,7 +62,8 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
public async Task<List<BusinessPlaceShiftResponse>> GetListAsync() public async Task<List<BusinessPlaceShiftResponse>> GetListAsync()
{ {
var result = await _dbContext.Queryable<BusinessShiftEntity>() var result = await _dbContext.Queryable<BusinessShiftEntity>()
.Select<BusinessPlaceShiftResponse>().ToListAsync(); .Select<BusinessPlaceShiftResponse>()
.ToListAsync();
return result; return result;
} }
@@ -71,15 +72,14 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
{ {
await CheckExistsAsync(request); await CheckExistsAsync(request);
Guid code = Guid.Empty;
if (!request.Id.HasValue) if (!request.Id.HasValue)
{ {
var entity = request.Adapt<BusinessShiftEntity>(); var entity = request.Adapt<BusinessShiftEntity>();
entity.CustomCode = request.CustomCode;
entity.Code = Guid.NewGuid(); entity.Code = Guid.NewGuid();
await _dbContext.InsertAsync(entity); await _dbContext.InsertAsync(entity);
code = entity.Code; return entity.Code;
} }
else else
{ {
@@ -89,10 +89,8 @@ public class BusinessPlaceShiftService : IBusinessPlaceShiftService
request.Adapt(entity); request.Adapt(entity);
await _dbContext.UpdateAsync(entity); await _dbContext.UpdateAsync(entity);
code = entity.Code; return entity.Code;
} }
return code;
} }
public async Task SaveMealShiftsAsync(List<BusinessPlaceShiftSaveMealShiftRequest> requests) public async Task SaveMealShiftsAsync(List<BusinessPlaceShiftSaveMealShiftRequest> requests)

View File

@@ -2,6 +2,8 @@
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.AspNetCore.DataAccess.SqlSugar.Aop;
using Kurisu.AspNetCore.EventBus.Abstractions;
using Kurisu.AspNetCore.Scope;
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;
@@ -218,5 +220,4 @@ public class DevicesController : ControllerBase
{ {
return await _deviceService.BulkUploadsAsync(request); return await _deviceService.BulkUploadsAsync(request);
} }
} }

View File

@@ -82,6 +82,7 @@ public class DeviceService : IDeviceService
if (!request.Id.HasValue) if (!request.Id.HasValue)
{ {
entity = request.Adapt<DeviceEntity>(); entity = request.Adapt<DeviceEntity>();
entity.UniqueNo = request.UniqueNo;
entity.Code = Guid.NewGuid(); entity.Code = Guid.NewGuid();
await _dbContext.InsertAsync(entity); await _dbContext.InsertAsync(entity);
//同时保存注册信息 //同时保存注册信息

View File

@@ -17,7 +17,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Kurisu.AspNetCore" Version="0.6.1" /> <PackageReference Include="Kurisu.AspNetCore" Version="0.7.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,13 +1,15 @@
using System.ComponentModel.DataAnnotations; using Dlhis.Basic.BusinessPlace.Response;
using Dlhis.Basic.BusinessPlace.Response;
using Dlhis.Basic.Device.Response; using Dlhis.Basic.Device.Response;
using Dlhis.Basic.Device.Services;
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.Basic.Organization.Services.Implements; using Dlhis.Basic.Organization.Services.Implements;
using Dlhis.Entity.Device.Entities;
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.Organization.Controllers; namespace Dlhis.Basic.Organization.Controllers;
@@ -42,7 +44,7 @@ public class GainfoPermissionsController : ControllerBase
/// <param name="deviceGroupCode"></param> /// <param name="deviceGroupCode"></param>
/// <returns></returns> /// <returns></returns>
[HttpGet("devicesUnderGroupByUserNo")] [HttpGet("devicesUnderGroupByUserNo")]
public async Task<List<GetDevicesUnderGroupByUserNoResponse>> GetDevicesUnderGroupByUserNoAsync(string userNo, string deviceGroupCode) public async Task<List<GetDevicesUnderGroupByUserNoResponse>> GetDevicesUnderGroupByUserNoAsync(string userNo, Guid deviceGroupCode)
{ {
return await _gainfoPermissions.GetDevicesUnderGroupByUserNoAsync(userNo, deviceGroupCode); return await _gainfoPermissions.GetDevicesUnderGroupByUserNoAsync(userNo, deviceGroupCode);
} }
@@ -57,4 +59,14 @@ public class GainfoPermissionsController : ControllerBase
{ {
return await _gainfoPermissions.GetAssignDeviceCodesAsync(request); return await _gainfoPermissions.GetAssignDeviceCodesAsync(request);
} }
/// <summary>
/// 当前绑定的设备组信息
/// </summary>
/// <returns></returns>
[HttpGet("assignGroups")]
public async Task<List<DeviceGroupTreeResponse>> GetAssignGroupAsync(string userNo)
{
return await _gainfoPermissions.GetAssignGroupAsync(userNo);
}
} }

View File

@@ -0,0 +1,7 @@
namespace Dlhis.Basic.Organization.Response
{
public class GetAssignGroupResponse
{
}
}

View File

@@ -2,7 +2,6 @@
using Dlhis.Basic.Device.Response; using Dlhis.Basic.Device.Response;
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.Implements;
using Kurisu.Core.DataAccess.Dto; using Kurisu.Core.DataAccess.Dto;
namespace Dlhis.Basic.Organization.Services; namespace Dlhis.Basic.Organization.Services;
@@ -11,7 +10,9 @@ public interface IGainfoPermissions : IScopeDependency
{ {
Task<Pagination<BusinessPlaceResponse>> GetPlaceByGainfoAsync(DeviceAssRequest request); Task<Pagination<BusinessPlaceResponse>> GetPlaceByGainfoAsync(DeviceAssRequest request);
Task<List<GetDevicesUnderGroupByUserNoResponse>> GetDevicesUnderGroupByUserNoAsync(string userNo, string deviceGroupCode); Task<List<GetDevicesUnderGroupByUserNoResponse>> GetDevicesUnderGroupByUserNoAsync(string userNo, Guid deviceGroupCode);
Task<Pagination<DevicePageResponse>> GetAssignDeviceCodesAsync(DeviceAssRequest request); Task<Pagination<DevicePageResponse>> GetAssignDeviceCodesAsync(DeviceAssRequest request);
Task<List<DeviceGroupTreeResponse>> GetAssignGroupAsync(string userNo);
} }

View File

@@ -35,7 +35,7 @@ public class DepartmentService : IDepartmentService
{ {
Name = x.Name, Name = x.Name,
No = x.Code, No = x.Code,
PNo = x.PCode, PNo = null,
Tenant = x.Code, Tenant = x.Code,
_Next = tops.Select(item => _Next = tops.Select(item =>
{ {

View File

@@ -1,4 +1,5 @@
using Dlhis.Basic.BusinessPlace.Response; using Dlhis.Basic.BusinessPlace.Response;
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.Basic.Organization.Request; using Dlhis.Basic.Organization.Request;
@@ -8,12 +9,11 @@ using Dlhis.Entity.Canteen.Entities;
using Dlhis.Entity.Canteen.Enums; 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 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.Extensions; using Kurisu.SqlSugar.Extensions;
using Kurisu.SqlSugar.Services; using Kurisu.SqlSugar.Services;
using Org.BouncyCastle.Asn1.Ocsp;
using Org.BouncyCastle.Crypto;
using SqlSugar; using SqlSugar;
namespace Dlhis.Basic.Organization.Services.Implements; namespace Dlhis.Basic.Organization.Services.Implements;
@@ -70,11 +70,14 @@ public class GainfoPermissions : IGainfoPermissions
.ToPageListAsync(request); .ToPageListAsync(request);
} }
public async Task<List<GetDevicesUnderGroupByUserNoResponse>> GetDevicesUnderGroupByUserNoAsync(string userNo, string deviceGroupCode) public async Task<List<GetDevicesUnderGroupByUserNoResponse>> GetDevicesUnderGroupByUserNoAsync(string userNo, Guid deviceGroupCode)
{ {
var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync(); var deviceGroups = await _dbContext.Queryable<DeviceGroupEntity>().ToListAsync();
var currentGroup = deviceGroups.Where(x => x.Code.ToString() == deviceGroupCode).FirstOrDefault(); var currentGroup = deviceGroups.Where(x => x.Code == deviceGroupCode).FirstOrDefault();
currentGroup.ThrowIfNull($"{deviceGroupCode}在设备组中不存在"); if (currentGroup == null)
{
return new List<GetDevicesUnderGroupByUserNoResponse>();
}
var groups = RecursionGetNext(currentGroup, deviceGroups).ToList(); var groups = RecursionGetNext(currentGroup, deviceGroups).ToList();
@@ -193,6 +196,16 @@ public class GainfoPermissions : IGainfoPermissions
} }
public async Task<List<DeviceGroupTreeResponse>> GetAssignGroupAsync(string userNo)
{
var groups = await _devicePermissionService.GetAssignmentsAsync(DeviceAssignmentTypeEnumType.Group, AssignTypeEnumType.User, userNo);
return await _dbContext.Queryable<DeviceGroupEntity>()
.Where(x => groups.Contains(x.Code))
.Select<DeviceGroupTreeResponse>()
.ToListAsync();
}
private IEnumerable<Guid> RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups) private IEnumerable<Guid> RecursionGetNext(DeviceGroupEntity current, List<DeviceGroupEntity> deviceGroups)
{ {
var next = deviceGroups.Where(x => x.PCode == current.Code).ToList(); var next = deviceGroups.Where(x => x.PCode == current.Code).ToList();

View File

@@ -0,0 +1,81 @@
using Dlhis.Canteen.Order.Request;
using Dlhis.Canteen.Order.Response;
using Dlhis.Canteen.Order.Services;
using Kurisu.Core.DataAccess.Dto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Canteen.Order.Controllers;
/// <summary>
/// 菜单菜品控制器
/// </summary>
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class MenuDishesController : ControllerBase
{
private readonly IMenuDishesService _menuDishesService;
public MenuDishesController(IMenuDishesService menuDishesService)
{
_menuDishesService = menuDishesService;
}
/// <summary>
/// 菜单分页
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpGet("pageMenu")]
public async Task<Pagination<GetMenuResponse>> GetMenuAsync([FromQuery]GetMenuRequest request)
{
return await _menuDishesService.GetMenuAsync(request);
}
/// <summary>
/// 菜单保存/更改
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("saveMenu")]
public async Task SaveMenuAsync(SaveMenuRequest request)
{
await _menuDishesService.SaveMenuAsync(request);
}
/// <summary>
/// 菜品分页
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpGet("pageDishes")]
public async Task<Pagination<GetDishesResponse>> GetDishesAsync([FromQuery] GetDishesRequest request)
{
return await _menuDishesService.GetDishesAsync(request);
}
/// <summary>
/// 菜品保存/更改
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("saveDishes")]
public async Task SaveDishesAsync(SaveDishesRequest request)
{
await _menuDishesService.SaveDishesAsync(request);
}
/// <summary>
/// 配置每日菜单菜品及限售
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("disposition")]
public async Task DispositionDishesAsync(DispositionDishesRequest request)
{
await _menuDishesService.DispositionDishesAsync(request);
}
}

View File

@@ -0,0 +1,69 @@
using Dlhis.Canteen.Order.Request;
using Dlhis.Canteen.Order.Response;
using Dlhis.Canteen.Order.Services;
using Kurisu.Core.DataAccess.Dto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Canteen.Order.Controllers;
/// <summary>
///订单/明细控制器
/// </summary>
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class MiniProgramOrderDetailController : ControllerBase
{
private readonly IMiniProgramOrderDetailService _miniProgramOrderDetailService;
public MiniProgramOrderDetailController(IMiniProgramOrderDetailService miniProgramOrderDetailService)
{
_miniProgramOrderDetailService = miniProgramOrderDetailService;
}
/// <summary>
/// 订单分页
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpGet("pageOrder")]
public async Task<Pagination<GetMiniProgramOrderResponse>> GetMiniProgramOrderAsync([FromQuery]GetMiniProgramOrderRequest request)
{
return await _miniProgramOrderDetailService.GetMiniProgramOrderAsync(request);
}
/// <summary>
/// 明细保存
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("saveDetail")]
public async Task SaveDetailAsync(SaveDetailRequest request)
{
await _miniProgramOrderDetailService.SaveDetailAsync(request);
}
/// <summary>
/// 明细分页
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[HttpGet("pageDetail")]
public async Task<Pagination<GetDetailResponse>> GetDetailAsync([FromQuery] GetDetailRequest request)
{
return await _miniProgramOrderDetailService.GetDetailAsync(request);
}
/// <summary>
/// 下单
/// </summary>
/// <returns></returns>
[HttpPost("order")]
public async Task OrderAsync(OrderRequest request)
{
await _miniProgramOrderDetailService.OrderAsync(request);
}
}

View File

@@ -0,0 +1,10 @@
namespace Dlhis.Canteen.Order.Request
{
public class DispositionDishesDto
{
public Guid DisherCode { get; set; }
public int RestrictedNum { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
namespace Dlhis.Canteen.Order.Request
{
public class DispositionDishesRequest
{
public Guid MenudCode { get; set; }
public List<DispositionDishesDto> DishersDtos { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
using Kurisu.Core.DataAccess.Dto;
namespace Dlhis.Canteen.Order.Request
{
public class GetDetailRequest : PageDto
{
}
}

View File

@@ -0,0 +1,9 @@
using Kurisu.Core.DataAccess.Dto;
namespace Dlhis.Canteen.Order.Request
{
public class GetDishesRequest : PageDto
{
public Guid? MenuCode { get; set; }
}
}

View File

@@ -0,0 +1,11 @@
using Kurisu.Core.DataAccess.Dto;
namespace Dlhis.Canteen.Order.Request
{
public class GetMenuRequest : PageDto
{
public Guid? PlaceCode { get; set; }
public string Factory { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using Kurisu.Core.DataAccess.Dto;
namespace Dlhis.Canteen.Order.Request
{
public class GetMiniProgramOrderRequest : PageDto
{
/// <summary>
/// 用餐日期
/// </summary>
public DateOnly? SysDate { get; set; }
}
}

View File

@@ -0,0 +1,50 @@
using Dlhis.Entity.Canteen.Enums;
using SqlSugar.DbConvert;
using SqlSugar;
namespace Dlhis.Canteen.Order.Request
{
public class OrderRequest
{
/// <summary>
/// 订餐人
/// </summary>
public string UserCode { get; set; }
/// <summary>
/// 食堂
/// </summary>
public Guid PlaceCode { get; set; }
/// <summary>
/// 餐次
/// </summary>
public ShiftEnumType ShiftType { get; set; }
/// <summary>
/// 配送地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 菜单
/// </summary>
public Guid MenuCode { get; set; }
/// <summary>
/// 菜品
/// </summary>
public Guid DishesCode { get; set; }
/// <summary>
/// 数量
/// </summary>
public int DishesNum { get; set; } = 1;
/// <summary>
/// 支付方式
/// </summary>
public CanteenPayEnumType PayType { get; set; }
}
}

View File

@@ -0,0 +1,61 @@
using Dlhis.Entity.Canteen.Enums;
using SqlSugar.DbConvert;
using SqlSugar;
namespace Dlhis.Canteen.Order.Request
{
public class SaveDetailRequest
{
public long? Id { get; set; }
/// <summary>
/// 订单号
/// </summary>
public string ThirdNo { get; set; }
/// <summary>
/// 营业日
/// </summary>
public DateOnly BusinessDate { get; set; }
/// <summary>
/// 餐次
/// </summary>
public ShiftEnumType ShiftType { get; set; }
/// <summary>
/// 菜品编码
/// </summary>
public Guid DishesCode { get; set; }
/// <summary>
/// 菜品名称
/// </summary>
public Guid DishesName { get; set; }
/// <summary>
/// 单价
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 单位
/// </summary>
public string Unit { get; set; }
/// <summary>
/// 数量
/// </summary>
public int Num { get; set; }
/// <summary>
/// 金额
/// </summary>
public decimal Amount { get; set; }
/// <summary>
/// 订单明细状态
/// </summary>
public OrderDetailsStatusEnumType OrderStatus { get; set; }
}
}

View File

@@ -0,0 +1,59 @@
using Dlhis.Entity.Canteen.Enums;
using SqlSugar.DbConvert;
using SqlSugar;
using System.ComponentModel.DataAnnotations;
namespace Dlhis.Canteen.Order.Request
{
public class SaveDishesRequest
{
public long? Id { get; set; }
/// <summary>
/// 大类
/// </summary>
public string Categories { get; set; }
/// <summary>
/// 小类
/// </summary>
public string SubCategories { get; set; }
/// <summary>
/// 菜品名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 类型
/// </summary>
[EnumDataType(typeof(CanteenDishesEnumType))]
public CanteenDishesEnumType Type { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 单价
/// </summary>
public decimal Amount { get; set; }
/// <summary>
/// 单位
/// </summary>
public string Unit { get; set; }
/// <summary>
/// 图片
/// </summary>
public string Image { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool Enable { get; set; }
}
}

View File

@@ -0,0 +1,44 @@
using Dlhis.Entity.Canteen.Enums;
using Dlhis.Entity.Device.Enums;
using SqlSugar;
using System.ComponentModel.DataAnnotations;
namespace Dlhis.Canteen.Order.Request
{
public class SaveMenuRequest
{
public long? Id { get; set; }
/// <summary>
/// 菜单名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 所属营业点
/// </summary>
[Required]
public Guid PlaceCode { get; set; }
/// <summary>
/// 厂区
/// </summary>
public string Factory { get; set; }
/// <summary>
/// 营业日期
/// </summary>
public DateOnly StartDate { get; set; }
/// <summary>
/// 餐次段
/// </summary>
public List<ShiftEnumType> ShiftTypes { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool Enable { get; set; }
}
}

View File

@@ -0,0 +1,71 @@
using Dlhis.Entity.Canteen.Enums;
using SqlSugar.DbConvert;
using SqlSugar;
using Kurisu.AspNetCore.Utils.Extensions;
namespace Dlhis.Canteen.Order.Response
{
public class GetDetailResponse
{
/// <summary>
/// 订单号
/// </summary>
public string ThirdNo { get; set; }
/// <summary>
/// 营业日
/// </summary>
public DateOnly BusinessDate { get; set; }
/// <summary>
/// 餐次
/// </summary>
public ShiftEnumType ShiftType { get; set; }
/// <summary>
/// 餐次CN
/// </summary>
public string ShiftTypeCN => ShiftType.GetDescription();
/// <summary>
/// 菜品编码
/// </summary>
public Guid DishesCode { get; set; }
/// <summary>
/// 菜品名称
/// </summary>
public string DishesName { get; set; }
/// <summary>
/// 单价
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 单位
/// </summary>
public string Unit { get; set; }
/// <summary>
/// 数量
/// </summary>
public int Num { get; set; }
/// <summary>
/// 金额
/// </summary>
public decimal Amount { get; set; }
/// <summary>
/// 订单明细状态
/// </summary>
public OrderDetailsStatusEnumType OrderStatus { get; set; }
/// <summary>
/// 订单明细状态CN
/// </summary>
public string OrderStatusCN => OrderStatus.GetDescription();
}
}

View File

@@ -0,0 +1,67 @@
using Dlhis.Entity.Canteen.Enums;
using SqlSugar.DbConvert;
using SqlSugar;
using Kurisu.AspNetCore.Utils.Extensions;
namespace Dlhis.Canteen.Order.Response
{
public class GetDishesResponse
{
/// <summary>
/// 大类
/// </summary>
public string Categories { get; set; }
/// <summary>
/// 小类
/// </summary>
public string SubCategories { get; set; }
/// <summary>
/// 菜品编码
/// </summary>
public Guid Code { get; set; }
/// <summary>
/// 菜品名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 菜品类型
/// </summary>
public CanteenDishesEnumType Type { get; set; }
/// <summary>
/// 菜品类型描述
/// </summary>
public string TypeDescription => Type.GetDescription();
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 单价
/// </summary>
public decimal Amount { get; set; }
/// <summary>
/// 单位
/// </summary>
public string Unit { get; set; }
/// <summary>
/// 图片
/// </summary>
public string Image { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool Enable { get; set; }
}
}

View File

@@ -0,0 +1,60 @@
using Dlhis.Entity.Canteen.Enums;
using Kurisu.AspNetCore.Utils.Extensions;
namespace Dlhis.Canteen.Order.Response
{
public class GetMenuResponse
{
/// <summary>
/// 菜单编码
/// </summary>
public Guid Code { get; set; }
/// <summary>
/// 菜单名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 所属营业点
/// </summary>
public Guid PlaceCode { get; set; }
/// <summary>
/// 所属营业点名称
/// </summary>
public string PlaceName { get; set; }
/// <summary>
/// 厂区
/// </summary>
public string Factory { get; set; }
/// <summary>
/// 营业日期
/// </summary>
public DateOnly StartDate { get; set; }
/// <summary>
/// 餐次段
/// </summary>
public List<ShiftEnumType> ShiftTypes
{
get
{
if (ShiftTypesSrt.IsEmpty()) ShiftTypesSrt = "[]";
return ShiftTypesSrt.ToObject<List<ShiftEnumType>>();
}
}
public string ShiftTypesSrt { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool Enable { get; set; }
}
}

View File

@@ -0,0 +1,136 @@
using Dlhis.Entity.Canteen.Enums;
using SqlSugar.DbConvert;
using SqlSugar;
using Kurisu.AspNetCore.Utils.Extensions;
namespace Dlhis.Canteen.Order.Response
{
public class GetMiniProgramOrderResponse
{
/// <summary>
/// 订单号
/// </summary>
public string No { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 工号
/// </summary>
public string Code { get; set; }
/// <summary>
/// 人事范围
/// </summary>
public string Werks { get; set; }
/// <summary>
/// 部门编码
/// </summary>
public string DepartmentNo { get; set; }
/// <summary>
/// 部门名称
/// </summary>
public string DepartmentName { get; set; }
/// <summary>
/// 成本中心
/// </summary>
public string CostId { get; set; }
/// <summary>
/// 工作地
/// </summary>
public string Workplace { get; set; }
/// <summary>
/// 厂区
/// </summary>
public string Factory { get; set; }
/// <summary>
/// 营业点
/// </summary>
public Guid PlaceCode { get; set; }
/// <summary>
/// 营业名称
/// </summary>
public string PlaceName { get; set; }
/// <summary>
/// 餐次
/// </summary>
public ShiftEnumType ShiftType { get; set; }
/// <summary>
/// 餐次CN
/// </summary>
public string ShiftTypeCN => ShiftType.GetDescription();
/// <summary>
/// 菜品
/// </summary>
public Guid DishesCode { get; set; }
/// <summary>
/// 菜品名称
/// </summary>
public string DishesName { get; set; }
/// <summary>
/// 手机号码
/// </summary>
public string Phone { get; set; }
/// <summary>
/// 用餐日期
/// </summary>
public DateOnly SysDate { get; set; }
/// <summary>
/// 下单时间
/// </summary>
public DateTime CostDate { get; set; }
/// <summary>
/// 支付方式
/// </summary>
public CanteenPayEnumType PayType { get; set; }
/// <summary>
/// 支付方式CN
/// </summary>
public string PayTypeCN => PayType.GetDescription();
/// <summary>
/// 订单状态
/// </summary>
public MiniProgramOrderStatusEnumType OrderStatus { get; set; }
/// <summary>
/// 订单状态CN
/// </summary>
public string OrderStatusCN => OrderStatus.GetDescription();
/// <summary>
/// 订单类型
/// </summary>
public CanteenDishesEnumType OrderType { get; set; }
/// <summary>
/// 订单类型CN
/// </summary>
public string OrderTypeCN => OrderType.GetDescription();
/// <summary>
/// 总金额
/// </summary>
public decimal TotalAmount { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using Dlhis.Canteen.Order.Request;
using Dlhis.Canteen.Order.Response;
using Kurisu.Core.DataAccess.Dto;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Canteen.Order.Services
{
public interface IMenuDishesService :IScopeDependency
{
Task<Pagination<GetMenuResponse>> GetMenuAsync(GetMenuRequest request);
Task SaveMenuAsync(SaveMenuRequest request);
Task<Pagination<GetDishesResponse>> GetDishesAsync(GetDishesRequest request);
Task SaveDishesAsync(SaveDishesRequest request);
Task DispositionDishesAsync(DispositionDishesRequest request);
}
}

View File

@@ -0,0 +1,18 @@
using Dlhis.Canteen.Order.Request;
using Dlhis.Canteen.Order.Response;
using Kurisu.Core.DataAccess.Dto;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.Canteen.Order.Services
{
public interface IMiniProgramOrderDetailService : IScopeDependency
{
Task<Pagination<GetMiniProgramOrderResponse>> GetMiniProgramOrderAsync(GetMiniProgramOrderRequest request);
Task SaveDetailAsync(SaveDetailRequest request);
Task<Pagination<GetDetailResponse>> GetDetailAsync( GetDetailRequest request);
Task OrderAsync(OrderRequest request);
}
}

View File

@@ -0,0 +1,118 @@
using Dlhis.Canteen.Order.Request;
using Dlhis.Canteen.Order.Response;
using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Canteen.Entities;
using Kurisu.AspNetCore.Utils.Extensions;
using Kurisu.Core.DataAccess.Dto;
using Kurisu.Core.User.Abstractions;
using Kurisu.SqlSugar.Extensions;
using Kurisu.SqlSugar.Services;
using Mapster;
namespace Dlhis.Canteen.Order.Services.Implements
{
public class MenuDishesService : IMenuDishesService
{
private readonly IDbContext _dbContext;
private readonly ICurrentUser _currentUser;
public MenuDishesService(IDbContext dbContext, ICurrentUser currentUser)
{
_dbContext = dbContext;
_currentUser = currentUser;
}
public async Task<Pagination<GetMenuResponse>> GetMenuAsync(GetMenuRequest request)
{
var page = await _dbContext.Queryable<CanteenMenuEntity>()
.LeftJoin<BusinessPlaceEntity>((x,place) => x.PlaceCode == place.Code)
.WhereIF(!request.Factory.IsEmpty(),x => x.Factory == request.Factory)
.WhereIF(request.PlaceCode.HasValue, x => request.PlaceCode == x.PlaceCode)
.WhereIF(!request.Search.IsEmpty(),x => x.Name.Contains(request.Search))
.Select((x,place) => new GetMenuResponse
{
ShiftTypesSrt = x.ShiftTypes.ToString(),
//ShiftTypesSrt = string.Join(", ", x.ShiftTypes.Select(enumValue => enumValue.GetDescription())),
PlaceName = place.Name,
},true)
.ToPageListAsync(request);
return page;
}
public async Task SaveMenuAsync(SaveMenuRequest request)
{
var place = await _dbContext.Queryable<BusinessPlaceEntity>()
.FirstAsync(x => x.Code == request.PlaceCode);
place.ThrowIfNull($"{request.PlaceCode}:该营业点不存在!");
if (!request.Id.HasValue)
{
var entity = request.Adapt<CanteenMenuEntity>();
entity.Code = Guid.NewGuid();
await _dbContext.InsertAsync(entity);
}
else
{
var entity = await _dbContext.Queryable<CanteenMenuEntity>()
.Where(x => x.Id == request.Id).FirstAsync();
request.Adapt(entity);
await _dbContext.UpdateAsync(entity);
}
}
public async Task<Pagination<GetDishesResponse>> GetDishesAsync(GetDishesRequest request)
{
if (!request.MenuCode.HasValue)
{
return await _dbContext.Queryable<CanteenDishesEntity>()
.Select<GetDishesResponse>()
.ToPageListAsync(request);
}
else
{
var disCodes = await _dbContext.Queryable<CanteenMenuDishersRelationshipEntity>()
.Where(x => x.MenuCode == request.MenuCode)
.Select(x => x.DishersCode)
.ToListAsync();
return await _dbContext.Queryable<CanteenDishesEntity>()
.Where(x => disCodes.Contains(x.Code))
.Select<GetDishesResponse>()
.ToPageListAsync(request);
}
}
public async Task SaveDishesAsync(SaveDishesRequest request)
{
if (!request.Id.HasValue)
{
var dishers = request.Adapt<CanteenDishesEntity>();
dishers.Code = Guid.NewGuid();
await _dbContext.InsertAsync(dishers);
}
else
{
var entity = await _dbContext.Queryable<CanteenDishesEntity>()
.Where(x => x.Id == request.Id).FirstAsync();
request.Adapt(entity);
await _dbContext.UpdateAsync(entity);
}
}
public async Task DispositionDishesAsync(DispositionDishesRequest request)
{
var lst = new List<CanteenMenuDishersRelationshipEntity>();
foreach (var dto in request.DishersDtos)
{
var entity = new CanteenMenuDishersRelationshipEntity
{
MenuCode = request.MenudCode,
DishersCode = dto.DisherCode,
RestrictedNum = dto.RestrictedNum,
};
lst.Add(entity);
}
await _dbContext.InsertAsync(lst);
}
}
}

View File

@@ -0,0 +1,176 @@
using Dlhis.Canteen.Order.Request;
using Dlhis.Canteen.Order.Response;
using Dlhis.Entity.Basic.Entity;
using Dlhis.Entity.Canteen.Entities;
using Dlhis.Entity.Canteen.Enums;
using Dlhis.Sys.Api;
using Kurisu.AspNetCore.Utils;
using Kurisu.AspNetCore.Utils.Extensions;
using Kurisu.Core.DataAccess.Dto;
using Kurisu.SqlSugar.Extensions;
using Kurisu.SqlSugar.Services;
using Mapster;
using SqlSugar;
namespace Dlhis.Canteen.Order.Services.Implements;
public class MiniProgramOrderDetailService : IMiniProgramOrderDetailService
{
private readonly IDbContext _dbContext;
private readonly ITenantApi _tenantApi;
public MiniProgramOrderDetailService(IDbContext dbContext, ITenantApi tenantApi)
{
_dbContext = dbContext;
_tenantApi = tenantApi;
}
public async Task<Pagination<GetMiniProgramOrderResponse>> GetMiniProgramOrderAsync(GetMiniProgramOrderRequest request)
{
var page = await _dbContext.Queryable<MiniProgramOrderEntity>()
.LeftJoin<BusinessPlaceEntity>((order,place) => order.PlaceCode == place.Code)
.LeftJoin<CanteenDishesEntity>((order, place,dishers) => order.DishesCode == dishers.Code)
.LeftJoin<DepartmentEntity>((order, place, dishers,depart) => order.DepartmentNo == depart.No)
.WhereIF(!request.Search.IsEmpty(), order => order.Name == request.Search || order.Code == request.Search)
.WhereIF(request.SysDate.HasValue,order=>order.SysDate == request.SysDate)
.OrderBy(order => order.CostDate,SqlSugar.OrderByType.Desc)
.Select((order, place, dishers, depart) => new GetMiniProgramOrderResponse
{
PlaceName = place.Name,
DepartmentName = depart.Name,
DishesName = dishers.Name,
},true)
.ToPageListAsync(request);
return page;
}
public async Task SaveDetailAsync(SaveDetailRequest request)
{
if (!request.Id.HasValue)
{
var entity = request.Adapt<OrderDetailsEntity>();
await _dbContext.InsertAsync(entity);
}
else
{
var entity = await _dbContext.Queryable<OrderDetailsEntity>()
.Where(x => x.Id == request.Id)
.FirstAsync();
request.Adapt(entity);
await _dbContext.UpdateAsync(entity);
}
}
public async Task<Pagination<GetDetailResponse>> GetDetailAsync(GetDetailRequest request)
{
var page = await _dbContext.Queryable<OrderDetailsEntity>()
.WhereIF(!request.Search.IsEmpty(),x => x.ThirdNo == request.Search)
.Select<GetDetailResponse>()
.ToPageListAsync(request);
return page;
}
public async Task OrderAsync(OrderRequest request)
{
//判断时间
DateTime currentTime = DateTime.Now;
TimeSpan ninePM = new TimeSpan(20, 30, 0);
if (currentTime.TimeOfDay > ninePM)
{
true.ThrowIfTrue("20:30之后无法订餐!");
}
//判断营业日
var dishes = await _dbContext.Queryable<CanteenDishesEntity>().Where(x => x.Code == request.DishesCode).FirstAsync();
dishes.Enable.ThrowIfFalse($"{dishes.Name}没启用!");
var menu = await _dbContext.Queryable<CanteenMenuEntity>().Where(x => x.Code == request.MenuCode).FirstAsync();
menu.Enable.ThrowIfFalse($"{dishes.Name}没启用!");
// 获取用餐日期
DateOnly tomorrow = DateOnly.FromDateTime(DateTime.Today.AddDays(1));
if (tomorrow != menu.StartDate)
{
true.ThrowIfTrue($"菜品:{dishes.Name}对应的菜单:{menu.Name}不在营业日!");
}
var restricted= await _dbContext.Queryable< CanteenMenuDishersRelationshipEntity>()
.Where(x => x.MenuCode == request.MenuCode && x.DishersCode == request.DishesCode).FirstAsync();
restricted.ThrowIfNull($"每日菜单:{menu.Name} 还没有配置菜品:{dishes.Name} 的限售数量!");
if (restricted.RestrictedNum < 0)
{
true.ThrowIfTrue($"菜品:{dishes.Name}已售罄!");
}
var gainfo = await _dbContext.Queryable<GainfoEntity>()
.Where(x => x.Code == request.UserCode)
.FirstAsync();
gainfo.ThrowIfNull($"用户{request.UserCode}无档案信息,无法订餐!");
//判断是否订过餐
var flag = await _dbContext.Queryable<MiniProgramOrderEntity>()
.Where(x => x.SysDate == tomorrow && x.ShiftType == request.ShiftType && x.Code == request.UserCode && x.OrderStatus == MiniProgramOrderStatusEnumType.I)
.AnyAsync();
flag.ThrowIfTrue($"工号:{request.UserCode} 姓名:{gainfo.Name} 已经定过{tomorrow}的{request.ShiftType.GetDescription()}!");
//支付方式
/* var result = await _tenantApi.GetTenantTreeAsync();
var tree = result.Data;
var shanxi = tree.Where(x => x.Name == "山西基地").FirstOrDefault();
var codes = shanxi.Next.Select(x => x.Code).ToList();
if (!codes.Contains(gainfo.Factory))
{
if (request.PayType == CanteenPayEnumType.Repair)
{
true.ThrowIfTrue($"非山西,支付方式不能为{request.PayType.GetDescription()}");
}
}*/
//生成订单
var order = new MiniProgramOrderEntity
{
No = "O" + SnowFlakeHelper.Instance.NextId(),
Name = gainfo.Name,
Code = gainfo.Code,
Werks = gainfo.Werks,
DepartmentNo = gainfo.DepartmentNo,
CostId = gainfo.CostId,
Workplace = gainfo.Workplace,
Factory = gainfo.Factory,
PlaceCode = request.PlaceCode,
ShiftType = request.ShiftType,
DishesCode = request.DishesCode,
Phone = gainfo.Phone,
SysDate = tomorrow,
CostDate = DateTime.Now,
PayType = request.PayType,
OrderStatus = MiniProgramOrderStatusEnumType.I,
OrderType = dishes.Type,
};
//生成订单明细
var detail = new OrderDetailsEntity
{
ThirdNo = order.No,
SysDate = tomorrow,
ShiftType= request.ShiftType,
DishesCode= request.DishesCode,
DishesName = dishes.Name,
Price = dishes.Amount,
Unit = dishes.Unit,
Num = request.DishesNum,
Amount = request.DishesNum * dishes.Amount,
OrderStatus = OrderDetailsStatusEnumType.I,
};
order.TotalAmount = detail.Amount;
await _dbContext.InsertAsync(order);
await _dbContext.InsertAsync(detail);
//扣减份数
var effect = await _dbContext.Updateable<CanteenMenuDishersRelationshipEntity>()
.SetColumns(x => x.RestrictedNum == restricted.RestrictedNum - request.DishesNum)
.SetColumns(x => x.Version == x.Version + 1)
.Where(x => x.MenuCode == request.MenuCode && x.DishersCode == request.DishesCode && x.Version == restricted.Version)
.ExecuteCommandAsync();
if (effect <= 0) throw new VersionExceptions("更新版本冲突");
}
}

View File

@@ -8,7 +8,8 @@
"AllowedHosts": "*", "AllowedHosts": "*",
"InternalRequest": { "InternalRequest": {
"CommonRequestUrl": "http://common", "CommonRequestUrl": "http://common",
"BasicRequestUrl": "http://basic" "BasicRequestUrl": "http://basic",
"SysRequestUrl": "http://sys"
}, },
"FilterOptions": { "FilterOptions": {
"EnableApiRequestLog": true "EnableApiRequestLog": true

View File

@@ -1,6 +1,7 @@
using Dlhis.Entity.Canteen.Enums; using Dlhis.Entity.Canteen.Enums;
using Kurisu.Core.DataAccess.Entity; using Kurisu.Core.DataAccess.Entity;
using Kurisu.SqlSugar; using Kurisu.SqlSugar;
using Mapster;
using SqlSugar; using SqlSugar;
using SqlSugar.DbConvert; using SqlSugar.DbConvert;
@@ -21,9 +22,15 @@ public class BusinessPlaceEntity : SugarBaseEntity, ITenantId
/// <summary> /// <summary>
/// 自定义代号 /// 自定义代号
/// </summary> /// </summary>
[AdaptIgnore(MemberSide.Destination)]
[SugarColumn(ColumnDescription = "自定义手工号")] [SugarColumn(ColumnDescription = "自定义手工号")]
public string CustomCode { get; set; } public string CustomCode { get; set; }
/// <summary>
/// 供应商
/// </summary>
[SugarColumn(ColumnDescription = "供应商")]
public string Supplier { get; set; }
/// <summary> /// <summary>
/// 营业点名称 /// 营业点名称

View File

@@ -1,5 +1,6 @@
using Kurisu.Core.DataAccess.Entity; using Kurisu.Core.DataAccess.Entity;
using Kurisu.SqlSugar; using Kurisu.SqlSugar;
using Mapster;
using SqlSugar; using SqlSugar;
namespace Dlhis.Entity.Basic.Entity; namespace Dlhis.Entity.Basic.Entity;
@@ -19,6 +20,7 @@ public class BusinessShiftEntity : SugarBaseEntity, ITenantId
/// <summary> /// <summary>
/// 自定义代号 /// 自定义代号
/// </summary> /// </summary>
[AdaptIgnore(MemberSide.Destination)]
[SugarColumn(ColumnDescription = "自定义手工号")] [SugarColumn(ColumnDescription = "自定义手工号")]
public string CustomCode { get; set; } public string CustomCode { get; set; }

View File

@@ -1,6 +1,7 @@
using Dlhis.Entity.Device.Enums; using Dlhis.Entity.Device.Enums;
using Kurisu.Core.DataAccess.Entity; using Kurisu.Core.DataAccess.Entity;
using Kurisu.SqlSugar; using Kurisu.SqlSugar;
using Mapster;
using SqlSugar; using SqlSugar;
using SqlSugar.DbConvert; using SqlSugar.DbConvert;
@@ -21,6 +22,7 @@ public class DeviceEntity : SugarBaseEntity, ITenantId
/// <summary> /// <summary>
/// 设备唯一码,IP/MAC/SNO /// 设备唯一码,IP/MAC/SNO
/// </summary> /// </summary>
[AdaptIgnore(MemberSide.Destination)]
[SugarColumn(ColumnDescription = "设备唯一码", IsNullable = false, UniqueGroupNameList = new[] { "Idx_Device_UniqueNo" })] [SugarColumn(ColumnDescription = "设备唯一码", IsNullable = false, UniqueGroupNameList = new[] { "Idx_Device_UniqueNo" })]
public string UniqueNo { get; set; } public string UniqueNo { get; set; }

View File

@@ -0,0 +1,65 @@
using Dlhis.Entity.Basic.Enums;
using Kurisu.SqlSugar;
using SqlSugar;
using SqlSugar.DbConvert;
namespace Dlhis.Entity.Basic.Entity;
/// <summary>
/// 餐补记录
/// </summary>
[SugarTable(TableName = "MealSupplementRecord", TableDescription = "餐补记录")]
public class MealSupplementRecordEntity : MealSupplementRequestRecordEntity
{
/// <summary>
/// 唯一号
/// </summary>
[SugarColumn(IsNullable = false, ColumnDescription = "唯一号", UniqueGroupNameList = new[] { "idx_MealSupplementRecord_UniqueId" })]
public override string UniqueId { get; set; }
/// <summary>
/// 工号
/// </summary>
[SugarColumn(IsNullable = false, ColumnDescription = "工号", IndexGroupNameList = new[] { "idx_MealSupplementRecord_Code" })]
public override string Code { get; set; }
/// <summary>
/// 餐补状态
/// </summary>
[SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))]
public MealSupplementStatusEnumtype Status { get; set; }
}
[SugarTable(TableName = "MealSupplementRequestRecord", TableDescription = "餐补请求记录")]
public class MealSupplementRequestRecordEntity : SugarBaseEntity
{
public virtual string UniqueId { get; set; }
public virtual string Code { get; set; }
/// <summary>
/// 考勤日期
/// </summary>
[SugarColumn(ColumnDataType = "date", IsNullable = false, ColumnDescription = "考勤日期")]
public DateTime Date { get; set; }
/// <summary>
/// 工作地
/// </summary>
[SugarColumn(IsNullable = false, ColumnDescription = "工作地")]
public string Workplace { get; set; }
/// <summary>
/// 厂区
/// </summary>
[SugarColumn(IsNullable = false, ColumnDescription = "厂区")]
public string Factory { get; set; }
public string Remark { get; set; }
/// <summary>
/// 餐补
/// </summary>
[SugarColumn(IsNullable = false, ColumnDescription = "餐补")]
public decimal Amount { get; set; }
}

View File

@@ -16,4 +16,10 @@ public class WerkEntity : SugarBaseEntity
/// 名称 /// 名称
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDataType = "bit", DefaultValue = "1")]
public bool Enable { get; set; }
} }

View File

@@ -0,0 +1,29 @@
using System.ComponentModel;
namespace Dlhis.Entity.Basic.Enums;
/// <summary>
/// 餐补状态
/// </summary>
[Description("餐补状态")]
public enum MealSupplementStatusEnumtype
{
/// <summary>
/// 待核算
/// </summary>
[Description("待核算")]
Wait = 0,
/// <summary>
/// 成功
/// </summary>
[Description("成功")]
Sucess = 1,
/// <summary>
/// 处理异常
/// </summary>
[Description("处理异常")]
Error = 99
}

View File

@@ -0,0 +1,80 @@
using Dlhis.Entity.Canteen.Enums;
using Kurisu.SqlSugar;
using SqlSugar;
using SqlSugar.DbConvert;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dlhis.Entity.Canteen.Entities
{
/// <summary>
/// 菜品表
/// </summary>
[SugarTable(TableName = "CanteenDishes", TableDescription = "菜品表")]
public class CanteenDishesEntity : SugarBaseEntity
{
/// <summary>
/// 大类
/// </summary>
[SugarColumn(ColumnDescription = "大类")]
public string Categories { get; set; }
/// <summary>
/// 小类
/// </summary>
[SugarColumn(ColumnDescription = "小类")]
public string SubCategories { get; set; }
/// <summary>
/// 菜品编码
/// </summary>
[SugarColumn(ColumnDescription = "菜品编码")]
public Guid Code { get; set; }
/// <summary>
/// 菜品名称
/// </summary>
[SugarColumn(ColumnDescription = "菜品名称")]
public string Name { get; set; }
/// <summary>
/// 类型
/// </summary>
[SugarColumn(ColumnDescription = "类型", ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))]
public CanteenDishesEnumType Type { get; set; }
/// <summary>
/// 描述
/// </summary>
[SugarColumn(ColumnDescription = "描述")]
public string Description { get; set; }
/// <summary>
/// 单价
/// </summary>
[SugarColumn(ColumnDescription = "单价")]
public decimal Amount { get; set; }
/// <summary>
/// 单位
/// </summary>
[SugarColumn(ColumnDescription = "单位")]
public string Unit { get; set; }
/// <summary>
/// 图片
/// </summary>
[SugarColumn(ColumnDescription = "图片")]
public string Image { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDataType = "bit", ColumnDescription = "是否启用")]
public bool Enable { get; set; }
}
}

View File

@@ -0,0 +1,32 @@
using Kurisu.SqlSugar;
using SqlSugar;
namespace Dlhis.Entity.Canteen.Entities
{
/// <summary>
/// 菜单菜品表
/// </summary>
[SugarTable(TableName = "CanteenMenuDishersRelationship", TableDescription = "菜单菜品表")]
public class CanteenMenuDishersRelationshipEntity : SugarBaseEntity
{
/// <summary>
/// 菜单code
/// </summary>
public Guid MenuCode { get; set; }
/// <summary>
/// 菜品code
/// </summary>
public Guid DishersCode { get; set; }
/// <summary>
/// 限售份数
/// </summary>
public int RestrictedNum { get; set; }
/// <summary>
/// 版本
/// </summary>
public int Version { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
using Dlhis.Entity.Canteen.Enums;
using Kurisu.SqlSugar;
using SqlSugar;
namespace Dlhis.Entity.Canteen.Entities;
/// <summary>
/// 菜单表
/// </summary>
[SugarTable(TableName = "CanteenMenu", TableDescription = "菜单表")]
public class CanteenMenuEntity : SugarBaseEntity
{
/// <summary>
/// 菜单编码
/// </summary>
[SugarColumn(ColumnDescription = "菜单编码")]
public Guid Code { get; set; }
/// <summary>
/// 菜单名称
/// </summary>
[SugarColumn(ColumnDescription = "菜单名称")]
public string Name { get; set; }
/// <summary>
/// 所属营业点
/// </summary>
[SugarColumn(ColumnDescription = "所属营业点")]
public Guid PlaceCode { get; set; }
/// <summary>
/// 厂区
/// </summary>
[SugarColumn(ColumnDescription = "厂区")]
public string Factory { get; set; }
/// <summary>
/// 营业日期
/// </summary>
[SugarColumn(ColumnDescription = "营业日期")]
public DateOnly StartDate { get; set; }
/// <summary>
/// 餐次段
/// </summary>
[SugarColumn(ColumnDataType = "varchar(150)", IsJson = true, ColumnDescription = "餐次段", DefaultValue = "[]")]
public List<ShiftEnumType> ShiftTypes { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDataType = "bit", ColumnDescription = "是否启用")]
public bool Enable { get; set; }
}

View File

@@ -0,0 +1,122 @@
using Dlhis.Entity.Canteen.Enums;
using Kurisu.SqlSugar;
using SqlSugar;
using SqlSugar.DbConvert;
namespace Dlhis.Entity.Canteen.Entities
{
/// <summary>
/// 小程序订单表
/// </summary>
[SugarTable(TableName = "MiniProgramOrder", TableDescription = "小程序订单表")]
public class MiniProgramOrderEntity : SugarBaseEntity
{
/// <summary>
/// 订单号
/// </summary>
[SugarColumn(ColumnDescription = "订单号")]
public string No { get; set; }
/// <summary>
/// 姓名
/// </summary>
[SugarColumn(ColumnDescription = "姓名")]
public string Name { get; set; }
/// <summary>
/// 工号
/// </summary>
[SugarColumn(ColumnDescription = "工号")]
public string Code { get; set; }
/// <summary>
/// 人事范围
/// </summary>
[SugarColumn(ColumnDescription = "人事范围")]
public string Werks { get; set; }
/// <summary>
/// 部门编码
/// </summary>
[SugarColumn(ColumnDescription = "部门编码")]
public string DepartmentNo { get; set; }
/// <summary>
/// 成本中心
/// </summary>
[SugarColumn(ColumnDescription = "成本中心")]
public string CostId { get; set; }
/// <summary>
/// 工作地
/// </summary>
[SugarColumn(ColumnDescription = "工作地")]
public string Workplace { get; set; }
/// <summary>
/// 厂区
/// </summary>
[SugarColumn(ColumnDescription = "厂区")]
public string Factory { get; set; }
/// <summary>
/// 营业点
/// </summary>
[SugarColumn(ColumnDescription = "营业点")]
public Guid PlaceCode { get; set; }
/// <summary>
/// 餐次
/// </summary>
[SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), ColumnDescription = "餐次")]
public ShiftEnumType ShiftType { get; set; }
/// <summary>
/// 菜品
/// </summary>
[SugarColumn(ColumnDescription = "菜品")]
public Guid DishesCode { get; set; }
/// <summary>
/// 手机号码
/// </summary>
[SugarColumn(ColumnDescription = "手机号码")]
public string Phone { get; set; }
/// <summary>
/// 用餐日期
/// </summary>
[SugarColumn(ColumnDescription = "用餐日期")]
public DateOnly SysDate { get; set; }
/// <summary>
/// 下单时间
/// </summary>
[SugarColumn(ColumnDescription = "下单时间")]
public DateTime CostDate { get; set; }
/// <summary>
/// 支付方式
/// </summary>
[SugarColumn(ColumnDescription = "支付方式", ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))]
public CanteenPayEnumType PayType { get; set; }
/// <summary>
/// 订单状态
/// </summary>
[SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), ColumnDescription = "订单状态")]
public MiniProgramOrderStatusEnumType OrderStatus { get; set; }
/// <summary>
/// 订单类型
/// </summary>
[SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), ColumnDescription = "订单类型")]
public CanteenDishesEnumType OrderType { get; set; }
/// <summary>
/// 总金额
/// </summary>
[SugarColumn(ColumnDescription = "总金额")]
public decimal TotalAmount { get; set; }
}
}

View File

@@ -0,0 +1,74 @@
using Dlhis.Entity.Canteen.Enums;
using Kurisu.SqlSugar;
using SqlSugar;
using SqlSugar.DbConvert;
namespace Dlhis.Entity.Canteen.Entities
{
/// <summary>
/// 订餐明细表
/// </summary>
[SugarTable(TableName = "OrderDetails", TableDescription = "订餐明细表")]
public class OrderDetailsEntity : SugarBaseEntity
{
/// <summary>
/// 订单号
/// </summary>
[SugarColumn(ColumnDescription = "订单号")]
public string ThirdNo { get; set; }
/// <summary>
/// 营业日(用餐日期)
/// </summary>
[SugarColumn(ColumnDescription = "营业日")]
public DateOnly SysDate { get; set; }
/// <summary>
/// 餐次
/// </summary>
[SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), ColumnDescription = "餐次")]
public ShiftEnumType ShiftType { get; set; }
/// <summary>
/// 菜品编码
/// </summary>
[SugarColumn(ColumnDescription = "菜品编码")]
public Guid DishesCode { get; set; }
/// <summary>
/// 菜品名称
/// </summary>
[SugarColumn(ColumnDescription = "菜品名称")]
public string DishesName { get; set; }
/// <summary>
/// 单价
/// </summary>
[SugarColumn(ColumnDescription = "单价")]
public decimal Price { get; set; }
/// <summary>
/// 单位
/// </summary>
[SugarColumn(ColumnDescription = "单位")]
public string Unit { get; set; }
/// <summary>
/// 数量
/// </summary>
[SugarColumn(ColumnDescription = "数量")]
public int Num { get; set; }
/// <summary>
/// 金额
/// </summary>
[SugarColumn(ColumnDescription = "金额")]
public decimal Amount { get; set; }
/// <summary>
/// 订单明细状态
/// </summary>
[SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), ColumnDescription = "订单明细状态")]
public OrderDetailsStatusEnumType OrderStatus { get; set; }
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dlhis.Entity.Canteen.Enums
{
/// <summary>
/// 菜品类型
/// </summary>
[Description("菜品类型")]
public enum CanteenDishesEnumType
{
/// <summary>
/// 订餐
/// </summary>
[Description("订餐")]
Order = 1,
/// <summary>
/// 扫码点餐
/// </summary>
[Description("扫码点餐")]
QrCode=2,
/// <summary>
/// 通用
/// </summary>
[Description("通用")]
General = 3,
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dlhis.Entity.Canteen.Enums
{
/// <summary>
/// 支付方式
/// </summary>
[Description("支付方式")]
public enum CanteenPayEnumType
{
/// <summary>
/// 餐补
/// </summary>
[Description("餐补")]
Repair = 1,
/// <summary>
/// 现场
/// </summary>
[Description("现场")]
Scene = 2,
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dlhis.Entity.Canteen.Enums
{
public enum MiniProgramOrderStatusEnumType
{
/// <summary>
/// 有效
/// </summary>
[Description("有效")]
I = 1,
/// <summary>
/// 取消
/// </summary>
[Description("取消")]
C = 2,
/// <summary>
/// 退单
/// </summary>
[Description("退单")]
X = 3,
/// <summary>
/// 免单
/// </summary>
[Description("免单")]
Z = 4,
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Dlhis.Entity.Canteen.Enums
{
/// <summary>
/// 订单明细状态
/// </summary>
[Description("订单明细状态")]
public enum OrderDetailsStatusEnumType
{
/// <summary>
/// 有效
/// </summary>
[Description("有效")]
I = 1,
}
}

View File

@@ -0,0 +1,41 @@
using System.ComponentModel;
namespace Dlhis.Entity.Canteen.Enums
{
/// <summary>
/// 餐次
/// </summary>
[Description("餐次")]
public enum ShiftEnumType
{
/// <summary>
/// 早餐
/// </summary>
[Description("早餐")]
Breakfast = 1,
/// <summary>
/// 午餐
/// </summary>
[Description("午餐")]
Lunch = 2,
/// <summary>
/// 晚餐
/// </summary>
[Description("晚餐")]
Dinner = 3,
/// <summary>
/// 宵夜
/// </summary>
[Description("宵夜")]
Nightsnack = 4,
/// <summary>
/// 凌晨餐
/// </summary>
[Description("凌晨餐")]
Midnightsnack = 5,
}
}

View File

@@ -42,7 +42,7 @@ public class ApkFileEntity : SugarBaseEntity
/// 产品代码 /// 产品代码
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "产品代码")] [SugarColumn(ColumnDescription = "产品代码")]
public string? ProductCode { get; set; } public string ProductCode { get; set; }
} }

View File

@@ -47,5 +47,11 @@ public class DeviceTaskEntity : SugarBaseEntity, ITenantId, IVersion
[SugarColumn(ColumnDataType = "longtext")] [SugarColumn(ColumnDataType = "longtext")]
public string ResultMessage { get; set; } public string ResultMessage { get; set; }
/// <summary>
/// 取消id
/// </summary>
public long CancellationId { get; set; }
public string TenantId { get; set; } public string TenantId { get; set; }
} }

View File

@@ -26,6 +26,13 @@ public enum DeviceTaskStatusEnumType
[Description("下发完成")] [Description("下发完成")]
Success = 10, Success = 10,
/// <summary>
/// 取消
/// </summary>
[Description("取消")]
Cancel = 95,
/// <summary> /// <summary>
/// 异常 /// 异常
/// </summary> /// </summary>

View File

@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Kurisu.AspNetCore" Version="0.7.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>
<ItemGroup>
<Folder Include="MealSupplement\Response\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Dlhis.Entity\Dlhis.Entity.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["Src/Dlhis.External/Dlhis.External.csproj", "Src/Dlhis.External/"]
COPY ["Src/Dlhis.Entity/Dlhis.Entity.csproj", "Src/Dlhis.Entity/"]
RUN dotnet restore "./Src/Dlhis.External/./Dlhis.External.csproj"
COPY . .
WORKDIR "/src/Src/Dlhis.External"
RUN dotnet build "./Dlhis.External.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./Dlhis.External.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Dlhis.External.dll"]

View File

@@ -0,0 +1,37 @@
using Dlhis.Entity.Basic.Entity;
using Dlhis.External.MealSupplement.Request;
using Kurisu.AspNetCore.EventBus.Abstractions;
using Kurisu.AspNetCore.EventBus.Abstractions.Handler;
using Kurisu.SqlSugar.Services;
using Mapster;
namespace Dlhis.External.MealSupplement.Channel;
public class MealSupplementHandler : IAsyncChannelHandler<MealSupplementMessage>
{
private readonly IServiceProvider _serviceProvider;
public MealSupplementHandler(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task InvokeAsync(MealSupplementMessage message)
{
using (var scope = _serviceProvider.CreateScope())
{
var db = scope.ServiceProvider.GetService<IDbContext>();
var existsIds = await db.Queryable<MealSupplementRecordEntity>().Select(x => x.UniqueId).ToListAsync();
var items = message.Items.Where(x => !existsIds.Contains(x.UniqueId)).ToList();
var entities = items.Adapt<List<MealSupplementRecordEntity>>();
await db.InsertAsync(entities);
}
}
}
public class MealSupplementMessage : IAsyncChannelMessage
{
public List<MealSupplementReceiveReuqest> Items { get; set; }
}

View File

@@ -0,0 +1,27 @@
using Dlhis.External.MealSupplement.Request;
using Dlhis.External.MealSupplement.Services;
using Microsoft.AspNetCore.Mvc;
namespace Dlhis.External.MealSupplement.Controller;
[Route("api/[controller]")]
[ApiController]
public class MealSupplementsController : ControllerBase
{
private readonly IMealSupplementService _mealSupplementService;
public MealSupplementsController(IMealSupplementService mealSupplementService)
{
_mealSupplementService = mealSupplementService;
}
/// <summary>
/// 接受餐补
/// </summary>
/// <returns></returns>
[HttpPost("receive")]
public async Task DoSupplements(List<MealSupplementReceiveReuqest> reuqests)
{
await _mealSupplementService.DoSupplementsAsync(reuqests);
}
}

View File

@@ -0,0 +1,45 @@
using System.ComponentModel.DataAnnotations;
namespace Dlhis.External.MealSupplement.Request;
public class MealSupplementReceiveReuqest
{
/// <summary>
/// 唯一号
/// </summary>
[Required(ErrorMessage = "唯一号必填")]
public string UniqueId { get; set; }
/// <summary>
/// 工号
/// </summary>
[Required(ErrorMessage = "工号必填")]
public string Code { get; set; }
/// <summary>
/// 考勤日期
/// </summary>
public DateTime Date { get; set; }
/// <summary>
/// 工作地
/// </summary>
[Required(ErrorMessage = "工作地")]
public string Workplace { get; set; }
/// <summary>
/// 厂区
/// </summary>
[Required(ErrorMessage = "厂区")]
public string Factory { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
/// <summary>
/// 餐补
/// </summary>
public decimal Amount { get; set; }
}

View File

@@ -0,0 +1,8 @@
using Dlhis.External.MealSupplement.Request;
namespace Dlhis.External.MealSupplement.Services;
public interface IMealSupplementService : IScopeDependency
{
Task DoSupplementsAsync(List<MealSupplementReceiveReuqest> reuqests);
}

View File

@@ -0,0 +1,26 @@
using Dlhis.Entity.Basic.Entity;
using Dlhis.External.MealSupplement.Channel;
using Dlhis.External.MealSupplement.Request;
using Kurisu.AspNetCore.EventBus.Abstractions;
using Kurisu.SqlSugar.Services;
using Mapster;
namespace Dlhis.External.MealSupplement.Services.Implements;
public class MealSupplementService : IMealSupplementService
{
private readonly IEventBus _eventBus;
private readonly IDbContext _dbContext;
public MealSupplementService(IEventBus eventBus, IDbContext dbContext)
{
_eventBus = eventBus;
_dbContext = dbContext;
}
public async Task DoSupplementsAsync(List<MealSupplementReceiveReuqest> reuqests)
{
await _dbContext.InsertAsync(reuqests.Adapt<List<MealSupplementRequestRecordEntity>>());
await _eventBus.PublishAsync(new MealSupplementMessage { Items = reuqests });
}
}

View File

@@ -0,0 +1,29 @@
using Kurisu.AspNetCore.EventBus.Extensions;
using Kurisu.AspNetCore.Startup;
using Kurisu.SqlSugar.Extensions;
using Kurisu.Startup;
using Microsoft.IdentityModel.Logging;
class Program
{
static void Main(string[] args)
{
KurisuHost.Run<Startup>(true, args);
}
}
public class Startup : DefaultStartup
{
public Startup(IConfiguration configuration) : base(configuration)
{
IdentityModelEventSource.ShowPII = true;
}
public override void ConfigureServices(IServiceCollection services)
{
base.ConfigureServices(services);
services.AddSqlSugar();
services.AddEventBus();
}
}

View File

@@ -0,0 +1,13 @@
{
"profiles": {
"Dlhis.External": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5020"
}
},
"$schema": "https://json.schemastore.org/launchsettings.json"
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,72 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"SqlSugarOptions": {
"DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;",
"SlaveConnectionString": [],
"Timeout": 30,
"SlowSqlTime": 1,
"EnableSqlLog": false
},
"SwaggerOptions": {
"Enable": true,
"Authority": "http://identity.oauth.svc.cluster.local",
"ClientId": "4fb184324eac4180",
"ClientSecret": "8ac8f235152f1524",
"Scopes": {
"openid": "openid",
"profile": "profile",
"yikatong": "yikatong"
}
},
"IdentityServerOptions": {
"Authority": "http://identity.oauth.svc.cluster.local",
"RequireHttpsMetadata": false,
"Issuer": "identity.isawesome.cn",
"Audience": "",
"Pat": {
"Enable": false,
"Scheme": "token",
"ClientId": "reference",
"ClientSecret": "123456"
}
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"System": "Warning",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "MySQL",
"Args": {
"connectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=log;charset=utf8mb4;",
"tableName": "Logs",
"autoCreateSqlTable": true
}
}
]
}
}
]
}
}

View File

@@ -0,0 +1,165 @@
using Dlhis.Entity.Device.Entities;
using Dlhis.Entity.Device.Enums;
using Kurisu.AspNetCore.Utils.Extensions;
using Kurisu.Core.DataAccess.Entity;
using Kurisu.SqlSugar.Services;
using SqlSugar;
using System.Linq.Expressions;
namespace Dlhis.ScheduledTask.CommonJobs;
public class CancelDuplicationTaskJob
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<CancelDuplicationTaskJob> _logger;
public CancelDuplicationTaskJob(IServiceProvider serviceProvider, ILogger<CancelDuplicationTaskJob> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
public async Task RunAsync()
{
_logger.LogInformation("抵消任务开始处理");
using (var scope = _serviceProvider.CreateScope())
{
var optionService = scope.ServiceProvider.GetService<ISqlSugarOptionsService>();
var db = scope.ServiceProvider.GetService<IDbContext>();
db.Client.QueryFilter.ClearAndBackup<ITenantId>();
optionService.IgnoreTenant = true;
try
{
//人员下发任务相关
var taskTypes = new List<DeviceTaskEnumType>() { DeviceTaskEnumType.Add, DeviceTaskEnumType.Delete, DeviceTaskEnumType.Update };
var deviceTasks = await db.Queryable<DeviceTaskEntity>()
.Where(x => x.Status == DeviceTaskStatusEnumType.Wait)//没有被获取
.Where(x => taskTypes.Contains(x.Type))
.OrderBy(x => x.CreateTime, OrderByType.Desc)
.ToListAsync();
var groupData = deviceTasks.GroupBy(x => new { x.TenantId, x.UserNo, x.DeviceUniqueNo });
foreach (var deviceTaskPack in groupData)
{
var uniqueInfo = deviceTaskPack.Key;
var data = deviceTaskPack.ToList();
foreach (var item in data)
{
try
{
Expression<Func<DeviceTaskEntity, bool>> where = LinqExpressionExtension.False<DeviceTaskEntity>();
var ignoreData = new List<IdVersion>();
//最新一条更新人员信息
if (item.Type == DeviceTaskEnumType.Update && item.Status == DeviceTaskStatusEnumType.Wait)
{
//获取过往的更新人员任务
ignoreData = data.Where(x => x.Type == DeviceTaskEnumType.Update)
.Where(x => x.Status == DeviceTaskStatusEnumType.Wait)
.Where(x => x.Id != item.Id)
.Where(x => item.CreateTime > x.CreateTime)
.Select(x => new IdVersion { Id = x.Id, Version = x.Version }).ToList();
}
//最新一条删除人员信息
else if (item.Type == DeviceTaskEnumType.Delete && item.Status == DeviceTaskStatusEnumType.Wait)
{
//存在成功下发的任务,此处可以直接把其他任务取消
if (await db.Queryable<DeviceTaskEntity>().Where(x => x.UserNo == item.UserNo)
.Where(x => x.DeviceUniqueNo == item.DeviceUniqueNo)
.Where(x => x.TenantId == item.TenantId).Where(x => x.Status == DeviceTaskStatusEnumType.Success).AnyAsync())
{
ignoreData.AddRange(data.Where(x => x.Type == DeviceTaskEnumType.Add
|| x.Type == DeviceTaskEnumType.Delete
|| x.Type == DeviceTaskEnumType.Update)
.Where(x => x.Status == DeviceTaskStatusEnumType.Wait)
.Where(x => x.Id != item.Id)
.Where(x => item.CreateTime > x.CreateTime)
.Select(x => new IdVersion { Id = x.Id, Version = x.Version })
);
}
else
{
var currentIds = new List<long> { item.Id };
var beforeTask = data.Where(x => x.Type == DeviceTaskEnumType.Add || x.Type == DeviceTaskEnumType.Update)
.Where(x => !currentIds.Contains(x.Id))
.Where(x => x.Status == DeviceTaskStatusEnumType.Wait)
.Where(x => item.CreateTime > x.CreateTime)
.FirstOrDefault();
//逻辑正确,最终beforeTask.type == DeviceTaskEnumType.Add
while (beforeTask != null && beforeTask.Type == DeviceTaskEnumType.Update)
{
ignoreData.Add(new IdVersion() { Id = beforeTask.Id, Version = beforeTask.Version });
currentIds.Add(beforeTask.Id);
beforeTask = data.Where(x => x.Type == DeviceTaskEnumType.Add || x.Type == DeviceTaskEnumType.Update)
.Where(x => !currentIds.Contains(x.Id))
.Where(x => x.Status == DeviceTaskStatusEnumType.Wait)
.Where(x => item.CreateTime > x.CreateTime)
.FirstOrDefault();
}
if (beforeTask != null)
{
ignoreData.Add(new IdVersion() { Id = beforeTask.Id, Version = beforeTask.Version });
ignoreData.Add(new IdVersion() { Id = item.Id, Version = item.Version });
}
}
}
if (ignoreData.Any())
{
ignoreData.ForEach(p =>
{
where = where.Or(x => x.Id == p.Id && x.Version == p.Version && x.Status == DeviceTaskStatusEnumType.Wait);
});
await db.Updateable<DeviceTaskEntity>()
.SetColumns(x => x.Version == x.Version + 1)
.SetColumns(x => x.Status == DeviceTaskStatusEnumType.Cancel)
.SetColumns(x => x.CancellationId == item.Id)
.SetColumns(x => x.ModifiedTime == DateTime.Now)
.Where(where)
.ExecuteCommandAsync();
data.ForEach(x =>
{
if (ignoreData.Any(p => p.Id == x.Id))
x.Status = DeviceTaskStatusEnumType.Cancel;
});
}
}
catch (Exception ex)
{
_logger.LogError(ex, "抵消处理异常:{message}", ex.Message);
}
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "抵消处理异常:{message}", ex.Message);
}
finally
{
db.Client.QueryFilter.Restore();
optionService.IgnoreTenant = false;
}
}
_logger.LogInformation("抵消任务处理完成");
}
class IdVersion
{
public long Id { get; set; }
public int Version { get; set; }
}
}

View File

@@ -53,10 +53,16 @@ public class JobPack : BaseAppPack
TimeZone = TimeZoneInfo.Local TimeZone = TimeZoneInfo.Local
}); });
RecurringJob.AddOrUpdate<TempCreateUserJob>("TempCreateUser", s => s.RunAsync(), "0 0 5 * * ?", new RecurringJobOptions //处理重复下发任务
RecurringJob.AddOrUpdate<CancelDuplicationTaskJob>("CancelDuplicationTask", s => s.RunAsync(), "0/15 * * * * ?", new RecurringJobOptions
{ {
TimeZone = TimeZoneInfo.Local TimeZone = TimeZoneInfo.Local
}); });
RecurringJob.AddOrUpdate<TempCreateUserJob>("TempCreateUser", s => s.RunAsync(), "0 0 5 * * ?", new RecurringJobOptions
{
TimeZone = TimeZoneInfo.Local
});
} }
} }

View File

@@ -65,7 +65,7 @@ public class JinkoSapService : IJinkoSapService
{ {
var apiUrl = "/RESTAdapter/Rest/EHR_PERSONNEL/"; var apiUrl = "/RESTAdapter/Rest/EHR_PERSONNEL/";
var werks = await _dbContext.Queryable<WerkEntity>().ToListAsync(); var werks = await _dbContext.Queryable<WerkEntity>().Where(x => x.Enable).ToListAsync();
List<SapPersonItem> persons = new(); List<SapPersonItem> persons = new();
List<SapPersonJobStatus> jobInfos = new(); List<SapPersonJobStatus> jobInfos = new();

View File

@@ -7,21 +7,18 @@ namespace Dlhis.ScheduledTask.TaskAssignment.Request;
public class DeviceTaskAssignmentRequest : PageDto public class DeviceTaskAssignmentRequest : PageDto
{ {
/// <summary> /// <summary>
/// 设备类型 /// 设备类型 DeviceTypeEnumType
/// </summary> /// </summary>
[EnumDataType(typeof(DeviceTypeEnumType))] [EnumDataType(typeof(DeviceTypeEnumType))]
public DeviceTypeEnumType? Type { get; set; } public DeviceTypeEnumType? Type { get; set; }
/// <summary> /// <summary>
/// 任务类型 /// 任务类型
/// </summary> /// </summary>
[EnumDataType(typeof(DeviceTaskEnumType))] public List<DeviceTaskEnumType> TaskTypes { get; set; }
public DeviceTaskEnumType? TaskType { get; set; }
/// <summary> /// <summary>
/// 任务下发状态 /// 任务下发状态 DeviceTaskStatusEnumType
/// </summary> /// </summary>
[EnumDataType(typeof(DeviceTaskStatusEnumType))] public List<DeviceTaskStatusEnumType> Status { get; set; }
public DeviceTaskStatusEnumType? Status { get; set; }
} }

View File

@@ -1,6 +1,5 @@
using Dlhis.Entity.Device.Enums; using Dlhis.Entity.Device.Enums;
using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.AspNetCore.Utils.Extensions;
using SqlSugar;
namespace Dlhis.ScheduledTask.TaskAssignment.Response; namespace Dlhis.ScheduledTask.TaskAssignment.Response;
@@ -83,14 +82,4 @@ public class DeviceTaskAssignmentResponse
/// 部署点 /// 部署点
/// </summary> /// </summary>
public string DeployPlace { get; set; } public string DeployPlace { get; set; }
/// <summary>
/// 连接信息
/// </summary>
public string ConnectionInfo { get; set; }
/// <summary>
/// 设备名称
/// </summary>
public string DeviceName { get; set; }
} }

View File

@@ -34,9 +34,9 @@ public class DeviceTaskAssignmentService : IDeviceTaskAssignmentService
|| ga.Code == request.Search || ga.Code == request.Search
|| deviceTask.DeviceUniqueNo == request.Search || deviceTask.DeviceUniqueNo == request.Search
) )
.WhereIF(request.TaskType.HasValue, deviceTask => deviceTask.Type == request.TaskType) .WhereIF(request.TaskTypes.IsPresent(), deviceTask => request.TaskTypes.Contains(deviceTask.Type))
.WhereIF(request.Type.HasValue, (deviceTask, ga, device) => device.Type == request.Type) .WhereIF(request.Type.HasValue, (deviceTask, ga, device) => device.Type == request.Type)
.WhereIF(request.Status.HasValue, deviceTask => deviceTask.Status == request.Status) .WhereIF(request.Status.IsPresent(), deviceTask => request.Status.Contains(deviceTask.Status))
.Where(deviceTask => 1 == 1) .Where(deviceTask => 1 == 1)
.OrderBy(deviceTask => deviceTask.CreateTime, OrderByType.Desc) .OrderBy(deviceTask => deviceTask.CreateTime, OrderByType.Desc)
.Select((deviceTask, ga, device) => new DeviceTaskAssignmentResponse .Select((deviceTask, ga, device) => new DeviceTaskAssignmentResponse
@@ -54,8 +54,6 @@ public class DeviceTaskAssignmentService : IDeviceTaskAssignmentService
LastUpdateTime = deviceTask.ModifiedTime, LastUpdateTime = deviceTask.ModifiedTime,
TenantId = deviceTask.TenantId, TenantId = deviceTask.TenantId,
DeployPlace = device.DeployPlace, DeployPlace = device.DeployPlace,
ConnectionInfo = device.ConnectionInfo,
DeviceName = device.Supplier
}) })
.ToPageListAsync(request); .ToPageListAsync(request);

View File

@@ -10,6 +10,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Ocelot" Version="23.1.0" /> <PackageReference Include="Ocelot" Version="23.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.8" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,16 +1,19 @@
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
var builder = WebApplication.CreateBuilder(args); using Gateway;
builder.Configuration.AddJsonFile("ocelot.json", true, true);
// Add services to the container.
builder.Services.AddOcelot(); public class Program
{
var app = builder.Build(); public static void Main(string[] args)
{
// Configure the HTTP request pipeline. Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(builder =>
app.UseOcelot().Wait(); {
builder.AddJsonFile("ocelot.json", true, true);
app.Run(); })
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.Build().Run();
}
}

41
Src/Gateway/Startup.cs Normal file
View File

@@ -0,0 +1,41 @@
using Microsoft.OpenApi.Models;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
namespace Gateway;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Gateway API", Version = "v1", Description = "# gateway api..." });
});
services.AddOcelot();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
var services = Configuration.GetSection("Services").Get<List<string>>();
foreach (var s in services)
{
c.SwaggerEndpoint($"/{s.ToLower()}/swagger/v1/swagger.json", s);
}
});
app.UseOcelot().Wait();
}
}

View File

@@ -5,5 +5,13 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
"Services": [
"Basic",
"Common",
"Canteen",
"Scheduled",
"User",
"Sys"
]
} }

View File

@@ -84,6 +84,17 @@
"Port": 31007 "Port": 31007
} }
] ]
},
{
"UpstreamPathTemplate": "/{url}/swagger/v1/swagger.json",
"DownstreamPathTemplate": "/{url}/swagger/v1/swagger.json",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "yikatong.isawesome.cn",
"Port": 443
}
]
} }
], ],
"GlobalConfiguration": {} "GlobalConfiguration": {}