diff --git a/Src/Dlhis.Basic/Appointment/Controllers/AppointmentsController.cs b/Src/Dlhis.Basic/Appointment/Controllers/AppointmentsController.cs index 8d9feb6a..41139c06 100644 --- a/Src/Dlhis.Basic/Appointment/Controllers/AppointmentsController.cs +++ b/Src/Dlhis.Basic/Appointment/Controllers/AppointmentsController.cs @@ -1,7 +1,6 @@ using Dlhis.Basic.Appointment.Request; using Dlhis.Basic.Appointment.Response; using Dlhis.Basic.Appointment.Services; -using Dlhis.Entity.Device.Enums; using Dlhis.Entity.Visitor.Enums; using Kurisu.AspNetCore.DataAccess.Dto; using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; @@ -159,6 +158,5 @@ public class AppointmentsController : ControllerBase public async Task> GetVisitorDevicesAsync(long detailId) { return await _appointmentService.GetVisitorDevicesAsync(detailId); - ; } } \ No newline at end of file diff --git a/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs b/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs index ba3482cd..747f7097 100644 --- a/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs +++ b/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs @@ -1,4 +1,5 @@ -using Dlhis.Canteen.Order.Request; +using Dlhis.Canteen.Dishes.Request; +using Dlhis.Canteen.Order.Request; using Dlhis.Canteen.Order.Response; using Dlhis.Canteen.Order.Services; using Kurisu.AspNetCore.DataAccess.Dto; @@ -18,10 +19,12 @@ namespace Dlhis.Canteen.Order.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; + _bookingOrderService = bookingOrderService; } /// @@ -90,27 +93,27 @@ public class OrdersController : ControllerBase // // //************************************************************** 订餐功能 ********************************************************************************** // - // /// - // /// 取消订单 - // /// - // /// - // /// - // [HttpPost("booking")] - // [Transactional] - // [IgnoreTenant] - // public async Task Booking(BookingMealRequest request) - // { - // return await _bookingOrderService.BookingAsync(request); - // } - // - // /// - // /// 订单分页 - // /// - // /// - // /// - // [HttpGet("booking/page")] - // public async Task> GetBookingPageAsync([FromQuery] OrderBookingPageRequest request) - // { - // return await _bookingOrderService.GetBookingPageAsync(request); - // } + /// + /// + /// + /// + /// + [HttpPost("booking")] + [Transactional] + [IgnoreTenant] + public async Task Booking(BookingMealRequest request) + { + return await _bookingOrderService.BookingAsync(request); + } + + /// + /// 订单分页 + /// + /// + /// + [HttpGet("booking/page")] + public async Task> GetBookingPageAsync([FromQuery] OrderBookingPageRequest request) + { + return await _bookingOrderService.GetBookingPageAsync(request); + } } \ No newline at end of file diff --git a/Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs b/Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs index 30ccaad0..8ff99ea8 100644 --- a/Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs +++ b/Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs @@ -13,8 +13,7 @@ public interface IBookingOrderService : IScopeDependency /// /// Task BookingAsync(BookingMealRequest request); - - + Task> GetBookingPageAsync(OrderBookingPageRequest request); Task UserCancelOrderAsync(OrderCancelRequest request); diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BookingOrderService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BookingOrderService.cs index e71257ed..d668ad76 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BookingOrderService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BookingOrderService.cs @@ -1,302 +1,312 @@ -// 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 Dlhis.Canteen.Setting.Services; -// using Dlhis.Basic.Api; -// using Kurisu.AspNetCore.Authentication.Abstractions; -// using Kurisu.AspNetCore.DataAccess.Dto; -// using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions; -// using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; -// using SqlSugar; -// using Mapster; -// -// namespace Dlhis.Canteen.Order.Services.Implements; -// -// public class BookingOrderService : BaseOrderService, IBookingOrderService -// { -// private readonly ICanteenSettingService _canteenSettingService; -// private readonly IDishesMenuApi _dishesMenuApi; -// private readonly IBusinessPlacePermissionsApi _businessPlacePermissionsApi; -// -// public BookingOrderService(ICanteenSettingService canteenSettingService, IDbContext dbContext, -// IDishesMenuApi dishesMenuApi, -// IBusinessPlacePermissionsApi businessPlacePermissionsApi, -// ICurrentUser currentUser, ILogger logger) -// : base(canteenSettingService, dbContext, currentUser, logger) -// { -// _canteenSettingService = canteenSettingService; -// _dishesMenuApi = dishesMenuApi; -// _businessPlacePermissionsApi = businessPlacePermissionsApi; -// } -// -// public async Task BookingAsync(BookingMealRequest request) -// { -// var gainfo = await CheckExistsMyBookingsAsync(request.BookingDate, request.ShiftType); -// -// var businessPlace = await DbContext.Queryable().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync(); -// -// //预定时间 -// var now = DateTime.Now; -// -// var bookingDeadline = await _canteenSettingService.GetSettingAsync(CanteenSettingItemEnumType.BookingDeadline, businessPlace.TenantId, gainfo.No, new TimeOnly(20, 30, 00)); -// var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan()); -// (now >= dealLine).ThrowIfTrue("超出订餐时间"); -// -// //菜单存在 -// var menuDetailResult = await _dishesMenuApi.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 = CanteenApplicationTypeEnumType.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(), -// IsOffline = false, -// IsCostCrossTenant = await _canteenSettingService.GetSettingAsync(CanteenSettingItemEnumType.AllowCrossTenant, businessPlace.TenantId, gainfo.No), -// -// OriginTenantId = gainfo.Factory, //人员可能跨基地消费 -// -// Status = BalanceRecordStatusEnumType.Valid, -// OrderStatus = CanteenOrderStatusEnumType.Success, -// -// CostDateTime = now, -// -// //标识当前消费的基地 -// TenantId = businessPlace.TenantId, -// }; -// -// await DbContext.InsertAsync(order); -// await CommonHelper.RetryAsync(async () => -// { -// await _dishesMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode); -// 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().Where(x => x.UserCode == order.UserCode).FirstAsync(); -// mealInfo.ThrowIfNull("余额不足,无法消费"); -// -// //金额+- -// mealInfo.Balance += order.Amount; -// (mealInfo.Balance < 0).ThrowIfTrue("余额不足,无法消费"); -// -// await DbContext.Updateable() -// .SetColumns(x => x.Balance == mealInfo.Balance) -// .SetColumns(x => x.Version == x.Version + 1) -// .SetColumns(x => x.ModifiedTime == DateTime.Now) -// .Where(x => x.UserCode == order.UserCode && x.Version == mealInfo.Version) //必须与查询时的version一致 -// .ExecuteCommandThrowVersionAsync(); -// } -// -// await DbContext.Updateable() -// .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 -// ) -// .ExecuteCommandThrowVersionAsync(); -// -// //写入记录 -// var balanceRecord = order.Adapt(); -// 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 = request.Number, -// TenantId = order.TenantId, -// }); -// }, 10); -// -// -// return new BookingResponse -// { -// No = order.No, -// CreateTime = order.CreateTime, -// Source = order.Source, -// Amount = Math.Abs(order.Amount) -// }; -// } -// -// -// public async Task> GetBookingPageAsync(OrderBookingPageRequest request) -// { -// var myCodes = (await _businessPlacePermissionsApi.GetMyAsync()).Data.Select(x => (Guid?)x.Code).ToList(); -// -// var page = await DbContext.Queryable() -// .LeftJoin((x, ga) => x.UserNo == ga.No) -// .LeftJoin((x, ga, dept) => dept.No == ga.DepartmentNo) -// .Where(x => myCodes.Contains(x.BusinessPlaceCode)) -// .WhereIF(request.OrderStatus.HasValue, x => x.OrderStatus == request.OrderStatus) -// .WhereIF(request.Source.HasValue, x => x.Source == request.Source) -// .WhereIF(request.Search.IsPresent(), (x, ga) => x.UserCode == request.Search || ga.Name.Contains(request.Search)) -// .WhereIF(request.BookingPeriod?.Start.HasValue == true && request.BookingPeriod?.End.HasValue == true, x => -// SqlFunc.Subqueryable() -// .Where(p => p.OrderNo == x.No) -// .Where(p => p.BookingDate >= request.BookingPeriod.Start) -// .Where(p => p.BookingDate <= request.BookingPeriod.End) -// .Any() -// ) -// .WhereIF(request.ShiftType.HasValue, x => x.ShiftType == request.ShiftType) -// .Select((x, ga, dept) => new OrderBookingResponse -// { -// No = x.No, -// DeliveryAddress = x.DeliveryAddress, -// Remark = x.Remark, -// Amount = SqlFunc.Abs(x.Amount), -// CreateTime = x.CreateTime, -// ShiftType = x.ShiftType, -// Status = x.OrderStatus, -// UserCode = x.UserCode, -// UserName = ga.Name, -// Source = x.Source, -// DepartmentName = dept.Name, -// }) -// .ToPageListAsync(request); -// -// var nos = page.Data.Select(x => x.No).ToList(); -// var details = await DbContext.Queryable() -// .LeftJoin((x, dishes) => x.DishesCode == dishes.CustomCode) -// .Where(x => nos.Contains(x.OrderNo)) -// .Select((x, dishes) => new { x.OrderNo, x.BookingDate, x.Number, dishes.Name }).ToListAsync(); -// -// page.Data.ForEach(x => -// { -// x.BookingDate = details.First(item => item.OrderNo == x.No).BookingDate; -// x.TotalNumber = details.Where(item => item.OrderNo == x.No).Sum(item => item.Number); -// x.DishesInfos = details.Where(item => item.OrderNo == x.No).Select(item => new -// { -// item.Name -// }) -// .ToList(); -// }); -// -// return page; -// } -// -// public async Task UserCancelOrderAsync(OrderCancelRequest request) -// { -// var order = await DbContext.Queryable().Where(x => x.No == request.No).FirstAsync(); -// order.ThrowIfNull("订单不存在"); -// -// var bookingDeadline = await _canteenSettingService.GetSettingAsync(CanteenSettingItemEnumType.BookingDeadline, order.TenantId, order.No, new TimeOnly(20, 30, 00)); -// var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan()); -// (DateTime.Now >= dealLine).ThrowIfTrue("不在订单取消允许范围内,不可操作"); -// -// await ManagerCancelOrderAsync(new OrderCancelRequest -// { -// No = request.No, -// Reason = request.Reason, -// }); -// } -// -// -// public async Task ManagerCancelOrderAsync(OrderCancelRequest request) -// { -// var now = DateTime.Now; -// var userId = CurrentUser.GetIntSubjectId(); -// -// var order = await DbContext.Queryable().Where(x => x.No == request.No).FirstAsync(); -// order.ThrowIfNull("订单不存在"); -// -// await DbContext.Updateable() -// .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(); -// -// await DbContext.Updateable() -// .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(); -// -// if (order.Source == BalanceRecordSourceEnumType.LocalTenantSubsidies) -// { -// await CommonHelper.RetryAsync(async () => -// { -// var mealInfo = await DbContext.Queryable().Where(x => x.UserCode == order.UserCode).FirstAsync(); -// var setBalance = mealInfo.Balance + Math.Abs(order.Amount); -// await DbContext.Updateable() -// .SetColumns(x => x.Version == x.Version + 1) -// .SetColumns(x => x.Balance == setBalance) -// .SetColumns(x => x.ModifiedTime == now) -// .SetColumns(x => x.ModifiedBy == userId) -// .Where(x => x.Id == mealInfo.Id && x.Version == mealInfo.Version) -// .ExecuteCommandThrowVersionAsync(); -// }, 5); -// } -// } -// -// -// /// -// /// 检查我的订餐是否存在,存在抛出异常 -// /// -// /// -// /// -// /// -// private async Task CheckExistsMyBookingsAsync(DateTime bookingDate, ShiftEnumType shiftType) -// { -// var subjectId = CurrentUser.GetIntSubjectId(); -// var gainfo = await DbContext.Queryable().Where(x => x.IdentityUserId == subjectId).FirstAsync(); -// var jinkoCode = CurrentUser.GetUserClaim("jinko-code") ?? string.Empty; -// if (jinkoCode.IsPresent()) -// { -// gainfo = await DbContext.Queryable().Where(x => x.Code == jinkoCode).FirstAsync(); -// } -// -// var start = bookingDate.Date.AddDays(-1); -// var end = start.AddDays(1).AddSeconds(-1); -// -// var exists = await DbContext.Queryable() -// .Where(x => x.ApplicationType == CanteenApplicationTypeEnumType.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; -// } -// } \ No newline at end of file +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 Dlhis.Canteen.Setting.Services; +using Dlhis.Basic.Api; +using Dlhis.Constants; +using Kurisu.AspNetCore.Authentication.Abstractions; +using Kurisu.AspNetCore.DataAccess.Dto; +using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions; +using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; +using SqlSugar; + +namespace Dlhis.Canteen.Order.Services.Implements; + +public class BookingOrderService : IBookingOrderService +{ + private readonly ICanteenSettingService _canteenSettingService; + private readonly IDbContext _dbContext; + private readonly IBusinessPlacePermissionsApi _businessPlacePermissionsApi; + private readonly ICurrentUser _currentUser; + + public BookingOrderService(ICanteenSettingService canteenSettingService, + IDbContext dbContext, + IBusinessPlacePermissionsApi businessPlacePermissionsApi, + ICurrentUser currentUser) + { + _canteenSettingService = canteenSettingService; + _dbContext = dbContext; + _businessPlacePermissionsApi = businessPlacePermissionsApi; + _currentUser = currentUser; + } + + public async Task BookingAsync(BookingMealRequest request) + { + var gainfo = await CheckExistsMyBookingsAsync(request.BookingDate, request.ShiftType); + + var businessPlace = await _dbContext.Queryable().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync(); + + //预定时间 + var now = DateTime.Now; + + var bookingDeadline = await _canteenSettingService.GetSettingAsync(CanteenSettingItemEnumType.BookingDeadline, businessPlace.TenantId, gainfo.No, new TimeOnly(20, 30, 00)); + var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan()); + (now >= dealLine).ThrowIfTrue("超出订餐时间"); + + //菜单存在 + var menuDetail = await GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, request.ShiftType, request.DishesCode); + menuDetail.ThrowIfNull("预定失败,菜品已经下架"); + + var order = new CanteenOrderEntity + { + RequestJson = request.ToJson(), + ThirdNo = string.Empty, + Type = BalanceRecordTypeEnumType.Out, + ApplicationType = CanteenApplicationTypeEnumType.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(), + IsOffline = false, + IsCostCrossTenant = await _canteenSettingService.GetSettingAsync(CanteenSettingItemEnumType.AllowCrossTenant, businessPlace.TenantId, gainfo.No), + + OriginTenantId = gainfo.Factory, //人员可能跨基地消费 + + Status = BalanceRecordStatusEnumType.Valid, + OrderStatus = CanteenOrderStatusEnumType.Success, + + CostDateTime = now, + + //标识当前消费的基地 + TenantId = businessPlace.TenantId, + }; + + await _dbContext.InsertAsync(order); + await CommonHelper.RetryAsync(async () => + { + menuDetail = await GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, request.ShiftType, request.DishesCode); + menuDetail.ThrowIfNull("预定失败,菜品已经下架"); + menuDetail.Number -= request.Number; + + (menuDetail.Number < 0).ThrowIfTrue($"{menuDetail.DishesName}剩余数量不足"); + + await _dbContext.Updateable() + .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 + ) + .ExecuteCommandThrowVersionAsync(); + + await _dbContext.InsertAsync(new CanteenOrderDetailEntity + { + OrderNo = order.No, + BookingDate = request.BookingDate, + DishesCode = request.DishesCode, + Price = menuDetail.Price, + Unit = request.Unit, + Number = request.Number, + TenantId = order.TenantId, + }); + }, 10); + + + return new BookingResponse + { + No = order.No, + CreateTime = order.CreateTime, + Source = order.Source, + Amount = Math.Abs(order.Amount) + }; + } + + + public async Task GetBookingDishesDetailAsync(DateTime date, Guid businessPlaceCode, ShiftEnumType shiftType, string dishesCode) + { + var detail = await _dbContext.Queryable() + .LeftJoin((x, d) => x.DishesCode == d.CustomCode) + .Where(x => x.StartDate <= date && date <= x.EndDate) + .Where(x => x.BusinessPlaceCode == businessPlaceCode) + .Where(x => x.ShiftType == shiftType) + .Where(x => x.DishesCode == dishesCode) + .Where((x, d) => d.Enable) + .Select((x, d) => new DishesMenuDetailDto + { + Date = date, + MenuId = x.Id, + DishesId = d.Id, + DishesCode = d.CustomCode, + DishesName = d.Name, + Price = x.Price == null || x.Price == 0 ? d.Price : x.Price.Value, + Number = x.Number, + Version = x.Version, + }) + .SingleAsync(); + + return detail; + } + + + public async Task> GetBookingPageAsync(OrderBookingPageRequest request) + { + var myCodes = (await _businessPlacePermissionsApi.GetMyAsync()).Select(x => (Guid?)x.Code).ToList(); + + var page = await _dbContext.Queryable() + .LeftJoin((x, ga) => x.UserNo == ga.No) + .LeftJoin((x, ga, dept) => dept.No == ga.DepartmentNo) + .Where(x => myCodes.Contains(x.BusinessPlaceCode)) + .WhereIF(request.OrderStatus.HasValue, x => x.OrderStatus == request.OrderStatus) + .WhereIF(request.Source.HasValue, x => x.Source == request.Source) + .WhereIF(request.Search.IsPresent(), (x, ga) => x.UserCode == request.Search || ga.Name.Contains(request.Search)) + .WhereIF(request.BookingPeriod?.Start.HasValue == true && request.BookingPeriod?.End.HasValue == true, x => + SqlFunc.Subqueryable() + .Where(p => p.OrderNo == x.No) + .Where(p => p.BookingDate >= request.BookingPeriod.Start) + .Where(p => p.BookingDate <= request.BookingPeriod.End) + .Any() + ) + .WhereIF(request.ShiftType.HasValue, x => x.ShiftType == request.ShiftType) + .Select((x, ga, dept) => new OrderBookingResponse + { + No = x.No, + DeliveryAddress = x.DeliveryAddress, + Remark = x.Remark, + Amount = SqlFunc.Abs(x.Amount), + CreateTime = x.CreateTime, + ShiftType = x.ShiftType, + Status = x.OrderStatus, + UserCode = x.UserCode, + UserName = ga.Name, + Source = x.Source, + DepartmentName = dept.Name, + }) + .ToPageListAsync(request); + + var nos = page.Data.Select(x => x.No).ToList(); + var details = await _dbContext.Queryable() + .LeftJoin((x, dishes) => x.DishesCode == dishes.CustomCode) + .Where(x => nos.Contains(x.OrderNo)) + .Select((x, dishes) => new { x.OrderNo, x.BookingDate, x.Number, dishes.Name }).ToListAsync(); + + page.Data.ForEach(x => + { + x.BookingDate = details.First(item => item.OrderNo == x.No).BookingDate; + x.TotalNumber = details.Where(item => item.OrderNo == x.No).Sum(item => item.Number); + x.DishesInfos = details.Where(item => item.OrderNo == x.No).Select(item => new + { + item.Name + }) + .ToList(); + }); + + return page; + } + + public async Task UserCancelOrderAsync(OrderCancelRequest request) + { + return; + + var order = await _dbContext.Queryable().Where(x => x.No == request.No).FirstAsync(); + order.ThrowIfNull("订单不存在"); + + var bookingDeadline = await _canteenSettingService.GetSettingAsync(CanteenSettingItemEnumType.BookingDeadline, order.TenantId, order.No, new TimeOnly(20, 30, 00)); + var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan()); + (DateTime.Now >= dealLine).ThrowIfTrue("不在订单取消允许范围内,不可操作"); + + await ManagerCancelOrderAsync(new OrderCancelRequest + { + No = request.No, + Reason = request.Reason, + }); + } + + + public async Task ManagerCancelOrderAsync(OrderCancelRequest request) + { + return; + + var now = DateTime.Now; + var userId = _currentUser.GetIntSubjectId(); + + var order = await _dbContext.Queryable().Where(x => x.No == request.No).FirstAsync(); + order.ThrowIfNull("订单不存在"); + + await _dbContext.Updateable() + .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(); + + await _dbContext.Updateable() + .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(); + } + + + /// + /// 检查我的订餐是否存在,存在抛出异常 + /// + /// + /// + /// + private async Task CheckExistsMyBookingsAsync(DateTime bookingDate, ShiftEnumType shiftType) + { + var subjectId = _currentUser.GetIntSubjectId(); + var gainfo = await _dbContext.Queryable().Where(x => x.IdentityUserId == subjectId).FirstAsync(); + var jinkoCode = _currentUser.GetUserClaim(UserClaimConstants.JinkoCode) ?? string.Empty; + if (jinkoCode.IsPresent()) + { + gainfo = await _dbContext.Queryable().Where(x => x.Code == jinkoCode).FirstAsync(); + } + + var start = bookingDate.Date.AddDays(-1); + var end = start.AddDays(1).AddSeconds(-1); + + var exists = await _dbContext.Queryable() + .Where(x => x.ApplicationType == CanteenApplicationTypeEnumType.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; + } +} + +public class DishesMenuDetailDto +{ + public DateTime Date { get; set; } + + public long MenuId { get; set; } + + public long DishesId { get; set; } + + public string DishesCode { get; set; } + + public string DishesName { get; set; } + + public decimal Price { get; set; } + + public int Number { get; set; } + + public int Version { get; set; } +} \ No newline at end of file