using Dlhis.Entity.Canteen.Entities; using Dlhis.Entity.Canteen.Enums; using Kurisu.AspNetCore.Utils.Extensions; using SqlSugar; using Dlhis.Basic.Dishes.Request; using Dlhis.Basic.Dishes.Response; using Dlhis.Basic.Dishes.Dto; using System.Linq.Expressions; using Dlhis.Basic.Places.Services; using Kurisu.AspNetCore.CustomClass; using Kurisu.AspNetCore.DataAccess.Dto; using Kurisu.AspNetCore.DataAccess.SqlSugar.Extensions; using Kurisu.AspNetCore.DataAccess.SqlSugar.Services; 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(DishesMenuPageRequest request) { return await _dbContext.Queryable() .Where(x => x.BusinessPlaceCode == request.BusinessPlaceCode) .GroupBy(x => new { x.BusinessPlaceCode, x.CustomCode, x.StartDate, x.EndDate }) .Select(x => new DishesMenuPageResponse { BusinessPlaceCode = x.BusinessPlaceCode, CustomCode = x.CustomCode, StartDate = x.StartDate, EndDate = x.EndDate, }) .ToPageListAsync(request); } public async Task GetDishesMenuDetailAsync(Guid businessPlaceCode, string customCode, DateTime startDate, DateTime endDate) { var data = await _dbContext.Queryable() .Where(x => x.BusinessPlaceCode == businessPlaceCode) .Where(x => x.CustomCode == customCode) .Where(x => x.StartDate == startDate) .Where(x => x.EndDate == endDate) .ToListAsync(); if (data.IsEmpty()) { return new DishesMenuSaveRequest { BusinessPlaceCode = businessPlaceCode, Items = new List { } }; } return new DishesMenuSaveRequest { BusinessPlaceCode = businessPlaceCode, Items = new List { new() { CustomCode = customCode, Period = new DateTimePeriod { Start = data[0].StartDate, End = data[0].EndDate, }, 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 => x.StartDate <= date && date <= x.EndDate) .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 = dishes.CustomCode, Description = dishes.Description, ImageUrl = dishes.ImageUrl, Price = SqlFunc.IIF(x.Price > 0, x.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 period = item.Period; 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, StartDate = period.Start.Value, EndDate = period.End.Value, ShiftType = shiftType, DishesCode = dishesCode, Number = number, Price = price, Type = CanteenApplicationTypeEnumType.Booking, Version = 0, }; }); }); }).ToList(); var keys = entities.DistinctBy(x => new { x.CustomCode, x.StartDate, x.EndDate, x.ShiftType }) .Select(x => new { x.CustomCode, x.StartDate, x.EndDate, x.ShiftType }) .ToList(); var deleteWhere = LinqExpressionExtensions.False(); keys.ForEach(x => { deleteWhere = deleteWhere.Or(item => item.BusinessPlaceCode == request.BusinessPlaceCode && item.CustomCode == x.CustomCode //&& SqlFunc.DateIsSame(item.StartDate, x.StartDate, DateType.Day) //&& SqlFunc.DateIsSame(item.EndDate, x.EndDate, DateType.Day) && item.ShiftType == x.ShiftType); }); await _dbContext.Client.Deleteable().Where(deleteWhere).ExecuteCommandAsync(); if (request.Items.Any()) { Expression> whereCheck = LinqExpressionExtensions.False(); request.Items.ForEach(p => { whereCheck = whereCheck.Or(x => x.BusinessPlaceCode == request.BusinessPlaceCode && !(x.EndDate < p.Period.Start || x.StartDate > p.Period.End) ); }); var duplicate = await _dbContext.Queryable().Where(whereCheck).AnyAsync(); duplicate.ThrowIfTrue("菜单时效冲突"); } 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 => 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; } //*********************************************************help methods********************************************************************** private static void CheckDuplicateData(DishesMenuSaveRequest request) { (request.Items.DistinctBy(x => new { x.CustomCode, x.Period.Start, x.Period.End }).Count() != request.Items.Count).ThrowIfTrue("菜单不可重复"); foreach (var item in request.Items) { var u = item.Period.Start.Value.ToString("yyyy-MM-dd") + "." + item.Period.End.Value.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()}下菜品不可重复"); } } } }