using Dlhis.Entity.Canteen.Entities; using Dlhis.Entity.Canteen.Enums; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Dto; using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; using SqlSugar; using Dlhis.Basic.Dishes.Request; using Dlhis.Basic.Dishes.Response; using Dlhis.Basic.BusinessPlace.Services; using Dlhis.Basic.Dishes.Dto; using Mapster; namespace Dlhis.Basic.Dishes.Services.Implements; public class DishesMenuService : IDishesMenuService { private readonly IDbContext _dbContext; private readonly IBusinessPlacePermissionsService _businessPlacePermissionsService; public DishesMenuService(IDbContext dbContext, IBusinessPlacePermissionsService businessPlacePermissionsService) { _dbContext = dbContext; _businessPlacePermissionsService = businessPlacePermissionsService; } public async Task> GetDishesMenuPageAsync(DisheMenuPageRequest request) { return await _dbContext.Queryable() .Where(x => x.BusinessPlaceCode == request.BusinessPlaceCode) .GroupBy(x => new { x.BusinessPlaceCode, x.CustomCode, x.Date }) .Select(x => new DishesMenuPageResponse { BusinessPlaceCode = x.BusinessPlaceCode, CustomCode = x.CustomCode, Date = x.Date, }) .ToPageListAsync(request); } public async Task GetDishesMenuDetailAsync(Guid businessPlaceCode, string customCode, DateTime date) { var data = await _dbContext.Queryable() .Where(x => x.BusinessPlaceCode == businessPlaceCode) .ToListAsync(); return new DishesMenuSaveRequest { BusinessPlaceCode = businessPlaceCode, Items = new List { new() { CustomCode = customCode, Date = date, ShiftTypes = data.GroupBy(x => x.ShiftType).Select(item => { var shiftType = item.Key; return new DishesMenuShiftTypeSaveRequest { ShiftType = shiftType, Dishes = item.Select(x => new MenuDishesSaveRequest { DishesCode = x.DishesCode, Number = x.Number, Price = x.Price, }).ToList() }; }).ToList() } } }; } public async Task> GetDishesUnderCurrentMenuAsync(Guid businessPlaceCode, DateTime date, ShiftEnumType? shiftType, Guid categoryCode) { var data = await _dbContext.Queryable() .LeftJoin((x, dishes) => x.DishesCode == dishes.CustomCode) .Where(x => x.BusinessPlaceCode == businessPlaceCode) .Where(x => SqlFunc.DateIsSame(x.Date, date, DateType.Day)) .Where((x, dishes) => dishes.Enable) .WhereIF(shiftType.HasValue, x => x.ShiftType == shiftType) .Where((x, dishes) => dishes.CategoryCode == categoryCode) .Select((x, dishes) => new DishesDetailResponse { BusinessPlaceCode = x.BusinessPlaceCode, CategoryCode = dishes.CategoryCode, CustomCode = x.CustomCode, Description = dishes.Description, ImageUrl = dishes.ImageUrl, Price = dishes.Price, Name = dishes.Name, Number = x.Number, CurrentUnits = dishes.Units.ToString() }) .ToListAsync(); return data; } public async Task SaveDishesMenuAsync(DishesMenuSaveRequest request) { //检验数据 CheckDuplicateData(request); //检验权限 var res = await _businessPlacePermissionsService.GetMyAsync(); var myBps = res.Select(x => x.Code).ToList(); myBps.Contains(request.BusinessPlaceCode).ThrowIfFalse("非经营营业点,无法保存菜单"); var entities = request.Items.SelectMany(item => { var customCode = item.CustomCode; var date = item.Date; return item.ShiftTypes.SelectMany(shiftTypeItem => { var shiftType = shiftTypeItem.ShiftType; return shiftTypeItem.Dishes.Select(dishesItem => { var dishesCode = dishesItem.DishesCode; var number = dishesItem.Number; var price = dishesItem.Price; return new DishesMenuEntity { BusinessPlaceCode = request.BusinessPlaceCode, CustomCode = customCode, Date = date, ShiftType = shiftType, DishesCode = dishesCode, Number = number, Price = price, Type = CanteenApplicaitonTypeEnumType.Booking, Version = 0, }; }); }); }).ToList(); var keys = entities.DistinctBy(x => new { x.Date, x.ShiftType }).Select(x => new { x.Date, x.ShiftType }).ToList(); var where = LinqExpressionExtension.False(); keys.ForEach(x => { where = where.Or(item => SqlFunc.DateIsSame(item.Date, x.Date, DateType.Day) && item.ShiftType == x.ShiftType); }); await _dbContext.Client.Deleteable().Where(where).ExecuteCommandAsync(); await _dbContext.InsertAsync(entities); } 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 => SqlFunc.DateIsSame(x.Date, date, DateType.Day)) .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 = x.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; } //*********************************************************help methods********************************************************************** private static void CheckDuplicateData(DishesMenuSaveRequest request) { (request.Items.DistinctBy(x => new { x.CustomCode, x.Date }).Count() != request.Items.Count).ThrowIfTrue("菜单不可重复"); foreach (var item in request.Items) { var u = item.Date.ToString("yyyy-MM-dd") + ". " + item.CustomCode; (item.ShiftTypes.DistinctBy(x => x.ShiftType).Count() != item.ShiftTypes.Count).ThrowIfTrue($"{u}的餐次不可重复添加"); foreach (var shiftTypeItem in item.ShiftTypes) { (shiftTypeItem.Dishes.DistinctBy(x => x.DishesCode).Count() != shiftTypeItem.Dishes.Count) .ThrowIfTrue($"{u}的{shiftTypeItem.ShiftType.GetDescription()}下菜品不可重复"); } } } }