diff --git a/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj b/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj index ae3784a1..2311965f 100644 --- a/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj +++ b/Src/Dlhis.Basic.Api/Dlhis.Basic.Api.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/Src/Dlhis.Basic.Api/Response/BusinessPlaceDto.cs b/Src/Dlhis.Basic.Api/Dtos/BusinessPlaceDto.cs similarity index 87% rename from Src/Dlhis.Basic.Api/Response/BusinessPlaceDto.cs rename to Src/Dlhis.Basic.Api/Dtos/BusinessPlaceDto.cs index cffafdb3..15003d35 100644 --- a/Src/Dlhis.Basic.Api/Response/BusinessPlaceDto.cs +++ b/Src/Dlhis.Basic.Api/Dtos/BusinessPlaceDto.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Dlhis.Basic.Api.Response +namespace Dlhis.Basic.Api.Dtos { public class BusinessPlaceDto { diff --git a/Src/Dlhis.Basic.Api/IBusinessPlacePermissionsApi.cs b/Src/Dlhis.Basic.Api/IBusinessPlacePermissionsApi.cs index 3b6be007..9d5cf5f4 100644 --- a/Src/Dlhis.Basic.Api/IBusinessPlacePermissionsApi.cs +++ b/Src/Dlhis.Basic.Api/IBusinessPlacePermissionsApi.cs @@ -1,4 +1,4 @@ -using Dlhis.Basic.Api.Response; +using Dlhis.Basic.Api.Dtos; using Kurisu.Core.Result; using Kurisu.RemoteCall.Attributes; @@ -9,5 +9,5 @@ public interface IBusinessPlacePermissionsApi { [Auth] [Get("/api/businessplacepermissions/my")] - Task> GetMyAsync(); + Task>> GetMyAsync(); } diff --git a/Src/Dlhis.Basic.Api/IDisheMenuApi.cs b/Src/Dlhis.Basic.Api/IDisheMenuApi.cs index 04482e6a..96b649da 100644 --- a/Src/Dlhis.Basic.Api/IDisheMenuApi.cs +++ b/Src/Dlhis.Basic.Api/IDisheMenuApi.cs @@ -16,6 +16,6 @@ public interface IDisheMenuApi /// /// [Auth] - [Get("/api/dishesMenus/detail")] + [Get("/api/dishesMenus/checkdetail")] Task> GetBookingDishesDetailAsync(DateTime date, Guid businessPlaceCode, int shiftType, string dishesCode); } \ No newline at end of file diff --git a/Src/Dlhis.Basic.Api/Response/GetMyResponse.cs b/Src/Dlhis.Basic.Api/Response/GetMyResponse.cs deleted file mode 100644 index 9e2df3ee..00000000 --- a/Src/Dlhis.Basic.Api/Response/GetMyResponse.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Dlhis.Basic.Api.Response -{ - public class GetMyResponse - { - public List dtos { get; set; } - } -} diff --git a/Src/Dlhis.Basic/BusinessPlace/Request/SaveBusinessPlacePermissionRequest.cs b/Src/Dlhis.Basic/BusinessPlace/Request/SaveBusinessPlacePermissionRequest.cs deleted file mode 100644 index 744ab2da..00000000 --- a/Src/Dlhis.Basic/BusinessPlace/Request/SaveBusinessPlacePermissionRequest.cs +++ /dev/null @@ -1,18 +0,0 @@ -using SqlSugar; - -namespace Dlhis.Basic.BusinessPlace.Request; - -public class SaveBusinessPlacePermissionRequest -{ - public long? Id { get; set; } - - /// - /// 管理人员userId - /// - public int UserId { get; set; } - - /// - /// 营业点 - /// - public Guid BusinessPlaceCode { get; set; } -} diff --git a/Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceDto.cs b/Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceDto.cs deleted file mode 100644 index a5dd68f7..00000000 --- a/Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceDto.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Dlhis.Basic.BusinessPlace.Response -{ - public class BusinessPlaceDto - { - public Guid Code { get; set; } - public string Name { get; set; } - } -} diff --git a/Src/Dlhis.Basic/BusinessPlace/Response/GetMyResponse.cs b/Src/Dlhis.Basic/BusinessPlace/Response/GetMyResponse.cs deleted file mode 100644 index 1a3b6fd2..00000000 --- a/Src/Dlhis.Basic/BusinessPlace/Response/GetMyResponse.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Dlhis.Basic.BusinessPlace.Response -{ - public class GetMyResponse - { - public List dtos { get; set; } - } -} diff --git a/Src/Dlhis.Basic/BusinessPlace/Services/IBusinessPlacePermissionsService.cs b/Src/Dlhis.Basic/BusinessPlace/Services/IBusinessPlacePermissionsService.cs deleted file mode 100644 index cbae1cfc..00000000 --- a/Src/Dlhis.Basic/BusinessPlace/Services/IBusinessPlacePermissionsService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Dlhis.Basic.BusinessPlace.Request; -using Dlhis.Basic.BusinessPlace.Response; -using Kurisu.Core.DataAccess.Dto; - -namespace Dlhis.Basic.BusinessPlace.Services; - -public interface IBusinessPlacePermissionsService : IScopeDependency -{ - Task> GetPageAsync(BusinessPlacePermissionPageRequest request); - - Task SaveBusinessPlacePermissionAsync(SaveBusinessPlacePermissionRequest request); - - Task GetMyAsync(); -} diff --git a/Src/Dlhis.Basic/BusinessPlace/Services/Implements/BusinessPlacePermissionsService.cs b/Src/Dlhis.Basic/BusinessPlace/Services/Implements/BusinessPlacePermissionsService.cs deleted file mode 100644 index 55d1fdca..00000000 --- a/Src/Dlhis.Basic/BusinessPlace/Services/Implements/BusinessPlacePermissionsService.cs +++ /dev/null @@ -1,66 +0,0 @@ -using Dlhis.Basic.BusinessPlace.Request; -using Dlhis.Basic.BusinessPlace.Response; -using Dlhis.Entity.Basic.Entity; -using Kurisu.Core.DataAccess.Dto; -using Kurisu.Core.User.Abstractions; -using Kurisu.SqlSugar.Services; -using Mapster; - -namespace Dlhis.Basic.BusinessPlace.Services.Implements; - -public class BusinessPlacePermissionsService : IBusinessPlacePermissionsService -{ - private readonly IDbContext _dbContext; - private readonly ICurrentUser _currentUser; - - public BusinessPlacePermissionsService(IDbContext dbContext, ICurrentUser currentUser) - { - _dbContext = dbContext; - _currentUser = currentUser; - } - - public async Task> GetPageAsync(BusinessPlacePermissionPageRequest request) - { - throw new NotImplementedException(); - } - - public async Task GetMyAsync() - { - var userId = _currentUser.GetIntSubjectId(); - - var guids = await _dbContext.Queryable() - .Where(x => x.ManagerUserId == userId) - .Select(x => x.BusinessPlaceCode) - .Distinct() - .ToListAsync(); - - var dtos = await _dbContext.Queryable() - .Where(x => guids.Contains(x.Code)) - .Select() - .ToListAsync(); - var myResponse = new GetMyResponse - { - dtos = dtos - }; - return myResponse; - } - - public async Task SaveBusinessPlacePermissionAsync(SaveBusinessPlacePermissionRequest request) - { - var userId = _currentUser.GetIntSubjectId(); - if (request.Id.HasValue) - { - var entity = await _dbContext.Queryable() - .Where(x => x.Id == request.Id).FirstAsync(); - - request.Adapt(entity); - await _dbContext.UpdateAsync(entity); - } - else - { - var entity = request.Adapt(); - entity.ManagerUserId = userId; - await _dbContext.InsertAsync(entity); - } - } -} diff --git a/Src/Dlhis.Basic/BusinessShift/Services/IBusinessPlaceShiftService.cs b/Src/Dlhis.Basic/BusinessShift/Services/IBusinessPlaceShiftService.cs index e5808234..e8498c95 100644 --- a/Src/Dlhis.Basic/BusinessShift/Services/IBusinessPlaceShiftService.cs +++ b/Src/Dlhis.Basic/BusinessShift/Services/IBusinessPlaceShiftService.cs @@ -1,4 +1,4 @@ -using Dlhis.Basic.BusinessPlace.Request; +using Dlhis.Basic.Places.Request; using Dlhis.Basic.BusinessPlace.Response; using Dlhis.Basic.BusinessShift.Request; using Dlhis.Basic.BusinessShift.Response; diff --git a/Src/Dlhis.Basic/BusinessShift/Services/Implements/BusinessPlaceShiftService.cs b/Src/Dlhis.Basic/BusinessShift/Services/Implements/BusinessPlaceShiftService.cs index dbf1d513..ef16b0b8 100644 --- a/Src/Dlhis.Basic/BusinessShift/Services/Implements/BusinessPlaceShiftService.cs +++ b/Src/Dlhis.Basic/BusinessShift/Services/Implements/BusinessPlaceShiftService.cs @@ -1,4 +1,4 @@ -using Dlhis.Basic.BusinessPlace.Request; +using Dlhis.Basic.Places.Request; using Dlhis.Basic.BusinessPlace.Response; using Dlhis.Basic.BusinessShift.Request; using Dlhis.Basic.BusinessShift.Response; diff --git a/Src/Dlhis.Basic/Dishes/Controller/DishesCategoriesController.cs b/Src/Dlhis.Basic/Dishes/Controller/DishesCategoriesController.cs index 7370ebe9..fd642e4c 100644 --- a/Src/Dlhis.Basic/Dishes/Controller/DishesCategoriesController.cs +++ b/Src/Dlhis.Basic/Dishes/Controller/DishesCategoriesController.cs @@ -1,6 +1,7 @@ using Dlhis.Basic.Dishes.Request; using Dlhis.Basic.Dishes.Response; using Dlhis.Basic.Dishes.Services; +using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -24,11 +25,25 @@ public class DishesCategoriesController : ControllerBase /// /// 获取分类树 /// + /// /// [HttpGet("tree")] - public async Task> TreeAsync() + public async Task> TreeAsync(Guid businessPlaceCode) { - return await _dishesCategoryService.TreeAsync(); + return await _dishesCategoryService.TreeAsync(businessPlaceCode); + } + + + /// + /// 获取分类树(无权限) + /// + /// + /// + [HttpGet("tree-all")] + [IgnoreTenant] + public async Task> TreeAllAsync(Guid businessPlaceCode) + { + return await _dishesCategoryService.TreeAllAsync(businessPlaceCode); } /// diff --git a/Src/Dlhis.Basic/Dishes/Controller/DishesMenusController.cs b/Src/Dlhis.Basic/Dishes/Controller/DishesMenusController.cs index 31c24e25..7014f9bd 100644 --- a/Src/Dlhis.Basic/Dishes/Controller/DishesMenusController.cs +++ b/Src/Dlhis.Basic/Dishes/Controller/DishesMenusController.cs @@ -38,6 +38,38 @@ public class DishesMenusController : ControllerBase return await _dishesMenuService.GetDishesMenuPageAsync(request); } + /// + /// 菜单详情 + /// + /// + /// + /// + /// + /// + [HttpGet("detail")] + public async Task GetDishesMenuDetailAsync(Guid businessPlaceCode, string customCode, DateTime startDate, DateTime endDate) + { + return await _dishesMenuService.GetDishesMenuDetailAsync(businessPlaceCode, customCode, startDate, endDate); + } + + /// + /// 根据参数获取菜品 + /// + /// + /// + /// + /// + /// + [HttpGet("dishes-selections")] + [IgnoreTenant] + public async Task> GetDishesUnderCurrentMenuAsync(Guid businessPlaceCode, + DateTime date, + ShiftEnumType? shiftType, + Guid categoryCode) + { + return await _dishesMenuService.GetDishesUnderCurrentMenuAsync(businessPlaceCode, date, shiftType, categoryCode); + } + /// /// 菜单保存/更改 /// @@ -51,14 +83,15 @@ public class DishesMenusController : ControllerBase } /// - /// 菜单明细 + /// 检查明细 /// /// /// /// /// /// - [HttpGet("detail")] + [HttpGet("checkdetail")] + [IgnoreTenant] public async Task GetBookingDishesDetailAsync(DateTime date, Guid businessPlaceCode, ShiftEnumType shiftType, string dishesCode) { return await _dishesMenuService.GetBookingDishesDetailAsync(date, businessPlaceCode, shiftType, dishesCode); @@ -103,7 +136,8 @@ public class DishesMenusController : ControllerBase /// /// [HttpGet("setting")] - public async Task GetDishesMenusBookingSetting([FromQuery] GetDishesMenusBookingRequest request) + [IgnoreTenant] + public async Task GetDishesMenusBookingSetting([FromQuery] GetDishesMenusBookingRequest request) { return await _dishesService.GetDishesMenusBookingSetting(request); } diff --git a/Src/Dlhis.Basic/Dishes/Request/DisheMenuPageRequest.cs b/Src/Dlhis.Basic/Dishes/Request/DisheMenuPageRequest.cs index 4494f433..9050763f 100644 --- a/Src/Dlhis.Basic/Dishes/Request/DisheMenuPageRequest.cs +++ b/Src/Dlhis.Basic/Dishes/Request/DisheMenuPageRequest.cs @@ -1,5 +1,4 @@ -using Dlhis.Entity.Canteen.Enums; -using Kurisu.Core.DataAccess.Dto; +using Kurisu.Core.DataAccess.Dto; namespace Dlhis.Basic.Dishes.Request; @@ -9,14 +8,4 @@ public class DisheMenuPageRequest : PageDto /// 营业点code /// public Guid BusinessPlaceCode { get; set; } - - /// - /// 餐次 - /// - public List ShiftTypes { get; set; } - - /// - /// 分类 - /// - public Guid? CategoryCode { get; set; } } diff --git a/Src/Dlhis.Basic/Dishes/Request/DishesCategorySaveRequest.cs b/Src/Dlhis.Basic/Dishes/Request/DishesCategorySaveRequest.cs index 80582418..604dfe68 100644 --- a/Src/Dlhis.Basic/Dishes/Request/DishesCategorySaveRequest.cs +++ b/Src/Dlhis.Basic/Dishes/Request/DishesCategorySaveRequest.cs @@ -6,6 +6,13 @@ public class DishesCategorySaveRequest { public long? Id { get; set; } + + /// + /// 营业点 + /// + [Required] + public Guid BusinessPlaceCode { get; set; } + /// /// PCode /// diff --git a/Src/Dlhis.Basic/Dishes/Request/DishesMenuNameDateSaveRequest.cs b/Src/Dlhis.Basic/Dishes/Request/DishesMenuNameDateSaveRequest.cs index 54b3bb35..e4518ecb 100644 --- a/Src/Dlhis.Basic/Dishes/Request/DishesMenuNameDateSaveRequest.cs +++ b/Src/Dlhis.Basic/Dishes/Request/DishesMenuNameDateSaveRequest.cs @@ -1,5 +1,6 @@ using System.ComponentModel.DataAnnotations; using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.Core.CustomClass; namespace Dlhis.Basic.Dishes.Request; @@ -11,29 +12,26 @@ public class DishesMenuNameDateSaveRequest : IValidatableObject public string CustomCode { get; set; } /// - /// 菜单日期 + /// 时间段 /// - public DateTime Date { get; set; } + [Required(ErrorMessage = "时间段不可为空")] + public DateTimePeriod Period { get; set; } /// /// 餐次数据 /// public List ShiftTypes { get; set; } - public IEnumerable Validate(ValidationContext validationContext) { - if (Date < DateTime.Today) + if (Period.Start > Period.End) { - yield return new ValidationResult("菜单日期不能小于当天"); + yield return new ValidationResult("时间范围有误", new[] { nameof(Period) }); } - //格式化 - Date = Date.Date; - if (CustomCode.IsEmpty()) { - CustomCode = Date.ToString("yyyy-MM-dd"); + CustomCode = Period.Start.Value.ToString("yyyy-MM-dd") + "." + Period.End.Value.ToString("yyyy-MM-dd"); } } } diff --git a/Src/Dlhis.Basic/Dishes/Request/GetDishesMenusBookingRequest.cs b/Src/Dlhis.Basic/Dishes/Request/GetDishesMenusBookingRequest.cs index af71ee69..5c5f7f30 100644 --- a/Src/Dlhis.Basic/Dishes/Request/GetDishesMenusBookingRequest.cs +++ b/Src/Dlhis.Basic/Dishes/Request/GetDishesMenusBookingRequest.cs @@ -1,9 +1,12 @@ -namespace Dlhis.Basic.Dishes.Request -{ - public class GetDishesMenusBookingRequest - { - public Guid PlaceCode { get; set; } +using System.ComponentModel.DataAnnotations; - public string Factory { get; set; } - } +namespace Dlhis.Basic.Dishes.Request; + +public class GetDishesMenusBookingRequest +{ + /// + /// 营业点 + /// + [Required(ErrorMessage = "请选择营业点")] + public Guid BusinessPlaceCode { get; set; } } diff --git a/Src/Dlhis.Basic/Dishes/Response/BalanceRecordSourceEnumDto.cs b/Src/Dlhis.Basic/Dishes/Response/BalanceRecordSourceEnumDto.cs index 9740a562..8a1570f6 100644 --- a/Src/Dlhis.Basic/Dishes/Response/BalanceRecordSourceEnumDto.cs +++ b/Src/Dlhis.Basic/Dishes/Response/BalanceRecordSourceEnumDto.cs @@ -1,11 +1,11 @@ using Dlhis.Entity.Canteen.Enums; using Kurisu.AspNetCore.Utils.Extensions; -namespace Dlhis.Basic.Dishes.Response +namespace Dlhis.Basic.Dishes.Response; + +public class BalanceRecordSourceEnumDto { - public class BalanceRecordSourceEnumDto - { - public BalanceRecordSourceEnumType Type { get; set; } - public string TypeCN => Type.GetDescription(); - } + public BalanceRecordSourceEnumType Type { get; set; } + + public string TypeDesc => Type.GetDescription(); } diff --git a/Src/Dlhis.Basic/Dishes/Response/BusinessShiftMealRelationshipResponse.cs b/Src/Dlhis.Basic/Dishes/Response/BusinessShiftMealRelationshipResponse.cs index 1c40fc37..0b49fd9f 100644 --- a/Src/Dlhis.Basic/Dishes/Response/BusinessShiftMealRelationshipResponse.cs +++ b/Src/Dlhis.Basic/Dishes/Response/BusinessShiftMealRelationshipResponse.cs @@ -1,29 +1,28 @@ using Dlhis.Entity.Canteen.Enums; using Kurisu.AspNetCore.Utils.Extensions; -namespace Dlhis.Basic.Dishes.Response +namespace Dlhis.Basic.Dishes.Response; + +public class BusinessShiftMealRelationshipResponse { - public class BusinessShiftMealRelationshipResponse - { - /// - /// 餐别Code - /// - public Guid ShiftCode { get; set; } + /// + /// 餐别Code + /// + public Guid ShiftCode { get; set; } - /// - /// 餐别手工号 - /// - public string ShiftCustomCode { get; set; } + /// + /// 餐别手工号 + /// + public string ShiftCustomCode { get; set; } - /// - /// 餐次 - /// - public ShiftEnumType ShiftType { get; set; } + /// + /// 餐次 + /// + public ShiftEnumType ShiftType { get; set; } - /// - /// 餐次CN - /// - public string ShiftTypeCN => ShiftType.GetDescription(); + /// + /// 餐次CN + /// + public string ShiftTypeDesc => ShiftType.GetDescription(); - } } diff --git a/Src/Dlhis.Basic/Dishes/Response/DishesCategoryResponse.cs b/Src/Dlhis.Basic/Dishes/Response/DishesCategoryResponse.cs index fdaca520..024d2606 100644 --- a/Src/Dlhis.Basic/Dishes/Response/DishesCategoryResponse.cs +++ b/Src/Dlhis.Basic/Dishes/Response/DishesCategoryResponse.cs @@ -2,6 +2,11 @@ public class DishesCategoryTreeResponse { + /// + /// 营业点code + /// + public Guid BusinessPlaceCode { get; set; } + public Guid? PCode { get; set; } public Guid Code { get; set; } diff --git a/Src/Dlhis.Basic/Dishes/Response/DishesDetailResponse.cs b/Src/Dlhis.Basic/Dishes/Response/DishesDetailResponse.cs index ce412352..4605c66d 100644 --- a/Src/Dlhis.Basic/Dishes/Response/DishesDetailResponse.cs +++ b/Src/Dlhis.Basic/Dishes/Response/DishesDetailResponse.cs @@ -1,4 +1,7 @@ -namespace Dlhis.Basic.Dishes.Response; +using Kurisu.AspNetCore.Utils.Extensions; +using Newtonsoft.Json; + +namespace Dlhis.Basic.Dishes.Response; public class DishesDetailResponse { @@ -32,12 +35,30 @@ public class DishesDetailResponse /// /// 单价 /// - public decimal Price { get; set; } + public decimal? Price { get; set; } + + /// + /// 剩余数量 + /// + public int Number { get; set; } /// /// 单位 /// - public List Units { get; set; } + public List Units + { + get + { + if (CurrentUnits.IsPresent()) + { + return CurrentUnits.ToObject>(); + } + return new() { "个" }; + } + } + + [JsonIgnore] + public string CurrentUnits { get; set; } /// /// 图片 diff --git a/Src/Dlhis.Basic/Dishes/Response/DishesMenuPageResponse.cs b/Src/Dlhis.Basic/Dishes/Response/DishesMenuPageResponse.cs index 3ccf7192..96414ae9 100644 --- a/Src/Dlhis.Basic/Dishes/Response/DishesMenuPageResponse.cs +++ b/Src/Dlhis.Basic/Dishes/Response/DishesMenuPageResponse.cs @@ -1,11 +1,7 @@ -using Dlhis.Entity.Canteen.Enums; - -namespace Dlhis.Basic.Dishes.Response; +namespace Dlhis.Basic.Dishes.Response; public class DishesMenuPageResponse { - public long? Id { get; set; } - /// /// 菜单编码 /// @@ -17,35 +13,12 @@ public class DishesMenuPageResponse public Guid BusinessPlaceCode { get; set; } /// - /// 营业日期 + /// 营业日期 开始 /// - public DateTime Date { get; set; } - + public DateTime StartDate { get; set; } /// - /// 餐次 + /// 营业日期 结束 /// - public ShiftEnumType ShiftType { get; set; } - - - /// - /// 菜品编码 - /// - public string DishesCode { get; set; } - - /// - /// 剩余数量 - /// - public int Number { get; set; } - - - /// - /// 单价 - /// - public decimal? Price { get; set; } - - /// - /// 是否启用 - /// - public bool Enable { get; set; } + public DateTime EndDate { get; set; } } diff --git a/Src/Dlhis.Basic/Dishes/Response/DishesMenusBookingSettingResponse.cs b/Src/Dlhis.Basic/Dishes/Response/DishesMenusBookingSettingResponse.cs new file mode 100644 index 00000000..f9b3a87c --- /dev/null +++ b/Src/Dlhis.Basic/Dishes/Response/DishesMenusBookingSettingResponse.cs @@ -0,0 +1,19 @@ +namespace Dlhis.Basic.Dishes.Response; + +public class DishesMenusBookingSettingResponse +{ + /// + /// 服务端时间 + /// + public DateTime ServerTime { get; set; } + + /// + /// 订餐期限 + /// + public DateTime Deadline { get; set; } + + /// + /// 支付方式 + /// + public List PayTypes { get; set; } +} diff --git a/Src/Dlhis.Basic/Dishes/Response/DishesResponse.cs b/Src/Dlhis.Basic/Dishes/Response/DishesResponse.cs index c2b58d8e..8e0f30aa 100644 --- a/Src/Dlhis.Basic/Dishes/Response/DishesResponse.cs +++ b/Src/Dlhis.Basic/Dishes/Response/DishesResponse.cs @@ -5,6 +5,8 @@ namespace Dlhis.Basic.Dishes.Response; public class DishesResponse { + public long Id { get; set; } + /// /// 分类 /// diff --git a/Src/Dlhis.Basic/Dishes/Response/GetDishesMenusBookingResponse.cs b/Src/Dlhis.Basic/Dishes/Response/GetDishesMenusBookingResponse.cs deleted file mode 100644 index 5473a443..00000000 --- a/Src/Dlhis.Basic/Dishes/Response/GetDishesMenusBookingResponse.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Dlhis.Entity.Canteen.Enums; -using SqlSugar.DbConvert; -using SqlSugar; - -namespace Dlhis.Basic.Dishes.Response -{ - public class GetDishesMenusBookingResponse - { - public List BusinessShiftMealRelationships { get; set; } - - public DateTime ServiceTime { get; set; } - - public List PayTypes { get; set; } - } -} diff --git a/Src/Dlhis.Basic/Dishes/Services/IDishesCategoryService.cs b/Src/Dlhis.Basic/Dishes/Services/IDishesCategoryService.cs index 2164e5e0..09d738d8 100644 --- a/Src/Dlhis.Basic/Dishes/Services/IDishesCategoryService.cs +++ b/Src/Dlhis.Basic/Dishes/Services/IDishesCategoryService.cs @@ -5,7 +5,11 @@ namespace Dlhis.Basic.Dishes.Services; public interface IDishesCategoryService : IScopeDependency { - Task> TreeAsync(); + Task> TreeAsync(Guid businessPlaceCode); + + + Task> TreeAllAsync(Guid businessPlaceCode); + Task SaveAsync(DishesCategorySaveRequest request); } diff --git a/Src/Dlhis.Basic/Dishes/Services/IDishesMenuService.cs b/Src/Dlhis.Basic/Dishes/Services/IDishesMenuService.cs index 87c38925..718b1efc 100644 --- a/Src/Dlhis.Basic/Dishes/Services/IDishesMenuService.cs +++ b/Src/Dlhis.Basic/Dishes/Services/IDishesMenuService.cs @@ -10,6 +10,10 @@ public interface IDishesMenuService : IScopeDependency { Task> GetDishesMenuPageAsync(DisheMenuPageRequest request); + Task GetDishesMenuDetailAsync(Guid businessPlaceCode, string customCode, DateTime startDate, DateTime endDate); + + Task> GetDishesUnderCurrentMenuAsync(Guid businessPlaceCode, DateTime date, ShiftEnumType? shiftType, Guid categoryCode); + Task SaveDishesMenuAsync(DishesMenuSaveRequest request); Task GetBookingDishesDetailAsync(DateTime date, Guid businessPlaceCode, ShiftEnumType shiftType, string dishesCode); diff --git a/Src/Dlhis.Basic/Dishes/Services/IDishesService.cs b/Src/Dlhis.Basic/Dishes/Services/IDishesService.cs index 6d6830a9..f9c0fbfd 100644 --- a/Src/Dlhis.Basic/Dishes/Services/IDishesService.cs +++ b/Src/Dlhis.Basic/Dishes/Services/IDishesService.cs @@ -12,6 +12,6 @@ public interface IDishesService : IScopeDependency Task GetDishesDetailByIdAsync(long id); - Task GetDishesMenusBookingSetting(GetDishesMenusBookingRequest request); + Task GetDishesMenusBookingSetting(GetDishesMenusBookingRequest request); } diff --git a/Src/Dlhis.Basic/Dishes/Services/Implements/DishesCategoryService.cs b/Src/Dlhis.Basic/Dishes/Services/Implements/DishesCategoryService.cs index 8fda1dc2..9a36e161 100644 --- a/Src/Dlhis.Basic/Dishes/Services/Implements/DishesCategoryService.cs +++ b/Src/Dlhis.Basic/Dishes/Services/Implements/DishesCategoryService.cs @@ -1,5 +1,7 @@ -using Dlhis.Basic.Dishes.Request; +using Dlhis.Basic.BusinessPlace.Services; +using Dlhis.Basic.Dishes.Request; using Dlhis.Basic.Dishes.Response; +using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Canteen.Entities; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.SqlSugar.Services; @@ -10,15 +12,31 @@ namespace Dlhis.Basic.Dishes.Services.Implements; public class DishesCategoryService : IDishesCategoryService { private readonly IDbContext _dbContext; + private readonly IBusinessPlacePermissionsService _businessPlacePermissionsService; - public DishesCategoryService(IDbContext dbContext) + public DishesCategoryService(IDbContext dbContext, IBusinessPlacePermissionsService businessPlacePermissionsService) { _dbContext = dbContext; + _businessPlacePermissionsService = businessPlacePermissionsService; } - public async Task> TreeAsync() + public async Task> TreeAsync(Guid businessPlaceCode) { - var categories = await _dbContext.Queryable().Select().ToListAsync(); + var mybCodes = await GetMyBusinessPlaceCodesAsync(); + mybCodes = mybCodes.Where(x => x == businessPlaceCode).ToList(); + + var categories = await _dbContext.Queryable() + .LeftJoin((x, bplace) => x.BusinessPlaceCode == bplace.Code) + .Where(x => mybCodes.Contains(x.BusinessPlaceCode)) + .Select((x, bplace) => new DishesCategoryTreeResponse + { + BusinessPlaceCode = bplace.Code, + Code = x.Code, + Name = x.Name, + PCode = x.PCode, + }) + .ToListAsync(); + var tops = categories.Where(x => !x.PCode.HasValue).ToList(); tops.ForEach(x => @@ -29,8 +47,36 @@ public class DishesCategoryService : IDishesCategoryService return tops; } + public async Task> TreeAllAsync(Guid businessPlaceCode) + { + var categories = await _dbContext.Queryable() + .LeftJoin((x, bplace) => x.BusinessPlaceCode == bplace.Code) + .Where(x => x.BusinessPlaceCode == businessPlaceCode) + .Select((x, bplace) => new DishesCategoryTreeResponse + { + BusinessPlaceCode = bplace.Code, + Code = x.Code, + Name = x.Name, + PCode = x.PCode, + }) + .ToListAsync(); + + var tops = categories.Where(x => !x.PCode.HasValue).ToList(); + + tops.ForEach(x => + { + RecursionGetNext(x, categories); + }); + + return tops; + } + + + public async Task SaveAsync(DishesCategorySaveRequest request) { + await CheckBusinessPlacePermissionAsync(request.BusinessPlaceCode); + if (!request.Id.HasValue) { var entity = request.Adapt(); @@ -62,4 +108,27 @@ public class DishesCategoryService : IDishesCategoryService } } } + + /// + /// 检查营业点权限 + /// + /// + /// + private async Task CheckBusinessPlacePermissionAsync(Guid businessPlaceCode) + { + var codes = await GetMyBusinessPlaceCodesAsync(); + codes.Contains(businessPlaceCode).ThrowIfFalse("无权操作当前营业点"); + } + + + /// + /// 获取我管理的营业点 + /// + /// + private async Task> GetMyBusinessPlaceCodesAsync() + { + var mybCodes = (await _businessPlacePermissionsService.GetMyAsync()).Select(x => x.Code).ToList(); + + return mybCodes; + } } diff --git a/Src/Dlhis.Basic/Dishes/Services/Implements/DishesMenuService.cs b/Src/Dlhis.Basic/Dishes/Services/Implements/DishesMenuService.cs index 69ef56fb..ac48ebe3 100644 --- a/Src/Dlhis.Basic/Dishes/Services/Implements/DishesMenuService.cs +++ b/Src/Dlhis.Basic/Dishes/Services/Implements/DishesMenuService.cs @@ -9,6 +9,8 @@ using Dlhis.Basic.Dishes.Request; using Dlhis.Basic.Dishes.Response; using Dlhis.Basic.BusinessPlace.Services; using Dlhis.Basic.Dishes.Dto; +using Kurisu.Core.CustomClass; +using System.Linq.Expressions; namespace Dlhis.Basic.Dishes.Services.Implements; @@ -26,10 +28,96 @@ public class DishesMenuService : IDishesMenuService public async Task> GetDishesMenuPageAsync(DisheMenuPageRequest request) { return await _dbContext.Queryable() - .Select() + .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) { //检验数据 @@ -37,14 +125,26 @@ public class DishesMenuService : IDishesMenuService //检验权限 var res = await _businessPlacePermissionsService.GetMyAsync(); - var myBps = res.dtos.Select(x => x.Code).ToList(); + var myBps = res.Select(x => x.Code).ToList(); myBps.Contains(request.BusinessPlaceCode).ThrowIfFalse("非经营营业点,无法保存菜单"); + if (request.Items.Any()) + { + Expression> whereCheck = LinqExpressionExtension.False(); + request.Items.ForEach(p => + { + whereCheck = whereCheck.Or(x => !(x.EndDate < p.Period.Start || x.StartDate > p.Period.End)); + }); + + var duplicate = await _dbContext.Queryable().Where(whereCheck).AnyAsync(); + duplicate.ThrowIfTrue("菜单时效冲突"); + } + var entities = request.Items.SelectMany(item => { var customCode = item.CustomCode; - var date = item.Date; + var period = item.Period; return item.ShiftTypes.SelectMany(shiftTypeItem => { @@ -60,7 +160,8 @@ public class DishesMenuService : IDishesMenuService { BusinessPlaceCode = request.BusinessPlaceCode, CustomCode = customCode, - Date = date, + StartDate = period.Start.Value, + EndDate = period.End.Value, ShiftType = shiftType, DishesCode = dishesCode, Number = number, @@ -68,37 +169,37 @@ public class DishesMenuService : IDishesMenuService Type = CanteenApplicaitonTypeEnumType.Booking, Version = 0, - Enable = true, }; }); }); }).ToList(); - var keys = entities.DistinctBy(x => new { x.Date, x.ShiftType }).Select(x => new { x.Date, x.ShiftType }).ToList(); + var keys = entities.DistinctBy(x => new { x.StartDate, x.EndDate, x.ShiftType }).Select(x => new { x.StartDate, x.EndDate, x.ShiftType }).ToList(); var where = LinqExpressionExtension.False(); keys.ForEach(x => { - where = where.Or(item => item.Date == x.Date && item.ShiftType == x.ShiftType); + where = where.Or(item => item.BusinessPlaceCode == request.BusinessPlaceCode + && 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(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 => x.Date == date) + .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 = x.Date, + Date = date, MenuId = x.Id, DishesId = d.Id, DishesCode = d.CustomCode, @@ -116,11 +217,11 @@ public class DishesMenuService : IDishesMenuService private static void CheckDuplicateData(DishesMenuSaveRequest request) { - (request.Items.DistinctBy(x => new { x.CustomCode, x.Date }).Count() != request.Items.Count).ThrowIfTrue("菜单不可重复"); + (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.Date.ToString("yyyy-MM-dd") + "-" + item.CustomCode; + 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}的餐次不可重复添加"); diff --git a/Src/Dlhis.Basic/Dishes/Services/Implements/DishesService.cs b/Src/Dlhis.Basic/Dishes/Services/Implements/DishesService.cs index 79fc41d6..7810608e 100644 --- a/Src/Dlhis.Basic/Dishes/Services/Implements/DishesService.cs +++ b/Src/Dlhis.Basic/Dishes/Services/Implements/DishesService.cs @@ -1,40 +1,44 @@ -using Dlhis.Basic.Dishes.Request; +using Dlhis.Basic.BusinessPlace.Services; +using Dlhis.Basic.Dishes.Request; using Dlhis.Basic.Dishes.Response; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Canteen.Entities; using Dlhis.Entity.Canteen.Enums; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Dto; +using Kurisu.Core.User.Abstractions; using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; using Mapster; -using System.Collections.Generic; -using System.Globalization; namespace Dlhis.Basic.Dishes.Services.Implements; public class DishesService : IDishesService { private readonly IDbContext _dbContext; - private readonly IConfiguration _configuration; + private readonly ICurrentUser _currentUser; + private readonly IBusinessPlacePermissionsService _businessPlacePermissionsService; - public DishesService(IDbContext dbContext, IConfiguration configuration) + public DishesService(IDbContext dbContext, ICurrentUser currentUser, IBusinessPlacePermissionsService businessPlacePermissionsService) { _dbContext = dbContext; - _configuration = configuration; + _currentUser = currentUser; + _businessPlacePermissionsService = businessPlacePermissionsService; } public async Task> GetDishesPageAsync(DishesPageRequest request) { - //todo 营业点权限 + var myCodes = await GetMyBusinessPlaceCodesAsync(); return await _dbContext.Queryable() .LeftJoin((x, category) => x.CategoryCode == category.Code) .WhereIF(request.Search.IsPresent(), x => x.CustomCode == request.Search || x.Name.Contains(request.Search)) .WhereIF(request.BusinessPlaceCodes.IsPresent(), x => request.BusinessPlaceCodes.Contains(x.BusinessPlaceCode)) + .Where(x => myCodes.Contains(x.BusinessPlaceCode)) .OrderBy(x => x.CreateTime, SqlSugar.OrderByType.Desc) .Select((x, category) => new DishesResponse { + Id = x.Id, CurrnetUnits = x.Units.ToString(), CategoryName = category.Name, @@ -61,55 +65,47 @@ public class DishesService : IDishesService } } - public async Task GetDishesMenusBookingSetting(GetDishesMenusBookingRequest request) + public async Task GetDishesMenusBookingSetting(GetDishesMenusBookingRequest request) { + 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 strDatetime = await _dbContext.Queryable() + var value = await _dbContext.Queryable() .Where(x => x.UniqueType == CanteenSettingUnqiueEnumType.Tenant && x.Item == CanteenSettingItemEnumType.BookingDeadline && x.Enable) .Select(x => x.Value) .FirstAsync(); - DateTime dateTime; - DateTime.TryParseExact(strDatetime, "HH:mm:ss", null, System.Globalization.DateTimeStyles.None, out dateTime); + if (!TimeOnly.TryParse(value, out var deadline)) + deadline = new TimeOnly(8, 30); - var res = new GetDishesMenusBookingResponse + + + var payTypes = new List() { new() { Type = BalanceRecordSourceEnumType.Cash } }; + + var selectTenantId = await _dbContext.Queryable() + .Where(x => x.Code == request.BusinessPlaceCode) + .Select(x => x.TenantId) + .FirstAsync(); + + if (gainfo.Factory == selectTenantId) { - ServiceTime = dateTime, - }; - - var shift = await _dbContext.Queryable() - .Where(x => x.PlaceCode == request.PlaceCode) - .FirstAsync(); - - var payTypes = new List(); - var dto1 = new BalanceRecordSourceEnumDto - { - Type = BalanceRecordSourceEnumType.Cash - }; - payTypes.Add(dto1); - - if (shift != null) - { - var businessShiftMealRelationships = await _dbContext.Queryable() - .Where(x => x.ShiftCode == shift.ShiftCode) - .Select() - .ToListAsync(); - res.BusinessShiftMealRelationships = businessShiftMealRelationships; - - if (shift.TenantId == request.Factory) - { - var dto2 = new BalanceRecordSourceEnumDto - { - Type = BalanceRecordSourceEnumType.LocalTenantSubsidies - }; - payTypes.Add(dto2); - } - - } - res.PayTypes = payTypes; - return res; + payTypes.Add(new BalanceRecordSourceEnumDto { Type = BalanceRecordSourceEnumType.LocalTenantSubsidies }); } + return new DishesMenusBookingSettingResponse + { + ServerTime = DateTime.Now, + Deadline = DateTime.Today.Add(deadline.ToTimeSpan()), + PayTypes = payTypes + }; + } + public async Task GetDishesDetailByIdAsync(long id) { return await _dbContext.Queryable() @@ -117,5 +113,17 @@ public class DishesService : IDishesService .Select() .SingleAsync(); } + + + + + /// + /// 获取我的营业点 + /// + /// + private async Task> GetMyBusinessPlaceCodesAsync() + { + return (await _businessPlacePermissionsService.GetMyAsync()).Select(x => x.Code).ToList(); + } } diff --git a/Src/Dlhis.Basic/Dlhis.Basic.csproj b/Src/Dlhis.Basic/Dlhis.Basic.csproj index 61d37f79..fa24f2db 100644 --- a/Src/Dlhis.Basic/Dlhis.Basic.csproj +++ b/Src/Dlhis.Basic/Dlhis.Basic.csproj @@ -17,7 +17,7 @@ - + @@ -27,6 +27,7 @@ + diff --git a/Src/Dlhis.Basic/MealUser/Controllers/MealUsersController.cs b/Src/Dlhis.Basic/MealUser/Controllers/MealUsersController.cs index 02fc4e33..04e365ac 100644 --- a/Src/Dlhis.Basic/MealUser/Controllers/MealUsersController.cs +++ b/Src/Dlhis.Basic/MealUser/Controllers/MealUsersController.cs @@ -1,5 +1,4 @@ -using Dlhis.Basic.MealUser.Request; -using Dlhis.Basic.MealUser.Response; +using Dlhis.Basic.MealUser.Response; using Dlhis.Basic.MealUser.Services; using Kurisu.Core.DataAccess.Dto; using Microsoft.AspNetCore.Authorization; @@ -28,19 +27,8 @@ public class MealUsersController : ControllerBase /// /// [HttpGet("page")] - public async Task> GetPageAsync([FromQuery] MealUserPageRequest request) + public async Task> GetPageAsync([FromQuery] PageDto request) { return await _mealUserService.GetPageAsync(request); } - - /// - /// 就餐人员保存 - /// - /// - /// - [HttpPost] - public async Task AddAsync(MealUserAddRequest request) - { - await _mealUserService.AddAsync(request); - } } diff --git a/Src/Dlhis.Basic/MealUser/Request/MealUserAddRequest.cs b/Src/Dlhis.Basic/MealUser/Request/MealUserAddRequest.cs deleted file mode 100644 index f4ee6ccc..00000000 --- a/Src/Dlhis.Basic/MealUser/Request/MealUserAddRequest.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using Dlhis.Entity.Canteen.Enums; - -namespace Dlhis.Basic.MealUser.Request; - -public class MealUserAddRequest -{ - /// - /// 档案号 - /// - [Required(ErrorMessage = "档案号不能为空")] - public string UserNo { get; set; } - - - /// - /// 用户类型 - /// - [EnumDataType(typeof(CanteenUserEnumType))] - public CanteenUserEnumType UserType { get; set; } -} diff --git a/Src/Dlhis.Basic/MealUser/Request/MealUserPageRequest.cs b/Src/Dlhis.Basic/MealUser/Request/MealUserPageRequest.cs deleted file mode 100644 index 667a21ed..00000000 --- a/Src/Dlhis.Basic/MealUser/Request/MealUserPageRequest.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Kurisu.Core.DataAccess.Dto; - -namespace Dlhis.Basic.MealUser.Request; - -public class MealUserPageRequest : PageDto -{ -} \ No newline at end of file diff --git a/Src/Dlhis.Basic/MealUser/Response/MealUserResponse.cs b/Src/Dlhis.Basic/MealUser/Response/MealUserResponse.cs index a750372e..27731ec5 100644 --- a/Src/Dlhis.Basic/MealUser/Response/MealUserResponse.cs +++ b/Src/Dlhis.Basic/MealUser/Response/MealUserResponse.cs @@ -1,6 +1,4 @@ -using Dlhis.Entity.Canteen.Enums; - -namespace Dlhis.Basic.MealUser.Response; +namespace Dlhis.Basic.MealUser.Response; public class MealUserResponse { @@ -15,13 +13,6 @@ public class MealUserResponse /// public string UserCode { get; set; } - - /// - /// 消费人员类型 - /// - public CanteenUserEnumType UserType { get; set; } - - /// /// 卡号 /// diff --git a/Src/Dlhis.Basic/MealUser/Services/IMealUserService.cs b/Src/Dlhis.Basic/MealUser/Services/IMealUserService.cs index 990a8e98..33dfe9f8 100644 --- a/Src/Dlhis.Basic/MealUser/Services/IMealUserService.cs +++ b/Src/Dlhis.Basic/MealUser/Services/IMealUserService.cs @@ -1,12 +1,9 @@ -using Dlhis.Basic.MealUser.Request; -using Dlhis.Basic.MealUser.Response; +using Dlhis.Basic.MealUser.Response; using Kurisu.Core.DataAccess.Dto; namespace Dlhis.Basic.MealUser.Services; public interface IMealUserService : IScopeDependency { - Task> GetPageAsync(MealUserPageRequest request); - - Task AddAsync(MealUserAddRequest request); + Task> GetPageAsync(PageDto request); } diff --git a/Src/Dlhis.Basic/MealUser/Services/Implements/MealUserService.cs b/Src/Dlhis.Basic/MealUser/Services/Implements/MealUserService.cs index 0469fe53..26bde8e4 100644 --- a/Src/Dlhis.Basic/MealUser/Services/Implements/MealUserService.cs +++ b/Src/Dlhis.Basic/MealUser/Services/Implements/MealUserService.cs @@ -1,9 +1,5 @@ -using Dlhis.Basic.MealUser.Request; -using Dlhis.Basic.MealUser.Response; -using Dlhis.Basic.Organization.Services; +using Dlhis.Basic.MealUser.Response; using Dlhis.Entity.Basic.Entity; -using Dlhis.Entity.Basic.Enums; -using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Dto; using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; @@ -13,17 +9,15 @@ namespace Dlhis.Basic.MealUser.Services.Implements; public class MealUserService : IMealUserService { private readonly IDbContext _dbContext; - private readonly IGainfoStore _gainfoStore; - public MealUserService(IDbContext dbContext, IGainfoStore gainfoStore) + public MealUserService(IDbContext dbContext) { _dbContext = dbContext; - _gainfoStore = gainfoStore; } - public async Task> GetPageAsync(MealUserPageRequest request) + public async Task> GetPageAsync(PageDto request) { - var page = await _dbContext.Queryable() + var page = await _dbContext.Queryable() .LeftJoin((x, ga) => x.UserNo == ga.No) .Select((x, ga) => new MealUserResponse { @@ -32,32 +26,9 @@ public class MealUserService : IMealUserService BalanceOfSubsidies = x.BalanceOfSubsidies, UserCode = ga.Code, UserNo = ga.No, - UserType = x.UserType }) .ToPageListAsync(request); return page; } - - public async Task AddAsync(MealUserAddRequest request) - { - //todo 获取档案信息 - - var gainfoEntity = await _gainfoStore.Queryable(GainfoStatusEnumType.Working) - .Where(x => x.No.ToString() == request.UserNo) - .FirstAsync(); - - gainfoEntity.ThrowIfNull($"档案[{request.UserNo}]不存在"); - - var entity = new CanteenUserEntity - { - UserNo = request.UserNo, - UserType = request.UserType, - Balance = 0, - BalanceOfRecharge = 0, - BalanceOfSubsidies = 0, - Version = 0, - }; - await _dbContext.InsertAsync(entity); - } } diff --git a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs index a3a881e5..b2b9d996 100644 --- a/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs +++ b/Src/Dlhis.Basic/Organization/Controllers/GainfosController.cs @@ -2,6 +2,7 @@ using Dlhis.Basic.Organization.Request; using Dlhis.Basic.Organization.Response; using Dlhis.Basic.Organization.Services; +using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; using Kurisu.Core.DataAccess.Dto; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -45,39 +46,6 @@ public class GainfosController : ControllerBase return await _gainfoService.GetPageAsync(request); } - /// - /// 档案表修改 - /// - /// - /// - [HttpPut("update")] - public async Task UpdateAsync(GainfoSaveRequest request) - { - await _gainfoService.UpdateAsync(request); - } - - /// - /// 离职 - /// - /// - /// - [HttpPost("dimission")] - public async Task DimissionAsync(GainfoDimissionRequest request) - { - await _gainfoService.DimissionAsync(request); - } - - /// - /// 入职 - /// - /// - /// - [HttpPost("onboarding")] - public async Task OnboardingAsync(GainfoDimissionRequest request) - { - await _gainfoService.OnboardingAsync(request); - } - /// /// 当前人员信息,余额 /// @@ -93,6 +61,7 @@ public class GainfosController : ControllerBase /// /// [HttpPost("face")] + [Transactional] public async Task UploadFaceAsync(GainfoUploadFaceRequest request) { await _gainfoService.UploadFaceAsync(request); diff --git a/Src/Dlhis.Basic/Organization/Response/GainfoDetailResponse.cs b/Src/Dlhis.Basic/Organization/Response/GainfoDetailResponse.cs index 6a3488fa..af1460b3 100644 --- a/Src/Dlhis.Basic/Organization/Response/GainfoDetailResponse.cs +++ b/Src/Dlhis.Basic/Organization/Response/GainfoDetailResponse.cs @@ -1,7 +1,5 @@ using Dlhis.Entity.Basic.Enums; using Kurisu.AspNetCore.Utils.Extensions; -using SqlSugar; -using System.ComponentModel.DataAnnotations; namespace Dlhis.Basic.Organization.Response; @@ -122,17 +120,11 @@ public class GainfoDetailResponse /// public string NationName { get; set; } - /// /// 人脸base64 /// public string Face { get; set; } - /// - /// 在职状态 - /// - public string Status { get; set; } - /// /// 厂区 /// diff --git a/Src/Dlhis.Basic/Organization/Response/GainfoPageResponse.cs b/Src/Dlhis.Basic/Organization/Response/GainfoPageResponse.cs index 4b8faadd..a43b0cf8 100644 --- a/Src/Dlhis.Basic/Organization/Response/GainfoPageResponse.cs +++ b/Src/Dlhis.Basic/Organization/Response/GainfoPageResponse.cs @@ -1,5 +1,7 @@ using Dlhis.Entity.Basic.Enums; +using Kurisu.AspNetCore.Utils.Converters; using Kurisu.AspNetCore.Utils.Extensions; +using Newtonsoft.Json; namespace Dlhis.Basic.Organization.Response; @@ -45,6 +47,7 @@ public class GainfoPageResponse /// /// 身份证号 /// + [JsonConverter(typeof(ObfuscateJsonConverter), 6)] public string IdNo { get; set; } /// @@ -86,6 +89,7 @@ public class GainfoPageResponse /// /// 手机号码 /// + [JsonConverter(typeof(ObfuscateJsonConverter), 4)] public string Phone { get; set; } /// diff --git a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs index 137700de..724575a5 100644 --- a/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs +++ b/Src/Dlhis.Basic/Organization/Services/Implements/GainfoService.cs @@ -13,7 +13,6 @@ using Kurisu.SqlSugar.Services; using Mapster; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Mvc; -using System.IdentityModel.Tokens.Jwt; using System.Linq.Expressions; namespace Dlhis.Basic.Organization.Services.Implements; @@ -28,7 +27,6 @@ public class GainfoService : IGainfoService private readonly IServiceProvider _serviceProvider; private readonly IConfiguration _configuration; private readonly ILogger _logger; - private readonly IDepartmentService _departmentService; public GainfoService(IGainfoStore gainfoStore, IDbContext dbContext, @@ -48,7 +46,6 @@ public class GainfoService : IGainfoService _serviceProvider = serviceProvider; _configuration = configuration; _logger = logger; - _departmentService = departmentService; } /// @@ -172,7 +169,7 @@ public class GainfoService : IGainfoService var info = await _gainfoStore.Queryable(GainfoStatusEnumType.Working) .LeftJoin((ga, department) => ga.DepartmentNo == department.No) - .LeftJoin((ga, department, mealUser) => ga.No == mealUser.UserNo) + .LeftJoin((ga, department, mealUser) => ga.No == mealUser.UserNo) .Where((ga, department) => ga.Id == gainfo.Id) .Select((ga, department, mealUser) => new GainfoCurrentResponse { @@ -427,13 +424,6 @@ public class GainfoService : IGainfoService OnboardingDate = ga.CreateTime, }) .FirstAsync(); - info.Status = request.Status.GetDescription(); - var trees = await _departmentService.GetTreeAsync(); - var res = trees.First(x => x.No == info.Factory); - if (res != null) - { - info.FactoryName = res.Name; - } if (info != null) { @@ -446,201 +436,6 @@ public class GainfoService : IGainfoService return info; } - public async Task>> GetWeekNumberAsync(WeekNumberRequest request, string token) - { - var werks = GetClaimValueFromToken(token, "tenant"); - - //获取近7天并转化为"yyyy-MM-dd"集合 - DateTime currentDate = DateTime.Now; - List times = new List(); - for (int i = 0; i < 7; i++) - { - DateTime date = currentDate.AddDays(-i); - string dateString = date.ToString("yyyy-MM-dd"); - times.Add(dateString); - } - - var dic = new Dictionary>(); - - foreach (var time in times) - { - var infos = await _gainfoStore.Queryable(GainfoStatusEnumType.Working) - .LeftJoin((ga, de) => ga.DepartmentNo == de.No) - .LeftJoin((ga, de, type) => ga.Native == type.Code && type.Type == "native") - .LeftJoin((ga, de, type, posi) => ga.Position == posi.Name) - .LeftJoin((ga, de, type, posi, type2) => ga.CountryNo == type2.Code && type2.Type == "country") - .LeftJoin((ga, de, type, posi, type2, type3) => ga.Nation == type3.Code && type3.Type == "nation") - .Where(ga => ga.CreateTime.ToString("yyyy-MM-dd") == time && ga.Werks == werks) - .Select((ga, de, type, posi, type2, type3) => new GainfoDetailResponse - { - No = ga.No, - SapNo = ga.SapNo, - Name = ga.Name, - Code = ga.Code, - DepartmentName = de.Name, - IdClass = ga.IdClass, - IdNo = ga.IdNo, - Gender = ga.Gender, - NativeName = type.Display, - Address = ga.Address, - Birthday = ga.Birthday, - Phone = ga.Phone, - Position = ga.Position, - Grade = posi.Grade, - Degree = ga.Degree, - Werks = ga.Werks, - CostId = ga.CostId, - Marital = ga.Marital, - CountryName = type2.Display, - NationName = type3.Display, - }).ToPageListAsync(request); - - dic[time] = infos; - } - return dic; - } - - public async Task>> GetDimissionWeekNumberAsync(WeekNumberRequest request, string token) - { - var werks = GetClaimValueFromToken(token, "tenant"); - - //获取近7天并转化为"yyyy-MM-dd"集合 - DateTime currentDate = DateTime.Now; - List times = new List(); - for (int i = 0; i < 7; i++) - { - DateTime date = currentDate.AddDays(-i); - string dateString = date.ToString("yyyy-MM-dd"); - times.Add(dateString); - } - - var dic = new Dictionary>(); - foreach (var time in times) - { - var infos = await _gainfoStore.Queryable(GainfoStatusEnumType.Leave) - .LeftJoin((ga, de) => ga.DepartmentNo == de.No) - .LeftJoin((ga, de, type) => ga.Native == type.Code && type.Type == "native") - .LeftJoin((ga, de, type, posi) => ga.Position == posi.Name) - .LeftJoin((ga, de, type, posi, type2) => ga.CountryNo == type2.Code && type2.Type == "country") - .LeftJoin((ga, de, type, posi, type2, type3) => ga.Nation == type3.Code && type3.Type == "nation") - .Where(ga => ga.CreateTime.ToString("yyyy-MM-dd") == time && ga.Werks == werks) - .Select((ga, de, type, posi, type2, type3) => new GainfoDetailResponse - { - No = ga.No, - SapNo = ga.SapNo, - Name = ga.Name, - Code = ga.Code, - DepartmentName = de.Name, - IdClass = ga.IdClass, - IdNo = ga.IdNo, - Gender = ga.Gender, - NativeName = type.Display, - Address = ga.Address, - Birthday = ga.Birthday, - Phone = ga.Phone, - Position = ga.Position, - Grade = posi.Grade, - Degree = ga.Degree, - Werks = ga.Werks, - CostId = ga.CostId, - Marital = ga.Marital, - CountryName = type2.Display, - NationName = type3.Display, - }).ToPageListAsync(request); - dic[time] = infos; - } - return dic; - } - - public async Task GetGainfoNumbersAsync(string token) - { - var werks = GetClaimValueFromToken(token, "tenant"); - - //在职人数 - var onlineNumber = await _gainfoStore.Queryable(GainfoStatusEnumType.Working) - .Where(ga => ga.Werks == werks) - .CountAsync(); - - //离职人数 - var offlineNumber = await _gainfoStore.Queryable(GainfoStatusEnumType.Leave) - .Where(ga => ga.Werks == werks) - .CountAsync(); - - //考勤总人数 - var attendanceNumber = onlineNumber + offlineNumber; - - var res = new GainfoGainfoNumbersResponse - { - OnlineNumber = onlineNumber, - OfflineNumber = offlineNumber, - AttendanceNumber = attendanceNumber - }; - return res; - } - - //-------------------------------------------help methods ------------------------------------------------ - - /// - /// 递归获取部门No - /// - /// - /// - private async Task> GetRecursionDepartmentNosAsync(List departmentNos) - { - if (departmentNos.IsEmpty()) - { - return new List(); - } - - var departments = await _dbContext.Queryable().ToListAsync(); - var currentNos = departments.Where(x => departmentNos.Contains(x.No)).ToList(); - - foreach (var item in currentNos) - { - RecursionGetNext(item.No, departments, departmentNos); - } - - return departmentNos.Distinct().ToList(); - - void RecursionGetNext(string currentCode, List departments, List result) - { - var next = departments.Where(x => x.PNo == currentCode).ToList(); - - foreach (var item in next) - { - result.Add(item.No); - RecursionGetNext(item.No, departments, result); - } - } - } - - /// - /// 解析token - /// - /// - /// - /// - /// - private string GetClaimValueFromToken(string token, string claimType) - { - try - { - var handler = new JwtSecurityTokenHandler(); - var jsonToken = handler.ReadToken(token) as JwtSecurityToken; - - if (jsonToken == null) - throw new Exception("Invalid JWT Token"); - - var claimValue = jsonToken.Claims.FirstOrDefault(c => c.Type == claimType)?.Value; - - return claimValue; - } - catch (Exception ex) - { - return null; - } - } - public async Task MigrationAsync(MigrationRequest request) { //档案数据 @@ -677,4 +472,41 @@ public class GainfoService : IGainfoService } } } + + //-------------------------------------------help methods ------------------------------------------------ + + /// + /// 递归获取部门No + /// + /// + /// + private async Task> GetRecursionDepartmentNosAsync(List departmentNos) + { + if (departmentNos.IsEmpty()) + { + return new List(); + } + + var departments = await _dbContext.Queryable().ToListAsync(); + var currentNos = departments.Where(x => departmentNos.Contains(x.No)).ToList(); + + foreach (var item in currentNos) + { + RecursionGetNext(item.No, departments, departmentNos); + } + + return departmentNos.Distinct().ToList(); + + void RecursionGetNext(string currentCode, List departments, List result) + { + var next = departments.Where(x => x.PNo == currentCode).ToList(); + + foreach (var item in next) + { + result.Add(item.No); + RecursionGetNext(item.No, departments, result); + } + } + } + } diff --git a/Src/Dlhis.Basic/Places/Controllers/BookingAddressController.cs b/Src/Dlhis.Basic/Places/Controllers/BookingAddressController.cs new file mode 100644 index 00000000..3f9eba2f --- /dev/null +++ b/Src/Dlhis.Basic/Places/Controllers/BookingAddressController.cs @@ -0,0 +1,61 @@ +using System.ComponentModel.DataAnnotations; +using Dlhis.Basic.Places.Request; +using Dlhis.Basic.Places.Response; +using Dlhis.Basic.Places.Services; +using Kurisu.AspNetCore.DataAccess.SqlSugar.Aop; +using Kurisu.Core.DataAccess.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Org.BouncyCastle.Asn1.Ocsp; + +namespace Dlhis.Basic.Places.Controllers; + +/// +/// 订餐地址 +/// +[Authorize] +[Route("api/[controller]")] +[ApiController] +public class BookingAddressController : ControllerBase +{ + private readonly IBookingAddressService _bookingAddresService; + + public BookingAddressController(IBookingAddressService bookingAddresService) + { + _bookingAddresService = bookingAddresService; + } + + /// + /// 地址分页 + /// + /// + /// + [HttpGet("page")] + public async Task> GetAddresPageAsync([FromQuery] BookingAddressPageRequest request) + { + return await _bookingAddresService.GetAddressPageAsync(request); + } + + /// + /// 所有地址 + /// + /// + /// + [HttpGet("all")] + [IgnoreTenant] + public async Task> GetAllAddressAsync([Required(ErrorMessage = "厂区不可为空")] string tenant) + { + return await _bookingAddresService.GetAllAddressAsync(tenant); + } + + /// + /// 地址保存 + /// + /// + /// + [HttpPost("save")] + public async Task SaveAddresAsync(BookingAddressSaveRequest request) + { + await _bookingAddresService.SaveAddressAsync(request); + } +} diff --git a/Src/Dlhis.Basic/BusinessPlace/Controllers/BusinessPlacePermissionsController.cs b/Src/Dlhis.Basic/Places/Controllers/BusinessPlacePermissionsController.cs similarity index 59% rename from Src/Dlhis.Basic/BusinessPlace/Controllers/BusinessPlacePermissionsController.cs rename to Src/Dlhis.Basic/Places/Controllers/BusinessPlacePermissionsController.cs index 99ac821c..e5e7e0c0 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Controllers/BusinessPlacePermissionsController.cs +++ b/Src/Dlhis.Basic/Places/Controllers/BusinessPlacePermissionsController.cs @@ -1,14 +1,15 @@ -using Dlhis.Basic.BusinessPlace.Request; +using Dlhis.Basic.Places.Request; using Dlhis.Basic.BusinessPlace.Response; using Dlhis.Basic.BusinessPlace.Services; using Kurisu.Core.DataAccess.Dto; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Dlhis.Basic.Places.Dtos; namespace Dlhis.Basic.BusinessPlace.Controllers; /// -/// 营业点管理 +/// 营业点权限管理 /// [Authorize] [Route("api/[controller]")] @@ -27,7 +28,7 @@ public class BusinessPlacePermissionsController /// /// /// - [Authorize(Roles = "admin,tenant-admin")] + [Authorize(Roles = "admin,tenant-admin,businessplace-manager")] [HttpGet("page")] public async Task> GetPageAsync([FromQuery] BusinessPlacePermissionPageRequest request) { @@ -39,7 +40,7 @@ public class BusinessPlacePermissionsController /// /// [HttpGet("my")] - public async Task GetMy() + public async Task> GetMy() { return await _businessPlacePermissionsService.GetMyAsync(); } @@ -52,8 +53,32 @@ public class BusinessPlacePermissionsController /// [Authorize(Roles = "admin,tenant-admin")] [HttpPost("save")] - public async Task SaveBusinessPlacePermissionAsync(SaveBusinessPlacePermissionRequest request) + public async Task SaveBusinessPlacePermissionAsync(BusinessPlacePermissionSaveRequest request) { await _businessPlacePermissionsService.SaveBusinessPlacePermissionAsync(request); } + + /// + /// 通过userid获取分配的营业点信息 + /// + /// + /// + [Authorize(Roles = "admin,tenant-admin")] + [HttpGet("assignments/{userId}")] + public async Task> GetBusinessPlacePermissionByUserIdAsyc(int userId) + { + return await _businessPlacePermissionsService.GetBusinessPlacePermissionByUserIdAsyc(userId); + } + + /// + /// 删除记录 + /// + /// + /// + [Authorize(Roles = "admin,tenant-admin")] + [HttpDelete("{id}")] + public async Task DeleteAssignmentAsync(int id) + { + await _businessPlacePermissionsService.DeleteAssignmentAsync(id); + } } diff --git a/Src/Dlhis.Basic/BusinessPlace/Controllers/BusinessPlacesController.cs b/Src/Dlhis.Basic/Places/Controllers/BusinessPlacesController.cs similarity index 90% rename from Src/Dlhis.Basic/BusinessPlace/Controllers/BusinessPlacesController.cs rename to Src/Dlhis.Basic/Places/Controllers/BusinessPlacesController.cs index acbc9541..dc4acda4 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Controllers/BusinessPlacesController.cs +++ b/Src/Dlhis.Basic/Places/Controllers/BusinessPlacesController.cs @@ -1,4 +1,4 @@ -using Dlhis.Basic.BusinessPlace.Request; +using Dlhis.Basic.Places.Request; using Dlhis.Basic.BusinessPlace.Response; using Dlhis.Basic.BusinessPlace.Services; using Dlhis.Basic.BusinessShift.Services; @@ -48,11 +48,23 @@ public class BusinessPlacesController : ControllerBase return await _businessPlaceService.GetOpenedListAsync(placeCode); } + /// + /// 获取启用的营业点(所有基地) + /// + /// + [HttpGet("list-all")] + [IgnoreTenant] + public async Task> GetAllList(string tenant) + { + return await _businessPlaceService.GetOpenedListAsync(null, tenant); + } + /// /// 营业点保存 /// /// /// + [Authorize(Roles = "admin,tenant-admin")] [HttpPost("save")] public async Task SaveAsync(BusinessPlaceSaveRequest request) { diff --git a/Src/Dlhis.Basic/Places/Dtos/BusinessPlaceDto.cs b/Src/Dlhis.Basic/Places/Dtos/BusinessPlaceDto.cs new file mode 100644 index 00000000..1f8a04cd --- /dev/null +++ b/Src/Dlhis.Basic/Places/Dtos/BusinessPlaceDto.cs @@ -0,0 +1,7 @@ +namespace Dlhis.Basic.Places.Dtos; + +public class BusinessPlaceDto +{ + public Guid Code { get; set; } + public string Name { get; set; } +} diff --git a/Src/Dlhis.Basic/Places/Request/BookingAddressPageRequest.cs b/Src/Dlhis.Basic/Places/Request/BookingAddressPageRequest.cs new file mode 100644 index 00000000..b08d1e3e --- /dev/null +++ b/Src/Dlhis.Basic/Places/Request/BookingAddressPageRequest.cs @@ -0,0 +1,8 @@ +using Kurisu.Core.DataAccess.Dto; + +namespace Dlhis.Basic.Places.Request; + +public class BookingAddressPageRequest : PageDto +{ + +} diff --git a/Src/Dlhis.Basic/Places/Request/BookingAddressSaveRequest.cs b/Src/Dlhis.Basic/Places/Request/BookingAddressSaveRequest.cs new file mode 100644 index 00000000..0d1764d3 --- /dev/null +++ b/Src/Dlhis.Basic/Places/Request/BookingAddressSaveRequest.cs @@ -0,0 +1,11 @@ +namespace Dlhis.Basic.Places.Request; + +public class BookingAddressSaveRequest +{ + public long? Id { get; set; } + + /// + /// 订餐地址 + /// + public string Address { get; set; } +} diff --git a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceGetByCodeRequest.cs b/Src/Dlhis.Basic/Places/Request/BusinessPlaceGetByCodeRequest.cs similarity index 88% rename from Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceGetByCodeRequest.cs rename to Src/Dlhis.Basic/Places/Request/BusinessPlaceGetByCodeRequest.cs index 5177dd0c..53ef9a11 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceGetByCodeRequest.cs +++ b/Src/Dlhis.Basic/Places/Request/BusinessPlaceGetByCodeRequest.cs @@ -1,7 +1,7 @@ using Kurisu.Core.DataAccess.Dto; using System.ComponentModel.DataAnnotations; -namespace Dlhis.Basic.BusinessPlace.Request +namespace Dlhis.Basic.Places.Request { public class BusinessPlaceGetByCodeRequest : PageDto { diff --git a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceGetShiftsRequest.cs b/Src/Dlhis.Basic/Places/Request/BusinessPlaceGetShiftsRequest.cs similarity index 85% rename from Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceGetShiftsRequest.cs rename to Src/Dlhis.Basic/Places/Request/BusinessPlaceGetShiftsRequest.cs index b2a0715e..fe12c984 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceGetShiftsRequest.cs +++ b/Src/Dlhis.Basic/Places/Request/BusinessPlaceGetShiftsRequest.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Dlhis.Basic.BusinessPlace.Request; +namespace Dlhis.Basic.Places.Request; public class BusinessPlaceGetShiftsRequest { diff --git a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlacePageRequest.cs b/Src/Dlhis.Basic/Places/Request/BusinessPlacePageRequest.cs similarity index 94% rename from Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlacePageRequest.cs rename to Src/Dlhis.Basic/Places/Request/BusinessPlacePageRequest.cs index 0107b3ce..7fe65972 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlacePageRequest.cs +++ b/Src/Dlhis.Basic/Places/Request/BusinessPlacePageRequest.cs @@ -2,7 +2,7 @@ using Dlhis.Entity.Canteen.Enums; using Kurisu.Core.DataAccess.Dto; -namespace Dlhis.Basic.BusinessPlace.Request; +namespace Dlhis.Basic.Places.Request; public class BusinessPlacePageRequest : PageDto { diff --git a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlacePermissionPageRequest.cs b/Src/Dlhis.Basic/Places/Request/BusinessPlacePermissionPageRequest.cs similarity index 69% rename from Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlacePermissionPageRequest.cs rename to Src/Dlhis.Basic/Places/Request/BusinessPlacePermissionPageRequest.cs index 4efbd299..f3cdc557 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlacePermissionPageRequest.cs +++ b/Src/Dlhis.Basic/Places/Request/BusinessPlacePermissionPageRequest.cs @@ -1,6 +1,6 @@ using Kurisu.Core.DataAccess.Dto; -namespace Dlhis.Basic.BusinessPlace.Request; +namespace Dlhis.Basic.Places.Request; public class BusinessPlacePermissionPageRequest : PageDto { diff --git a/Src/Dlhis.Basic/Places/Request/BusinessPlacePermissionSaveRequest.cs b/Src/Dlhis.Basic/Places/Request/BusinessPlacePermissionSaveRequest.cs new file mode 100644 index 00000000..9e900c9c --- /dev/null +++ b/Src/Dlhis.Basic/Places/Request/BusinessPlacePermissionSaveRequest.cs @@ -0,0 +1,14 @@ +namespace Dlhis.Basic.Places.Request; + +public class BusinessPlacePermissionSaveRequest +{ + /// + /// 管理人员userId + /// + public int UserId { get; set; } + + /// + /// 营业点 + /// + public List BusinessPlaceCodes { get; set; } = new(); +} diff --git a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceSaveRequest.cs b/Src/Dlhis.Basic/Places/Request/BusinessPlaceSaveRequest.cs similarity index 96% rename from Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceSaveRequest.cs rename to Src/Dlhis.Basic/Places/Request/BusinessPlaceSaveRequest.cs index 35c7cb27..fc2c7e71 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceSaveRequest.cs +++ b/Src/Dlhis.Basic/Places/Request/BusinessPlaceSaveRequest.cs @@ -1,7 +1,7 @@ using System.ComponentModel.DataAnnotations; using Dlhis.Entity.Canteen.Enums; -namespace Dlhis.Basic.BusinessPlace.Request; +namespace Dlhis.Basic.Places.Request; /// /// 营业点保存参数 diff --git a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceSaveShiftRequest.cs b/Src/Dlhis.Basic/Places/Request/BusinessPlaceSaveShiftRequest.cs similarity index 83% rename from Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceSaveShiftRequest.cs rename to Src/Dlhis.Basic/Places/Request/BusinessPlaceSaveShiftRequest.cs index 23fc1140..5bb64cab 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Request/BusinessPlaceSaveShiftRequest.cs +++ b/Src/Dlhis.Basic/Places/Request/BusinessPlaceSaveShiftRequest.cs @@ -1,4 +1,4 @@ -namespace Dlhis.Basic.BusinessPlace.Request; +namespace Dlhis.Basic.Places.Request; public class BusinessPlaceSaveShiftRequest { diff --git a/Src/Dlhis.Basic/BusinessPlace/Request/DispositionDeviceRequest.cs b/Src/Dlhis.Basic/Places/Request/DispositionDeviceRequest.cs similarity index 76% rename from Src/Dlhis.Basic/BusinessPlace/Request/DispositionDeviceRequest.cs rename to Src/Dlhis.Basic/Places/Request/DispositionDeviceRequest.cs index bf940fca..56b7c5f4 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Request/DispositionDeviceRequest.cs +++ b/Src/Dlhis.Basic/Places/Request/DispositionDeviceRequest.cs @@ -1,4 +1,4 @@ -namespace Dlhis.Basic.BusinessPlace.Request +namespace Dlhis.Basic.Places.Request { public class DispositionDeviceRequest { diff --git a/Src/Dlhis.Basic/Places/Response/BookingAddressPageResponse.cs b/Src/Dlhis.Basic/Places/Response/BookingAddressPageResponse.cs new file mode 100644 index 00000000..9e47928e --- /dev/null +++ b/Src/Dlhis.Basic/Places/Response/BookingAddressPageResponse.cs @@ -0,0 +1,11 @@ +namespace Dlhis.Basic.Places.Response; + +public class BookingAddressPageResponse +{ + public long Id { get; set; } + + /// + /// 订餐地址 + /// + public string Address { get; set; } +} diff --git a/Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceListResponse.cs b/Src/Dlhis.Basic/Places/Response/BusinessPlaceListResponse.cs similarity index 100% rename from Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceListResponse.cs rename to Src/Dlhis.Basic/Places/Response/BusinessPlaceListResponse.cs diff --git a/Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlacePermissionPageResponse.cs b/Src/Dlhis.Basic/Places/Response/BusinessPlacePermissionPageResponse.cs similarity index 92% rename from Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlacePermissionPageResponse.cs rename to Src/Dlhis.Basic/Places/Response/BusinessPlacePermissionPageResponse.cs index cac2e41e..9a1273e2 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlacePermissionPageResponse.cs +++ b/Src/Dlhis.Basic/Places/Response/BusinessPlacePermissionPageResponse.cs @@ -7,7 +7,7 @@ public class BusinessPlacePermissionPageResponse /// /// 用户id /// - public string UserId { get; set; } + public int UserId { get; set; } /// /// 用户name diff --git a/Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceResponse.cs b/Src/Dlhis.Basic/Places/Response/BusinessPlaceResponse.cs similarity index 100% rename from Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceResponse.cs rename to Src/Dlhis.Basic/Places/Response/BusinessPlaceResponse.cs diff --git a/Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceWithShiftResponse.cs b/Src/Dlhis.Basic/Places/Response/BusinessPlaceWithShiftResponse.cs similarity index 100% rename from Src/Dlhis.Basic/BusinessPlace/Response/BusinessPlaceWithShiftResponse.cs rename to Src/Dlhis.Basic/Places/Response/BusinessPlaceWithShiftResponse.cs diff --git a/Src/Dlhis.Basic/BusinessPlace/Response/DeviceCodeNameDetail.cs b/Src/Dlhis.Basic/Places/Response/DeviceCodeNameDetail.cs similarity index 100% rename from Src/Dlhis.Basic/BusinessPlace/Response/DeviceCodeNameDetail.cs rename to Src/Dlhis.Basic/Places/Response/DeviceCodeNameDetail.cs diff --git a/Src/Dlhis.Basic/Places/Services/IBookingAddressService.cs b/Src/Dlhis.Basic/Places/Services/IBookingAddressService.cs new file mode 100644 index 00000000..9e558f2d --- /dev/null +++ b/Src/Dlhis.Basic/Places/Services/IBookingAddressService.cs @@ -0,0 +1,14 @@ +using Dlhis.Basic.Places.Request; +using Dlhis.Basic.Places.Response; +using Kurisu.Core.DataAccess.Dto; + +namespace Dlhis.Basic.Places.Services; + +public interface IBookingAddressService : IScopeDependency +{ + Task> GetAddressPageAsync(BookingAddressPageRequest request); + + Task> GetAllAddressAsync(string tenant); + + Task SaveAddressAsync(BookingAddressSaveRequest request); +} diff --git a/Src/Dlhis.Basic/Places/Services/IBusinessPlacePermissionsService.cs b/Src/Dlhis.Basic/Places/Services/IBusinessPlacePermissionsService.cs new file mode 100644 index 00000000..5d069b56 --- /dev/null +++ b/Src/Dlhis.Basic/Places/Services/IBusinessPlacePermissionsService.cs @@ -0,0 +1,19 @@ +using Dlhis.Basic.Places.Request; +using Dlhis.Basic.BusinessPlace.Response; +using Kurisu.Core.DataAccess.Dto; +using Dlhis.Basic.Places.Dtos; + +namespace Dlhis.Basic.BusinessPlace.Services; + +public interface IBusinessPlacePermissionsService : IScopeDependency +{ + Task> GetPageAsync(BusinessPlacePermissionPageRequest request); + + Task SaveBusinessPlacePermissionAsync(BusinessPlacePermissionSaveRequest request); + + Task> GetMyAsync(); + + Task> GetBusinessPlacePermissionByUserIdAsyc(int id); + + Task DeleteAssignmentAsync(int id); +} diff --git a/Src/Dlhis.Basic/BusinessPlace/Services/IBusinessPlaceService.cs b/Src/Dlhis.Basic/Places/Services/IBusinessPlaceService.cs similarity index 92% rename from Src/Dlhis.Basic/BusinessPlace/Services/IBusinessPlaceService.cs rename to Src/Dlhis.Basic/Places/Services/IBusinessPlaceService.cs index 7228c137..ce09d910 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Services/IBusinessPlaceService.cs +++ b/Src/Dlhis.Basic/Places/Services/IBusinessPlaceService.cs @@ -1,4 +1,4 @@ -using Dlhis.Basic.BusinessPlace.Request; +using Dlhis.Basic.Places.Request; using Dlhis.Basic.BusinessPlace.Response; using Kurisu.Core.DataAccess.Dto; @@ -17,7 +17,7 @@ public interface IBusinessPlaceService : IScopeDependency /// 获取可用的营业点 /// /// - Task> GetOpenedListAsync(Guid? placeCode); + Task> GetOpenedListAsync(Guid? placeCode = null, string tenant = null); /// /// 保存营业点 diff --git a/Src/Dlhis.Basic/Places/Services/Implements/BookingAddressService.cs b/Src/Dlhis.Basic/Places/Services/Implements/BookingAddressService.cs new file mode 100644 index 00000000..c3fab27c --- /dev/null +++ b/Src/Dlhis.Basic/Places/Services/Implements/BookingAddressService.cs @@ -0,0 +1,53 @@ +using Dlhis.Basic.Places.Request; +using Dlhis.Basic.Places.Response; +using Dlhis.Entity.Basic.Entity; +using Kurisu.AspNetCore.Utils.Extensions; +using Kurisu.Core.DataAccess.Dto; +using Kurisu.SqlSugar.Extensions; +using Kurisu.SqlSugar.Services; +using Mapster; + +namespace Dlhis.Basic.Places.Services.Implements; + +public class BookingAddressService : IBookingAddressService +{ + private readonly IDbContext _dbContext; + + public BookingAddressService(IDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task> GetAddressPageAsync(BookingAddressPageRequest request) + { + return await _dbContext.Queryable() + .WhereIF(request.Search.IsPresent(), x => x.Address.Contains(request.Search)) + .Select() + .ToPageListAsync(request); + } + + public async Task SaveAddressAsync(BookingAddressSaveRequest request) + { + if (!request.Id.HasValue) + { + var entity = request.Adapt(); + await _dbContext.InsertAsync(entity); + } + else + { + var entity = await _dbContext.Queryable() + .Where(x => x.Id == request.Id) + .FirstAsync(); + request.Adapt(entity); + await _dbContext.UpdateAsync(entity); + } + } + + public async Task> GetAllAddressAsync(string tenant) + { + return await _dbContext.Queryable() + .Where(x => x.TenantId == tenant) + .Select() + .ToListAsync(); + } +} diff --git a/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlacePermissionsService.cs b/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlacePermissionsService.cs new file mode 100644 index 00000000..6b0cd8e2 --- /dev/null +++ b/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlacePermissionsService.cs @@ -0,0 +1,124 @@ +using Dlhis.Basic.Places.Request; +using Dlhis.Basic.BusinessPlace.Response; +using Dlhis.Entity.Basic.Entity; +using Kurisu.Core.DataAccess.Dto; +using Kurisu.Core.User.Abstractions; +using Kurisu.SqlSugar.Services; +using Mapster; +using Dlhis.Basic.Places.Dtos; +using Kurisu.SqlSugar.Extensions; +using Dlhis.Sys.Api; +using Microsoft.AspNetCore.Mvc; +using System.Security.Claims; + +namespace Dlhis.Basic.BusinessPlace.Services.Implements; + +public class BusinessPlacePermissionsService : IBusinessPlacePermissionsService +{ + private readonly IDbContext _dbContext; + private readonly ICurrentUser _currentUser; + private readonly IUserApi _userApi; + + public BusinessPlacePermissionsService(IDbContext dbContext, ICurrentUser currentUser, IUserApi userApi) + { + _dbContext = dbContext; + _currentUser = currentUser; + _userApi = userApi; + } + + public async Task> GetPageAsync(BusinessPlacePermissionPageRequest request) + { + var page = await _dbContext.Queryable() + .LeftJoin((x, bplace) => x.BusinessPlaceCode == bplace.Code) + .Select((x, bplace) => new BusinessPlacePermissionPageResponse + { + UserId = x.ManagerUserId, + BusinessPlaceCode = x.BusinessPlaceCode, + BusinessPlaceName = bplace.Name, + }) + .ToPageListAsync(request); + + var usersResult = await _userApi.GetUserByIdsAsync(page.Data.Select(x => x.UserId).Distinct().ToList()); + var users = usersResult.Data; + + page.Data.ForEach(item => + { + item.UserName = users.FirstOrDefault(x => x.Id == item.UserId)?.UserName; + }); + + return page; + } + + public async Task> GetMyAsync() + { + var userId = _currentUser.GetIntSubjectId(); + var role = _currentUser.GetUserClaim(ClaimTypes.Role); + var isAdmin = role == "admin" || role == "tenant-admin"; + + var codes = new List(); + if (isAdmin) + { + codes = await _dbContext.Queryable() + .Select(x => x.Code) + .ToListAsync(); + } + else + { + codes = await _dbContext.Queryable() + .Where(x => x.ManagerUserId == userId) + .Select(x => x.BusinessPlaceCode) + .Distinct() + .ToListAsync(); + } + + + return await _dbContext.Queryable() + .Where(x => codes.Contains(x.Code)) + .Select() + .ToListAsync(); + } + + public async Task SaveBusinessPlacePermissionAsync(BusinessPlacePermissionSaveRequest request) + { + var userId = _currentUser.GetIntSubjectId(); + + await _dbContext.Client.Deleteable() + .Where(x => x.ManagerUserId == request.UserId) + .ExecuteCommandAsync(); + + await _dbContext.InsertAsync(request.BusinessPlaceCodes.Select(x => new BusinessPlaceManagerRelationshipEntity + { + BusinessPlaceCode = x, + ManagerUserId = request.UserId + }).ToList()); + } + + public async Task> GetBusinessPlacePermissionByUserIdAsyc(int id) + { + var infos = await _dbContext.Queryable() + .LeftJoin((x, bplace) => x.BusinessPlaceCode == bplace.Code) + .Where(x => x.ManagerUserId == id) + .Select((x, bplace) => new BusinessPlacePermissionPageResponse + { + UserId = x.ManagerUserId, + BusinessPlaceCode = x.BusinessPlaceCode, + BusinessPlaceName = bplace.Name, + }) + .ToListAsync(); + + var userResult = await _userApi.GetUserByIdAsync(id); + var user = userResult.Data; + + infos.ForEach(item => + { + item.UserName = user?.UserName; + }); + + return infos; + } + + public async Task DeleteAssignmentAsync(int id) + { + await _dbContext.Client.Deleteable().Where(x => x.Id == id).ExecuteCommandAsync(); + } +} diff --git a/Src/Dlhis.Basic/BusinessPlace/Services/Implements/BusinessPlaceService.cs b/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlaceService.cs similarity index 85% rename from Src/Dlhis.Basic/BusinessPlace/Services/Implements/BusinessPlaceService.cs rename to Src/Dlhis.Basic/Places/Services/Implements/BusinessPlaceService.cs index 79a25b9f..23508ed8 100644 --- a/Src/Dlhis.Basic/BusinessPlace/Services/Implements/BusinessPlaceService.cs +++ b/Src/Dlhis.Basic/Places/Services/Implements/BusinessPlaceService.cs @@ -1,4 +1,4 @@ -using Dlhis.Basic.BusinessPlace.Request; +using Dlhis.Basic.Places.Request; using Dlhis.Basic.BusinessPlace.Response; using Dlhis.Entity.Basic.Entity; using Dlhis.Entity.Canteen.Enums; @@ -13,15 +13,18 @@ namespace Dlhis.Basic.BusinessPlace.Services.Implements; public class BusinessPlaceService : IBusinessPlaceService { private readonly IDbContext _dbContext; + private readonly IBusinessPlacePermissionsService _businessPlacePermissionsService; - public BusinessPlaceService(IDbContext dbContext) + public BusinessPlaceService(IDbContext dbContext, IBusinessPlacePermissionsService businessPlacePermissionsService) { _dbContext = dbContext; + _businessPlacePermissionsService = businessPlacePermissionsService; } - public async Task> GetPageAsync(BusinessPlacePageRequest request) { + var myCodes = await GetMyBusinessPlaceCodesAsync(); + var page = await _dbContext.Queryable() .LeftJoin((x, ps) => x.Code == ps.PlaceCode) .LeftJoin((x, ps, s) => s.Code == ps.ShiftCode) @@ -30,6 +33,7 @@ public class BusinessPlaceService : IBusinessPlaceService .WhereIF(request.Catalog.HasValue, x => x.Catalog == request.Catalog) .WhereIF(request.Status.HasValue, x => x.Status == request.Status) .WhereIF(request.Source.HasValue, x => x.Source == request.Source) + .Where(x => myCodes.Contains(x.Code)) .Select((x, ps, s) => new BusinessPlaceResponse { Id = x.Id, @@ -49,13 +53,17 @@ public class BusinessPlaceService : IBusinessPlaceService } - public async Task> GetOpenedListAsync(Guid? placeCode) + public async Task> GetOpenedListAsync(Guid? placeCode = null, string tenant = null) { + var myCodes = await GetMyBusinessPlaceCodesAsync(); + var list = await _dbContext.Queryable() .LeftJoin((x, ps) => x.Code == ps.PlaceCode) .LeftJoin((x, ps, s) => s.Code == ps.ShiftCode) .Where(x => x.Status == CanteenBusinessPlaceStatusEnumType.Opened) .WhereIF(placeCode.HasValue, x => x.Code == placeCode) + .WhereIF(tenant.IsPresent(), x => x.TenantId == tenant) + .Where(x => myCodes.Contains(x.Code)) .Select((x, ps, s) => new BusinessPlaceListResponse { Id = x.Id, @@ -150,4 +158,13 @@ public class BusinessPlaceService : IBusinessPlaceService existsSameCustomCode.ThrowIfTrue($"自定义手工号[{request.CustomCode}]存在重复,请检查."); } + + /// + /// 获取我的营业点 + /// + /// + private async Task> GetMyBusinessPlaceCodesAsync() + { + return (await _businessPlacePermissionsService.GetMyAsync()).Select(x => x.Code).ToList(); + } } diff --git a/Src/Dlhis.Canteen/MealSupplementRecord/Controller/MealSupplementRecordController.cs b/Src/Dlhis.Canteen/MealSupplementRecord/Controller/MealSupplementRecordController.cs new file mode 100644 index 00000000..5e0a8418 --- /dev/null +++ b/Src/Dlhis.Canteen/MealSupplementRecord/Controller/MealSupplementRecordController.cs @@ -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; + +/// +/// 原始餐补 +/// +[Authorize] +[Route("api/[controller]")] +[ApiController] +public class MealSupplementRecordController +{ + private readonly IMealSupplementRecordService _mealSupplementRecordService; + + public MealSupplementRecordController(IMealSupplementRecordService mealSupplementRecordService) + { + _mealSupplementRecordService = mealSupplementRecordService; + } + + /// + /// 餐补分页 + /// + /// + /// + [HttpGet("page")] + public async Task> MealSupplementRecordPageAsync([FromQuery] MealSupplementRecordRequest request) + { + return await _mealSupplementRecordService.GetPageAsync(request); + } +} diff --git a/Src/Dlhis.Canteen/MealSupplementRecord/Request/MealSupplementRecordRequest.cs b/Src/Dlhis.Canteen/MealSupplementRecord/Request/MealSupplementRecordRequest.cs new file mode 100644 index 00000000..93d14930 --- /dev/null +++ b/Src/Dlhis.Canteen/MealSupplementRecord/Request/MealSupplementRecordRequest.cs @@ -0,0 +1,8 @@ +using Kurisu.Core.DataAccess.Dto; + +namespace Dlhis.Canteen.MealSupplementRecord.Request; + +public class MealSupplementRecordRequest : PageDto +{ + +} diff --git a/Src/Dlhis.Canteen/MealSupplementRecord/Response/MealSupplementRecordResponse.cs b/Src/Dlhis.Canteen/MealSupplementRecord/Response/MealSupplementRecordResponse.cs new file mode 100644 index 00000000..fe39466d --- /dev/null +++ b/Src/Dlhis.Canteen/MealSupplementRecord/Response/MealSupplementRecordResponse.cs @@ -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 +{ + /// + /// 唯一号 + /// + public string UniqueId { get; set; } + + /// + /// 工号 + /// + public string Code { get; set; } + + public string UserName { get; set; } + + /// + /// 餐补状态 + /// + public MealSupplementStatusEnumtype Status { get; set; } + + /// + /// 餐补状态 + /// + public string StatusDesc => Status.GetDescription(); + + /// + /// 考勤日期 + /// + public DateTime Date { get; set; } + + /// + /// 工作地 + /// + public string Workplace { get; set; } + + /// + /// 厂区 + /// + public string Factory { get; set; } + + + public string Remark { get; set; } + + /// + /// 餐补 + /// + public decimal Amount { get; set; } + + /// + /// 处理结果 + /// + public string Result { get; set; } + + /// + /// 状态同步 + /// + public bool Sync { get; set; } +} diff --git a/Src/Dlhis.Canteen/MealSupplementRecord/Services/IMealSupplementRecordService.cs b/Src/Dlhis.Canteen/MealSupplementRecord/Services/IMealSupplementRecordService.cs new file mode 100644 index 00000000..89c1624c --- /dev/null +++ b/Src/Dlhis.Canteen/MealSupplementRecord/Services/IMealSupplementRecordService.cs @@ -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> GetPageAsync(MealSupplementRecordRequest request); +} diff --git a/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs b/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs new file mode 100644 index 00000000..2d1630ee --- /dev/null +++ b/Src/Dlhis.Canteen/MealSupplementRecord/Services/Implements/MealSupplementRecordService.cs @@ -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> GetPageAsync(MealSupplementRecordRequest request) + { + var page = await _dbContext.Queryable() + .LeftJoin((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; + } +} diff --git a/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs b/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs index 317fbe83..f55573a0 100644 --- a/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs +++ b/Src/Dlhis.Canteen/Order/Controllers/BalancesController.cs @@ -25,10 +25,11 @@ public class BalancesController : ControllerBase } /// - /// 获取记录分页 + /// 获取所有消费记录分页 /// /// /// + [Authorize(Roles = "admin,tenant-admin")] [DataPermission] [HttpGet] public async Task> GetPageAsync([FromQuery] BalanceRecordPageRequest request) @@ -154,7 +155,7 @@ public class BalancesController : ControllerBase /// /// [HttpGet("spendingDetails")] - public async Task> GetSpendingDetailsAsync([FromQuery]SpendingDetailRequest request) + public async Task> GetSpendingDetailsAsync([FromQuery] SpendingDetailRequest request) { return await _balanceService.GetSpendingDetailsAsync(request); } @@ -181,27 +182,14 @@ public class BalancesController : ControllerBase return await _balanceService.GetConsumeDeviceAsync(request); } - - /// - /// 电子餐券申请记录查询 - /// - /// - [HttpGet("oaemealvoucher")] - public async Task> GetOaEMealVoucherAsync([FromQuery] OaEMealVoucherRequest request) - { - return await _balanceService.GetOaEMealVoucherAsync(request); - } - - /// - /// 电子餐券使用记录查询 + /// 查询餐补入账记录 /// /// /// - [HttpGet("oaemealvoucherdetail")] - public async Task> GetOaEMealVoucherDetailAsync([FromQuery] OaEMealVoucherDetailRequest request) + [HttpGet("balanceOfMealSupplementRecordByUser")] + public async Task> BalanceRecordByUserAsync([FromQuery] BalanceRecordByUserRequest request) { - return await _balanceService.GetOaEMealVoucherDetailAsync(request); + return await _balanceService.GetBalanceOfMealSupplementRecordByUser(request); } - } diff --git a/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs b/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs index 9d0f7b96..35ef5f69 100644 --- a/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs +++ b/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs @@ -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; - } - - /// - /// 订单分页 - /// - /// - /// - [HttpGet("page")] - public async Task> GetPageAsync([FromQuery] OrderPageRequest request) - { - return await _orderService.GetPageAsync(request); + _bookingOrderService = bookingOrderService; } /// @@ -59,25 +50,67 @@ public class OrdersController : ControllerBase return await _orderService.AddAsync(request); } + /// + /// 订单聚合数据 + /// + /// + [HttpGet("aggregation")] + [IgnoreTenant] + public async Task> GetOrdersAggregationAsync([FromQuery] PageDto page) + { + return await _orderService.GetOrdersAggregationAsync(page); + } + + /// + /// 取消订单 + /// + /// + /// + [HttpPut("user-cancel")] + [Transactional] + [IgnoreTenant] + public async Task CancelOrderAsync(OrderCancelRequest request) + { + await _bookingOrderService.UserCancelOrderAsync(request); + } + + + + /// + /// 取消订单 + /// + /// + /// + [HttpPut("manager-cancel")] + [Transactional] + [IgnoreTenant] + public async Task ManagerCancelOrderAsync(OrderCancelRequest request) + { + await _bookingOrderService.ManagerCancelOrderAsync(request); + } + + //************************************************************** 订餐功能 ********************************************************************************** /// /// 订餐 /// /// - [IgnoreTenant] [HttpPost("booking")] - public async Task Booking(BookingMealRequest request) + [Transactional] + [IgnoreTenant] + public async Task Booking(BookingMealRequest request) { - await _orderService.Booking(request); + return await _bookingOrderService.BookingAsync(request); } /// - /// 充值 + /// 订单分页 /// + /// /// - [HttpPost("recharge")] - public async Task ReCharge() + [HttpGet("booking/page")] + public async Task> GetBookingPageAsync([FromQuery] OrderBookingPageRequest request) { - + return await _bookingOrderService.GetBookingPageAsync(request); } } diff --git a/Src/Dlhis.Canteen/Order/Request/BalanceRecordByUserRequest.cs b/Src/Dlhis.Canteen/Order/Request/BalanceRecordByUserRequest.cs new file mode 100644 index 00000000..dded4745 --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Request/BalanceRecordByUserRequest.cs @@ -0,0 +1,11 @@ +using Kurisu.Core.DataAccess.Dto; + +namespace Dlhis.Canteen.Order.Request; + +public class BalanceRecordByUserRequest : PageDto +{ + /// + /// 用户档案号 + /// + public string UserNo { get; set; } +} diff --git a/Src/Dlhis.Canteen/Order/Request/BalanceRecordUserPageRequest.cs b/Src/Dlhis.Canteen/Order/Request/BalanceRecordUserPageRequest.cs index 719f7e3f..8e544b15 100644 --- a/Src/Dlhis.Canteen/Order/Request/BalanceRecordUserPageRequest.cs +++ b/Src/Dlhis.Canteen/Order/Request/BalanceRecordUserPageRequest.cs @@ -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; } + /// + /// 消费应用类型 + /// + public CanteenApplicaitonTypeEnumType? ApplicationType { get; set; } + /// /// 日期范围查询 /// public DateTimePeriod SearchDateTimePeriod { get; set; } + public IEnumerable 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) { diff --git a/Src/Dlhis.Canteen/Order/Request/BookingMealRequest.cs b/Src/Dlhis.Canteen/Order/Request/BookingMealRequest.cs index 9872a497..388dc9f0 100644 --- a/Src/Dlhis.Canteen/Order/Request/BookingMealRequest.cs +++ b/Src/Dlhis.Canteen/Order/Request/BookingMealRequest.cs @@ -30,12 +30,28 @@ public class BookingMealRequest : IValidatableObject [Required(ErrorMessage = "选菜不能为空")] public string DishesCode { get; set; } + /// + /// 购买数量 + /// + [Range(0, 100)] + public int Number { get; set; } + + /// + /// 单位 + /// + public string Unit { get; set; } + /// /// 消费来源 /// [EnumDataType(typeof(BalanceRecordSourceEnumType))] public BalanceRecordSourceEnumType Source { get; set; } + /// + /// 配送地址 + /// + [Required] + public string DeliveryAddress { get; set; } public IEnumerable Validate(ValidationContext validationContext) { diff --git a/Src/Dlhis.Canteen/Order/Request/OaEMealVoucherDetailRequest.cs b/Src/Dlhis.Canteen/Order/Request/OaEMealVoucherDetailRequest.cs deleted file mode 100644 index 75ce0571..00000000 --- a/Src/Dlhis.Canteen/Order/Request/OaEMealVoucherDetailRequest.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Kurisu.Core.DataAccess.Dto; - -namespace Dlhis.Canteen.Dishes.Request -{ - public class OaEMealVoucherDetailRequest : PageDto - { - /// - /// 餐券id - /// - public long OaEMealVoucherId { get; set; } - } -} diff --git a/Src/Dlhis.Canteen/Order/Request/OaEMealVoucherRequest.cs b/Src/Dlhis.Canteen/Order/Request/OaEMealVoucherRequest.cs deleted file mode 100644 index ae1ffa86..00000000 --- a/Src/Dlhis.Canteen/Order/Request/OaEMealVoucherRequest.cs +++ /dev/null @@ -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 - { - /// - /// 用户学工号 - /// - public string UserCode { get; set; } - } -} diff --git a/Src/Dlhis.Canteen/Order/Request/OrderBookingPageRequest.cs b/Src/Dlhis.Canteen/Order/Request/OrderBookingPageRequest.cs new file mode 100644 index 00000000..24cab90b --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Request/OrderBookingPageRequest.cs @@ -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 +{ + /// + /// 订单状态 CanteenOrderStatusEnumType + /// + [EnumDataType(typeof(CanteenOrderStatusEnumType))] + public CanteenOrderStatusEnumType? OrderStatus { get; set; } +} diff --git a/Src/Dlhis.Canteen/Order/Request/OrderCancelRequest.cs b/Src/Dlhis.Canteen/Order/Request/OrderCancelRequest.cs new file mode 100644 index 00000000..35c8c079 --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Request/OrderCancelRequest.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; + +namespace Dlhis.Canteen.Order.Request; + +public class OrderCancelRequest +{ + /// + /// + /// + [Required(ErrorMessage = "订单号")] + public string No { get; set; } + + /// + /// 取消原因 + /// + [Required] + public string Reason { get; set; } +} diff --git a/Src/Dlhis.Canteen/Order/Request/OrderPageRequest.cs b/Src/Dlhis.Canteen/Order/Request/OrderPageRequest.cs deleted file mode 100644 index ad268044..00000000 --- a/Src/Dlhis.Canteen/Order/Request/OrderPageRequest.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Kurisu.Core.DataAccess.Dto; - -namespace Dlhis.Canteen.Order.Request; - -public class OrderPageRequest : PageDto -{ - -} diff --git a/Src/Dlhis.Canteen/Order/Request/SaveDetailRequest.cs b/Src/Dlhis.Canteen/Order/Request/SaveDetailRequest.cs deleted file mode 100644 index a7ed3d5d..00000000 --- a/Src/Dlhis.Canteen/Order/Request/SaveDetailRequest.cs +++ /dev/null @@ -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; } - - /// - /// 订单号 - /// - public string ThirdNo { get; set; } - - /// - /// 营业日 - /// - public DateOnly BusinessDate { get; set; } - - /// - /// 餐次 - /// - public ShiftEnumType ShiftType { get; set; } - - /// - /// 菜品编码 - /// - public Guid DishesCode { get; set; } - - /// - /// 菜品名称 - /// - public Guid DishesName { get; set; } - - /// - /// 单价 - /// - public decimal Price { get; set; } - - /// - /// 单位 - /// - public string Unit { get; set; } - - /// - /// 数量 - /// - public int Num { get; set; } - - /// - /// 金额 - /// - public decimal Amount { get; set; } - - /// - /// 订单明细状态 - /// - public OrderDetailsStatusEnumType OrderStatus { get; set; } - } -} diff --git a/Src/Dlhis.Canteen/Order/Response/BalanceRecordByUserResponse.cs b/Src/Dlhis.Canteen/Order/Response/BalanceRecordByUserResponse.cs new file mode 100644 index 00000000..367262ea --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Response/BalanceRecordByUserResponse.cs @@ -0,0 +1,24 @@ +namespace Dlhis.Canteen.Order.Response; + +public class BalanceRecordByUserResponse +{ + /// + /// 流水号 + /// + public string No { get; set; } + + /// + /// 金额 + /// + public decimal Amount { get; set; } + + /// + /// 消费时间 + /// + public DateTime CostDateTime { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } +} diff --git a/Src/Dlhis.Canteen/Order/Response/BalanceRecordUserResponse.cs b/Src/Dlhis.Canteen/Order/Response/BalanceRecordUserResponse.cs index 1ab529aa..9ad32164 100644 --- a/Src/Dlhis.Canteen/Order/Response/BalanceRecordUserResponse.cs +++ b/Src/Dlhis.Canteen/Order/Response/BalanceRecordUserResponse.cs @@ -49,4 +49,15 @@ public class BalanceRecordUserResponse /// 记录产生日期 /// public DateTime CostDateTime { get; set; } + + + /// + /// 消费应用类型 + /// + public CanteenApplicaitonTypeEnumType ApplicationType { get; set; } + + /// + /// 消费应用类型 + /// + public string ApplicationTypeDesc => ApplicationType.GetDescription(); } diff --git a/Src/Dlhis.Canteen/Order/Response/BookingResponse.cs b/Src/Dlhis.Canteen/Order/Response/BookingResponse.cs new file mode 100644 index 00000000..beb1dfd5 --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Response/BookingResponse.cs @@ -0,0 +1,32 @@ +using Dlhis.Entity.Canteen.Enums; +using Kurisu.AspNetCore.Utils.Extensions; + +namespace Dlhis.Canteen.Order.Response; + +public class BookingResponse +{ + /// + /// 订单号 + /// + public string No { get; set; } + + /// + /// 订单时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 消费金额 + /// + public decimal Amount { get; set; } + + /// + /// 支付方式 + /// + public BalanceRecordSourceEnumType Source { get; set; } + + /// + /// 支付方式 + /// + public string SourceDesc => Source.GetDescription(); +} diff --git a/Src/Dlhis.Canteen/Order/Response/DishesDto.cs b/Src/Dlhis.Canteen/Order/Response/DishesDto.cs new file mode 100644 index 00000000..5ce96c19 --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Response/DishesDto.cs @@ -0,0 +1,34 @@ +using Newtonsoft.Json; + +namespace Dlhis.Canteen.Order.Response; + +public class DishesDto +{ + [JsonIgnore] + public string No { get; set; } + + /// + /// 菜品编码 + /// + public string DishesCode { get; set; } + + /// + /// 菜品名称 + /// + public string Name { get; set; } + + /// + /// 购买单价 + /// + public decimal Price { get; set; } + + /// + /// 购买数量 + /// + public int Number { get; set; } + + /// + /// 图片 + /// + public string ImageUrl { get; set; } +} diff --git a/Src/Dlhis.Canteen/Order/Response/GetDetailResponse.cs b/Src/Dlhis.Canteen/Order/Response/GetDetailResponse.cs deleted file mode 100644 index 956a1ac6..00000000 --- a/Src/Dlhis.Canteen/Order/Response/GetDetailResponse.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Dlhis.Entity.Canteen.Enums; -using Kurisu.AspNetCore.Utils.Extensions; - -namespace Dlhis.Canteen.Order.Response; - -public class GetDetailResponse -{ - /// - /// 订单号 - /// - public string ThirdNo { get; set; } - - /// - /// 营业日 - /// - public DateOnly SysDate { get; set; } - - /// - /// 餐次 - /// - public ShiftEnumType ShiftType { get; set; } - - /// - /// 餐次CN - /// - public string ShiftTypeCN => ShiftType.GetDescription(); - - /// - /// 菜品编码 - /// - public Guid DishesCode { get; set; } - - /// - /// 菜品名称 - /// - public string DishesName { get; set; } - - /// - /// 单价 - /// - public decimal Price { get; set; } - - /// - /// 单位 - /// - public string Unit { get; set; } - - /// - /// 数量 - /// - public int Num { get; set; } - - /// - /// 金额 - /// - public decimal Amount { get; set; } - - /// - /// 订单明细状态 - /// - public OrderDetailsStatusEnumType OrderStatus { get; set; } - - /// - /// 订单明细状态CN - /// - public string OrderStatusCN => OrderStatus.GetDescription(); -} \ No newline at end of file diff --git a/Src/Dlhis.Canteen/Order/Response/OaEMealVoucherDetailResponse.cs b/Src/Dlhis.Canteen/Order/Response/OaEMealVoucherDetailResponse.cs deleted file mode 100644 index d57c1e7e..00000000 --- a/Src/Dlhis.Canteen/Order/Response/OaEMealVoucherDetailResponse.cs +++ /dev/null @@ -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; } - - /// - /// 身份证 - /// - public string IdNo { get; set; } - - /// - /// 用餐人 - /// - public string Name { get; set; } - - /// - /// 手机号 - /// - public string Phone { get; set; } - - /// - /// 就餐开始 - /// - public DateTime Start { get; set; } - - /// - /// 就餐结束 - /// - public DateTime End { get; set; } - - /// - /// 就餐天数 - /// - public int Days { get; set; } - - /// - /// 金额 - /// - public decimal Amount { get; set; } - - /// - /// 二维码 - /// - public string QrCode { get; set; } - - /// - /// 状态 - /// - public string Status { get; set; } - - /// - /// 信息 - /// - public string Message { get; set; } - } -} diff --git a/Src/Dlhis.Canteen/Order/Response/OaEMealVoucherResponse.cs b/Src/Dlhis.Canteen/Order/Response/OaEMealVoucherResponse.cs deleted file mode 100644 index d21260fd..00000000 --- a/Src/Dlhis.Canteen/Order/Response/OaEMealVoucherResponse.cs +++ /dev/null @@ -1,97 +0,0 @@ -namespace Dlhis.Canteen.Order.Response; - -public class OaEMealVoucherResponse -{ - public long Id { get; set; } - - /// - /// 标题 - /// - public string Title { get; set; } - - /// - /// 申请人工号 - /// - public string UserCode { get; set; } - - /// - /// 申请人名称 - /// - public string Name { get; set; } - - /// - /// 基地代码 - /// - public string TenantId { get; set; } - - /// - /// 基地名称 - /// - public string TenantName { get; set; } - - /// - /// 成本中心 - /// - public string CostId { get; set; } - - /// - /// 成本中心名称 - /// - public string CostName { get; set; } - - /// - /// 来宾公司 - /// - public string Company { get; set; } - - /// - /// 联系人 - /// - public string Phone { get; set; } - - /// - /// 来宾人数 - /// - public int Num { get; set; } - - /// - /// 就餐食堂 - /// - public string Canteen { get; set; } - - /// - /// 就餐事由 - /// - public string Reason { get; set; } - - /// - /// 就餐次 - /// - public string CanteenShift { get; set; } - - /// - /// oa流程id - /// - public string OaId { get; set; } - - /// - /// 部门号 - /// - public string DepartmentNo { get; set; } - - /// - /// 部门名称 - /// - public string DepartmentName { get; set; } - - - /// - /// 申请日期 - /// - public DateTime LogDate { get; set; } - - /// - /// 数据创建时间 - /// - public DateTime CreateTime { get; set; } -} diff --git a/Src/Dlhis.Canteen/Order/Response/OrderAggregationResponse.cs b/Src/Dlhis.Canteen/Order/Response/OrderAggregationResponse.cs new file mode 100644 index 00000000..c00cfec1 --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Response/OrderAggregationResponse.cs @@ -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; } + + /// + /// 营业点 + /// + public string BusinessPlaceName { get; set; } + + /// + /// 购买菜品 + /// + public List Dishes { get; set; } + + + /// + /// 金额 + /// + public decimal Amount + { + get + { + if (Dishes.IsPresent()) + { + return Dishes.Sum(x => x.Number * x.Price); + } + + return 0; + } + } + + /// + /// 共计数量 + /// + public int Count + { + get + { + if (Dishes.IsPresent()) + { + return Dishes.Count; + } + + return 0; + } + } + + /// + /// 订单时间 + /// + public DateTime CreateTime { get; set; } + + public string Remark { get; set; } + + /// + /// 订单状态 + /// + public CanteenOrderStatusEnumType OrderStatus { get; set; } + + + public string OrderStatusDesc => OrderStatus.GetDescription(); +} diff --git a/Src/Dlhis.Canteen/Order/Response/OrderBookingResponse.cs b/Src/Dlhis.Canteen/Order/Response/OrderBookingResponse.cs new file mode 100644 index 00000000..06385b0d --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Response/OrderBookingResponse.cs @@ -0,0 +1,58 @@ +using Dlhis.Entity.Canteen.Enums; +using Kurisu.AspNetCore.Utils.Extensions; + +namespace Dlhis.Canteen.Order.Response; + +public class OrderBookingResponse +{ + /// + /// 订单号 + /// + public string No { get; set; } + + /// + /// 备注 + /// + public string Remark { get; set; } + + /// + /// 配送地址 + /// + public string DeliveryAddress { get; set; } + + /// + /// 订单金额 + /// + public decimal Amount { get; set; } + + /// + /// 工号 + /// + public string UserCode { get; set; } + + /// + /// 用户 + /// + public string UserName { get; set; } + + /// + /// 餐次 + /// + public ShiftEnumType? ShiftType { get; set; } + + /// + /// 餐次 + /// + public string ShiftTypeDesc => ShiftType.GetDescription(); + + + /// + /// 订单时间 + /// + public DateTime CreateTime { get; set; } + + + public CanteenOrderStatusEnumType Status { get; set; } + + public string StatusDesc => Status.GetDescription(); +} diff --git a/Src/Dlhis.Canteen/Order/Response/OrderDetailResponse.cs b/Src/Dlhis.Canteen/Order/Response/OrderDetailResponse.cs new file mode 100644 index 00000000..f0af992a --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Response/OrderDetailResponse.cs @@ -0,0 +1,34 @@ +//namespace Dlhis.Canteen.Order.Response; + +//public class OrderDetailResponse +//{ +// /// +// /// 菜品编码 +// /// +// public string DishesCode { get; set; } + +// /// +// /// 菜品名称 +// /// +// public string Name { get; set; } + +// /// +// /// 单价 +// /// +// public decimal Price { get; set; } + +// /// +// /// 数量 +// /// +// public int Number { get; set; } + +// /// +// /// 单位 +// /// +// public string Unit { get; set; } + +// /// +// /// 图片 +// /// +// public string ImageUrl { get; set; } +//} diff --git a/Src/Dlhis.Canteen/Order/Response/OrderResponse.cs b/Src/Dlhis.Canteen/Order/Response/OrderResponse.cs deleted file mode 100644 index 0486b439..00000000 --- a/Src/Dlhis.Canteen/Order/Response/OrderResponse.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Dlhis.Canteen.Order.Response; - -public class OrderResponse -{ -} diff --git a/Src/Dlhis.Canteen/Order/Services/IBalanceService.cs b/Src/Dlhis.Canteen/Order/Services/IBalanceService.cs index dfe66e07..5d846bbc 100644 --- a/Src/Dlhis.Canteen/Order/Services/IBalanceService.cs +++ b/Src/Dlhis.Canteen/Order/Services/IBalanceService.cs @@ -35,7 +35,5 @@ public interface IBalanceService : IScopeDependency Task> GetConsumeDeviceAsync(GetConsumeDeviceRequest request); - Task> GetOaEMealVoucherAsync([FromQuery] OaEMealVoucherRequest request); - - Task> GetOaEMealVoucherDetailAsync([FromQuery] OaEMealVoucherDetailRequest request); + Task> GetBalanceOfMealSupplementRecordByUser(BalanceRecordByUserRequest request); } diff --git a/Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs b/Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs new file mode 100644 index 00000000..3266c9ee --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs @@ -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 +{ + /// + /// 订餐 + /// + /// + /// + Task BookingAsync(BookingMealRequest request); + + + Task> GetBookingPageAsync(OrderBookingPageRequest request); + + Task UserCancelOrderAsync(OrderCancelRequest request); + + Task ManagerCancelOrderAsync(OrderCancelRequest request); +} diff --git a/Src/Dlhis.Canteen/Order/Services/IOrderService.cs b/Src/Dlhis.Canteen/Order/Services/IOrderService.cs index f78863cb..029f951d 100644 --- a/Src/Dlhis.Canteen/Order/Services/IOrderService.cs +++ b/Src/Dlhis.Canteen/Order/Services/IOrderService.cs @@ -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> GetPageAsync(OrderPageRequest request); - + Task AddAsync(OrderAddRequest request); /// @@ -18,10 +16,5 @@ public interface IOrderService : IScopeDependency /// Task DeviceConsume(OrderAddRequest request); - /// - /// 订餐 - /// - /// - /// - Task Booking(BookingMealRequest request); + Task> GetOrdersAggregationAsync(PageDto page); } diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs index f216236b..ab663500 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs @@ -521,13 +521,14 @@ public class BalanceService : IBalanceService .LeftJoin((record, ga) => record.UserNo == ga.No) .LeftJoin((record, ga, department) => ga.DepartmentNo == department.No) .LeftJoin((record, ga, department, bplace) => record.BusinessPlaceCode == bplace.Code) - .LeftJoin((record, ga, department, bplace, bshift) => record.BusinessShiftCode == bshift.Code) - .LeftJoin((record, ga, department, bplace, bshift, type) => record.BusinessShiftCode.ToString() == type.Code) + .LeftJoin((record, ga, department, bplace, bshiftR) => bplace.Code == bshiftR.PlaceCode) + .LeftJoin((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().Where(x => x.UserNo == balanceRecord.UserNo).SingleAsync(); + var canteenUser = await _dbContext.Queryable().Where(x => x.UserNo == balanceRecord.UserNo).SingleAsync(); //金额 + canteenUser.Balance += Math.Abs(balanceRecord.Amount); - var effect = await _dbContext.Updateable() + var effect = await _dbContext.Updateable() .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> GetBalanceOfMealSupplementRecordByUser(BalanceRecordByUserRequest request) + { + var page = await _dbContext.Queryable() + .Where(x => x.Source == BalanceRecordSourceEnumType.LocalTenantSubsidies || x.Source == BalanceRecordSourceEnumType.OtherTenantSubsidies) + .Where(x => x.UserNo == request.UserNo) + .Select() + .ToPageListAsync(request); + + page.Data.Add(new BalanceRecordByUserResponse + { + Amount = 20, + CostDateTime = DateTime.Now.Date, + Remark = "2024-03-21 餐补", + No = "129876578" + }); + + return page; + } + /// /// 获取离线设备 @@ -839,26 +860,6 @@ public class BalanceService : IBalanceService return list; } - - public async Task> GetOaEMealVoucherAsync(OaEMealVoucherRequest request) - { - var page = await _dbContext.Queryable() - .Where(x => x.UserCode == request.UserCode) - .Select() - .ToPageListAsync(request); - return page; - } - - public async Task> GetOaEMealVoucherDetailAsync(OaEMealVoucherDetailRequest request) - { - var page = await _dbContext.Queryable() - .Where(x => x.VoucherId == request.OaEMealVoucherId) - .Select() - .ToPageListAsync(request); - - return page; - } - /// /// 获取当前年所有月 /// diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs new file mode 100644 index 00000000..33ee4ffc --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs @@ -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 _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; + + /// + /// 检查权限 + /// + /// + /// + /// + protected async Task CheckPermissionAsync(string userNo, string deviceUniqueNo) + { + var uniqueNosResult = await _devicePermissionApi.GetCanteenDeviceUniqueNosByUserNoAsync(userNo); + var uniqueNos = uniqueNosResult.Data; + + uniqueNos.Contains(deviceUniqueNo).ThrowIfFalse("无消费权限"); + } + + + /// + /// 设备并发更新 需要抛出VersionExceptions + /// + /// + /// + /// 并发冲突处理次数 + /// + /// + /// + protected async Task ContinueUpdateAsync(Func 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 ?? "操作失败,请重试"); + } + + + /// + /// 获取参数配置 + /// + /// + /// + /// + /// + protected async Task GetSettingAsync(CanteenSettingItemEnumType item, T defaultValue = default) + { + if (_settings == null) + { + 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(); + } + _settings = await _canteenSettingService.GetUserSettingAsync(gainfo.No); + } + + + if (_settings.TryGetValue(item, out var v)) + { + try + { + if (int.TryParse(v, out var n)) + { + return n.Adapt(); + } + + return v.Adapt(); + } + catch (Exception) + { + return defaultValue; + } + } + + return defaultValue; + } +} diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BookingOrderService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BookingOrderService.cs new file mode 100644 index 00000000..f177f75f --- /dev/null +++ b/Src/Dlhis.Canteen/Order/Services/Implements/BookingOrderService.cs @@ -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 logger) + : base(canteenSettingService, dbContext, currentUser, devicePermissionApi, logger) + { + _disheMenuApi = disheMenuApi; + _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 GetSettingAsync(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(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().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() + .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() + .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(); + 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> 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) + .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(CanteenSettingItemEnumType.BookingDeadline) ?? new TimeOnly(20, 30, 00); + var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan()); + (now >= dealLine).ThrowIfTrue("不在订单取消允许范围内,不可操作"); + + 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(); + + var balance = await DbContext.Queryable().Where(x => x.No == request.No).SingleAsync(); + 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(); + + var amount = Math.Abs(order.Amount); + + //尝试5次 + await ContinueUpdateAsync(async () => + { + var mealInfo = await DbContext.Queryable().Where(x => x.UserNo == order.UserNo).FirstAsync(); + + var effect = await DbContext.Updateable() + .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().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(); + + var balance = await DbContext.Queryable().Where(x => x.No == request.No).SingleAsync(); + 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(); + + var amount = Math.Abs(order.Amount); + + //尝试5次 + await ContinueUpdateAsync(async () => + { + var mealInfo = await DbContext.Queryable().Where(x => x.UserNo == order.UserNo).FirstAsync(); + + var effect = await DbContext.Updateable() + .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); + } + + + /// + /// 检查我的订餐是否存在,存在抛出异常 + /// + /// + /// + /// + 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 == 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; + } +} diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs index e390d2ca..07bc6916 100644 --- a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs +++ b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs @@ -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 _logger; - - public OrderService(IDbContext dbContext, - ICanteenSettingService canteenSettingService, - IDevicePermissionApi devicePermissionApi, - ICurrentUser currentUser, - IDisheMenuApi disheMenuApi, + public OrderService(ICanteenSettingService canteenSettingService, IDbContext dbContext, + ICurrentUser currentUser, IDevicePermissionApi devicePermissionApi, ILogger logger) + : base(canteenSettingService, dbContext, currentUser, devicePermissionApi, logger) { - _dbContext = dbContext; - _canteenSettingService = canteenSettingService; - _devicePermissionApi = devicePermissionApi; - _currentUser = currentUser; - _disheMenuApi = disheMenuApi; - _logger = logger; } - public async Task> GetPageAsync(OrderPageRequest request) - { - var page = await _dbContext.Queryable() - .Select() - .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().Where(x => x.Code == jinkoCode).FirstAsync(); - - var businessPlace = await _dbContext.Queryable().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync(); - - //预定时间 - var now = DateTime.Now; - - var settings = await _canteenSettingService.GetUserSettingAsync(gainfo.Code); - var bookingDeadline = GetSetting(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(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().Where(x => x.UserNo == order.UserNo).FirstAsync(); - //金额+- - canteenUser.Balance += order.Amount; - (canteenUser.Balance < 0).ThrowIfTrue("余额不足,无法消费"); - - var effect = await _dbContext.Updateable() - .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() - .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(); - 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 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() + var gainfo = await DbContext.Queryable() .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() + var canteenUserExists = await DbContext.Queryable() .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() + return await DbContext.Queryable() .LeftJoin((ga, department) => ga.DepartmentNo == department.No) - .LeftJoin((ga, department, mealUser) => ga.No == mealUser.UserNo) + .LeftJoin((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 /// private async Task ConsumeAsync(ConsumeRequest request, GainfoEntity gainfo) { - var device = await _dbContext.Queryable().Where(x => x.UniqueNo == request.DeviceUniqueNo).Where(x => x.Enable).FirstAsync(); + var device = await DbContext.Queryable().Where(x => x.UniqueNo == request.DeviceUniqueNo).Where(x => x.Enable).FirstAsync(); device.ThrowIfNull("设备不存在或者尚未启用"); - var registry = await _dbContext.Queryable().Where(x => x.DeviceUniqueNo == request.DeviceUniqueNo).FirstAsync(); + var registry = await DbContext.Queryable().Where(x => x.DeviceUniqueNo == request.DeviceUniqueNo).FirstAsync(); registry.ThrowIfNull("设备尚未注册"); - var businessPlaceInfo = await _dbContext.Queryable() + var businessPlaceInfo = await DbContext.Queryable() .LeftJoin((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().Where(x => x.ShiftCode == businessPlaceInfo.ShiftCode).ToListAsync(); + var shifts = await DbContext.Queryable().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(settings, CanteenSettingItemEnumType.BusinessSwitchTime); + var switchTime = await GetSettingAsync(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(settings, CanteenSettingItemEnumType.AllowCrossTenant), + IsCostCrossTenant = await GetSettingAsync(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() + await DbContext.Updateable() .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() - .SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Successful) + await DbContext.Updateable() + .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 /// 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(settings, CanteenSettingItemEnumType.AllowCrossTenant), + IsCostCrossTenant = await GetSettingAsync(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() + await DbContext.Updateable() .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() - .SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Successful) + await DbContext.Updateable() + .SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Success) .Where(x => x.Id == orderId) .ExecuteCommandAsync(); } + public async Task> GetOrdersAggregationAsync(PageDto page) + { + 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 pageResult = await DbContext.Queryable().Where(x => x.UserNo == gainfo.No) + .LeftJoin((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((x, bplace, detail) => x.No == detail.OrderNo) + + var nos = pageResult.Data.Select(x => x.No).ToList(); + var dtos = await DbContext.Queryable() + .LeftJoin((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 ************************************************************/ - /// - /// 设备并发更新 需要抛出VersionExceptions - /// - /// - /// - /// 并发冲突处理次数 - /// - /// - private async Task ContinueUpdateAsync(Func 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("操作失败,请重试"); - } - - - /// - /// 获取参数配置 - /// - /// - /// - /// - /// - /// - private static T GetSetting(Dictionary settings, CanteenSettingItemEnumType item, T defaultValue = default) - { - if (settings.TryGetValue(item, out var v)) - { - try - { - if (int.TryParse(v, out var n)) - { - return n.Adapt(); - } - - return v.Adapt(); - } - catch (Exception) - { - return defaultValue; - } - } - - return defaultValue; - } /// /// 验证参数 /// - /// /// /// /// /// /// - private async Task Verify(Dictionary settings, List shifts, DateTime costDateTime, CanteenOrderEntity order) + private async Task Verify(List 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() + var balanceRecords = await DbContext.Queryable() .Where(x => x.UserNo == order.UserNo) .Where(x => x.CreateTime >= beginOfDay && x.CreateTime <= endOfDay) //今天消费记录 .ToListAsync(); - var dayMarketCostMax = GetSetting(settings, CanteenSettingItemEnumType.DayMarketCostMax); + var dayMarketCostMax = await GetSettingAsync(CanteenSettingItemEnumType.DayMarketCostMax); if (dayMarketCostMax != default) { - var businessPlaceCodes = await _dbContext.Queryable() + var businessPlaceCodes = await DbContext.Queryable() .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(settings, CanteenSettingItemEnumType.OnceCostMax); + var onceCostMax = await GetSettingAsync(CanteenSettingItemEnumType.OnceCostMax); if (onceCostMax != default) { if (Math.Abs(order.Amount) > onceCostMax) @@ -556,7 +402,7 @@ public class OrderService : IOrderService } } - var dayCostMax = GetSetting(settings, CanteenSettingItemEnumType.DayCostMax); + var dayCostMax = await GetSettingAsync(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 /// private async Task GenerateRechargeRecordAsync(long orderId) { - var order = await _dbContext.Queryable().Where(x => x.Id == orderId).FirstAsync(); + var order = await DbContext.Queryable().Where(x => x.Id == orderId).FirstAsync(); await ContinueUpdateAsync(async () => { - var canteenUser = await _dbContext.Queryable().Where(x => x.UserNo == order.UserNo).FirstAsync(); + var canteenUser = await DbContext.Queryable().Where(x => x.UserNo == order.UserNo).FirstAsync(); //金额+- canteenUser.Balance += order.Amount; - var effect = await _dbContext.Updateable() + var effect = await DbContext.Updateable() .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(); - await _dbContext.InsertAsync(balanceRecord); + await DbContext.InsertAsync(balanceRecord); }, 5); } @@ -604,25 +450,24 @@ public class OrderService : IOrderService /// 生成充值记录 /// /// - /// /// /// /// /// /// - private async Task GenerateConsumeRecordAsync(long orderId, Dictionary settings, List shifts, DateTime costDateTime) + private async Task GenerateConsumeRecordAsync(long orderId, List shifts, DateTime costDateTime) { - var order = await _dbContext.Queryable().Where(x => x.Id == orderId).FirstAsync(); + var order = await DbContext.Queryable().Where(x => x.Id == orderId).FirstAsync(); //校验 - await Verify(settings, shifts, costDateTime, order); + await Verify(shifts, costDateTime, order); - var allowNoBalance = GetSetting(settings, CanteenSettingItemEnumType.AllowNoBalance); + var allowNoBalance = await GetSettingAsync(CanteenSettingItemEnumType.AllowNoBalance); await ContinueUpdateAsync(async () => { if (!allowNoBalance) { - var canteenUser = await _dbContext.Queryable().Where(x => x.UserNo == order.UserNo).FirstAsync(); + var canteenUser = await DbContext.Queryable().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() + var effect = await DbContext.Updateable() .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(); - await _dbContext.InsertAsync(balanceRecord); + await DbContext.InsertAsync(balanceRecord); }, 5); } - /// - /// 检查我的订餐是否存在,存在抛出异常 - /// - /// - /// - private async Task CheckExistsMyBookingsAsync(DateTime bookingDate) - { - var jinkoCode = _currentUser.GetUserClaim("jinko-code"); - var gainfo = await _dbContext.Queryable().Where(x => x.Code == jinkoCode).FirstAsync(); - var start = bookingDate.Date; - var end = start.AddDays(1).AddSeconds(-1); - - var exists = await _dbContext.Queryable().Where(x => x.ApplicationType == CanteenApplicaitonTypeEnumType.Booking) - .Where(x => x.UserNo == gainfo.No) - .Where(x => x.CreateTime >= start && x.CreateTime <= end) - .AnyAsync(); - - exists.ThrowIfTrue("不可重复订餐"); - } } diff --git a/Src/Dlhis.Canteen/Program.cs b/Src/Dlhis.Canteen/Program.cs index b9710d07..198c78c7 100644 --- a/Src/Dlhis.Canteen/Program.cs +++ b/Src/Dlhis.Canteen/Program.cs @@ -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(); } diff --git a/Src/Dlhis.Canteen/appsettings.Development.json b/Src/Dlhis.Canteen/appsettings.Development.json index 49e0aa9e..f67d9370 100644 --- a/Src/Dlhis.Canteen/appsettings.Development.json +++ b/Src/Dlhis.Canteen/appsettings.Development.json @@ -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", diff --git a/Src/Dlhis.Common/ApiLog/ApiLogController.cs b/Src/Dlhis.Common/ApiLog/Controller/ApiLogController.cs similarity index 83% rename from Src/Dlhis.Common/ApiLog/ApiLogController.cs rename to Src/Dlhis.Common/ApiLog/Controller/ApiLogController.cs index 355730be..91478b33 100644 --- a/Src/Dlhis.Common/ApiLog/ApiLogController.cs +++ b/Src/Dlhis.Common/ApiLog/Controller/ApiLogController.cs @@ -1,11 +1,11 @@ -using Dlhis.Common.Request; -using Dlhis.Common.Response; -using Dlhis.Common.Services.Implements; +using Dlhis.Common.ApiLog.Request; +using Dlhis.Common.ApiLog.Response; +using Dlhis.Common.ApiLog.Services.Implements; using Kurisu.Core.DataAccess.Dto; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace Dlhis.Common.ApiLog +namespace Dlhis.Common.ApiLog.Controller { /// /// API日志控制器 diff --git a/Src/Dlhis.Common/Request/ApiLogRequest.cs b/Src/Dlhis.Common/ApiLog/Request/ApiLogRequest.cs similarity index 88% rename from Src/Dlhis.Common/Request/ApiLogRequest.cs rename to Src/Dlhis.Common/ApiLog/Request/ApiLogRequest.cs index ca4d00cc..c08de14e 100644 --- a/Src/Dlhis.Common/Request/ApiLogRequest.cs +++ b/Src/Dlhis.Common/ApiLog/Request/ApiLogRequest.cs @@ -1,7 +1,7 @@ using Kurisu.Core.DataAccess.Dto; using System.ComponentModel.DataAnnotations; -namespace Dlhis.Common.Request +namespace Dlhis.Common.ApiLog.Request { public class ApiLogRequest : PageDto { diff --git a/Src/Dlhis.Common/Response/ApiLogResponse.cs b/Src/Dlhis.Common/ApiLog/Response/ApiLogResponse.cs similarity index 96% rename from Src/Dlhis.Common/Response/ApiLogResponse.cs rename to Src/Dlhis.Common/ApiLog/Response/ApiLogResponse.cs index ff51f853..8d1aaf82 100644 --- a/Src/Dlhis.Common/Response/ApiLogResponse.cs +++ b/Src/Dlhis.Common/ApiLog/Response/ApiLogResponse.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace Dlhis.Common.Response +namespace Dlhis.Common.ApiLog.Response { public class ApiLogResponse { diff --git a/Src/Dlhis.Common/Services/ApiLogService.cs b/Src/Dlhis.Common/ApiLog/Services/ApiLogService.cs similarity index 80% rename from Src/Dlhis.Common/Services/ApiLogService.cs rename to Src/Dlhis.Common/ApiLog/Services/ApiLogService.cs index 2a6b9550..e9d9cc66 100644 --- a/Src/Dlhis.Common/Services/ApiLogService.cs +++ b/Src/Dlhis.Common/ApiLog/Services/ApiLogService.cs @@ -1,6 +1,6 @@ -using Dlhis.Common.Request; -using Dlhis.Common.Response; -using Dlhis.Common.Services.Implements; +using Dlhis.Common.ApiLog.Request; +using Dlhis.Common.ApiLog.Response; +using Dlhis.Common.ApiLog.Services.Implements; using Dlhis.Entity.Common; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Dto; @@ -8,7 +8,7 @@ using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; using SqlSugar; -namespace Dlhis.Common.Services +namespace Dlhis.Common.ApiLog.Services { public class ApiLogService : IApiLogService { @@ -24,7 +24,7 @@ namespace Dlhis.Common.Services var logs = await _dbContext.ChangeDb("log").Queryable() .WhereIF(request.Search.IsPresent(), x => x.Message.Contains(request.Search)) .WhereIF(request.Level.HasValue, x => x.Level == request.Level) - .OrderBy(x => x.Timestamp,OrderByType.Desc) + .OrderBy(x => x.Timestamp, OrderByType.Desc) .Select() .ToPageListAsync(request); diff --git a/Src/Dlhis.Common/Services/Implements/IApiLogService.cs b/Src/Dlhis.Common/ApiLog/Services/Implements/IApiLogService.cs similarity index 59% rename from Src/Dlhis.Common/Services/Implements/IApiLogService.cs rename to Src/Dlhis.Common/ApiLog/Services/Implements/IApiLogService.cs index 4006c3b1..b8f27280 100644 --- a/Src/Dlhis.Common/Services/Implements/IApiLogService.cs +++ b/Src/Dlhis.Common/ApiLog/Services/Implements/IApiLogService.cs @@ -1,8 +1,8 @@ -using Dlhis.Common.Request; -using Dlhis.Common.Response; +using Dlhis.Common.ApiLog.Request; +using Dlhis.Common.ApiLog.Response; using Kurisu.Core.DataAccess.Dto; -namespace Dlhis.Common.Services.Implements +namespace Dlhis.Common.ApiLog.Services.Implements { public interface IApiLogService : IScopeDependency { diff --git a/Src/Dlhis.Common/Dlhis.Common.csproj b/Src/Dlhis.Common/Dlhis.Common.csproj index 02b72955..fd153a15 100644 --- a/Src/Dlhis.Common/Dlhis.Common.csproj +++ b/Src/Dlhis.Common/Dlhis.Common.csproj @@ -25,4 +25,8 @@ + + + + diff --git a/Src/Dlhis.Common/FileOperation/Controllers/ApkFileController.cs b/Src/Dlhis.Common/FileOperation/Controllers/ApkFileController.cs index 7ab679b7..a57f65ef 100644 --- a/Src/Dlhis.Common/FileOperation/Controllers/ApkFileController.cs +++ b/Src/Dlhis.Common/FileOperation/Controllers/ApkFileController.cs @@ -1,8 +1,6 @@ using Dlhis.Common.FileOperation.Request; using Dlhis.Common.FileOperation.Response; using Dlhis.Common.FileOperation.Services; -using Dlhis.Common.Request; -using Dlhis.Common.Response; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Org.BouncyCastle.Asn1.Ocsp; @@ -10,8 +8,9 @@ using Org.BouncyCastle.Asn1.Ocsp; namespace Dlhis.Common.FileOperation.Controllers; /// -/// 文件上传/下载 +/// APK文件操作 /// +[Obsolete("作废重写")] [Authorize] [Route("api/[controller]")] [ApiController] @@ -28,7 +27,7 @@ public class ApkFileController : ControllerBase /// /// /// - [HttpPost("minlo")] + [HttpPost("minio")] [RequestSizeLimit(300_000_000)] public async Task FormSingleFileUpload([FromForm] ApkRequest request) { @@ -56,9 +55,6 @@ public class ApkFileController : ControllerBase { return await _apkFIileService.GetLastVersionAsync(productCode); } - - - } diff --git a/Src/Dlhis.Common/Request/ApkRequest.cs b/Src/Dlhis.Common/FileOperation/Request/ApkRequest.cs similarity index 85% rename from Src/Dlhis.Common/Request/ApkRequest.cs rename to Src/Dlhis.Common/FileOperation/Request/ApkRequest.cs index 86156c02..aca49440 100644 --- a/Src/Dlhis.Common/Request/ApkRequest.cs +++ b/Src/Dlhis.Common/FileOperation/Request/ApkRequest.cs @@ -1,4 +1,4 @@ -namespace Dlhis.Common.Request +namespace Dlhis.Common.FileOperation.Request { public class ApkRequest { @@ -25,6 +25,6 @@ /// /// 产品代码 /// - public string? ProductCode { get; set; } + public string ProductCode { get; set; } } } diff --git a/Src/Dlhis.Common/FileOperation/Request/UploadFileReuqest.cs b/Src/Dlhis.Common/FileOperation/Request/UploadFileReuqest.cs index 1863e728..ac690a39 100644 --- a/Src/Dlhis.Common/FileOperation/Request/UploadFileReuqest.cs +++ b/Src/Dlhis.Common/FileOperation/Request/UploadFileReuqest.cs @@ -4,8 +4,14 @@ namespace Dlhis.Common.FileOperation.Request; public class UploadFileReuqest { + /// + /// bucket + /// [FromRoute] public string Bucket { get; set; } + /// + /// 文件 + /// public IFormFile File { get; set; } } diff --git a/Src/Dlhis.Common/Response/ApkFile1Response.cs b/Src/Dlhis.Common/FileOperation/Response/ApkFile1Response.cs similarity index 93% rename from Src/Dlhis.Common/Response/ApkFile1Response.cs rename to Src/Dlhis.Common/FileOperation/Response/ApkFile1Response.cs index 560d4356..143be5fb 100644 --- a/Src/Dlhis.Common/Response/ApkFile1Response.cs +++ b/Src/Dlhis.Common/FileOperation/Response/ApkFile1Response.cs @@ -1,6 +1,6 @@ using SqlSugar; -namespace Dlhis.Common.Response +namespace Dlhis.Common.FileOperation.Response { public class ApkFile1Response { diff --git a/Src/Dlhis.Common/Response/ApkFileFormLocalResponse.cs b/Src/Dlhis.Common/FileOperation/Response/ApkFileFormLocalResponse.cs similarity index 91% rename from Src/Dlhis.Common/Response/ApkFileFormLocalResponse.cs rename to Src/Dlhis.Common/FileOperation/Response/ApkFileFormLocalResponse.cs index 6d91bf30..b4c78bf2 100644 --- a/Src/Dlhis.Common/Response/ApkFileFormLocalResponse.cs +++ b/Src/Dlhis.Common/FileOperation/Response/ApkFileFormLocalResponse.cs @@ -1,4 +1,4 @@ -namespace Dlhis.Common.Response +namespace Dlhis.Common.FileOperation.Response { public class ApkFileFormLocalResponse { diff --git a/Src/Dlhis.Common/Services/Implements/ApkFIileService.cs b/Src/Dlhis.Common/FileOperation/Services/ApkFIileService.cs similarity index 91% rename from Src/Dlhis.Common/Services/Implements/ApkFIileService.cs rename to Src/Dlhis.Common/FileOperation/Services/ApkFIileService.cs index 03848263..2ebc1240 100644 --- a/Src/Dlhis.Common/Services/Implements/ApkFIileService.cs +++ b/Src/Dlhis.Common/FileOperation/Services/ApkFIileService.cs @@ -1,13 +1,13 @@ -using Dlhis.Common.FileOperation.Services; -using Dlhis.Common.Request; -using Dlhis.Common.Response; +using Dlhis.Common.ApiLog.Response; +using Dlhis.Common.FileOperation.Request; +using Dlhis.Common.FileOperation.Response; using Dlhis.Entity.Common; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.SqlSugar.Services; using Mapster; using Microsoft.AspNetCore.Mvc; -namespace Dlhis.Common.Services.Implements; +namespace Dlhis.Common.FileOperation.Services; public class ApkFIileService : IApkFIileService { @@ -143,7 +143,7 @@ public class ApkFIileService : IApkFIileService catch (Exception) { return null; - throw; + throw; } } /// @@ -155,7 +155,7 @@ public class ApkFIileService : IApkFIileService { var info = await _dbContext.Queryable() .Where(x => x.Name == fileName) - .OrderByDescending(x => x.VersionCode) + .OrderByDescending(x => x.VersionCode) .FirstAsync(); info.ThrowIfNull($"没有{fileName}信息"); var res = info.Adapt(); @@ -173,6 +173,16 @@ public class ApkFIileService : IApkFIileService string path = filePath + fileName; return new FileStreamResult(new FileStream(path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName }; } + + Task IApkFIileService.FormSingleFileUpload(ApkRequest request) + { + throw new NotImplementedException(); + } + + public Task GetLastVersionAsync(string productCode) + { + throw new NotImplementedException(); + } } diff --git a/Src/Dlhis.Common/FileOperation/Services/IApkFIileService.cs b/Src/Dlhis.Common/FileOperation/Services/IApkFIileService.cs index 5dfa8536..047b8f6b 100644 --- a/Src/Dlhis.Common/FileOperation/Services/IApkFIileService.cs +++ b/Src/Dlhis.Common/FileOperation/Services/IApkFIileService.cs @@ -1,7 +1,5 @@ using Dlhis.Common.FileOperation.Request; using Dlhis.Common.FileOperation.Response; -using Dlhis.Common.Request; -using Dlhis.Common.Response; using Microsoft.AspNetCore.Mvc; namespace Dlhis.Common.FileOperation.Services; @@ -23,8 +21,6 @@ public interface IApkFIileService : IScopeDependency Task GetLastVersionAsync(string productCode); - - } diff --git a/Src/Dlhis.Common/FileOperation/Services/IMinioService.cs b/Src/Dlhis.Common/FileOperation/Services/IMinioService.cs index 7fd36cc2..f70c17f0 100644 --- a/Src/Dlhis.Common/FileOperation/Services/IMinioService.cs +++ b/Src/Dlhis.Common/FileOperation/Services/IMinioService.cs @@ -1,4 +1,4 @@ -using Dlhis.Common.Request; +using Dlhis.Common.FileOperation.Request; namespace Dlhis.Common.FileOperation.Services; diff --git a/Src/Dlhis.Common/FileOperation/Services/Implements/ApkFIileService.cs b/Src/Dlhis.Common/FileOperation/Services/Implements/ApkFIileService.cs index 4f5743aa..9b920f5c 100644 --- a/Src/Dlhis.Common/FileOperation/Services/Implements/ApkFIileService.cs +++ b/Src/Dlhis.Common/FileOperation/Services/Implements/ApkFIileService.cs @@ -1,8 +1,6 @@ using Dlhis.Common.FileOperation.Request; using Dlhis.Common.FileOperation.Response; using Dlhis.Common.FileOperation.Services; -using Dlhis.Common.Request; -using Dlhis.Common.Response; using Dlhis.Entity.Common; using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.SqlSugar.Services; diff --git a/Src/Dlhis.Common/FileOperation/Services/Implements/MinioService.cs b/Src/Dlhis.Common/FileOperation/Services/Implements/MinioService.cs index 3abff519..f18cfb9c 100644 --- a/Src/Dlhis.Common/FileOperation/Services/Implements/MinioService.cs +++ b/Src/Dlhis.Common/FileOperation/Services/Implements/MinioService.cs @@ -1,6 +1,5 @@ using Dlhis.Common.FileOperation.Configurations; using Dlhis.Common.FileOperation.Request; -using Dlhis.Common.Request; using Microsoft.Extensions.Options; using Minio; using Minio.DataModel.Args; diff --git a/Src/Dlhis.Common/Services/IApkFIileService.cs b/Src/Dlhis.Common/Services/IApkFIileService.cs deleted file mode 100644 index c6d9624b..00000000 --- a/Src/Dlhis.Common/Services/IApkFIileService.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Dlhis.Common.Request; -using Dlhis.Common.Response; -using Microsoft.AspNetCore.Mvc; - -namespace Dlhis.Common.Services; - - public interface IApkFIileService : IScopeDependency -{ - /// - /// 文件上传 - /// - /// - /// - Task FormSingleFileUpload(ApkRequest request); - - /// - /// 文件下载 - /// - /// - Task RequestDownloadFile(string fileName); - - /// - /// 本地上传 - /// - /// - /// - Task FormLocalFileUpload(ApkRequest request); - - Task LatestFile(string fileName); - - /// - /// 本地下载 - /// - /// - /// - IActionResult FormLocalDownloadFile(string fileName); -} - - - diff --git a/Src/Dlhis.Entity/Basic/Entity/BookingAddressEntity.cs b/Src/Dlhis.Entity/Basic/Entity/BookingAddressEntity.cs new file mode 100644 index 00000000..54e8f17a --- /dev/null +++ b/Src/Dlhis.Entity/Basic/Entity/BookingAddressEntity.cs @@ -0,0 +1,20 @@ +using Kurisu.Core.DataAccess.Entity; +using Kurisu.SqlSugar; +using SqlSugar; + +namespace Dlhis.Entity.Basic.Entity; + +/// +/// 就餐地址 +/// +[SugarTable(TableName = "BookingAddress", TableDescription = "就餐地址")] +public class BookingAddressEntity : SugarBaseEntity, ITenantId +{ + /// + /// 订餐地址 + /// + [SugarColumn(ColumnDescription = "订餐地址")] + public string Address { get; set; } + + public string TenantId { get; set; } +} diff --git a/Src/Dlhis.Entity/Basic/Entity/BusinessPlaceShiftRelationshipEntity.cs b/Src/Dlhis.Entity/Basic/Entity/BusinessPlaceShiftRelationshipEntity.cs index b4419ca8..e96e4a78 100644 --- a/Src/Dlhis.Entity/Basic/Entity/BusinessPlaceShiftRelationshipEntity.cs +++ b/Src/Dlhis.Entity/Basic/Entity/BusinessPlaceShiftRelationshipEntity.cs @@ -4,14 +4,14 @@ using SqlSugar; namespace Dlhis.Entity.Basic.Entity; -[SugarTable(TableName = "BusinessPlaceShiftRelationship", TableDescription = "营业点餐次关系")] +[SugarTable(TableName = "BusinessPlaceShiftRelationship", TableDescription = "营业点餐别关系")] public class BusinessPlaceShiftRelationshipEntity : SugarBaseEntity, ITenantId { [SugarColumn(ColumnDescription = "营业点code")] public Guid PlaceCode { get; set; } - [SugarColumn(ColumnDescription = "餐次code")] + [SugarColumn(ColumnDescription = "餐别code")] public Guid ShiftCode { get; set; } public string TenantId { get; set; } diff --git a/Src/Dlhis.Entity/Basic/Entity/CanteenUserEntity.cs b/Src/Dlhis.Entity/Basic/Entity/GainfoMealEntity.cs similarity index 70% rename from Src/Dlhis.Entity/Basic/Entity/CanteenUserEntity.cs rename to Src/Dlhis.Entity/Basic/Entity/GainfoMealEntity.cs index 7a18bed6..e7766a76 100644 --- a/Src/Dlhis.Entity/Basic/Entity/CanteenUserEntity.cs +++ b/Src/Dlhis.Entity/Basic/Entity/GainfoMealEntity.cs @@ -1,16 +1,14 @@ -using Dlhis.Entity.Canteen.Enums; -using Kurisu.Core.DataAccess.Entity; +using Kurisu.Core.DataAccess.Entity; using Kurisu.SqlSugar; using SqlSugar; -using SqlSugar.DbConvert; namespace Dlhis.Entity.Basic.Entity; /// /// 就餐人员 /// -[SugarTable(TableName = "CanteenUser", TableDescription = "就餐人员")] -public class CanteenUserEntity : SugarBaseEntity, IVersion, ITenantId +[SugarTable(TableName = "GainfoMeal", TableDescription = "就餐人员")] +public class GainfoMealEntity : SugarBaseEntity, IVersion, ITenantId { /// /// 档案号 @@ -19,10 +17,10 @@ public class CanteenUserEntity : SugarBaseEntity, IVersion, ITenantId public string UserNo { get; set; } /// - /// 消费人员类型 + /// 工号 /// - [SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), ColumnDescription = "消费人员类型")] - public CanteenUserEnumType UserType { get; set; } + [SugarColumn(IsNullable = false, ColumnDescription = "工号", UniqueGroupNameList = new[] { "idx_CanteenUser_UserCode" })] + public string UserCode { get; set; } /// /// 余额 diff --git a/Src/Dlhis.Entity/Canteen/Entities/OrderDetailEntity.cs b/Src/Dlhis.Entity/Canteen/Entities/CanteenOrderDetailEntity.cs similarity index 67% rename from Src/Dlhis.Entity/Canteen/Entities/OrderDetailEntity.cs rename to Src/Dlhis.Entity/Canteen/Entities/CanteenOrderDetailEntity.cs index 53b59bd9..1627a0f7 100644 --- a/Src/Dlhis.Entity/Canteen/Entities/OrderDetailEntity.cs +++ b/Src/Dlhis.Entity/Canteen/Entities/CanteenOrderDetailEntity.cs @@ -1,16 +1,14 @@ -using Dlhis.Entity.Canteen.Enums; -using Kurisu.Core.DataAccess.Entity; +using Kurisu.Core.DataAccess.Entity; using Kurisu.SqlSugar; using SqlSugar; -using SqlSugar.DbConvert; namespace Dlhis.Entity.Canteen.Entities; /// /// 订餐明细表 /// -[SugarTable(TableName = "OrderDetail", TableDescription = "订单明细表")] -public class OrderDetailEntity : SugarBaseEntity, ITenantId +[SugarTable(TableName = "CanteenOrderDetail", TableDescription = "订单明细表")] +public class CanteenOrderDetailEntity : SugarBaseEntity, ITenantId { /// /// 订单号 @@ -18,6 +16,12 @@ public class OrderDetailEntity : SugarBaseEntity, ITenantId [SugarColumn(ColumnDescription = "订单号")] public string OrderNo { get; set; } + /// + /// 菜单日期 + /// + [SugarColumn(ColumnDescription = "订餐日期")] + public DateTime BookingDate { get; set; } + /// /// 菜品编码 /// @@ -42,13 +46,5 @@ public class OrderDetailEntity : SugarBaseEntity, ITenantId [SugarColumn(ColumnDescription = "单位")] public string Unit { get; set; } - - /// - /// 订单明细状态 - /// - [SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert), ColumnDescription = "状态")] - public OrderDetailsStatusEnumType Status { get; set; } - - public string TenantId { get; set; } } diff --git a/Src/Dlhis.Entity/Canteen/Entities/CanteenOrderEntity.cs b/Src/Dlhis.Entity/Canteen/Entities/CanteenOrderEntity.cs index 38195904..2a927612 100644 --- a/Src/Dlhis.Entity/Canteen/Entities/CanteenOrderEntity.cs +++ b/Src/Dlhis.Entity/Canteen/Entities/CanteenOrderEntity.cs @@ -34,6 +34,12 @@ public class CanteenOrderEntity : BalanceRecordEntity [SugarColumn(ColumnDataType = "bit", ColumnDescription = "请求json")] public bool IsOffline { get; set; } + /// + /// 配送地址 + /// + [SugarColumn(ColumnDescription = "配送地址")] + public string DeliveryAddress { get; set; } + /// /// 处理结果 /// diff --git a/Src/Dlhis.Entity/Canteen/Entities/DishesCategoryEntity.cs b/Src/Dlhis.Entity/Canteen/Entities/DishesCategoryEntity.cs index 0f40049f..7ee20c16 100644 --- a/Src/Dlhis.Entity/Canteen/Entities/DishesCategoryEntity.cs +++ b/Src/Dlhis.Entity/Canteen/Entities/DishesCategoryEntity.cs @@ -7,6 +7,12 @@ namespace Dlhis.Entity.Canteen.Entities; [SugarTable(TableName = "DishesCategory", TableDescription = "菜品分类")] public class DishesCategoryEntity : SugarBaseEntity, ITenantId { + /// + /// 营业点 + /// + [SugarColumn(ColumnDescription = "营业点", IsNullable = false)] + public Guid BusinessPlaceCode { get; set; } + /// /// PCode /// @@ -21,13 +27,13 @@ public class DishesCategoryEntity : SugarBaseEntity, ITenantId /// /// 分类名称 /// - [SugarColumn(IsNullable = false, ColumnDescription = "名称")] + [SugarColumn(ColumnDescription = "名称", IsNullable = false)] public string Name { get; set; } /// /// 序号 /// - [SugarColumn(IsNullable = false, ColumnDescription = "序号", DefaultValue = "100")] + [SugarColumn(ColumnDescription = "序号", IsNullable = false, DefaultValue = "100")] public int Sequence { get; set; } = 100; diff --git a/Src/Dlhis.Entity/Canteen/Entities/DishesMenuEntity.cs b/Src/Dlhis.Entity/Canteen/Entities/DishesMenuEntity.cs index 928c9040..237f2b01 100644 --- a/Src/Dlhis.Entity/Canteen/Entities/DishesMenuEntity.cs +++ b/Src/Dlhis.Entity/Canteen/Entities/DishesMenuEntity.cs @@ -31,11 +31,16 @@ public class DishesMenuEntity : SugarBaseEntity, ITenantId, IVersion public Guid BusinessPlaceCode { get; set; } /// - /// 营业日期 + /// 营业日期-开始 /// - [SugarColumn(ColumnDataType = "date", ColumnDescription = "营业日期")] - public DateTime Date { get; set; } + [SugarColumn(ColumnDescription = "营业日期开始")] + public DateTime StartDate { get; set; } + /// + /// 营业日期-结束 + /// + [SugarColumn(ColumnDescription = "营业日期结束")] + public DateTime EndDate { get; set; } /// /// 餐次 @@ -54,25 +59,18 @@ public class DishesMenuEntity : SugarBaseEntity, ITenantId, IVersion /// public int Number { get; set; } - /// /// 单价 /// public decimal? Price { get; set; } - /// - /// 是否启用 - /// - [SugarColumn(ColumnDataType = "bit", ColumnDescription = "是否启用")] - public bool Enable { get; set; } - - - public string TenantId { get; set; } - /// /// 并发控制 /// public int Version { get; set; } + + + public string TenantId { get; set; } } diff --git a/Src/Dlhis.Entity/Basic/Entity/MealSupplementRecordEntity.cs b/Src/Dlhis.Entity/Canteen/Entities/MealSupplementRecordEntity.cs similarity index 83% rename from Src/Dlhis.Entity/Basic/Entity/MealSupplementRecordEntity.cs rename to Src/Dlhis.Entity/Canteen/Entities/MealSupplementRecordEntity.cs index 8a993992..7875ae74 100644 --- a/Src/Dlhis.Entity/Basic/Entity/MealSupplementRecordEntity.cs +++ b/Src/Dlhis.Entity/Canteen/Entities/MealSupplementRecordEntity.cs @@ -3,7 +3,7 @@ using Kurisu.SqlSugar; using SqlSugar; using SqlSugar.DbConvert; -namespace Dlhis.Entity.Basic.Entity; +namespace Dlhis.Entity.Canteen.Entities; /// /// 餐补记录 @@ -12,7 +12,7 @@ namespace Dlhis.Entity.Basic.Entity; public class MealSupplementRecordEntity : MealSupplementRequestRecordEntity { /// - /// 唯一号 + /// 唯一号(流水号) /// [SugarColumn(IsNullable = false, ColumnDescription = "唯一号", UniqueGroupNameList = new[] { "idx_MealSupplementRecord_UniqueId" })] public override string UniqueId { get; set; } @@ -28,8 +28,23 @@ public class MealSupplementRecordEntity : MealSupplementRequestRecordEntity /// [SugarColumn(ColumnDataType = "varchar(50)", SqlParameterDbType = typeof(EnumToStringConvert))] public MealSupplementStatusEnumtype Status { get; set; } + + /// + /// 处理结果 + /// + [SugarColumn(ColumnDescription = "处理结果", ColumnDataType = "varchar(2000)")] + public string Result { get; set; } + + /// + /// 状态同步 + /// + public bool Sync { get; set; } } + +/// +/// 餐补请求记录 +/// [SugarTable(TableName = "MealSupplementRequestRecord", TableDescription = "餐补请求记录")] public class MealSupplementRequestRecordEntity : SugarBaseEntity { diff --git a/Src/Dlhis.Entity/Canteen/Enums/BalanceRecordSourceEnumType.cs b/Src/Dlhis.Entity/Canteen/Enums/BalanceRecordSourceEnumType.cs index 73c52bc0..ab2d91bc 100644 --- a/Src/Dlhis.Entity/Canteen/Enums/BalanceRecordSourceEnumType.cs +++ b/Src/Dlhis.Entity/Canteen/Enums/BalanceRecordSourceEnumType.cs @@ -57,12 +57,12 @@ public enum BalanceRecordSourceEnumType /// /// 来自本基地补贴 /// - [Description("本基地补贴")] + [Description("本基地餐补")] LocalTenantSubsidies = 300, /// /// 来自其他基地补贴 /// - [Description("其他基地补贴")] + [Description("其他基地餐补")] OtherTenantSubsidies, } \ No newline at end of file diff --git a/Src/Dlhis.Entity/Canteen/Enums/CanteenOrderStatusEnumType.cs b/Src/Dlhis.Entity/Canteen/Enums/CanteenOrderStatusEnumType.cs index 9a670e93..d1a689e5 100644 --- a/Src/Dlhis.Entity/Canteen/Enums/CanteenOrderStatusEnumType.cs +++ b/Src/Dlhis.Entity/Canteen/Enums/CanteenOrderStatusEnumType.cs @@ -3,9 +3,9 @@ namespace Dlhis.Entity.Canteen.Enums; /// -/// 就餐订单状态 +/// 餐饮订单状态 /// -[Description("就餐订单状态")] +[Description("餐饮订单状态")] public enum CanteenOrderStatusEnumType { /// @@ -18,7 +18,7 @@ public enum CanteenOrderStatusEnumType /// 成功 /// [Description("成功")] - Successful = 1, + Success = 1, /// /// 取消 diff --git a/Src/Dlhis.Entity/Canteen/Enums/CanteenUserEnumType.cs b/Src/Dlhis.Entity/Canteen/Enums/CanteenUserEnumType.cs deleted file mode 100644 index 9bc892fd..00000000 --- a/Src/Dlhis.Entity/Canteen/Enums/CanteenUserEnumType.cs +++ /dev/null @@ -1,30 +0,0 @@ - - -using System.ComponentModel; - -namespace Dlhis.Entity.Canteen.Enums; - -/// -/// 就餐人员类型 -/// -[Description("就餐人员类型")] -public enum CanteenUserEnumType -{ - /// - /// 本基地 - /// - [Description("本基地人员")] - LocalTenant = 1, - - /// - /// 其他基地 - /// - [Description("其他基地人员")] - OtherTenant, - - /// - /// 外部人员 - /// - [Description("外部人员")] - External -} \ No newline at end of file diff --git a/Src/Dlhis.Entity/Canteen/Enums/MiniProgramOrderStatusEnumType.cs b/Src/Dlhis.Entity/Canteen/Enums/MiniProgramOrderStatusEnumType.cs deleted file mode 100644 index 56eb9ba1..00000000 --- a/Src/Dlhis.Entity/Canteen/Enums/MiniProgramOrderStatusEnumType.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Dlhis.Entity.Canteen.Enums -{ - public enum MiniProgramOrderStatusEnumType - { - /// - /// 有效 - /// - [Description("有效")] - I = 1, - - /// - /// 取消 - /// - [Description("取消")] - C = 2, - - /// - /// 退单 - /// - [Description("退单")] - X = 3, - - /// - /// 免单 - /// - [Description("免单")] - Z = 4, - } -} diff --git a/Src/Dlhis.Entity/Canteen/Enums/OrderDetailsStatusEnumType.cs b/Src/Dlhis.Entity/Canteen/Enums/OrderDetailsStatusEnumType.cs deleted file mode 100644 index 0b4eed43..00000000 --- a/Src/Dlhis.Entity/Canteen/Enums/OrderDetailsStatusEnumType.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.ComponentModel; - -namespace Dlhis.Entity.Canteen.Enums -{ - /// - /// 订单明细状态 OrderDetailsStatusEnumType - /// - [Description("订单明细状态")] - public enum OrderDetailsStatusEnumType - { - /// - /// 有效 - /// - [Description("有效")] - I = 1, - } -} diff --git a/Src/Dlhis.Entity/Common/ApiLogEntity.cs b/Src/Dlhis.Entity/Common/ApiLogEntity.cs index 70e0849e..2f8fd03a 100644 --- a/Src/Dlhis.Entity/Common/ApiLogEntity.cs +++ b/Src/Dlhis.Entity/Common/ApiLogEntity.cs @@ -1,6 +1,7 @@ using SqlSugar; using SqlSugar.DbConvert; using Microsoft.Extensions.Logging; +using Kurisu.SqlSugar; namespace Dlhis.Entity.Common; @@ -8,7 +9,7 @@ namespace Dlhis.Entity.Common; /// api日志表 /// [SugarTable(TableName = "Logs", TableDescription = "api日志表")] -public class ApiLogEntity +public class ApiLogEntity : SugarBaseEntity { /// /// 时间 diff --git a/Src/Dlhis.External/MealSupplement/Channel/MealSupplementHandler.cs b/Src/Dlhis.External/MealSupplement/Channel/MealSupplementHandler.cs index 25622039..fad99d18 100644 --- a/Src/Dlhis.External/MealSupplement/Channel/MealSupplementHandler.cs +++ b/Src/Dlhis.External/MealSupplement/Channel/MealSupplementHandler.cs @@ -1,4 +1,4 @@ -using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Canteen.Entities; using Dlhis.External.MealSupplement.Request; using Kurisu.AspNetCore.EventBus.Abstractions; using Kurisu.AspNetCore.EventBus.Abstractions.Handler; diff --git a/Src/Dlhis.External/MealSupplement/Services/Implements/MealSupplementService.cs b/Src/Dlhis.External/MealSupplement/Services/Implements/MealSupplementService.cs index 701b9430..bb1f1200 100644 --- a/Src/Dlhis.External/MealSupplement/Services/Implements/MealSupplementService.cs +++ b/Src/Dlhis.External/MealSupplement/Services/Implements/MealSupplementService.cs @@ -1,4 +1,4 @@ -using Dlhis.Entity.Basic.Entity; +using Dlhis.Entity.Canteen.Entities; using Dlhis.External.MealSupplement.Channel; using Dlhis.External.MealSupplement.Request; using Kurisu.AspNetCore.EventBus.Abstractions; diff --git a/Src/Dlhis.ScheduledTask/CommonJobs/DelApiLogTaskJob.cs b/Src/Dlhis.ScheduledTask/CommonJobs/DelApiLogTaskJob.cs new file mode 100644 index 00000000..4fcde1c1 --- /dev/null +++ b/Src/Dlhis.ScheduledTask/CommonJobs/DelApiLogTaskJob.cs @@ -0,0 +1,51 @@ +using Dlhis.Entity.Common; +using Kurisu.SqlSugar.Services; +using SqlSugar; + +namespace Dlhis.ScheduledTask.CommonJobs; + + public class DelApiLogTaskJob +{ + private readonly IDbContext _dbContext; + private readonly Logger _logger; + + public DelApiLogTaskJob(IDbContext dbContext, Logger logger) + { + _dbContext = dbContext; + _logger = logger; + } + + public async Task RunAsync() + { + try + { + DateTime now = DateTime.Now; + DateTime todayStart = now.Date; + DateTime threeDaysAgoStart = todayStart.AddDays(-7); + + var logs = await _dbContext.ChangeDb("log") + .Queryable() + .Where(x => x._ts >= threeDaysAgoStart && x._ts <= now) + .Select(x => x.Id) + .ToListAsync(); + + var lst = new List(); + foreach (var id in logs) + { + var entity = new ApiLogEntity + { + Id = id, + }; + lst.Add(entity); + } + await _dbContext.ChangeDb("log").DeleteReallyAsync(lst); + } + catch (Exception ex) + { + _logger.LogError(ex, "删除日志异常:{message}", ex.Message); + } + + } +} + + diff --git a/Src/Dlhis.ScheduledTask/Packs/JobPack.cs b/Src/Dlhis.ScheduledTask/Packs/JobPack.cs index bacad69f..57729a3d 100644 --- a/Src/Dlhis.ScheduledTask/Packs/JobPack.cs +++ b/Src/Dlhis.ScheduledTask/Packs/JobPack.cs @@ -64,5 +64,10 @@ public class JobPack : BaseAppPack { TimeZone = TimeZoneInfo.Local }); + //删除前三天前的日志 + RecurringJob.AddOrUpdate("DelApiLogTask", s => s.RunAsync(), "0 0 */7 * *", new RecurringJobOptions + { + TimeZone = TimeZoneInfo.Local + }); } } diff --git a/Src/Dlhis.ScheduledTask/Packs/SqlSugarPack.cs b/Src/Dlhis.ScheduledTask/Packs/SqlSugarPack.cs index 6ba87c85..ae038436 100644 --- a/Src/Dlhis.ScheduledTask/Packs/SqlSugarPack.cs +++ b/Src/Dlhis.ScheduledTask/Packs/SqlSugarPack.cs @@ -25,6 +25,20 @@ public class SqlSugarPack : BaseAppPack InitKeyType = InitKeyType.Attribute, IsAutoCloseConnection = true, + MoreSettings = new ConnMoreSettings + { + DisableNvarchar = true, + } + }, + new ConnectionConfig + { + ConfigId = "log", + + ConnectionString = configuration.GetSection("SqlSugarOptions:LogConnectionString").Value, + DbType = DbType.MySql, + InitKeyType = InitKeyType.Attribute, + IsAutoCloseConnection = true, + MoreSettings = new ConnMoreSettings { DisableNvarchar = true, diff --git a/Src/Dlhis.ScheduledTask/appsettings.json b/Src/Dlhis.ScheduledTask/appsettings.json index caf7f060..92cb3b23 100644 --- a/Src/Dlhis.ScheduledTask/appsettings.json +++ b/Src/Dlhis.ScheduledTask/appsettings.json @@ -18,6 +18,7 @@ "SlaveConnectionString": [], "FaceConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=face;charset=utf8mb4;", "IdentityConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=identity;charset=utf8mb4;", + "LogConnectionString": "server=192.168.199.124;port=3306;userid=root;password=dlhis123;database=log;charset=utf8mb4;", "Timeout": 30, "SlowSqlTime": 1, "EnableSqlLog": false diff --git a/Src/Dlhis.Sys.Api/IUserApi.cs b/Src/Dlhis.Sys.Api/IUserApi.cs index 643fce04..fba7db5f 100644 --- a/Src/Dlhis.Sys.Api/IUserApi.cs +++ b/Src/Dlhis.Sys.Api/IUserApi.cs @@ -10,4 +10,8 @@ public interface IUserApi [Auth] [Get("/api/users")] Task> GetUserByIdAsync(int id); + + [Auth] + [Post("/api/users/by-ids")] + Task>> GetUserByIdsAsync(List ids); } \ No newline at end of file diff --git a/Src/Dlhis.Sys/Identity/Controllers/UsersController.cs b/Src/Dlhis.Sys/Identity/Controllers/UsersController.cs index 229708bc..c3f4ffa5 100644 --- a/Src/Dlhis.Sys/Identity/Controllers/UsersController.cs +++ b/Src/Dlhis.Sys/Identity/Controllers/UsersController.cs @@ -56,6 +56,25 @@ public class UsersController : ControllerBase return await _userService.GetUserByIdAsync(id); } + [Authorize] + [HttpPost("by-ids")] + public async Task> GetUserByIdsAsync(List ids) + { + return await _userService.GetUserByIdsAsync(ids); + } + + /// + /// + /// + /// + /// + [Authorize(Roles = "admin")] + [HttpPost("create")] + public async Task CreateUserAsync(UserCreateRequest request) + { + await _userService.CreateUserAsync(request); + } + /// /// 上传头像 /// diff --git a/Src/Dlhis.Sys/Identity/Request/UserCreateRequest.cs b/Src/Dlhis.Sys/Identity/Request/UserCreateRequest.cs new file mode 100644 index 00000000..b080a1ad --- /dev/null +++ b/Src/Dlhis.Sys/Identity/Request/UserCreateRequest.cs @@ -0,0 +1,25 @@ +using System.ComponentModel.DataAnnotations; + +namespace Dlhis.Sys.Identity.Request; + +public class UserCreateRequest +{ + /// + /// 用户名 + /// + [Required] + public string Username { get; set; } + + /// + /// 密码 + /// + [MinLength(6)] + [Required] + public string Password { get; set; } + + /// + /// 厂区 + /// + [Required] + public string Tenant { get; set; } +} diff --git a/Src/Dlhis.Sys/Identity/Services/IUserService.cs b/Src/Dlhis.Sys/Identity/Services/IUserService.cs index 98932a32..02622619 100644 --- a/Src/Dlhis.Sys/Identity/Services/IUserService.cs +++ b/Src/Dlhis.Sys/Identity/Services/IUserService.cs @@ -15,4 +15,9 @@ public interface IUserService : IScopeDependency Task GetUserByIdAsync(int id); Task UploadUserAvatarAsync(UserAvatarUploadRequest request); -} + + + Task> GetUserByIdsAsync(List ids); + + Task CreateUserAsync(UserCreateRequest request); +} \ No newline at end of file diff --git a/Src/Dlhis.Sys/Identity/Services/Implements/UserService.cs b/Src/Dlhis.Sys/Identity/Services/Implements/UserService.cs index 55877e73..2868ad2a 100644 --- a/Src/Dlhis.Sys/Identity/Services/Implements/UserService.cs +++ b/Src/Dlhis.Sys/Identity/Services/Implements/UserService.cs @@ -5,6 +5,7 @@ using Kurisu.AspNetCore.Utils.Extensions; using Kurisu.Core.DataAccess.Dto; using Kurisu.SqlSugar.Extensions; using Kurisu.SqlSugar.Services; +using Microsoft.AspNetCore.Identity; namespace Dlhis.Sys.Identity.Services.Implements; @@ -12,11 +13,9 @@ public class UserService : IUserService { private readonly IDbContext _dbContext; - public UserService(IDbContext dbContext, IConfiguration configuration) + public UserService(IDbContext dbContext) { - var identityConnection = configuration.GetSection("SqlSugarOptions:IdentityConnectionString").Value; - dbContext.Client.CurrentConnectionConfig.ConnectionString = identityConnection; - _dbContext = dbContext; + _dbContext = dbContext.ChangeDb("identity"); } public async Task> GetPageAsync(UserPageRequest request) @@ -63,4 +62,31 @@ public class UserService : IUserService { var user = await _dbContext.Queryable().Where(x => x.Id == request.UserNo).Select().FirstAsync(); } + + public async Task> GetUserByIdsAsync(List ids) + { + var users = await _dbContext.Queryable().Where(x => ids.Contains(x.Id)).Select().ToListAsync(); + return users; + } + + public async Task CreateUserAsync(UserCreateRequest request) + { + var hasher = new PasswordHasher(); + + var user = new UserEntity + { + UserName = request.Username, + NormalizedUserName = request.Username.ToUpper(), + }; + request.Password = hasher.HashPassword(user, request.Password); + user.PasswordHash = request.Password; + + var id = await _dbContext.InsertReturnIdentityAsync(user); + + await _dbContext.InsertAsync(new UserTenantEntity + { + TenantCode = request.Tenant, + UserId = (int)id + }); + } } diff --git a/Src/Dlhis.Sys/SqlSugarPack.cs b/Src/Dlhis.Sys/SqlSugarPack.cs index 9458f466..98f4153a 100644 --- a/Src/Dlhis.Sys/SqlSugarPack.cs +++ b/Src/Dlhis.Sys/SqlSugarPack.cs @@ -16,7 +16,7 @@ public class SqlSugarPack : BaseAppPack return new List { - new ConnectionConfig + new() { ConfigId = "identity",