Squashed commit of the following:
commitafdd9e6f14Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 21:48:05 2024 +0800 fix 价格默认获取菜单中的设置 commita3cfc472c8Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 21:40:04 2024 +0800 fix 时间范围逻辑 commit83f8906f12Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 21:32:55 2024 +0800 fix 时间范围逻辑 commit35660b1d0cAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 21:29:36 2024 +0800 fix 数据范围罗逻辑修改 commit7407955bc5Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 21:14:06 2024 +0800 fix 分类树增加营业点参数 commited5196d1a1Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 21:02:52 2024 +0800 feat 用户创建 commitd25909a235Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 20:51:20 2024 +0800 fix 菜单明细调整 commit8915f9ff0fAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 20:42:08 2024 +0800 fix 判断提前 commit45aa52aa2aAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 20:34:22 2024 +0800 fix 逻辑取反 commit89904fead1Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 20:23:20 2024 +0800 fix 菜单时效范围 commit573911f907Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 19:13:33 2024 +0800 fix 订单聚合返回状态 commit93c38be18aAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 18:40:12 2024 +0800 fix 订单查询 commite256d18d36Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 18:14:33 2024 +0800 fix 订单取消接口,分页权限控制 commit1218aec811Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 17:32:45 2024 +0800 fix 营业点权限控制优化 commit226c61ee41Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 17:09:42 2024 +0800 fix tenantId赋值 commit28d2c1d8d4Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 17:05:37 2024 +0800 fix ignoretenant commit5ae6dd97b4Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 16:53:40 2024 +0800 fix ignoretenant commit4c866eaf3fAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 16:40:24 2024 +0800 feat 获取所有地址 commit2ca8f2db49Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 16:22:47 2024 +0800 fix 优化查询 commit212a1fa073Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 16:01:49 2024 +0800 fix 临时数据模拟 commit0eb76e878cAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 15:48:59 2024 +0800 fix 处理删除缺少判断 commitc582fb40c0Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 15:40:22 2024 +0800 fix 查询优化 commit6d3a19b283Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 11:48:45 2024 +0800 fix 错误值修改 commitc39f77008dAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 11:31:50 2024 +0800 fix 营业点控制(admin),unit返回 commita5dcab1d07Author: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 11:16:23 2024 +0800 fix 营业点分页控制 commit02084be82bAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 11:01:14 2024 +0800 fix 分类控制菜品获取 commit96c5c5febaAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 10:39:58 2024 +0800 fix DI commit367ede2eebAuthor: liguoyang <Ligy.97@foxmail.com> Date: Thu Mar 21 10:35:24 2024 +0800 fix 订餐返回当前信息,增加数量入参和响应 commit0e1f6cb4a0Author: liguoyang <Ligy.97@foxmail.com> Date: Wed Mar 20 16:40:10 2024 +0800 fix 餐补查询代码调整 commit21fc2f78d3Author: liguoyang <Ligy.97@foxmail.com> Date: Wed Mar 20 15:52:46 2024 +0800 fix 支付批量操作 commit878b44a146Merge:a90d4e6bf5c937Author: cheche <717840555@qq.com> Date: Wed Mar 20 15:27:39 2024 +0800 Merge branch 'development' of https://git.dlhis.com/liguoyang/jinko.yikatong into development commita90d4e66a7Author: cheche <717840555@qq.com> Date: Wed Mar 20 15:27:37 2024 +0800 fix 餐补查询及日志删除 commitbf5c937037Author: liguoyang <Ligy.97@foxmail.com> Date: Wed Mar 20 15:12:30 2024 +0800 fix 补充营业点分配权限接口 commit07672f1d32Author: liguoyang <Ligy.97@foxmail.com> Date: Wed Mar 20 13:56:33 2024 +0800 fix 优化changeDb commit7090ee4a33Author: liguoyang <Ligy.97@foxmail.com> Date: Wed Mar 20 13:41:25 2024 +0800 fix 敏感信息混淆 commit4366b68831Author: liguoyang <Ligy.97@foxmail.com> Date: Wed Mar 20 12:42:48 2024 +0800 fix 代码优化 commit03b73515b5Author: liguoyang <Ligy.97@foxmail.com> Date: Wed Mar 20 10:59:08 2024 +0800 fix tree返回营业点 commit1ce60bedc2Merge:aba4fa72d83930Author: cheche <717840555@qq.com> Date: Wed Mar 20 09:55:17 2024 +0800 Merge branch 'development' of https://git.dlhis.com/liguoyang/jinko.yikatong into development commitaba4fa7ee9Author: cheche <717840555@qq.com> Date: Wed Mar 20 09:55:13 2024 +0800 fix 删除日志优化 commit2d8393068fAuthor: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 20:53:16 2024 +0800 feat 订单聚合接口 commit0cde1d3d92Author: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 20:03:06 2024 +0800 fix 表名称调整 commitf003e30169Author: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 19:51:56 2024 +0800 fix 订餐null异常处理 commitf427338715Author: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 18:43:19 2024 +0800 feat 获取菜品 commit3a65d95701Merge:9a7091b7432faeAuthor: cheche <717840555@qq.com> Date: Tue Mar 19 18:36:16 2024 +0800 Merge branch 'development' of https://git.dlhis.com/liguoyang/jinko.yikatong into development commit9a7091b4e0Author: cheche <717840555@qq.com> Date: Tue Mar 19 18:36:14 2024 +0800 fix 删除日志try commit7432fae103Author: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 18:02:31 2024 +0800 fix 配送点增加 commitecd162c7afAuthor: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 17:51:15 2024 +0800 fix 预定就餐送货地点 commit1c7a054ed4Author: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 15:53:22 2024 +0800 feat 获取所有营业点接口 commit84398a566eMerge:217d9f784b4025Author: cheche <717840555@qq.com> Date: Tue Mar 19 15:26:42 2024 +0800 Merge branch 'development' of https://git.dlhis.com/liguoyang/jinko.yikatong into development commit217d9f7770Author: cheche <717840555@qq.com> Date: Tue Mar 19 15:26:40 2024 +0800 feat 配送点管理 commit84b402538eAuthor: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 14:59:21 2024 +0800 fix 菜单分页响应调整,增加详情接口 commit098d7c7e9dAuthor: liguoyang <Ligy.97@foxmail.com> Date: Tue Mar 19 14:26:24 2024 +0800 fix 代码优化
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
using Dlhis.Canteen.MealSupplementRecord.Request;
|
||||
using Dlhis.Canteen.MealSupplementRecord.Response;
|
||||
using Dlhis.Canteen.MealSupplementRecord.Services;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Dlhis.Canteen.MealSupplementRecord.Controller;
|
||||
|
||||
/// <summary>
|
||||
/// 原始餐补
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class MealSupplementRecordController
|
||||
{
|
||||
private readonly IMealSupplementRecordService _mealSupplementRecordService;
|
||||
|
||||
public MealSupplementRecordController(IMealSupplementRecordService mealSupplementRecordService)
|
||||
{
|
||||
_mealSupplementRecordService = mealSupplementRecordService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 餐补分页
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("page")]
|
||||
public async Task<Pagination<MealSupplementRecordResponse>> MealSupplementRecordPageAsync([FromQuery] MealSupplementRecordRequest request)
|
||||
{
|
||||
return await _mealSupplementRecordService.GetPageAsync(request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
namespace Dlhis.Canteen.MealSupplementRecord.Request;
|
||||
|
||||
public class MealSupplementRecordRequest : PageDto
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Dlhis.Entity.Basic.Enums;
|
||||
using SqlSugar.DbConvert;
|
||||
using SqlSugar;
|
||||
using Kurisu.AspNetCore.Utils.Extensions;
|
||||
|
||||
namespace Dlhis.Canteen.MealSupplementRecord.Response;
|
||||
|
||||
public class MealSupplementRecordResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一号
|
||||
/// </summary>
|
||||
public string UniqueId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工号
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 餐补状态
|
||||
/// </summary>
|
||||
public MealSupplementStatusEnumtype Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 餐补状态
|
||||
/// </summary>
|
||||
public string StatusDesc => Status.GetDescription();
|
||||
|
||||
/// <summary>
|
||||
/// 考勤日期
|
||||
/// </summary>
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工作地
|
||||
/// </summary>
|
||||
public string Workplace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 厂区
|
||||
/// </summary>
|
||||
public string Factory { get; set; }
|
||||
|
||||
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 餐补
|
||||
/// </summary>
|
||||
public decimal Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 处理结果
|
||||
/// </summary>
|
||||
public string Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态同步
|
||||
/// </summary>
|
||||
public bool Sync { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Dlhis.Canteen.MealSupplementRecord.Request;
|
||||
using Dlhis.Canteen.MealSupplementRecord.Response;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
namespace Dlhis.Canteen.MealSupplementRecord.Services;
|
||||
|
||||
public interface IMealSupplementRecordService : IScopeDependency
|
||||
{
|
||||
Task<Pagination<MealSupplementRecordResponse>> GetPageAsync(MealSupplementRecordRequest request);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Dlhis.Canteen.MealSupplementRecord.Request;
|
||||
using Dlhis.Canteen.MealSupplementRecord.Response;
|
||||
using Dlhis.Canteen.MealSupplementRecord.Services;
|
||||
using Dlhis.Entity.Basic.Entity;
|
||||
using Dlhis.Entity.Canteen.Entities;
|
||||
using Kurisu.AspNetCore.Utils.Extensions;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
using Kurisu.SqlSugar.Extensions;
|
||||
using Kurisu.SqlSugar.Services;
|
||||
|
||||
namespace Dlhis.Canteen.MealSupplementRecord.Services.Implements;
|
||||
|
||||
public class MealSupplementRecordService : IMealSupplementRecordService
|
||||
{
|
||||
|
||||
private readonly IDbContext _dbContext;
|
||||
|
||||
public MealSupplementRecordService(IDbContext dbContext)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
public async Task<Pagination<MealSupplementRecordResponse>> GetPageAsync(MealSupplementRecordRequest request)
|
||||
{
|
||||
var page = await _dbContext.Queryable<MealSupplementRecordEntity>()
|
||||
.LeftJoin<GainfoEntity>((x, ga) => x.Code == ga.Code)
|
||||
.WhereIF(request.Search.IsPresent(), (x, ga) => x.Code == request.Search || ga.Name.Contains(request.Search))
|
||||
.Select((x, ga) => new MealSupplementRecordResponse
|
||||
{
|
||||
Amount = x.Amount,
|
||||
Code = x.Code,
|
||||
Date = x.Date,
|
||||
Factory = x.Factory,
|
||||
Remark = x.Remark,
|
||||
Result = x.Result,
|
||||
Status = x.Status,
|
||||
Sync = x.Sync,
|
||||
UniqueId = x.UniqueId,
|
||||
UserName = ga.Name,
|
||||
Workplace = x.Workplace,
|
||||
})
|
||||
.ToPageListAsync(request);
|
||||
|
||||
return page;
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,11 @@ public class BalancesController : ControllerBase
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取记录分页
|
||||
/// 获取所有消费记录分页
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize(Roles = "admin,tenant-admin")]
|
||||
[DataPermission]
|
||||
[HttpGet]
|
||||
public async Task<Pagination<BalanceRecordResponse>> GetPageAsync([FromQuery] BalanceRecordPageRequest request)
|
||||
@@ -154,7 +155,7 @@ public class BalancesController : ControllerBase
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("spendingDetails")]
|
||||
public async Task<Pagination<SpendingDetailResponse>> GetSpendingDetailsAsync([FromQuery]SpendingDetailRequest request)
|
||||
public async Task<Pagination<SpendingDetailResponse>> GetSpendingDetailsAsync([FromQuery] SpendingDetailRequest request)
|
||||
{
|
||||
return await _balanceService.GetSpendingDetailsAsync(request);
|
||||
}
|
||||
@@ -181,27 +182,14 @@ public class BalancesController : ControllerBase
|
||||
return await _balanceService.GetConsumeDeviceAsync(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)
|
||||
[HttpGet("balanceOfMealSupplementRecordByUser")]
|
||||
public async Task<Pagination<BalanceRecordByUserResponse>> BalanceRecordByUserAsync([FromQuery] BalanceRecordByUserRequest request)
|
||||
{
|
||||
return await _balanceService.GetOaEMealVoucherDetailAsync(request);
|
||||
return await _balanceService.GetBalanceOfMealSupplementRecordByUser(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,21 +18,12 @@ namespace Dlhis.Canteen.Dishes.Controllers;
|
||||
public class OrdersController : ControllerBase
|
||||
{
|
||||
private readonly IOrderService _orderService;
|
||||
private readonly IBookingOrderService _bookingOrderService;
|
||||
|
||||
public OrdersController(IOrderService orderService)
|
||||
public OrdersController(IOrderService orderService, IBookingOrderService bookingOrderService)
|
||||
{
|
||||
_orderService = orderService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单分页
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("page")]
|
||||
public async Task<Pagination<OrderResponse>> GetPageAsync([FromQuery] OrderPageRequest request)
|
||||
{
|
||||
return await _orderService.GetPageAsync(request);
|
||||
_bookingOrderService = bookingOrderService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -59,25 +50,67 @@ public class OrdersController : ControllerBase
|
||||
return await _orderService.AddAsync(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单聚合数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("aggregation")]
|
||||
[IgnoreTenant]
|
||||
public async Task<Pagination<OrderAggregationResponse>> GetOrdersAggregationAsync([FromQuery] PageDto page)
|
||||
{
|
||||
return await _orderService.GetOrdersAggregationAsync(page);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消订单
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("user-cancel")]
|
||||
[Transactional]
|
||||
[IgnoreTenant]
|
||||
public async Task CancelOrderAsync(OrderCancelRequest request)
|
||||
{
|
||||
await _bookingOrderService.UserCancelOrderAsync(request);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 取消订单
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("manager-cancel")]
|
||||
[Transactional]
|
||||
[IgnoreTenant]
|
||||
public async Task ManagerCancelOrderAsync(OrderCancelRequest request)
|
||||
{
|
||||
await _bookingOrderService.ManagerCancelOrderAsync(request);
|
||||
}
|
||||
|
||||
//************************************************************** 订餐功能 **********************************************************************************
|
||||
|
||||
/// <summary>
|
||||
/// 订餐
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[IgnoreTenant]
|
||||
[HttpPost("booking")]
|
||||
public async Task Booking(BookingMealRequest request)
|
||||
[Transactional]
|
||||
[IgnoreTenant]
|
||||
public async Task<BookingResponse> Booking(BookingMealRequest request)
|
||||
{
|
||||
await _orderService.Booking(request);
|
||||
return await _bookingOrderService.BookingAsync(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 充值
|
||||
/// 订单分页
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("recharge")]
|
||||
public async Task ReCharge()
|
||||
[HttpGet("booking/page")]
|
||||
public async Task<Pagination<OrderBookingResponse>> GetBookingPageAsync([FromQuery] OrderBookingPageRequest request)
|
||||
{
|
||||
|
||||
return await _bookingOrderService.GetBookingPageAsync(request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Request;
|
||||
|
||||
public class BalanceRecordByUserRequest : PageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户档案号
|
||||
/// </summary>
|
||||
public string UserNo { get; set; }
|
||||
}
|
||||
@@ -3,7 +3,7 @@ using Kurisu.Core.CustomClass;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
namespace Dlhis.Canteen.Dishes.Request
|
||||
namespace Dlhis.Canteen.Order.Request
|
||||
{
|
||||
public class BalanceRecordUserPageRequest : PageDto, IValidatableObject
|
||||
{
|
||||
@@ -13,11 +13,17 @@ namespace Dlhis.Canteen.Dishes.Request
|
||||
[EnumDataType(typeof(DateTimeSearchEnumType))]
|
||||
public DateTimeSearchEnumType? SearchDateTimeDimension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消费应用类型
|
||||
/// </summary>
|
||||
public CanteenApplicaitonTypeEnumType? ApplicationType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 日期范围查询
|
||||
/// </summary>
|
||||
public DateTimePeriod SearchDateTimePeriod { get; set; }
|
||||
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
@@ -43,8 +49,8 @@ namespace Dlhis.Canteen.Dishes.Request
|
||||
}
|
||||
else if (SearchDateTimeDimension == DateTimeSearchEnumType.Season)
|
||||
{
|
||||
SearchDateTimePeriod.Start = now.AddMonths(0 - ((now.Month - 1) % 3));
|
||||
SearchDateTimePeriod.End = now.AddMonths(3 - ((now.Month - 1) % 3)).AddMonths(1).AddDays(-1);
|
||||
SearchDateTimePeriod.Start = now.AddMonths(0 - (now.Month - 1) % 3);
|
||||
SearchDateTimePeriod.End = now.AddMonths(3 - (now.Month - 1) % 3).AddMonths(1).AddDays(-1);
|
||||
}
|
||||
else if (SearchDateTimeDimension == DateTimeSearchEnumType.HalfOfYear)
|
||||
{
|
||||
|
||||
@@ -30,12 +30,28 @@ public class BookingMealRequest : IValidatableObject
|
||||
[Required(ErrorMessage = "选菜不能为空")]
|
||||
public string DishesCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 购买数量
|
||||
/// </summary>
|
||||
[Range(0, 100)]
|
||||
public int Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单位
|
||||
/// </summary>
|
||||
public string Unit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消费来源
|
||||
/// </summary>
|
||||
[EnumDataType(typeof(BalanceRecordSourceEnumType))]
|
||||
public BalanceRecordSourceEnumType Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 配送地址
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string DeliveryAddress { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
namespace Dlhis.Canteen.Dishes.Request
|
||||
{
|
||||
public class OaEMealVoucherDetailRequest : PageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 餐券id
|
||||
/// </summary>
|
||||
public long OaEMealVoucherId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using Dlhis.Entity.Canteen.Enums;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Dlhis.Canteen.Dishes.Request
|
||||
{
|
||||
public class OaEMealVoucherRequest : PageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户学工号
|
||||
/// </summary>
|
||||
public string UserCode { get; set; }
|
||||
}
|
||||
}
|
||||
14
Src/Dlhis.Canteen/Order/Request/OrderBookingPageRequest.cs
Normal file
14
Src/Dlhis.Canteen/Order/Request/OrderBookingPageRequest.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Dlhis.Entity.Canteen.Enums;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Request;
|
||||
|
||||
public class OrderBookingPageRequest : PageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单状态 CanteenOrderStatusEnumType
|
||||
/// </summary>
|
||||
[EnumDataType(typeof(CanteenOrderStatusEnumType))]
|
||||
public CanteenOrderStatusEnumType? OrderStatus { get; set; }
|
||||
}
|
||||
18
Src/Dlhis.Canteen/Order/Request/OrderCancelRequest.cs
Normal file
18
Src/Dlhis.Canteen/Order/Request/OrderCancelRequest.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Request;
|
||||
|
||||
public class OrderCancelRequest
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "订单号")]
|
||||
public string No { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 取消原因
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Reason { get; set; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Request;
|
||||
|
||||
public class OrderPageRequest : PageDto
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class BalanceRecordByUserResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 流水号
|
||||
/// </summary>
|
||||
public string No { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 金额
|
||||
/// </summary>
|
||||
public decimal Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消费时间
|
||||
/// </summary>
|
||||
public DateTime CostDateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
@@ -49,4 +49,15 @@ public class BalanceRecordUserResponse
|
||||
/// 记录产生日期
|
||||
/// </summary>
|
||||
public DateTime CostDateTime { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 消费应用类型
|
||||
/// </summary>
|
||||
public CanteenApplicaitonTypeEnumType ApplicationType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消费应用类型
|
||||
/// </summary>
|
||||
public string ApplicationTypeDesc => ApplicationType.GetDescription();
|
||||
}
|
||||
|
||||
32
Src/Dlhis.Canteen/Order/Response/BookingResponse.cs
Normal file
32
Src/Dlhis.Canteen/Order/Response/BookingResponse.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Dlhis.Entity.Canteen.Enums;
|
||||
using Kurisu.AspNetCore.Utils.Extensions;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class BookingResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string No { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消费金额
|
||||
/// </summary>
|
||||
public decimal Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付方式
|
||||
/// </summary>
|
||||
public BalanceRecordSourceEnumType Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付方式
|
||||
/// </summary>
|
||||
public string SourceDesc => Source.GetDescription();
|
||||
}
|
||||
34
Src/Dlhis.Canteen/Order/Response/DishesDto.cs
Normal file
34
Src/Dlhis.Canteen/Order/Response/DishesDto.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class DishesDto
|
||||
{
|
||||
[JsonIgnore]
|
||||
public string No { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜品编码
|
||||
/// </summary>
|
||||
public string DishesCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 菜品名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 购买单价
|
||||
/// </summary>
|
||||
public decimal Price { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 购买数量
|
||||
/// </summary>
|
||||
public int Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 图片
|
||||
/// </summary>
|
||||
public string ImageUrl { get; set; }
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
using Dlhis.Entity.Canteen.Enums;
|
||||
using Kurisu.AspNetCore.Utils.Extensions;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class GetDetailResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string ThirdNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 营业日
|
||||
/// </summary>
|
||||
public DateOnly SysDate { 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();
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Response
|
||||
{
|
||||
public class OaEMealVoucherDetailResponse
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
public long VoucherId { get; set; }
|
||||
|
||||
public int Sequence { get; set; }
|
||||
|
||||
public string DinnerType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 身份证
|
||||
/// </summary>
|
||||
public string IdNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用餐人
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 就餐开始
|
||||
/// </summary>
|
||||
public DateTime Start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 就餐结束
|
||||
/// </summary>
|
||||
public DateTime End { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 就餐天数
|
||||
/// </summary>
|
||||
public int Days { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 金额
|
||||
/// </summary>
|
||||
public decimal Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 二维码
|
||||
/// </summary>
|
||||
public string QrCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
public string Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 信息
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class OaEMealVoucherResponse
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标题
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 申请人工号
|
||||
/// </summary>
|
||||
public string UserCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 申请人名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 基地代码
|
||||
/// </summary>
|
||||
public string TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 基地名称
|
||||
/// </summary>
|
||||
public string TenantName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 成本中心
|
||||
/// </summary>
|
||||
public string CostId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 成本中心名称
|
||||
/// </summary>
|
||||
public string CostName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来宾公司
|
||||
/// </summary>
|
||||
public string Company { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 联系人
|
||||
/// </summary>
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 来宾人数
|
||||
/// </summary>
|
||||
public int Num { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 就餐食堂
|
||||
/// </summary>
|
||||
public string Canteen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 就餐事由
|
||||
/// </summary>
|
||||
public string Reason { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 就餐次
|
||||
/// </summary>
|
||||
public string CanteenShift { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// oa流程id
|
||||
/// </summary>
|
||||
public string OaId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 部门号
|
||||
/// </summary>
|
||||
public string DepartmentNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 部门名称
|
||||
/// </summary>
|
||||
public string DepartmentName { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 申请日期
|
||||
/// </summary>
|
||||
public DateTime LogDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据创建时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
}
|
||||
67
Src/Dlhis.Canteen/Order/Response/OrderAggregationResponse.cs
Normal file
67
Src/Dlhis.Canteen/Order/Response/OrderAggregationResponse.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using Dlhis.Entity.Canteen.Enums;
|
||||
using Kurisu.AspNetCore.Utils.Extensions;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class OrderAggregationResponse
|
||||
{
|
||||
public string No { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 营业点
|
||||
/// </summary>
|
||||
public string BusinessPlaceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 购买菜品
|
||||
/// </summary>
|
||||
public List<DishesDto> Dishes { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 金额
|
||||
/// </summary>
|
||||
public decimal Amount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Dishes.IsPresent())
|
||||
{
|
||||
return Dishes.Sum(x => x.Number * x.Price);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 共计数量
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Dishes.IsPresent())
|
||||
{
|
||||
return Dishes.Count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单状态
|
||||
/// </summary>
|
||||
public CanteenOrderStatusEnumType OrderStatus { get; set; }
|
||||
|
||||
|
||||
public string OrderStatusDesc => OrderStatus.GetDescription();
|
||||
}
|
||||
58
Src/Dlhis.Canteen/Order/Response/OrderBookingResponse.cs
Normal file
58
Src/Dlhis.Canteen/Order/Response/OrderBookingResponse.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Dlhis.Entity.Canteen.Enums;
|
||||
using Kurisu.AspNetCore.Utils.Extensions;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class OrderBookingResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string No { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 配送地址
|
||||
/// </summary>
|
||||
public string DeliveryAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单金额
|
||||
/// </summary>
|
||||
public decimal Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工号
|
||||
/// </summary>
|
||||
public string UserCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 餐次
|
||||
/// </summary>
|
||||
public ShiftEnumType? ShiftType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 餐次
|
||||
/// </summary>
|
||||
public string ShiftTypeDesc => ShiftType.GetDescription();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 订单时间
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
|
||||
public CanteenOrderStatusEnumType Status { get; set; }
|
||||
|
||||
public string StatusDesc => Status.GetDescription();
|
||||
}
|
||||
34
Src/Dlhis.Canteen/Order/Response/OrderDetailResponse.cs
Normal file
34
Src/Dlhis.Canteen/Order/Response/OrderDetailResponse.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
//namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
//public class OrderDetailResponse
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 菜品编码
|
||||
// /// </summary>
|
||||
// public string DishesCode { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// 菜品名称
|
||||
// /// </summary>
|
||||
// public string Name { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// 单价
|
||||
// /// </summary>
|
||||
// public decimal Price { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// 数量
|
||||
// /// </summary>
|
||||
// public int Number { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// 单位
|
||||
// /// </summary>
|
||||
// public string Unit { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// 图片
|
||||
// /// </summary>
|
||||
// public string ImageUrl { get; set; }
|
||||
//}
|
||||
@@ -1,5 +0,0 @@
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class OrderResponse
|
||||
{
|
||||
}
|
||||
@@ -35,7 +35,5 @@ public interface IBalanceService : IScopeDependency
|
||||
Task<Pagination<DevicePageResponse>> GetConsumeDeviceAsync(GetConsumeDeviceRequest request);
|
||||
|
||||
|
||||
Task<Pagination<OaEMealVoucherResponse>> GetOaEMealVoucherAsync([FromQuery] OaEMealVoucherRequest request);
|
||||
|
||||
Task<Pagination<OaEMealVoucherDetailResponse>> GetOaEMealVoucherDetailAsync([FromQuery] OaEMealVoucherDetailRequest request);
|
||||
Task<Pagination<BalanceRecordByUserResponse>> GetBalanceOfMealSupplementRecordByUser(BalanceRecordByUserRequest request);
|
||||
}
|
||||
|
||||
23
Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs
Normal file
23
Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Dlhis.Canteen.Dishes.Request;
|
||||
using Dlhis.Canteen.Order.Request;
|
||||
using Dlhis.Canteen.Order.Response;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Services;
|
||||
|
||||
public interface IBookingOrderService : IScopeDependency
|
||||
{
|
||||
/// <summary>
|
||||
/// 订餐
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
Task<BookingResponse> BookingAsync(BookingMealRequest request);
|
||||
|
||||
|
||||
Task<Pagination<OrderBookingResponse>> GetBookingPageAsync(OrderBookingPageRequest request);
|
||||
|
||||
Task UserCancelOrderAsync(OrderCancelRequest request);
|
||||
|
||||
Task ManagerCancelOrderAsync(OrderCancelRequest request);
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Dlhis.Canteen.Dishes.Request;
|
||||
using Dlhis.Canteen.Order.Request;
|
||||
using Dlhis.Canteen.Order.Request;
|
||||
using Dlhis.Canteen.Order.Response;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
|
||||
@@ -7,8 +6,7 @@ namespace Dlhis.Canteen.Order.Services;
|
||||
|
||||
public interface IOrderService : IScopeDependency
|
||||
{
|
||||
Task<Pagination<OrderResponse>> GetPageAsync(OrderPageRequest request);
|
||||
|
||||
|
||||
Task<OrderResultResponse> AddAsync(OrderAddRequest request);
|
||||
|
||||
/// <summary>
|
||||
@@ -18,10 +16,5 @@ public interface IOrderService : IScopeDependency
|
||||
/// <returns></returns>
|
||||
Task<OrderResultResponse> DeviceConsume(OrderAddRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// 订餐
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
Task Booking(BookingMealRequest request);
|
||||
Task<Pagination<OrderAggregationResponse>> GetOrdersAggregationAsync(PageDto page);
|
||||
}
|
||||
|
||||
@@ -521,13 +521,14 @@ public class BalanceService : IBalanceService
|
||||
.LeftJoin<GainfoEntity>((record, ga) => record.UserNo == ga.No)
|
||||
.LeftJoin<DepartmentEntity>((record, ga, department) => ga.DepartmentNo == department.No)
|
||||
.LeftJoin<BusinessPlaceEntity>((record, ga, department, bplace) => record.BusinessPlaceCode == bplace.Code)
|
||||
.LeftJoin<BusinessShiftEntity>((record, ga, department, bplace, bshift) => record.BusinessShiftCode == bshift.Code)
|
||||
.LeftJoin<BasicTypeEntity>((record, ga, department, bplace, bshift, type) => record.BusinessShiftCode.ToString() == type.Code)
|
||||
.LeftJoin<BusinessPlaceShiftRelationshipEntity>((record, ga, department, bplace, bshiftR) => bplace.Code == bshiftR.PlaceCode)
|
||||
.LeftJoin<BusinessShiftEntity>((record, ga, department, bplace, bshiftR, shift) => shift.Code == bshiftR.ShiftCode)
|
||||
.WhereIF(request.SearchDateTimePeriod?.Start.HasValue == true, record => record.CostDate >= request.SearchDateTimePeriod.Start)
|
||||
.WhereIF(request.SearchDateTimePeriod?.End.HasValue == true, record => record.CostDate <= request.SearchDateTimePeriod.End)
|
||||
.WhereIF(request.ApplicationType.HasValue, record => record.ApplicationType == request.ApplicationType)
|
||||
.Where((record, ga) => ga.IdentityUserId == userId)
|
||||
.OrderBy(record => record.CreateTime, OrderByType.Desc)
|
||||
.Select((record, ga, department, bplace, bshift, type) => new BalanceRecordUserResponse
|
||||
.Select((record, ga, department, bplace, bshiftR, shift) => new BalanceRecordUserResponse
|
||||
{
|
||||
Id = record.Id,
|
||||
Amount = record.Amount,
|
||||
@@ -536,8 +537,9 @@ public class BalanceService : IBalanceService
|
||||
Source = record.Source,
|
||||
No = record.No,
|
||||
BusinessPlaceName = bplace.Name,
|
||||
BusinessShiftName = type.Display,
|
||||
CostDateTime = record.CostDateTime
|
||||
BusinessShiftName = shift.Name,
|
||||
CostDateTime = record.CostDateTime,
|
||||
ApplicationType = record.ApplicationType,
|
||||
})
|
||||
.ToPageListAsync(request);
|
||||
|
||||
@@ -558,12 +560,12 @@ public class BalanceService : IBalanceService
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
//重算金额
|
||||
var canteenUser = await _dbContext.Queryable<CanteenUserEntity>().Where(x => x.UserNo == balanceRecord.UserNo).SingleAsync();
|
||||
var canteenUser = await _dbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == balanceRecord.UserNo).SingleAsync();
|
||||
|
||||
//金额 +
|
||||
canteenUser.Balance += Math.Abs(balanceRecord.Amount);
|
||||
|
||||
var effect = await _dbContext.Updateable<CanteenUserEntity>()
|
||||
var effect = await _dbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == canteenUser.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == balanceRecord.UserNo && x.Version == canteenUser.Version)
|
||||
@@ -742,6 +744,25 @@ public class BalanceService : IBalanceService
|
||||
return page;
|
||||
}
|
||||
|
||||
public async Task<Pagination<BalanceRecordByUserResponse>> GetBalanceOfMealSupplementRecordByUser(BalanceRecordByUserRequest request)
|
||||
{
|
||||
var page = await _dbContext.Queryable<BalanceRecordEntity>()
|
||||
.Where(x => x.Source == BalanceRecordSourceEnumType.LocalTenantSubsidies || x.Source == BalanceRecordSourceEnumType.OtherTenantSubsidies)
|
||||
.Where(x => x.UserNo == request.UserNo)
|
||||
.Select<BalanceRecordByUserResponse>()
|
||||
.ToPageListAsync(request);
|
||||
|
||||
page.Data.Add(new BalanceRecordByUserResponse
|
||||
{
|
||||
Amount = 20,
|
||||
CostDateTime = DateTime.Now.Date,
|
||||
Remark = "2024-03-21 餐补",
|
||||
No = "129876578"
|
||||
});
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取离线设备
|
||||
@@ -839,26 +860,6 @@ public class BalanceService : IBalanceService
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public async Task<Pagination<OaEMealVoucherResponse>> GetOaEMealVoucherAsync(OaEMealVoucherRequest request)
|
||||
{
|
||||
var page = await _dbContext.Queryable<OaEMealVoucherEntity>()
|
||||
.Where(x => x.UserCode == request.UserCode)
|
||||
.Select<OaEMealVoucherResponse>()
|
||||
.ToPageListAsync(request);
|
||||
return page;
|
||||
}
|
||||
|
||||
public async Task<Pagination<OaEMealVoucherDetailResponse>> GetOaEMealVoucherDetailAsync(OaEMealVoucherDetailRequest request)
|
||||
{
|
||||
var page = await _dbContext.Queryable<OaEMealVoucherDetailEntity>()
|
||||
.Where(x => x.VoucherId == request.OaEMealVoucherId)
|
||||
.Select<OaEMealVoucherDetailResponse>()
|
||||
.ToPageListAsync(request);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前年所有月
|
||||
/// </summary>
|
||||
|
||||
129
Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs
Normal file
129
Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using Dlhis.Basic.Api;
|
||||
using Dlhis.Canteen.Setting.Services;
|
||||
using Dlhis.Entity.Basic.Entity;
|
||||
using Dlhis.Entity.Canteen.Enums;
|
||||
using Kurisu.AspNetCore.UnifyResultAndValidation;
|
||||
using Kurisu.AspNetCore.Utils.Extensions;
|
||||
using Kurisu.Core.User.Abstractions;
|
||||
using Kurisu.SqlSugar.Services;
|
||||
using Mapster;
|
||||
using SqlSugar;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Services.Implements;
|
||||
|
||||
public abstract class BaseOrderService
|
||||
{
|
||||
private readonly ICanteenSettingService _canteenSettingService;
|
||||
private readonly IDbContext _dbContext;
|
||||
private readonly ICurrentUser _currentUser;
|
||||
private readonly IDevicePermissionApi _devicePermissionApi;
|
||||
private readonly ILogger _logger;
|
||||
private Dictionary<CanteenSettingItemEnumType, string> _settings;
|
||||
|
||||
public BaseOrderService(ICanteenSettingService canteenSettingService,
|
||||
IDbContext dbContext,
|
||||
ICurrentUser currentUser,
|
||||
IDevicePermissionApi devicePermissionApi,
|
||||
ILogger logger)
|
||||
{
|
||||
_canteenSettingService = canteenSettingService;
|
||||
_dbContext = dbContext;
|
||||
_currentUser = currentUser;
|
||||
_devicePermissionApi = devicePermissionApi;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
protected IDbContext DbContext => _dbContext;
|
||||
|
||||
protected ICurrentUser CurrentUser => _currentUser;
|
||||
|
||||
/// <summary>
|
||||
/// 检查权限
|
||||
/// </summary>
|
||||
/// <param name="userNo"></param>
|
||||
/// <param name="deviceUniqueNo"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task CheckPermissionAsync(string userNo, string deviceUniqueNo)
|
||||
{
|
||||
var uniqueNosResult = await _devicePermissionApi.GetCanteenDeviceUniqueNosByUserNoAsync(userNo);
|
||||
var uniqueNos = uniqueNosResult.Data;
|
||||
|
||||
uniqueNos.Contains(deviceUniqueNo).ThrowIfFalse("无消费权限");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设备并发更新 需要抛出VersionExceptions
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="func"></param>
|
||||
/// <param name="retry">并发冲突处理次数</param>
|
||||
/// <param name="errorMessage"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
protected async Task ContinueUpdateAsync(Func<Task> func, int retry, string errorMessage = null)
|
||||
{
|
||||
for (int i = 0; i < retry; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
await func();
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (ex is VersionExceptions)
|
||||
{
|
||||
_logger.LogWarning(ex, ex.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
throw new UserFriendlyException(errorMessage ?? "操作失败,请重试");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取参数配置
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<T> GetSettingAsync<T>(CanteenSettingItemEnumType item, T defaultValue = default)
|
||||
{
|
||||
if (_settings == null)
|
||||
{
|
||||
var subjectId = _currentUser.GetIntSubjectId();
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdentityUserId == subjectId).FirstAsync();
|
||||
var jinkoCode = _currentUser.GetUserClaim("jinko-code") ?? string.Empty;
|
||||
if (jinkoCode.IsPresent())
|
||||
{
|
||||
gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
}
|
||||
_settings = await _canteenSettingService.GetUserSettingAsync(gainfo.No);
|
||||
}
|
||||
|
||||
|
||||
if (_settings.TryGetValue(item, out var v))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (int.TryParse(v, out var n))
|
||||
{
|
||||
return n.Adapt<T>();
|
||||
}
|
||||
|
||||
return v.Adapt<T>();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
using Dlhis.Canteen.Dishes.Request;
|
||||
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 Kurisu.AspNetCore.Utils.Extensions;
|
||||
using Kurisu.AspNetCore.Utils;
|
||||
using Kurisu.Core.DataAccess.Dto;
|
||||
using Kurisu.SqlSugar.Services;
|
||||
using Kurisu.Core.User.Abstractions;
|
||||
using Dlhis.Canteen.Setting.Services;
|
||||
using Dlhis.Basic.Api;
|
||||
using Kurisu.SqlSugar.Extensions;
|
||||
using SqlSugar;
|
||||
using Mapster;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Services.Implements;
|
||||
|
||||
public class BookingOrderService : BaseOrderService, IBookingOrderService
|
||||
{
|
||||
private readonly IDisheMenuApi _disheMenuApi;
|
||||
private readonly IBusinessPlacePermissionsApi _businessPlacePermissionsApi;
|
||||
|
||||
public BookingOrderService(ICanteenSettingService canteenSettingService, IDbContext dbContext,
|
||||
IDisheMenuApi disheMenuApi,
|
||||
IBusinessPlacePermissionsApi businessPlacePermissionsApi,
|
||||
ICurrentUser currentUser, IDevicePermissionApi devicePermissionApi, ILogger<BookingOrderService> logger)
|
||||
: base(canteenSettingService, dbContext, currentUser, devicePermissionApi, logger)
|
||||
{
|
||||
_disheMenuApi = disheMenuApi;
|
||||
_businessPlacePermissionsApi = businessPlacePermissionsApi;
|
||||
}
|
||||
|
||||
public async Task<BookingResponse> BookingAsync(BookingMealRequest request)
|
||||
{
|
||||
var gainfo = await CheckExistsMyBookingsAsync(request.BookingDate, request.ShiftType);
|
||||
|
||||
var businessPlace = await DbContext.Queryable<BusinessPlaceEntity>().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync();
|
||||
|
||||
//预定时间
|
||||
var now = DateTime.Now;
|
||||
|
||||
var bookingDeadline = await GetSettingAsync<TimeOnly?>(CanteenSettingItemEnumType.BookingDeadline) ?? new TimeOnly(20, 30, 00);
|
||||
var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan());
|
||||
(now >= dealLine).ThrowIfTrue("超出订餐时间");
|
||||
|
||||
//菜单存在
|
||||
var menuDetailResult = await _disheMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode);
|
||||
var menuDetail = menuDetailResult.Data;
|
||||
menuDetail.ThrowIfNull("预定失败,菜品已经下架");
|
||||
|
||||
var order = new CanteenOrderEntity
|
||||
{
|
||||
RequestJson = request.ToJson(),
|
||||
ThirdNo = string.Empty,
|
||||
Type = BalanceRecordTypeEnumType.Out,
|
||||
ApplicationType = CanteenApplicaitonTypeEnumType.Booking,
|
||||
Name = gainfo.Name,
|
||||
Source = request.Source,
|
||||
UserNo = gainfo.No,
|
||||
UserCode = gainfo.Code,
|
||||
Amount = -Math.Abs(menuDetail.Price * request.Number),
|
||||
BusinessPlaceCode = request.BusinessPlaceCode,
|
||||
BusinessShiftCode = null,
|
||||
ShiftType = request.ShiftType,
|
||||
CostDate = now.Date,
|
||||
CostId = gainfo.CostId,
|
||||
DepartmentNo = gainfo.DepartmentNo,
|
||||
DeviceUniqueNo = string.Empty,
|
||||
DeliveryAddress = request.DeliveryAddress,
|
||||
|
||||
No = SnowFlakeHelper.Instance.NextId().ToString(),
|
||||
SubsidiesFromMonth = now.ToString("yyyyMM"),
|
||||
IsOffline = false,
|
||||
IsCostCrossTenant = await GetSettingAsync<bool>(CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
|
||||
OriginTenantId = gainfo.Factory,//人员可能跨基地消费
|
||||
|
||||
Status = BalanceRecordStatusEnumType.Valid,
|
||||
OrderStatus = CanteenOrderStatusEnumType.Success,
|
||||
|
||||
CostDateTime = now,
|
||||
|
||||
//标识当前消费的基地
|
||||
TenantId = businessPlace.TenantId,
|
||||
};
|
||||
|
||||
var orderId = await DbContext.InsertReturnIdentityAsync(order);
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
await _disheMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode);
|
||||
var menuDetail = menuDetailResult.Data;
|
||||
menuDetail.ThrowIfNull("预定失败,菜品已经下架");
|
||||
menuDetail.Number -= request.Number;
|
||||
|
||||
(menuDetail.Number < 0).ThrowIfTrue($"{menuDetail.DishesName}已售罄");
|
||||
|
||||
//餐补
|
||||
if (request.Source == BalanceRecordSourceEnumType.LocalTenantSubsidies)
|
||||
{
|
||||
|
||||
var mealInfo = await DbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
if (mealInfo == null)
|
||||
{
|
||||
await DbContext.InsertAsync(new GainfoMealEntity
|
||||
{
|
||||
Balance = 0,
|
||||
BalanceOfRecharge = 0,
|
||||
BalanceOfSubsidies = 0,
|
||||
UserCode = gainfo.Code,
|
||||
UserNo = gainfo.No,
|
||||
Version = 0,
|
||||
});
|
||||
|
||||
(mealInfo == null).ThrowIfTrue("余额不足,无法消费");
|
||||
}
|
||||
//金额+-
|
||||
mealInfo.Balance += order.Amount;
|
||||
(mealInfo.Balance < 0).ThrowIfTrue("余额不足,无法消费");
|
||||
|
||||
var effectMeal = await DbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == mealInfo.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == order.UserNo && x.Version == mealInfo.Version)//必须与查询时的version一致
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effectMeal <= 0) throw new VersionExceptions("更新版本冲突");
|
||||
}
|
||||
|
||||
|
||||
var effectMenu = await DbContext.Updateable<DishesMenuEntity>()
|
||||
.SetColumns(x => x.Number == menuDetail.Number)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.Where(x => x.StartDate <= menuDetail.Date && menuDetail.Date <= x.EndDate
|
||||
&& x.ShiftType == request.ShiftType
|
||||
&& x.BusinessPlaceCode == request.BusinessPlaceCode
|
||||
&& x.DishesCode == request.DishesCode
|
||||
&& x.Version == menuDetail.Version
|
||||
)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effectMenu <= 0) throw new VersionExceptions("更新版本冲突");
|
||||
|
||||
//写入记录
|
||||
var balanceRecord = order.Adapt<BalanceRecordEntity>();
|
||||
await DbContext.InsertAsync(balanceRecord);
|
||||
|
||||
await DbContext.InsertAsync(new CanteenOrderDetailEntity
|
||||
{
|
||||
OrderNo = order.No,
|
||||
BookingDate = request.BookingDate,
|
||||
DishesCode = request.DishesCode,
|
||||
Price = menuDetail.Price,
|
||||
Unit = request.Unit,
|
||||
Number = 1,
|
||||
TenantId = order.TenantId,
|
||||
});
|
||||
|
||||
}, 10);
|
||||
|
||||
|
||||
return new BookingResponse
|
||||
{
|
||||
No = order.No,
|
||||
CreateTime = order.CreateTime,
|
||||
Source = order.Source,
|
||||
Amount = Math.Abs(order.Amount)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public async Task<Pagination<OrderBookingResponse>> GetBookingPageAsync(OrderBookingPageRequest request)
|
||||
{
|
||||
var myCodes = (await _businessPlacePermissionsApi.GetMyAsync()).Data.Select(x => (Guid?)x.Code).ToList();
|
||||
|
||||
var page = await DbContext.Queryable<CanteenOrderEntity>()
|
||||
.LeftJoin<GainfoEntity>((x, ga) => x.UserNo == ga.No)
|
||||
.Where(x => myCodes.Contains(x.BusinessPlaceCode))
|
||||
.WhereIF(request.OrderStatus.HasValue, x => x.OrderStatus == request.OrderStatus)
|
||||
.WhereIF(request.Search.IsPresent(), (x, ga) => x.UserCode == request.Search || ga.Name.Contains(request.Search))
|
||||
.Select((x, ga) => new OrderBookingResponse
|
||||
{
|
||||
No = x.No,
|
||||
DeliveryAddress = x.DeliveryAddress,
|
||||
Remark = x.Remark,
|
||||
Amount = x.Amount,
|
||||
CreateTime = x.CreateTime,
|
||||
ShiftType = x.ShiftType,
|
||||
Status = x.OrderStatus,
|
||||
UserCode = x.UserCode,
|
||||
UserName = ga.Name
|
||||
})
|
||||
.ToPageListAsync(request);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
public async Task UserCancelOrderAsync(OrderCancelRequest request)
|
||||
{
|
||||
//预定时间
|
||||
var now = DateTime.Now;
|
||||
var userId = CurrentUser.GetIntSubjectId();
|
||||
|
||||
var bookingDeadline = await GetSettingAsync<TimeOnly?>(CanteenSettingItemEnumType.BookingDeadline) ?? new TimeOnly(20, 30, 00);
|
||||
var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan());
|
||||
(now >= dealLine).ThrowIfTrue("不在订单取消允许范围内,不可操作");
|
||||
|
||||
var order = await DbContext.Queryable<CanteenOrderEntity>().Where(x => x.No == request.No).FirstAsync();
|
||||
order.ThrowIfNull("订单不存在");
|
||||
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Cancel)
|
||||
.SetColumns(x => x.Remark == request.Reason)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.SetColumns(x => x.ModifiedBy == userId)
|
||||
.Where(x => x.No == request.No)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
var balance = await DbContext.Queryable<BalanceRecordEntity>().Where(x => x.No == request.No).SingleAsync();
|
||||
await DbContext.Updateable<BalanceRecordEntity>()
|
||||
.SetColumns(x => x.Status == BalanceRecordStatusEnumType.Obsolute)
|
||||
.SetColumns(x => x.Remark == request.Reason)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.SetColumns(x => x.ModifiedBy == userId)
|
||||
.Where(x => x.No == request.No)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
var amount = Math.Abs(order.Amount);
|
||||
|
||||
//尝试5次
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
var mealInfo = await DbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
|
||||
var effect = await DbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == x.Balance + amount)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.SetColumns(x => x.ModifiedBy == userId)
|
||||
.Where(x => x.Id == mealInfo.Id && x.Version == mealInfo.Version)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effect <= 0)
|
||||
{
|
||||
throw new VersionExceptions("取消订单失败!");
|
||||
}
|
||||
|
||||
}, 5);
|
||||
}
|
||||
|
||||
|
||||
public async Task ManagerCancelOrderAsync(OrderCancelRequest request)
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
var userId = CurrentUser.GetIntSubjectId();
|
||||
|
||||
var order = await DbContext.Queryable<CanteenOrderEntity>().Where(x => x.No == request.No).FirstAsync();
|
||||
order.ThrowIfNull("订单不存在");
|
||||
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Cancel)
|
||||
.SetColumns(x => x.Remark == request.Reason)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.SetColumns(x => x.ModifiedBy == userId)
|
||||
.Where(x => x.No == request.No)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
var balance = await DbContext.Queryable<BalanceRecordEntity>().Where(x => x.No == request.No).SingleAsync();
|
||||
await DbContext.Updateable<BalanceRecordEntity>()
|
||||
.SetColumns(x => x.Status == BalanceRecordStatusEnumType.Obsolute)
|
||||
.SetColumns(x => x.Remark == request.Reason)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.SetColumns(x => x.ModifiedBy == userId)
|
||||
.Where(x => x.No == request.No)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
var amount = Math.Abs(order.Amount);
|
||||
|
||||
//尝试5次
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
var mealInfo = await DbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
|
||||
var effect = await DbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == x.Balance + amount)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.SetColumns(x => x.ModifiedBy == userId)
|
||||
.Where(x => x.Id == mealInfo.Id && x.Version == mealInfo.Version)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effect <= 0)
|
||||
{
|
||||
throw new VersionExceptions("取消订单失败!");
|
||||
}
|
||||
|
||||
}, 5);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查我的订餐是否存在,存在抛出异常
|
||||
/// </summary>
|
||||
/// <param name="bookingDate"></param>
|
||||
/// <param name="shiftType"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<GainfoEntity> CheckExistsMyBookingsAsync(DateTime bookingDate, ShiftEnumType shiftType)
|
||||
{
|
||||
var subjectId = CurrentUser.GetIntSubjectId();
|
||||
var gainfo = await DbContext.Queryable<GainfoEntity>().Where(x => x.IdentityUserId == subjectId).FirstAsync();
|
||||
var jinkoCode = CurrentUser.GetUserClaim("jinko-code") ?? string.Empty;
|
||||
if (jinkoCode.IsPresent())
|
||||
{
|
||||
gainfo = await DbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
}
|
||||
|
||||
var start = bookingDate.Date.AddDays(-1);
|
||||
var end = start.AddDays(1).AddSeconds(-1);
|
||||
|
||||
var exists = await DbContext.Queryable<CanteenOrderEntity>()
|
||||
.Where(x => x.ApplicationType == CanteenApplicaitonTypeEnumType.Booking)
|
||||
.Where(x => x.OrderStatus == CanteenOrderStatusEnumType.Success)
|
||||
.Where(x => x.ShiftType == shiftType)
|
||||
.Where(x => x.UserNo == gainfo.No)
|
||||
.Where(x => x.CreateTime >= start && x.CreateTime <= end)
|
||||
.AnyAsync();
|
||||
|
||||
exists.ThrowIfTrue("不可重复订餐");
|
||||
|
||||
return gainfo;
|
||||
}
|
||||
}
|
||||
@@ -21,154 +21,15 @@ using Dlhis.Canteen.Order.Request;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Services.Implements;
|
||||
|
||||
public class OrderService : IOrderService
|
||||
public class OrderService : BaseOrderService, IOrderService
|
||||
{
|
||||
private readonly IDbContext _dbContext;
|
||||
private readonly ICanteenSettingService _canteenSettingService;
|
||||
private readonly IDevicePermissionApi _devicePermissionApi;
|
||||
private readonly ICurrentUser _currentUser;
|
||||
private readonly IDisheMenuApi _disheMenuApi;
|
||||
private readonly ILogger<OrderService> _logger;
|
||||
|
||||
public OrderService(IDbContext dbContext,
|
||||
ICanteenSettingService canteenSettingService,
|
||||
IDevicePermissionApi devicePermissionApi,
|
||||
ICurrentUser currentUser,
|
||||
IDisheMenuApi disheMenuApi,
|
||||
public OrderService(ICanteenSettingService canteenSettingService, IDbContext dbContext,
|
||||
ICurrentUser currentUser, IDevicePermissionApi devicePermissionApi,
|
||||
ILogger<OrderService> logger)
|
||||
: base(canteenSettingService, dbContext, currentUser, devicePermissionApi, logger)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_canteenSettingService = canteenSettingService;
|
||||
_devicePermissionApi = devicePermissionApi;
|
||||
_currentUser = currentUser;
|
||||
_disheMenuApi = disheMenuApi;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<Pagination<OrderResponse>> GetPageAsync(OrderPageRequest request)
|
||||
{
|
||||
var page = await _dbContext.Queryable<CanteenOrderEntity>()
|
||||
.Select<OrderResponse>()
|
||||
.ToPageListAsync(request);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
private async Task CheckPAsync(string userNo, string deviceUniqueNo)
|
||||
{
|
||||
var uniqueNosResult = await _devicePermissionApi.GetCanteenDeviceUniqueNosByUserNoAsync(userNo);
|
||||
var uniqueNos = uniqueNosResult.Data;
|
||||
|
||||
uniqueNos.Contains(deviceUniqueNo).ThrowIfFalse("无消费权限");
|
||||
}
|
||||
|
||||
public async Task Booking(BookingMealRequest request)
|
||||
{
|
||||
await CheckExistsMyBookingsAsync(request.BookingDate);
|
||||
|
||||
var jinkoCode = _currentUser.GetUserClaim("jinko-code");
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
|
||||
var businessPlace = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync();
|
||||
|
||||
//预定时间
|
||||
var now = DateTime.Now;
|
||||
|
||||
var settings = await _canteenSettingService.GetUserSettingAsync(gainfo.Code);
|
||||
var bookingDeadline = GetSetting<TimeOnly?>(settings, CanteenSettingItemEnumType.BookingDeadline) ?? new TimeOnly(20, 30, 00);
|
||||
var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan());
|
||||
(now >= dealLine).ThrowIfTrue("超出订餐时间");
|
||||
|
||||
//菜单存在
|
||||
var menuDetailResult = await _disheMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode);
|
||||
var menuDetail = menuDetailResult.Data;
|
||||
menuDetail.ThrowIfNull("预定失败,菜品已经下架");
|
||||
|
||||
var order = new CanteenOrderEntity
|
||||
{
|
||||
RequestJson = request.ToJson(),
|
||||
ThirdNo = string.Empty,
|
||||
Type = BalanceRecordTypeEnumType.Out,
|
||||
ApplicationType = CanteenApplicaitonTypeEnumType.Booking,
|
||||
Name = gainfo.Name,
|
||||
Source = request.Source,
|
||||
UserNo = gainfo.No,
|
||||
UserCode = gainfo.Code,
|
||||
Amount = -Math.Abs(menuDetail.Price),
|
||||
BusinessPlaceCode = request.BusinessPlaceCode,
|
||||
BusinessShiftCode = null,
|
||||
ShiftType = request.ShiftType,
|
||||
CostDate = now.Date,
|
||||
CostId = gainfo.CostId,
|
||||
DepartmentNo = gainfo.DepartmentNo,
|
||||
DeviceUniqueNo = string.Empty,
|
||||
|
||||
No = SnowFlakeHelper.Instance.NextId().ToString(),
|
||||
SubsidiesFromMonth = now.ToString("yyyyMM"),
|
||||
IsOffline = false,
|
||||
IsCostCrossTenant = GetSetting<bool>(settings, CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
|
||||
OriginTenantId = gainfo.Factory,//人员可能跨基地消费
|
||||
|
||||
Status = BalanceRecordStatusEnumType.Valid,
|
||||
OrderStatus = CanteenOrderStatusEnumType.Successful,
|
||||
|
||||
CostDateTime = now,
|
||||
|
||||
//标识当前消费的基地
|
||||
TenantId = businessPlace.TenantId,
|
||||
};
|
||||
|
||||
var orderId = await _dbContext.InsertReturnIdentityAsync(order);
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
await _disheMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode);
|
||||
var menuDetail = menuDetailResult.Data;
|
||||
menuDetail.ThrowIfNull("预定失败,菜品已经下架");
|
||||
menuDetail.Number -= 1;
|
||||
|
||||
(menuDetail.Number < 0).ThrowIfTrue($"{menuDetail.DishesName}已售罄");
|
||||
|
||||
var canteenUser = await _dbContext.Queryable<CanteenUserEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
//金额+-
|
||||
canteenUser.Balance += order.Amount;
|
||||
(canteenUser.Balance < 0).ThrowIfTrue("余额不足,无法消费");
|
||||
|
||||
var effect = await _dbContext.Updateable<CanteenUserEntity>()
|
||||
.SetColumns(x => x.Balance == canteenUser.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == order.UserNo && x.Version == canteenUser.Version)//必须与查询时的version一致
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effect <= 0) throw new VersionExceptions("更新版本冲突");
|
||||
|
||||
effect = await _dbContext.Updateable<DishesMenuEntity>()
|
||||
.SetColumns(x => x.Number == menuDetail.Number)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.Where(x => x.Date == menuDetail.Date && x.ShiftType == request.ShiftType && x.BusinessPlaceCode == request.BusinessPlaceCode && x.Version == menuDetail.Version)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effect <= 0) throw new VersionExceptions("更新版本冲突");
|
||||
|
||||
//写入记录
|
||||
var balanceRecord = order.Adapt<BalanceRecordEntity>();
|
||||
await _dbContext.InsertAsync(balanceRecord);
|
||||
|
||||
await _dbContext.InsertAsync(new OrderDetailEntity
|
||||
{
|
||||
OrderNo = order.No,
|
||||
DishesCode = request.DishesCode,
|
||||
Price = menuDetail.Price,
|
||||
Status = OrderDetailsStatusEnumType.I,
|
||||
//Unit
|
||||
Number = 1,
|
||||
});
|
||||
|
||||
}, 10);
|
||||
}
|
||||
|
||||
|
||||
public async Task<OrderResultResponse> DeviceConsume(OrderAddRequest request)
|
||||
{
|
||||
return await AddAsync(request);
|
||||
@@ -180,27 +41,26 @@ public class OrderService : IOrderService
|
||||
_ = long.TryParse(request.UserUniqueNo, out var userId);
|
||||
|
||||
//根据档案号
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>()
|
||||
var gainfo = await DbContext.Queryable<GainfoEntity>()
|
||||
.Where(x => x.No == request.UserUniqueNo || x.Code == request.UserUniqueNo || x.Id == userId || x.CardNo == request.UserUniqueNo)
|
||||
.FirstAsync();
|
||||
|
||||
gainfo.ThrowIfNull($"无消费权限");
|
||||
//消费权限控制
|
||||
await CheckPAsync(gainfo.No, request.DeviceUniqueNo);
|
||||
await CheckPermissionAsync(gainfo.No, request.DeviceUniqueNo);
|
||||
|
||||
var canteenUserExists = await _dbContext.Queryable<CanteenUserEntity>()
|
||||
var canteenUserExists = await DbContext.Queryable<GainfoMealEntity>()
|
||||
.Where(x => x.UserNo == gainfo.No)
|
||||
.AnyAsync();
|
||||
|
||||
if (!canteenUserExists)
|
||||
{
|
||||
await _dbContext.InsertAsync(new CanteenUserEntity
|
||||
await DbContext.InsertAsync(new GainfoMealEntity
|
||||
{
|
||||
UserNo = gainfo.No,
|
||||
Balance = 0,
|
||||
BalanceOfRecharge = 0,
|
||||
BalanceOfSubsidies = 0,
|
||||
UserType = CanteenUserEnumType.LocalTenant,
|
||||
TenantId = gainfo.Factory,
|
||||
Version = 0,
|
||||
|
||||
@@ -223,9 +83,9 @@ public class OrderService : IOrderService
|
||||
}
|
||||
|
||||
//获取人员余额
|
||||
return await _dbContext.Queryable<GainfoEntity>()
|
||||
return await DbContext.Queryable<GainfoEntity>()
|
||||
.LeftJoin<DepartmentEntity>((ga, department) => ga.DepartmentNo == department.No)
|
||||
.LeftJoin<CanteenUserEntity>((ga, department, mealUser) => ga.No == mealUser.UserNo)
|
||||
.LeftJoin<GainfoMealEntity>((ga, department, mealUser) => ga.No == mealUser.UserNo)
|
||||
.Where(ga => ga.Id == gainfo.Id)
|
||||
.Select((ga, department, mealUser) => new OrderResultResponse
|
||||
{
|
||||
@@ -246,11 +106,11 @@ public class OrderService : IOrderService
|
||||
/// <returns></returns>
|
||||
private async Task ConsumeAsync(ConsumeRequest request, GainfoEntity gainfo)
|
||||
{
|
||||
var device = await _dbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == request.DeviceUniqueNo).Where(x => x.Enable).FirstAsync();
|
||||
var device = await DbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == request.DeviceUniqueNo).Where(x => x.Enable).FirstAsync();
|
||||
device.ThrowIfNull("设备不存在或者尚未启用");
|
||||
var registry = await _dbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.DeviceUniqueNo).FirstAsync();
|
||||
var registry = await DbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.DeviceUniqueNo).FirstAsync();
|
||||
registry.ThrowIfNull("设备尚未注册");
|
||||
var businessPlaceInfo = await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||
var businessPlaceInfo = await DbContext.Queryable<BusinessPlaceEntity>()
|
||||
.LeftJoin<BusinessPlaceShiftRelationshipEntity>((x, sr) => x.Code == sr.PlaceCode)
|
||||
.Where(x => x.Code == registry.BusinessPlaceCode)
|
||||
.Select((x, sr) => new
|
||||
@@ -263,7 +123,7 @@ public class OrderService : IOrderService
|
||||
businessPlaceInfo.ThrowIfNull("营业点尚未设置");
|
||||
|
||||
//获取当前消费餐次
|
||||
var shifts = await _dbContext.Queryable<BusinessShiftMealRelationshipEntity>().Where(x => x.ShiftCode == businessPlaceInfo.ShiftCode).ToListAsync();
|
||||
var shifts = await DbContext.Queryable<BusinessShiftMealRelationshipEntity>().Where(x => x.ShiftCode == businessPlaceInfo.ShiftCode).ToListAsync();
|
||||
|
||||
var shift = shifts.FirstOrDefault(x => new TimePeriod()
|
||||
{
|
||||
@@ -272,8 +132,7 @@ public class OrderService : IOrderService
|
||||
|
||||
}.IsPresent1(request.CostDateTime));
|
||||
|
||||
var settings = await _canteenSettingService.GetUserSettingAsync(request.UserUniqueNo);
|
||||
var switchTime = GetSetting<TimeOnly?>(settings, CanteenSettingItemEnumType.BusinessSwitchTime);
|
||||
var switchTime = await GetSettingAsync<TimeOnly?>(CanteenSettingItemEnumType.BusinessSwitchTime);
|
||||
|
||||
var shiftTimePeriod = new TimePeriod()
|
||||
{
|
||||
@@ -321,7 +180,7 @@ public class OrderService : IOrderService
|
||||
No = SnowFlakeHelper.Instance.NextId().ToString(),
|
||||
SubsidiesFromMonth = request.CostDateTime.ToString("yyyyMM"),
|
||||
IsOffline = request.IsOffline,
|
||||
IsCostCrossTenant = GetSetting<bool>(settings, CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
IsCostCrossTenant = await GetSettingAsync<bool>(CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
|
||||
OriginTenantId = gainfo.Factory,//人员可能跨基地消费
|
||||
|
||||
@@ -336,14 +195,14 @@ public class OrderService : IOrderService
|
||||
TenantId = businessPlaceInfo.TenantId,
|
||||
};
|
||||
|
||||
var orderId = await _dbContext.InsertReturnIdentityAsync(order);
|
||||
var orderId = await DbContext.InsertReturnIdentityAsync(order);
|
||||
try
|
||||
{
|
||||
await GenerateConsumeRecordAsync(orderId, settings, shifts, request.CostDateTime);
|
||||
await GenerateConsumeRecordAsync(orderId, shifts, request.CostDateTime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await _dbContext.Updateable<CanteenOrderEntity>()
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Failure)
|
||||
.SetColumns(x => x.Result == ex.Message)
|
||||
.SetColumns(x => x.ModifiedTime == DateTime.Now)
|
||||
@@ -353,8 +212,8 @@ public class OrderService : IOrderService
|
||||
throw;
|
||||
}
|
||||
|
||||
await _dbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Successful)
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Success)
|
||||
.SetColumns(x => x.ModifiedTime == DateTime.Now)
|
||||
.Where(x => x.Id == orderId)
|
||||
.ExecuteCommandAsync();
|
||||
@@ -368,8 +227,6 @@ public class OrderService : IOrderService
|
||||
/// <returns></returns>
|
||||
private async Task RechargeAsync(RechargeRequest request, GainfoEntity gainfo)
|
||||
{
|
||||
var settings = await _canteenSettingService.GetUserSettingAsync(request.UserUniqueNo);
|
||||
|
||||
var order = new CanteenOrderEntity
|
||||
{
|
||||
RequestJson = request.ToJson(),
|
||||
@@ -390,7 +247,7 @@ public class OrderService : IOrderService
|
||||
|
||||
No = SnowFlakeHelper.Instance.NextId().ToString(),
|
||||
SubsidiesFromMonth = request.CostDateTime.ToString("yyyyMM"),
|
||||
IsCostCrossTenant = GetSetting<bool>(settings, CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
IsCostCrossTenant = await GetSettingAsync<bool>(CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
|
||||
OriginTenantId = gainfo.Factory,//人员可能跨基地消费
|
||||
|
||||
@@ -404,14 +261,14 @@ public class OrderService : IOrderService
|
||||
TenantId = gainfo.Factory,
|
||||
};
|
||||
|
||||
var orderId = await _dbContext.InsertReturnIdentityAsync(order);
|
||||
var orderId = await DbContext.InsertReturnIdentityAsync(order);
|
||||
try
|
||||
{
|
||||
await GenerateRechargeRecordAsync(orderId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await _dbContext.Updateable<CanteenOrderEntity>()
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Failure)
|
||||
.SetColumns(x => x.Result == ex.Message)
|
||||
.Where(x => x.Id == orderId)
|
||||
@@ -420,88 +277,77 @@ public class OrderService : IOrderService
|
||||
throw;
|
||||
}
|
||||
|
||||
await _dbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Successful)
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Success)
|
||||
.Where(x => x.Id == orderId)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
|
||||
public async Task<Pagination<OrderAggregationResponse>> GetOrdersAggregationAsync(PageDto page)
|
||||
{
|
||||
var subjectId = CurrentUser.GetIntSubjectId();
|
||||
var gainfo = await DbContext.Queryable<GainfoEntity>().Where(x => x.IdentityUserId == subjectId).FirstAsync();
|
||||
var jinkoCode = CurrentUser.GetUserClaim("jinko-code") ?? string.Empty;
|
||||
if (jinkoCode.IsPresent())
|
||||
{
|
||||
gainfo = await DbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
}
|
||||
|
||||
var pageResult = await DbContext.Queryable<CanteenOrderEntity>().Where(x => x.UserNo == gainfo.No)
|
||||
.LeftJoin<BusinessPlaceEntity>((x, bplace) => x.BusinessPlaceCode == bplace.Code)
|
||||
.Where(x => x.ApplicationType == CanteenApplicaitonTypeEnumType.Booking)
|
||||
.Select((x, bplace) => new OrderAggregationResponse
|
||||
{
|
||||
No = x.No,
|
||||
BusinessPlaceName = bplace.Name,
|
||||
CreateTime = x.CreateTime,
|
||||
Remark = x.Remark,
|
||||
OrderStatus = x.OrderStatus,
|
||||
})
|
||||
.ToPageListAsync(page);
|
||||
|
||||
//.LeftJoin<CanteenOrderDetailEntity>((x, bplace, detail) => x.No == detail.OrderNo)
|
||||
|
||||
var nos = pageResult.Data.Select(x => x.No).ToList();
|
||||
var dtos = await DbContext.Queryable<CanteenOrderDetailEntity>()
|
||||
.LeftJoin<DishesEntity>((x, d) => x.DishesCode == d.CustomCode)
|
||||
.Where(x => nos.Contains(x.OrderNo))
|
||||
.Select((x, d) => new DishesDto
|
||||
{
|
||||
No = x.OrderNo,
|
||||
DishesCode = x.DishesCode,
|
||||
Name = d.Name,
|
||||
ImageUrl = d.ImageUrl,
|
||||
Number = x.Number,
|
||||
Price = x.Price,
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
pageResult.Data.ForEach(item =>
|
||||
{
|
||||
item.Dishes = dtos.Where(x => x.No == item.No).ToList();
|
||||
});
|
||||
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
|
||||
//******************************************************* help methods ************************************************************/
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设备并发更新 需要抛出VersionExceptions
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="func"></param>
|
||||
/// <param name="retry">并发冲突处理次数</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
private async Task ContinueUpdateAsync(Func<Task> func, int retry)
|
||||
{
|
||||
for (int i = 0; i < retry; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
await func();
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (ex is VersionExceptions)
|
||||
{
|
||||
_logger.LogWarning(ex, ex.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
throw new UserFriendlyException("操作失败,请重试");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取参数配置
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
private static T GetSetting<T>(Dictionary<CanteenSettingItemEnumType, string> settings, CanteenSettingItemEnumType item, T defaultValue = default)
|
||||
{
|
||||
if (settings.TryGetValue(item, out var v))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (int.TryParse(v, out var n))
|
||||
{
|
||||
return n.Adapt<T>();
|
||||
}
|
||||
|
||||
return v.Adapt<T>();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 验证参数
|
||||
/// </summary>
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="shifts"></param>
|
||||
/// <param name="costDateTime"></param>
|
||||
/// <param name="order"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
private async Task Verify(Dictionary<CanteenSettingItemEnumType, string> settings, List<BusinessShiftMealRelationshipEntity> shifts, DateTime costDateTime, CanteenOrderEntity order)
|
||||
private async Task Verify(List<BusinessShiftMealRelationshipEntity> shifts, DateTime costDateTime, CanteenOrderEntity order)
|
||||
{
|
||||
//在线
|
||||
if (!order.IsOffline)
|
||||
@@ -517,15 +363,15 @@ public class OrderService : IOrderService
|
||||
var beginOfDay = DateTime.Today;
|
||||
var endOfDay = beginOfDay.AddHours(23).AddMinutes(59).AddSeconds(59);
|
||||
|
||||
var balanceRecords = await _dbContext.Queryable<BalanceRecordEntity>()
|
||||
var balanceRecords = await DbContext.Queryable<BalanceRecordEntity>()
|
||||
.Where(x => x.UserNo == order.UserNo)
|
||||
.Where(x => x.CreateTime >= beginOfDay && x.CreateTime <= endOfDay) //今天消费记录
|
||||
.ToListAsync();
|
||||
|
||||
var dayMarketCostMax = GetSetting<decimal>(settings, CanteenSettingItemEnumType.DayMarketCostMax);
|
||||
var dayMarketCostMax = await GetSettingAsync<decimal>(CanteenSettingItemEnumType.DayMarketCostMax);
|
||||
if (dayMarketCostMax != default)
|
||||
{
|
||||
var businessPlaceCodes = await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||
var businessPlaceCodes = await DbContext.Queryable<BusinessPlaceEntity>()
|
||||
.Where(x => x.Catalog == CanteenBusinessPlaceCatalogEnumType.Supermarket)
|
||||
.Select(x => x.Code).ToListAsync();
|
||||
|
||||
@@ -536,7 +382,7 @@ public class OrderService : IOrderService
|
||||
}
|
||||
}
|
||||
|
||||
var allowRepeatInOneShift = GetSetting(settings, CanteenSettingItemEnumType.AllowRepeatInOneShift, true);
|
||||
var allowRepeatInOneShift = await GetSettingAsync(CanteenSettingItemEnumType.AllowRepeatInOneShift, true);
|
||||
if (!allowRepeatInOneShift)
|
||||
{
|
||||
//todo 餐次问题
|
||||
@@ -547,7 +393,7 @@ public class OrderService : IOrderService
|
||||
}
|
||||
}
|
||||
|
||||
var onceCostMax = GetSetting<decimal>(settings, CanteenSettingItemEnumType.OnceCostMax);
|
||||
var onceCostMax = await GetSettingAsync<decimal>(CanteenSettingItemEnumType.OnceCostMax);
|
||||
if (onceCostMax != default)
|
||||
{
|
||||
if (Math.Abs(order.Amount) > onceCostMax)
|
||||
@@ -556,7 +402,7 @@ public class OrderService : IOrderService
|
||||
}
|
||||
}
|
||||
|
||||
var dayCostMax = GetSetting<decimal>(settings, CanteenSettingItemEnumType.DayCostMax);
|
||||
var dayCostMax = await GetSettingAsync<decimal>(CanteenSettingItemEnumType.DayCostMax);
|
||||
if (dayCostMax != default)
|
||||
{
|
||||
var cost = balanceRecords.Where(x => x.Type == BalanceRecordTypeEnumType.Out).Sum(x => Math.Abs(x.Amount));
|
||||
@@ -577,15 +423,15 @@ public class OrderService : IOrderService
|
||||
/// <exception cref="VersionExceptions"></exception>
|
||||
private async Task GenerateRechargeRecordAsync(long orderId)
|
||||
{
|
||||
var order = await _dbContext.Queryable<CanteenOrderEntity>().Where(x => x.Id == orderId).FirstAsync();
|
||||
var order = await DbContext.Queryable<CanteenOrderEntity>().Where(x => x.Id == orderId).FirstAsync();
|
||||
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
var canteenUser = await _dbContext.Queryable<CanteenUserEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
var canteenUser = await DbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
//金额+-
|
||||
canteenUser.Balance += order.Amount;
|
||||
|
||||
var effect = await _dbContext.Updateable<CanteenUserEntity>()
|
||||
var effect = await DbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == canteenUser.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == order.UserNo && x.Version == canteenUser.Version)
|
||||
@@ -595,7 +441,7 @@ public class OrderService : IOrderService
|
||||
|
||||
//写入记录
|
||||
var balanceRecord = order.Adapt<BalanceRecordEntity>();
|
||||
await _dbContext.InsertAsync(balanceRecord);
|
||||
await DbContext.InsertAsync(balanceRecord);
|
||||
|
||||
}, 5);
|
||||
}
|
||||
@@ -604,25 +450,24 @@ public class OrderService : IOrderService
|
||||
/// 生成充值记录
|
||||
/// </summary>
|
||||
/// <param name="orderId"></param>
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="shifts"></param>
|
||||
/// <param name="costDateTime"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
/// <exception cref="VersionExceptions"></exception>
|
||||
private async Task GenerateConsumeRecordAsync(long orderId, Dictionary<CanteenSettingItemEnumType, string> settings, List<BusinessShiftMealRelationshipEntity> shifts, DateTime costDateTime)
|
||||
private async Task GenerateConsumeRecordAsync(long orderId, List<BusinessShiftMealRelationshipEntity> shifts, DateTime costDateTime)
|
||||
{
|
||||
var order = await _dbContext.Queryable<CanteenOrderEntity>().Where(x => x.Id == orderId).FirstAsync();
|
||||
var order = await DbContext.Queryable<CanteenOrderEntity>().Where(x => x.Id == orderId).FirstAsync();
|
||||
//校验
|
||||
await Verify(settings, shifts, costDateTime, order);
|
||||
await Verify(shifts, costDateTime, order);
|
||||
|
||||
var allowNoBalance = GetSetting<bool>(settings, CanteenSettingItemEnumType.AllowNoBalance);
|
||||
var allowNoBalance = await GetSettingAsync<bool>(CanteenSettingItemEnumType.AllowNoBalance);
|
||||
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
if (!allowNoBalance)
|
||||
{
|
||||
var canteenUser = await _dbContext.Queryable<CanteenUserEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
var canteenUser = await DbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
//金额+-
|
||||
canteenUser.Balance += order.Amount;
|
||||
if (canteenUser.Balance < 0)
|
||||
@@ -630,7 +475,7 @@ public class OrderService : IOrderService
|
||||
throw new UserFriendlyException("余额不足,无法消费");
|
||||
}
|
||||
|
||||
var effect = await _dbContext.Updateable<CanteenUserEntity>()
|
||||
var effect = await DbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == canteenUser.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == order.UserNo && x.Version == canteenUser.Version)//必须与查询时的version一致
|
||||
@@ -641,29 +486,10 @@ public class OrderService : IOrderService
|
||||
|
||||
//写入记录
|
||||
var balanceRecord = order.Adapt<BalanceRecordEntity>();
|
||||
await _dbContext.InsertAsync(balanceRecord);
|
||||
await DbContext.InsertAsync(balanceRecord);
|
||||
|
||||
}, 5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查我的订餐是否存在,存在抛出异常
|
||||
/// </summary>
|
||||
/// <param name="bookingDate"></param>
|
||||
/// <returns></returns>
|
||||
private async Task CheckExistsMyBookingsAsync(DateTime bookingDate)
|
||||
{
|
||||
var jinkoCode = _currentUser.GetUserClaim("jinko-code");
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
|
||||
var start = bookingDate.Date;
|
||||
var end = start.AddDays(1).AddSeconds(-1);
|
||||
|
||||
var exists = await _dbContext.Queryable<CanteenOrderEntity>().Where(x => x.ApplicationType == CanteenApplicaitonTypeEnumType.Booking)
|
||||
.Where(x => x.UserNo == gainfo.No)
|
||||
.Where(x => x.CreateTime >= start && x.CreateTime <= end)
|
||||
.AnyAsync();
|
||||
|
||||
exists.ThrowIfTrue("不可重复订餐");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,18 +22,7 @@ public class Startup : DefaultStartup
|
||||
|
||||
public override void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
base.ConfigureServices(services);
|
||||
//protected static string Obfuscate(string value)
|
||||
//{
|
||||
// var last4Chars = "****";
|
||||
// if (value.IsPresent() && value.Length > 4)
|
||||
// {
|
||||
// last4Chars = value.Substring(value.Length - 4);
|
||||
// }
|
||||
|
||||
// return "****" + last4Chars;
|
||||
//}
|
||||
|
||||
base.ConfigureServices(services);
|
||||
services.AddRedis();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,13 @@
|
||||
"BasicRequestUrl": "http://localhost:5002",
|
||||
"SysRequestUrl": "http://localhost:5003"
|
||||
},
|
||||
"SqlSugarOptions": {
|
||||
"DefaultConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=yikatong;charset=utf8mb4;",
|
||||
"SlaveConnectionString": [],
|
||||
"Timeout": 30,
|
||||
"SlowSqlTime": 1,
|
||||
"EnableSqlLog": true
|
||||
},
|
||||
"SwaggerOptions": {
|
||||
"Enable": true,
|
||||
"Authority": "https://yikatong.isawesome.cn/oauth2",
|
||||
|
||||
Reference in New Issue
Block a user