Merge branch 'development' of https://git.dlhis.com/liguoyang/jinko.yikatong into development
This commit is contained in:
@@ -10,4 +10,8 @@
|
||||
<PackageReference Include="Kurisu.RemoteCall" Version="0.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Response\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -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<DefaultApiResult<GetMyResponse>> GetMyAsync();
|
||||
Task<DefaultApiResult<List<BusinessPlaceDto>>> GetMyAsync();
|
||||
}
|
||||
|
||||
@@ -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<BusinessPlaceDto> dtos { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
public class DishesCategoryTreeResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 营业点code
|
||||
/// </summary>
|
||||
public Guid BusinessPlaceCode { get; set; }
|
||||
|
||||
public Guid? PCode { get; set; }
|
||||
|
||||
public Guid Code { get; set; }
|
||||
|
||||
@@ -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,30 @@ 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<List<DishesCategoryTreeResponse>> TreeAsync()
|
||||
{
|
||||
var categories = await _dbContext.Queryable<DishesCategoryEntity>().Select<DishesCategoryTreeResponse>().ToListAsync();
|
||||
var mybCodes = await GetMyBusinessPlaceCodesAsync();
|
||||
|
||||
var categories = await _dbContext.Queryable<DishesCategoryEntity>()
|
||||
.LeftJoin<BusinessPlaceEntity>((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 =>
|
||||
@@ -31,6 +48,8 @@ public class DishesCategoryService : IDishesCategoryService
|
||||
|
||||
public async Task SaveAsync(DishesCategorySaveRequest request)
|
||||
{
|
||||
await CheckBusinessPlacePermissionAsync(request.BusinessPlaceCode);
|
||||
|
||||
if (!request.Id.HasValue)
|
||||
{
|
||||
var entity = request.Adapt<DishesCategoryEntity>();
|
||||
@@ -62,4 +81,27 @@ public class DishesCategoryService : IDishesCategoryService
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查营业点权限
|
||||
/// </summary>
|
||||
/// <param name="businessPlaceCode"></param>
|
||||
/// <returns></returns>
|
||||
private async Task CheckBusinessPlacePermissionAsync(Guid businessPlaceCode)
|
||||
{
|
||||
var codes = await GetMyBusinessPlaceCodesAsync();
|
||||
codes.Contains(businessPlaceCode).ThrowIfFalse("无权操作当前营业点");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取我管理的营业点
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<List<Guid>> GetMyBusinessPlaceCodesAsync()
|
||||
{
|
||||
var mybCodes = (await _businessPlacePermissionsService.GetMyAsync()).Select(x => x.Code).ToList();
|
||||
|
||||
return mybCodes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ 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("非经营营业点,无法保存菜单");
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Kurisu.AspNetCore" Version="0.7.1" />
|
||||
<PackageReference Include="Kurisu.AspNetCore" Version="0.7.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// 身份证号
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(ObfuscateJsonConverter), 6)]
|
||||
public string IdNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -86,6 +89,7 @@ public class GainfoPageResponse
|
||||
/// <summary>
|
||||
/// 手机号码
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(ObfuscateJsonConverter), 4)]
|
||||
public string Phone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,11 +4,12 @@ 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;
|
||||
|
||||
/// <summary>
|
||||
/// 营业点管理
|
||||
/// 营业点权限管理
|
||||
/// </summary>
|
||||
[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
@@ -27,7 +28,7 @@ public class BusinessPlacePermissionsController
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize(Roles = "admin,tenant-admin")]
|
||||
[Authorize(Roles = "admin,tenant-admin,businessplace-manager")]
|
||||
[HttpGet("page")]
|
||||
public async Task<Pagination<BusinessPlacePermissionPageResponse>> GetPageAsync([FromQuery] BusinessPlacePermissionPageRequest request)
|
||||
{
|
||||
@@ -39,7 +40,7 @@ public class BusinessPlacePermissionsController
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("my")]
|
||||
public async Task<GetMyResponse> GetMy()
|
||||
public async Task<List<BusinessPlaceDto>> GetMy()
|
||||
{
|
||||
return await _businessPlacePermissionsService.GetMyAsync();
|
||||
}
|
||||
@@ -56,4 +57,28 @@ public class BusinessPlacePermissionsController
|
||||
{
|
||||
await _businessPlacePermissionsService.SaveBusinessPlacePermissionAsync(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过userid获取分配的营业点信息
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize(Roles = "admin,tenant-admin")]
|
||||
[HttpGet("assignments/{userId}")]
|
||||
public async Task<List<BusinessPlacePermissionPageResponse>> GetBusinessPlacePermissionByUserIdAsyc(int userId)
|
||||
{
|
||||
return await _businessPlacePermissionsService.GetBusinessPlacePermissionByUserIdAsyc(userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除记录
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize(Roles = "admin,tenant-admin")]
|
||||
[HttpDelete("{id}")]
|
||||
public async Task DeleteAssignmentAsync(int id)
|
||||
{
|
||||
await _businessPlacePermissionsService.DeleteAssignmentAsync(id);
|
||||
}
|
||||
}
|
||||
|
||||
7
Src/Dlhis.Basic/Places/Dtos/BusinessPlaceDto.cs
Normal file
7
Src/Dlhis.Basic/Places/Dtos/BusinessPlaceDto.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Dlhis.Basic.Places.Dtos;
|
||||
|
||||
public class BusinessPlaceDto
|
||||
{
|
||||
public Guid Code { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Dlhis.Basic.BusinessPlace.Response
|
||||
{
|
||||
public class BusinessPlaceDto
|
||||
{
|
||||
public Guid Code { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ public class BusinessPlacePermissionPageResponse
|
||||
/// <summary>
|
||||
/// 用户id
|
||||
/// </summary>
|
||||
public string UserId { get; set; }
|
||||
public int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户name
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Dlhis.Basic.BusinessPlace.Response
|
||||
{
|
||||
public class GetMyResponse
|
||||
{
|
||||
public List<BusinessPlaceDto> dtos { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
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;
|
||||
|
||||
@@ -10,5 +11,9 @@ public interface IBusinessPlacePermissionsService : IScopeDependency
|
||||
|
||||
Task SaveBusinessPlacePermissionAsync(BusinessPlacePermissionSaveRequest request);
|
||||
|
||||
Task<GetMyResponse> GetMyAsync();
|
||||
Task<List<BusinessPlaceDto>> GetMyAsync();
|
||||
|
||||
Task<List<BusinessPlacePermissionPageResponse>> GetBusinessPlacePermissionByUserIdAsyc(int id);
|
||||
|
||||
Task DeleteAssignmentAsync(int id);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ 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;
|
||||
|
||||
namespace Dlhis.Basic.BusinessPlace.Services.Implements;
|
||||
|
||||
@@ -12,19 +16,39 @@ public class BusinessPlacePermissionsService : IBusinessPlacePermissionsService
|
||||
{
|
||||
private readonly IDbContext _dbContext;
|
||||
private readonly ICurrentUser _currentUser;
|
||||
private readonly IUserApi _userApi;
|
||||
|
||||
public BusinessPlacePermissionsService(IDbContext dbContext, ICurrentUser currentUser)
|
||||
public BusinessPlacePermissionsService(IDbContext dbContext, ICurrentUser currentUser, IUserApi userApi)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_currentUser = currentUser;
|
||||
_userApi = userApi;
|
||||
}
|
||||
|
||||
public async Task<Pagination<BusinessPlacePermissionPageResponse>> GetPageAsync(BusinessPlacePermissionPageRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var page = await _dbContext.Queryable<BusinessPlaceManagerRelationshipEntity>()
|
||||
.LeftJoin<BusinessPlaceEntity>((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<GetMyResponse> GetMyAsync()
|
||||
public async Task<List<BusinessPlaceDto>> GetMyAsync()
|
||||
{
|
||||
var userId = _currentUser.GetIntSubjectId();
|
||||
|
||||
@@ -34,15 +58,10 @@ public class BusinessPlacePermissionsService : IBusinessPlacePermissionsService
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
var dtos = await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||
return await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||
.Where(x => guids.Contains(x.Code))
|
||||
.Select<BusinessPlaceDto>()
|
||||
.ToListAsync();
|
||||
var myResponse = new GetMyResponse
|
||||
{
|
||||
dtos = dtos
|
||||
};
|
||||
return myResponse;
|
||||
}
|
||||
|
||||
public async Task SaveBusinessPlacePermissionAsync(BusinessPlacePermissionSaveRequest request)
|
||||
@@ -63,4 +82,33 @@ public class BusinessPlacePermissionsService : IBusinessPlacePermissionsService
|
||||
await _dbContext.InsertAsync(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<BusinessPlacePermissionPageResponse>> GetBusinessPlacePermissionByUserIdAsyc(int id)
|
||||
{
|
||||
var infos = await _dbContext.Queryable<BusinessPlaceManagerRelationshipEntity>()
|
||||
.LeftJoin<BusinessPlaceEntity>((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<BusinessPlaceManagerRelationshipEntity>().Where(x => x.Id == id).ExecuteCommandAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ 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.Canteen.Dishes.Controllers;
|
||||
|
||||
@@ -19,21 +18,12 @@ namespace Dlhis.Canteen.Dishes.Controllers;
|
||||
public class OrdersController : ControllerBase
|
||||
{
|
||||
private readonly IOrderService _orderService;
|
||||
private readonly IBookingOrderService _bookingOrderService;
|
||||
|
||||
public OrdersController(IOrderService orderService)
|
||||
public OrdersController(IOrderService orderService, IBookingOrderService bookingOrderService)
|
||||
{
|
||||
_orderService = orderService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单分页
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("page")]
|
||||
public async Task<Pagination<OrderResponse>> GetPageAsync([FromQuery] OrderPageRequest request)
|
||||
{
|
||||
return await _orderService.GetPageAsync(request);
|
||||
_bookingOrderService = bookingOrderService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -60,39 +50,6 @@ public class OrdersController : ControllerBase
|
||||
return await _orderService.AddAsync(request);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 订餐
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("booking")]
|
||||
[Transactional]
|
||||
public async Task Booking(BookingMealRequest request)
|
||||
{
|
||||
await _orderService.BookingAsync(request);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 获取详情
|
||||
///// </summary>
|
||||
///// <param name="no"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet("details")]
|
||||
//public async Task<List<OrderDetailResponse>> GetDetailsAsync(string no)
|
||||
//{
|
||||
// return await _orderService.GetDetailsAsync(no);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 充值
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("recharge")]
|
||||
public async Task ReCharge()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单聚合数据
|
||||
/// </summary>
|
||||
@@ -102,4 +59,28 @@ public class OrdersController : ControllerBase
|
||||
{
|
||||
return await _orderService.GetOrdersAggregationAsync(page);
|
||||
}
|
||||
|
||||
//************************************************************** 订餐功能 **********************************************************************************
|
||||
|
||||
/// <summary>
|
||||
/// 订餐
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("booking")]
|
||||
[Transactional]
|
||||
public async Task Booking(BookingMealRequest request)
|
||||
{
|
||||
await _bookingOrderService.BookingAsync(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 订单分页
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("booking/page")]
|
||||
public async Task<Pagination<OrderBookingResponse>> GetBookingPageAsync([FromQuery] OrderBookingPageRequest request)
|
||||
{
|
||||
return await _bookingOrderService.GetBookingPageAsync(request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Dlhis.Canteen.Order.Request;
|
||||
|
||||
public class OrderPageRequest : PageDto
|
||||
public class OrderBookingPageRequest : PageDto
|
||||
{
|
||||
|
||||
}
|
||||
34
Src/Dlhis.Canteen/Order/Response/OrderBookingResponse.cs
Normal file
34
Src/Dlhis.Canteen/Order/Response/OrderBookingResponse.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class OrderBookingResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 订单号
|
||||
/// </summary>
|
||||
public string No { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 配送地址
|
||||
/// </summary>
|
||||
public string DeliveryAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单金额
|
||||
/// </summary>
|
||||
public decimal Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 工号
|
||||
/// </summary>
|
||||
public string UserCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string UserNo { get; set; }
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
namespace Dlhis.Canteen.Order.Response;
|
||||
|
||||
public class OrderResponse
|
||||
{
|
||||
}
|
||||
21
Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs
Normal file
21
Src/Dlhis.Canteen/Order/Services/IBookingOrderService.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// 订餐
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
Task BookingAsync(BookingMealRequest request);
|
||||
|
||||
|
||||
Task<Pagination<OrderBookingResponse>> GetBookingPageAsync(OrderBookingPageRequest request);
|
||||
|
||||
Task CancelOrderAsync();
|
||||
}
|
||||
@@ -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,7 +6,7 @@ namespace Dlhis.Canteen.Order.Services;
|
||||
|
||||
public interface IOrderService : IScopeDependency
|
||||
{
|
||||
Task<Pagination<OrderResponse>> GetPageAsync(OrderPageRequest request);
|
||||
|
||||
|
||||
|
||||
Task<OrderResultResponse> AddAsync(OrderAddRequest request);
|
||||
@@ -19,20 +18,5 @@ public interface IOrderService : IScopeDependency
|
||||
/// <returns></returns>
|
||||
Task<OrderResultResponse> DeviceConsume(OrderAddRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// 订餐
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
Task BookingAsync(BookingMealRequest request);
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 获取订单详情
|
||||
///// </summary>
|
||||
///// <param name="no"></param>
|
||||
///// <returns></returns>
|
||||
//Task<List<OrderDetailResponse>> GetDetailsAsync(string no);
|
||||
|
||||
Task<Pagination<OrderAggregationResponse>> GetOrdersAggregationAsync(PageDto page);
|
||||
}
|
||||
|
||||
133
Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs
Normal file
133
Src/Dlhis.Canteen/Order/Services/Implements/BaseOrderService.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using Dlhis.Basic.Api;
|
||||
using Dlhis.Canteen.Setting.Services;
|
||||
using Dlhis.Entity.Basic.Entity;
|
||||
using Dlhis.Entity.Canteen.Enums;
|
||||
using Kurisu.AspNetCore.UnifyResultAndValidation;
|
||||
using Kurisu.AspNetCore.Utils.Extensions;
|
||||
using Kurisu.Core.User.Abstractions;
|
||||
using Kurisu.SqlSugar.Services;
|
||||
using Mapster;
|
||||
using SqlSugar;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Services.Implements;
|
||||
|
||||
public abstract class BaseOrderService
|
||||
{
|
||||
private readonly ICanteenSettingService _canteenSettingService;
|
||||
private readonly IDbContext _dbContext;
|
||||
private readonly ICurrentUser _currentUser;
|
||||
private readonly IDevicePermissionApi _devicePermissionApi;
|
||||
private readonly ILogger _logger;
|
||||
private Dictionary<CanteenSettingItemEnumType, string> _settings;
|
||||
|
||||
public BaseOrderService(ICanteenSettingService canteenSettingService,
|
||||
IDbContext dbContext,
|
||||
ICurrentUser currentUser,
|
||||
IDevicePermissionApi devicePermissionApi,
|
||||
ILogger logger)
|
||||
{
|
||||
_canteenSettingService = canteenSettingService;
|
||||
_dbContext = dbContext;
|
||||
_currentUser = currentUser;
|
||||
_devicePermissionApi = devicePermissionApi;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
protected BaseOrderService(ICanteenSettingService canteenSettingService)
|
||||
{
|
||||
_canteenSettingService = canteenSettingService;
|
||||
}
|
||||
|
||||
protected IDbContext DbContext => _dbContext;
|
||||
|
||||
protected ICurrentUser CurrentUser => _currentUser;
|
||||
|
||||
/// <summary>
|
||||
/// 检查权限
|
||||
/// </summary>
|
||||
/// <param name="userNo"></param>
|
||||
/// <param name="deviceUniqueNo"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task CheckPermissionAsync(string userNo, string deviceUniqueNo)
|
||||
{
|
||||
var uniqueNosResult = await _devicePermissionApi.GetCanteenDeviceUniqueNosByUserNoAsync(userNo);
|
||||
var uniqueNos = uniqueNosResult.Data;
|
||||
|
||||
uniqueNos.Contains(deviceUniqueNo).ThrowIfFalse("无消费权限");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设备并发更新 需要抛出VersionExceptions
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="func"></param>
|
||||
/// <param name="retry">并发冲突处理次数</param>
|
||||
/// <param name="errorMessage"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
protected async Task ContinueUpdateAsync(Func<Task> func, int retry, string errorMessage = null)
|
||||
{
|
||||
for (int i = 0; i < retry; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
await func();
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (ex is VersionExceptions)
|
||||
{
|
||||
_logger.LogWarning(ex, ex.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
throw new UserFriendlyException(errorMessage ?? "操作失败,请重试");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取参数配置
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<T> GetSettingAsync<T>(CanteenSettingItemEnumType item, T defaultValue = default)
|
||||
{
|
||||
if (_settings == null)
|
||||
{
|
||||
var subjectId = _currentUser.GetIntSubjectId();
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdentityUserId == subjectId).FirstAsync();
|
||||
var jinkoCode = _currentUser.GetUserClaim("jinko-code") ?? string.Empty;
|
||||
if (jinkoCode.IsPresent())
|
||||
{
|
||||
gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
}
|
||||
_settings = await _canteenSettingService.GetUserSettingAsync(gainfo.No);
|
||||
}
|
||||
|
||||
|
||||
if (_settings.TryGetValue(item, out var v))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (int.TryParse(v, out var n))
|
||||
{
|
||||
return n.Adapt<T>();
|
||||
}
|
||||
|
||||
return v.Adapt<T>();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
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 IDbContext _dbContext;
|
||||
private readonly ICurrentUser _currentUser;
|
||||
private readonly IDisheMenuApi _disheMenuApi;
|
||||
|
||||
public BookingOrderService(ICanteenSettingService canteenSettingService, IDisheMenuApi disheMenuApi) : base(canteenSettingService)
|
||||
{
|
||||
_disheMenuApi = disheMenuApi;
|
||||
}
|
||||
|
||||
public async Task BookingAsync(BookingMealRequest request)
|
||||
{
|
||||
var gainfo = await CheckExistsMyBookingsAsync(request.BookingDate, request.ShiftType);
|
||||
|
||||
var businessPlace = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync();
|
||||
|
||||
//预定时间
|
||||
var now = DateTime.Now;
|
||||
|
||||
var bookingDeadline = await GetSettingAsync<TimeOnly?>(CanteenSettingItemEnumType.BookingDeadline) ?? new TimeOnly(20, 30, 00);
|
||||
var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan());
|
||||
(now >= dealLine).ThrowIfTrue("超出订餐时间");
|
||||
|
||||
//菜单存在
|
||||
var menuDetailResult = await _disheMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode);
|
||||
var menuDetail = menuDetailResult.Data;
|
||||
menuDetail.ThrowIfNull("预定失败,菜品已经下架");
|
||||
|
||||
var order = new CanteenOrderEntity
|
||||
{
|
||||
RequestJson = request.ToJson(),
|
||||
ThirdNo = string.Empty,
|
||||
Type = BalanceRecordTypeEnumType.Out,
|
||||
ApplicationType = CanteenApplicaitonTypeEnumType.Booking,
|
||||
Name = gainfo.Name,
|
||||
Source = request.Source,
|
||||
UserNo = gainfo.No,
|
||||
UserCode = gainfo.Code,
|
||||
Amount = -Math.Abs(menuDetail.Price),
|
||||
BusinessPlaceCode = request.BusinessPlaceCode,
|
||||
BusinessShiftCode = null,
|
||||
ShiftType = request.ShiftType,
|
||||
CostDate = now.Date,
|
||||
CostId = gainfo.CostId,
|
||||
DepartmentNo = gainfo.DepartmentNo,
|
||||
DeviceUniqueNo = string.Empty,
|
||||
DeliveryAddress = request.DeliveryAddress,
|
||||
|
||||
No = SnowFlakeHelper.Instance.NextId().ToString(),
|
||||
SubsidiesFromMonth = now.ToString("yyyyMM"),
|
||||
IsOffline = false,
|
||||
IsCostCrossTenant = await GetSettingAsync<bool>(CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
|
||||
OriginTenantId = gainfo.Factory,//人员可能跨基地消费
|
||||
|
||||
Status = BalanceRecordStatusEnumType.Valid,
|
||||
OrderStatus = CanteenOrderStatusEnumType.Success,
|
||||
|
||||
CostDateTime = now,
|
||||
|
||||
//标识当前消费的基地
|
||||
TenantId = businessPlace.TenantId,
|
||||
};
|
||||
|
||||
var orderId = await _dbContext.InsertReturnIdentityAsync(order);
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
await _disheMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode);
|
||||
var menuDetail = menuDetailResult.Data;
|
||||
menuDetail.ThrowIfNull("预定失败,菜品已经下架");
|
||||
menuDetail.Number -= 1;
|
||||
|
||||
(menuDetail.Number < 0).ThrowIfTrue($"{menuDetail.DishesName}已售罄");
|
||||
|
||||
var mealInfo = await _dbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
if (mealInfo == null)
|
||||
{
|
||||
await _dbContext.InsertAsync(new GainfoMealEntity
|
||||
{
|
||||
Balance = 0,
|
||||
BalanceOfRecharge = 0,
|
||||
BalanceOfSubsidies = 0,
|
||||
UserCode = gainfo.Code,
|
||||
UserNo = gainfo.No,
|
||||
Version = 0,
|
||||
});
|
||||
|
||||
(mealInfo == null).ThrowIfTrue("余额不足,无法消费");
|
||||
}
|
||||
//金额+-
|
||||
mealInfo.Balance += order.Amount;
|
||||
(mealInfo.Balance < 0).ThrowIfTrue("余额不足,无法消费");
|
||||
|
||||
var effect = await _dbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == mealInfo.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == order.UserNo && x.Version == mealInfo.Version)//必须与查询时的version一致
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effect <= 0) throw new VersionExceptions("更新版本冲突");
|
||||
|
||||
effect = await _dbContext.Updateable<DishesMenuEntity>()
|
||||
.SetColumns(x => x.Number == menuDetail.Number)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.Where(x => x.Date == menuDetail.Date
|
||||
&& x.ShiftType == request.ShiftType
|
||||
&& x.BusinessPlaceCode == request.BusinessPlaceCode
|
||||
&& x.DishesCode == request.DishesCode
|
||||
&& x.Version == menuDetail.Version
|
||||
)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effect <= 0) throw new VersionExceptions("更新版本冲突");
|
||||
|
||||
//写入记录
|
||||
var balanceRecord = order.Adapt<BalanceRecordEntity>();
|
||||
await _dbContext.InsertAsync(balanceRecord);
|
||||
|
||||
await _dbContext.InsertAsync(new CanteenOrderDetailEntity
|
||||
{
|
||||
OrderNo = order.No,
|
||||
DishesCode = request.DishesCode,
|
||||
Price = menuDetail.Price,
|
||||
//Unit
|
||||
Number = 1,
|
||||
});
|
||||
|
||||
}, 10);
|
||||
}
|
||||
|
||||
|
||||
public async Task<Pagination<OrderBookingResponse>> GetBookingPageAsync(OrderBookingPageRequest request)
|
||||
{
|
||||
var page = await _dbContext.Queryable<CanteenOrderEntity>()
|
||||
.LeftJoin<GainfoEntity>((x, ga) => x.UserNo == ga.No)
|
||||
.Select(x => new OrderBookingResponse
|
||||
{
|
||||
No = x.No,
|
||||
DeliveryAddress = x.DeliveryAddress,
|
||||
Remark = x.Remark,
|
||||
Amount = x.Amount
|
||||
})
|
||||
.ToPageListAsync(request);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
public async Task CancelOrderAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查我的订餐是否存在,存在抛出异常
|
||||
/// </summary>
|
||||
/// <param name="bookingDate"></param>
|
||||
/// <param name="shiftType"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<GainfoEntity> CheckExistsMyBookingsAsync(DateTime bookingDate, ShiftEnumType shiftType)
|
||||
{
|
||||
var subjectId = _currentUser.GetIntSubjectId();
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdentityUserId == subjectId).FirstAsync();
|
||||
var jinkoCode = _currentUser.GetUserClaim("jinko-code") ?? string.Empty;
|
||||
if (jinkoCode.IsPresent())
|
||||
{
|
||||
gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
}
|
||||
|
||||
var start = bookingDate.Date.AddDays(-1);
|
||||
var end = start.AddDays(1).AddSeconds(-1);
|
||||
|
||||
var exists = await _dbContext.Queryable<CanteenOrderEntity>()
|
||||
.Where(x => x.ApplicationType == CanteenApplicaitonTypeEnumType.Booking)
|
||||
.Where(x => x.ShiftType == shiftType)
|
||||
.Where(x => x.UserNo == gainfo.No)
|
||||
.Where(x => x.CreateTime >= start && x.CreateTime <= end)
|
||||
.AnyAsync();
|
||||
|
||||
exists.ThrowIfTrue("不可重复订餐");
|
||||
|
||||
return gainfo;
|
||||
}
|
||||
}
|
||||
@@ -18,193 +18,18 @@ using SqlSugar;
|
||||
using Dlhis.Canteen.Order.Response;
|
||||
using Dlhis.Canteen.Dishes;
|
||||
using Dlhis.Canteen.Order.Request;
|
||||
using System.Numerics;
|
||||
using MySqlX.XDevAPI.Relational;
|
||||
|
||||
namespace Dlhis.Canteen.Order.Services.Implements;
|
||||
|
||||
public class OrderService : IOrderService
|
||||
public class OrderService : BaseOrderService, IOrderService
|
||||
{
|
||||
private readonly IDbContext _dbContext;
|
||||
private readonly ICanteenSettingService _canteenSettingService;
|
||||
private readonly IDevicePermissionApi _devicePermissionApi;
|
||||
private readonly ICurrentUser _currentUser;
|
||||
private readonly IDisheMenuApi _disheMenuApi;
|
||||
private readonly ILogger<OrderService> _logger;
|
||||
|
||||
public OrderService(IDbContext dbContext,
|
||||
ICanteenSettingService canteenSettingService,
|
||||
IDevicePermissionApi devicePermissionApi,
|
||||
ICurrentUser currentUser,
|
||||
IDisheMenuApi disheMenuApi,
|
||||
public OrderService(ICanteenSettingService canteenSettingService, IDbContext dbContext,
|
||||
ICurrentUser currentUser, IDevicePermissionApi devicePermissionApi,
|
||||
ILogger<OrderService> logger)
|
||||
: base(canteenSettingService, dbContext, currentUser, devicePermissionApi, logger)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_canteenSettingService = canteenSettingService;
|
||||
_devicePermissionApi = devicePermissionApi;
|
||||
_currentUser = currentUser;
|
||||
_disheMenuApi = disheMenuApi;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<Pagination<OrderResponse>> GetPageAsync(OrderPageRequest request)
|
||||
{
|
||||
var page = await _dbContext.Queryable<CanteenOrderEntity>()
|
||||
.Select<OrderResponse>()
|
||||
.ToPageListAsync(request);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
private async Task CheckPAsync(string userNo, string deviceUniqueNo)
|
||||
{
|
||||
var uniqueNosResult = await _devicePermissionApi.GetCanteenDeviceUniqueNosByUserNoAsync(userNo);
|
||||
var uniqueNos = uniqueNosResult.Data;
|
||||
|
||||
uniqueNos.Contains(deviceUniqueNo).ThrowIfFalse("无消费权限");
|
||||
}
|
||||
|
||||
public async Task BookingAsync(BookingMealRequest request)
|
||||
{
|
||||
var gainfo = await CheckExistsMyBookingsAsync(request.BookingDate, request.ShiftType);
|
||||
|
||||
var businessPlace = await _dbContext.Queryable<BusinessPlaceEntity>().Where(x => x.Code == request.BusinessPlaceCode).FirstAsync();
|
||||
|
||||
//预定时间
|
||||
var now = DateTime.Now;
|
||||
|
||||
var settings = await _canteenSettingService.GetUserSettingAsync(gainfo.Code);
|
||||
var bookingDeadline = GetSetting<TimeOnly?>(settings, CanteenSettingItemEnumType.BookingDeadline) ?? new TimeOnly(20, 30, 00);
|
||||
var dealLine = DateTime.Today.Add(bookingDeadline.ToTimeSpan());
|
||||
(now >= dealLine).ThrowIfTrue("超出订餐时间");
|
||||
|
||||
//菜单存在
|
||||
var menuDetailResult = await _disheMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode);
|
||||
var menuDetail = menuDetailResult.Data;
|
||||
menuDetail.ThrowIfNull("预定失败,菜品已经下架");
|
||||
|
||||
var order = new CanteenOrderEntity
|
||||
{
|
||||
RequestJson = request.ToJson(),
|
||||
ThirdNo = string.Empty,
|
||||
Type = BalanceRecordTypeEnumType.Out,
|
||||
ApplicationType = CanteenApplicaitonTypeEnumType.Booking,
|
||||
Name = gainfo.Name,
|
||||
Source = request.Source,
|
||||
UserNo = gainfo.No,
|
||||
UserCode = gainfo.Code,
|
||||
Amount = -Math.Abs(menuDetail.Price),
|
||||
BusinessPlaceCode = request.BusinessPlaceCode,
|
||||
BusinessShiftCode = null,
|
||||
ShiftType = request.ShiftType,
|
||||
CostDate = now.Date,
|
||||
CostId = gainfo.CostId,
|
||||
DepartmentNo = gainfo.DepartmentNo,
|
||||
DeviceUniqueNo = string.Empty,
|
||||
DeliveryAddress = request.DeliveryAddress,
|
||||
|
||||
No = SnowFlakeHelper.Instance.NextId().ToString(),
|
||||
SubsidiesFromMonth = now.ToString("yyyyMM"),
|
||||
IsOffline = false,
|
||||
IsCostCrossTenant = GetSetting<bool>(settings, CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
|
||||
OriginTenantId = gainfo.Factory,//人员可能跨基地消费
|
||||
|
||||
Status = BalanceRecordStatusEnumType.Valid,
|
||||
OrderStatus = CanteenOrderStatusEnumType.Successful,
|
||||
|
||||
CostDateTime = now,
|
||||
|
||||
//标识当前消费的基地
|
||||
TenantId = businessPlace.TenantId,
|
||||
};
|
||||
|
||||
var orderId = await _dbContext.InsertReturnIdentityAsync(order);
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
await _disheMenuApi.GetBookingDishesDetailAsync(request.BookingDate, request.BusinessPlaceCode, (int)request.ShiftType, request.DishesCode);
|
||||
var menuDetail = menuDetailResult.Data;
|
||||
menuDetail.ThrowIfNull("预定失败,菜品已经下架");
|
||||
menuDetail.Number -= 1;
|
||||
|
||||
(menuDetail.Number < 0).ThrowIfTrue($"{menuDetail.DishesName}已售罄");
|
||||
|
||||
var mealInfo = await _dbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
if (mealInfo == null)
|
||||
{
|
||||
await _dbContext.InsertAsync(new GainfoMealEntity
|
||||
{
|
||||
Balance = 0,
|
||||
BalanceOfRecharge = 0,
|
||||
BalanceOfSubsidies = 0,
|
||||
UserCode = gainfo.Code,
|
||||
UserNo = gainfo.No,
|
||||
Version = 0,
|
||||
});
|
||||
|
||||
(mealInfo == null).ThrowIfTrue("余额不足,无法消费");
|
||||
}
|
||||
//金额+-
|
||||
mealInfo.Balance += order.Amount;
|
||||
(mealInfo.Balance < 0).ThrowIfTrue("余额不足,无法消费");
|
||||
|
||||
var effect = await _dbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == mealInfo.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == order.UserNo && x.Version == mealInfo.Version)//必须与查询时的version一致
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effect <= 0) throw new VersionExceptions("更新版本冲突");
|
||||
|
||||
effect = await _dbContext.Updateable<DishesMenuEntity>()
|
||||
.SetColumns(x => x.Number == menuDetail.Number)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.SetColumns(x => x.ModifiedTime == now)
|
||||
.Where(x => x.Date == menuDetail.Date
|
||||
&& x.ShiftType == request.ShiftType
|
||||
&& x.BusinessPlaceCode == request.BusinessPlaceCode
|
||||
&& x.DishesCode == request.DishesCode
|
||||
&& x.Version == menuDetail.Version
|
||||
)
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
if (effect <= 0) throw new VersionExceptions("更新版本冲突");
|
||||
|
||||
//写入记录
|
||||
var balanceRecord = order.Adapt<BalanceRecordEntity>();
|
||||
await _dbContext.InsertAsync(balanceRecord);
|
||||
|
||||
await _dbContext.InsertAsync(new CanteenOrderDetailEntity
|
||||
{
|
||||
OrderNo = order.No,
|
||||
DishesCode = request.DishesCode,
|
||||
Price = menuDetail.Price,
|
||||
//Unit
|
||||
Number = 1,
|
||||
});
|
||||
|
||||
}, 10);
|
||||
}
|
||||
|
||||
|
||||
//public async Task<List<OrderDetailResponse>> GetDetailsAsync(string no)
|
||||
//{
|
||||
// return await _dbContext.Queryable<CanteenOrderDetailEntity>()
|
||||
// .LeftJoin<DishesEntity>((x, d) => x.DishesCode == d.CustomCode)
|
||||
// .Where(x => x.OrderNo == no)
|
||||
// .Select((x, d) => new OrderDetailResponse
|
||||
// {
|
||||
// DishesCode = x.DishesCode,
|
||||
// Price = x.Price,
|
||||
// Name = d.Name,
|
||||
// Number = x.Number,
|
||||
// Unit = x.Unit,
|
||||
// ImageUrl = d.ImageUrl,
|
||||
// })
|
||||
// .ToListAsync();
|
||||
//}
|
||||
|
||||
|
||||
public async Task<OrderResultResponse> DeviceConsume(OrderAddRequest request)
|
||||
{
|
||||
return await AddAsync(request);
|
||||
@@ -216,21 +41,21 @@ public class OrderService : IOrderService
|
||||
_ = long.TryParse(request.UserUniqueNo, out var userId);
|
||||
|
||||
//根据档案号
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>()
|
||||
var gainfo = await DbContext.Queryable<GainfoEntity>()
|
||||
.Where(x => x.No == request.UserUniqueNo || x.Code == request.UserUniqueNo || x.Id == userId || x.CardNo == request.UserUniqueNo)
|
||||
.FirstAsync();
|
||||
|
||||
gainfo.ThrowIfNull($"无消费权限");
|
||||
//消费权限控制
|
||||
await CheckPAsync(gainfo.No, request.DeviceUniqueNo);
|
||||
await CheckPermissionAsync(gainfo.No, request.DeviceUniqueNo);
|
||||
|
||||
var canteenUserExists = await _dbContext.Queryable<GainfoMealEntity>()
|
||||
var canteenUserExists = await DbContext.Queryable<GainfoMealEntity>()
|
||||
.Where(x => x.UserNo == gainfo.No)
|
||||
.AnyAsync();
|
||||
|
||||
if (!canteenUserExists)
|
||||
{
|
||||
await _dbContext.InsertAsync(new GainfoMealEntity
|
||||
await DbContext.InsertAsync(new GainfoMealEntity
|
||||
{
|
||||
UserNo = gainfo.No,
|
||||
Balance = 0,
|
||||
@@ -258,7 +83,7 @@ public class OrderService : IOrderService
|
||||
}
|
||||
|
||||
//获取人员余额
|
||||
return await _dbContext.Queryable<GainfoEntity>()
|
||||
return await DbContext.Queryable<GainfoEntity>()
|
||||
.LeftJoin<DepartmentEntity>((ga, department) => ga.DepartmentNo == department.No)
|
||||
.LeftJoin<GainfoMealEntity>((ga, department, mealUser) => ga.No == mealUser.UserNo)
|
||||
.Where(ga => ga.Id == gainfo.Id)
|
||||
@@ -281,11 +106,11 @@ public class OrderService : IOrderService
|
||||
/// <returns></returns>
|
||||
private async Task ConsumeAsync(ConsumeRequest request, GainfoEntity gainfo)
|
||||
{
|
||||
var device = await _dbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == request.DeviceUniqueNo).Where(x => x.Enable).FirstAsync();
|
||||
var device = await DbContext.Queryable<DeviceEntity>().Where(x => x.UniqueNo == request.DeviceUniqueNo).Where(x => x.Enable).FirstAsync();
|
||||
device.ThrowIfNull("设备不存在或者尚未启用");
|
||||
var registry = await _dbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.DeviceUniqueNo).FirstAsync();
|
||||
var registry = await DbContext.Queryable<DeviceRegistryEntity>().Where(x => x.DeviceUniqueNo == request.DeviceUniqueNo).FirstAsync();
|
||||
registry.ThrowIfNull("设备尚未注册");
|
||||
var businessPlaceInfo = await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||
var businessPlaceInfo = await DbContext.Queryable<BusinessPlaceEntity>()
|
||||
.LeftJoin<BusinessPlaceShiftRelationshipEntity>((x, sr) => x.Code == sr.PlaceCode)
|
||||
.Where(x => x.Code == registry.BusinessPlaceCode)
|
||||
.Select((x, sr) => new
|
||||
@@ -298,7 +123,7 @@ public class OrderService : IOrderService
|
||||
businessPlaceInfo.ThrowIfNull("营业点尚未设置");
|
||||
|
||||
//获取当前消费餐次
|
||||
var shifts = await _dbContext.Queryable<BusinessShiftMealRelationshipEntity>().Where(x => x.ShiftCode == businessPlaceInfo.ShiftCode).ToListAsync();
|
||||
var shifts = await DbContext.Queryable<BusinessShiftMealRelationshipEntity>().Where(x => x.ShiftCode == businessPlaceInfo.ShiftCode).ToListAsync();
|
||||
|
||||
var shift = shifts.FirstOrDefault(x => new TimePeriod()
|
||||
{
|
||||
@@ -307,8 +132,7 @@ public class OrderService : IOrderService
|
||||
|
||||
}.IsPresent1(request.CostDateTime));
|
||||
|
||||
var settings = await _canteenSettingService.GetUserSettingAsync(request.UserUniqueNo);
|
||||
var switchTime = GetSetting<TimeOnly?>(settings, CanteenSettingItemEnumType.BusinessSwitchTime);
|
||||
var switchTime = await GetSettingAsync<TimeOnly?>(CanteenSettingItemEnumType.BusinessSwitchTime);
|
||||
|
||||
var shiftTimePeriod = new TimePeriod()
|
||||
{
|
||||
@@ -356,7 +180,7 @@ public class OrderService : IOrderService
|
||||
No = SnowFlakeHelper.Instance.NextId().ToString(),
|
||||
SubsidiesFromMonth = request.CostDateTime.ToString("yyyyMM"),
|
||||
IsOffline = request.IsOffline,
|
||||
IsCostCrossTenant = GetSetting<bool>(settings, CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
IsCostCrossTenant = await GetSettingAsync<bool>(CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
|
||||
OriginTenantId = gainfo.Factory,//人员可能跨基地消费
|
||||
|
||||
@@ -371,14 +195,14 @@ public class OrderService : IOrderService
|
||||
TenantId = businessPlaceInfo.TenantId,
|
||||
};
|
||||
|
||||
var orderId = await _dbContext.InsertReturnIdentityAsync(order);
|
||||
var orderId = await DbContext.InsertReturnIdentityAsync(order);
|
||||
try
|
||||
{
|
||||
await GenerateConsumeRecordAsync(orderId, settings, shifts, request.CostDateTime);
|
||||
await GenerateConsumeRecordAsync(orderId, shifts, request.CostDateTime);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await _dbContext.Updateable<CanteenOrderEntity>()
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Failure)
|
||||
.SetColumns(x => x.Result == ex.Message)
|
||||
.SetColumns(x => x.ModifiedTime == DateTime.Now)
|
||||
@@ -388,8 +212,8 @@ public class OrderService : IOrderService
|
||||
throw;
|
||||
}
|
||||
|
||||
await _dbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Successful)
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Success)
|
||||
.SetColumns(x => x.ModifiedTime == DateTime.Now)
|
||||
.Where(x => x.Id == orderId)
|
||||
.ExecuteCommandAsync();
|
||||
@@ -403,8 +227,6 @@ public class OrderService : IOrderService
|
||||
/// <returns></returns>
|
||||
private async Task RechargeAsync(RechargeRequest request, GainfoEntity gainfo)
|
||||
{
|
||||
var settings = await _canteenSettingService.GetUserSettingAsync(request.UserUniqueNo);
|
||||
|
||||
var order = new CanteenOrderEntity
|
||||
{
|
||||
RequestJson = request.ToJson(),
|
||||
@@ -425,7 +247,7 @@ public class OrderService : IOrderService
|
||||
|
||||
No = SnowFlakeHelper.Instance.NextId().ToString(),
|
||||
SubsidiesFromMonth = request.CostDateTime.ToString("yyyyMM"),
|
||||
IsCostCrossTenant = GetSetting<bool>(settings, CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
IsCostCrossTenant = await GetSettingAsync<bool>(CanteenSettingItemEnumType.AllowCrossTenant),
|
||||
|
||||
OriginTenantId = gainfo.Factory,//人员可能跨基地消费
|
||||
|
||||
@@ -439,14 +261,14 @@ public class OrderService : IOrderService
|
||||
TenantId = gainfo.Factory,
|
||||
};
|
||||
|
||||
var orderId = await _dbContext.InsertReturnIdentityAsync(order);
|
||||
var orderId = await DbContext.InsertReturnIdentityAsync(order);
|
||||
try
|
||||
{
|
||||
await GenerateRechargeRecordAsync(orderId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await _dbContext.Updateable<CanteenOrderEntity>()
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Failure)
|
||||
.SetColumns(x => x.Result == ex.Message)
|
||||
.Where(x => x.Id == orderId)
|
||||
@@ -455,8 +277,8 @@ public class OrderService : IOrderService
|
||||
throw;
|
||||
}
|
||||
|
||||
await _dbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Successful)
|
||||
await DbContext.Updateable<CanteenOrderEntity>()
|
||||
.SetColumns(x => x.OrderStatus == CanteenOrderStatusEnumType.Success)
|
||||
.Where(x => x.Id == orderId)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
@@ -464,15 +286,15 @@ public class OrderService : IOrderService
|
||||
|
||||
public async Task<Pagination<OrderAggregationResponse>> GetOrdersAggregationAsync(PageDto page)
|
||||
{
|
||||
var subjectId = _currentUser.GetIntSubjectId();
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdentityUserId == subjectId).FirstAsync();
|
||||
var jinkoCode = _currentUser.GetUserClaim("jinko-code") ?? string.Empty;
|
||||
var subjectId = CurrentUser.GetIntSubjectId();
|
||||
var gainfo = await DbContext.Queryable<GainfoEntity>().Where(x => x.IdentityUserId == subjectId).FirstAsync();
|
||||
var jinkoCode = CurrentUser.GetUserClaim("jinko-code") ?? string.Empty;
|
||||
if (jinkoCode.IsPresent())
|
||||
{
|
||||
gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
gainfo = await DbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
}
|
||||
|
||||
var pageResult = await _dbContext.Queryable<CanteenOrderEntity>().Where(x => x.UserNo == gainfo.No)
|
||||
var pageResult = await DbContext.Queryable<CanteenOrderEntity>().Where(x => x.UserNo == gainfo.No)
|
||||
.LeftJoin<BusinessPlaceEntity>((x, bplace) => x.BusinessPlaceCode == bplace.Code)
|
||||
.Where(x => x.ApplicationType == CanteenApplicaitonTypeEnumType.Booking)
|
||||
.Select((x, bplace) => new OrderAggregationResponse
|
||||
@@ -485,7 +307,7 @@ public class OrderService : IOrderService
|
||||
//.LeftJoin<CanteenOrderDetailEntity>((x, bplace, detail) => x.No == detail.OrderNo)
|
||||
|
||||
var nos = pageResult.Data.Select(x => x.No).ToList();
|
||||
var dtos = await _dbContext.Queryable<CanteenOrderDetailEntity>()
|
||||
var dtos = await DbContext.Queryable<CanteenOrderDetailEntity>()
|
||||
.LeftJoin<DishesEntity>((x, d) => x.DishesCode == d.CustomCode)
|
||||
.Where(x => nos.Contains(x.OrderNo))
|
||||
.Select((x, d) => new DishesDto
|
||||
@@ -512,78 +334,17 @@ public class OrderService : IOrderService
|
||||
//******************************************************* help methods ************************************************************/
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设备并发更新 需要抛出VersionExceptions
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="func"></param>
|
||||
/// <param name="retry">并发冲突处理次数</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
private async Task ContinueUpdateAsync(Func<Task> func, int retry)
|
||||
{
|
||||
for (int i = 0; i < retry; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
await func();
|
||||
return;
|
||||
}
|
||||
catch (Exception ex) when (ex is VersionExceptions)
|
||||
{
|
||||
_logger.LogWarning(ex, ex.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
throw new UserFriendlyException("操作失败,请重试");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取参数配置
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
private static T GetSetting<T>(Dictionary<CanteenSettingItemEnumType, string> settings, CanteenSettingItemEnumType item, T defaultValue = default)
|
||||
{
|
||||
if (settings.TryGetValue(item, out var v))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (int.TryParse(v, out var n))
|
||||
{
|
||||
return n.Adapt<T>();
|
||||
}
|
||||
|
||||
return v.Adapt<T>();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 验证参数
|
||||
/// </summary>
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="shifts"></param>
|
||||
/// <param name="costDateTime"></param>
|
||||
/// <param name="order"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
private async Task Verify(Dictionary<CanteenSettingItemEnumType, string> settings, List<BusinessShiftMealRelationshipEntity> shifts, DateTime costDateTime, CanteenOrderEntity order)
|
||||
private async Task Verify(List<BusinessShiftMealRelationshipEntity> shifts, DateTime costDateTime, CanteenOrderEntity order)
|
||||
{
|
||||
//在线
|
||||
if (!order.IsOffline)
|
||||
@@ -599,15 +360,15 @@ public class OrderService : IOrderService
|
||||
var beginOfDay = DateTime.Today;
|
||||
var endOfDay = beginOfDay.AddHours(23).AddMinutes(59).AddSeconds(59);
|
||||
|
||||
var balanceRecords = await _dbContext.Queryable<BalanceRecordEntity>()
|
||||
var balanceRecords = await DbContext.Queryable<BalanceRecordEntity>()
|
||||
.Where(x => x.UserNo == order.UserNo)
|
||||
.Where(x => x.CreateTime >= beginOfDay && x.CreateTime <= endOfDay) //今天消费记录
|
||||
.ToListAsync();
|
||||
|
||||
var dayMarketCostMax = GetSetting<decimal>(settings, CanteenSettingItemEnumType.DayMarketCostMax);
|
||||
var dayMarketCostMax = await GetSettingAsync<decimal>(CanteenSettingItemEnumType.DayMarketCostMax);
|
||||
if (dayMarketCostMax != default)
|
||||
{
|
||||
var businessPlaceCodes = await _dbContext.Queryable<BusinessPlaceEntity>()
|
||||
var businessPlaceCodes = await DbContext.Queryable<BusinessPlaceEntity>()
|
||||
.Where(x => x.Catalog == CanteenBusinessPlaceCatalogEnumType.Supermarket)
|
||||
.Select(x => x.Code).ToListAsync();
|
||||
|
||||
@@ -618,7 +379,7 @@ public class OrderService : IOrderService
|
||||
}
|
||||
}
|
||||
|
||||
var allowRepeatInOneShift = GetSetting(settings, CanteenSettingItemEnumType.AllowRepeatInOneShift, true);
|
||||
var allowRepeatInOneShift = await GetSettingAsync(CanteenSettingItemEnumType.AllowRepeatInOneShift, true);
|
||||
if (!allowRepeatInOneShift)
|
||||
{
|
||||
//todo 餐次问题
|
||||
@@ -629,7 +390,7 @@ public class OrderService : IOrderService
|
||||
}
|
||||
}
|
||||
|
||||
var onceCostMax = GetSetting<decimal>(settings, CanteenSettingItemEnumType.OnceCostMax);
|
||||
var onceCostMax = await GetSettingAsync<decimal>(CanteenSettingItemEnumType.OnceCostMax);
|
||||
if (onceCostMax != default)
|
||||
{
|
||||
if (Math.Abs(order.Amount) > onceCostMax)
|
||||
@@ -638,7 +399,7 @@ public class OrderService : IOrderService
|
||||
}
|
||||
}
|
||||
|
||||
var dayCostMax = GetSetting<decimal>(settings, CanteenSettingItemEnumType.DayCostMax);
|
||||
var dayCostMax = await GetSettingAsync<decimal>(CanteenSettingItemEnumType.DayCostMax);
|
||||
if (dayCostMax != default)
|
||||
{
|
||||
var cost = balanceRecords.Where(x => x.Type == BalanceRecordTypeEnumType.Out).Sum(x => Math.Abs(x.Amount));
|
||||
@@ -659,15 +420,15 @@ public class OrderService : IOrderService
|
||||
/// <exception cref="VersionExceptions"></exception>
|
||||
private async Task GenerateRechargeRecordAsync(long orderId)
|
||||
{
|
||||
var order = await _dbContext.Queryable<CanteenOrderEntity>().Where(x => x.Id == orderId).FirstAsync();
|
||||
var order = await DbContext.Queryable<CanteenOrderEntity>().Where(x => x.Id == orderId).FirstAsync();
|
||||
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
var canteenUser = await _dbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
var canteenUser = await DbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
//金额+-
|
||||
canteenUser.Balance += order.Amount;
|
||||
|
||||
var effect = await _dbContext.Updateable<GainfoMealEntity>()
|
||||
var effect = await DbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == canteenUser.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == order.UserNo && x.Version == canteenUser.Version)
|
||||
@@ -677,7 +438,7 @@ public class OrderService : IOrderService
|
||||
|
||||
//写入记录
|
||||
var balanceRecord = order.Adapt<BalanceRecordEntity>();
|
||||
await _dbContext.InsertAsync(balanceRecord);
|
||||
await DbContext.InsertAsync(balanceRecord);
|
||||
|
||||
}, 5);
|
||||
}
|
||||
@@ -686,25 +447,24 @@ public class OrderService : IOrderService
|
||||
/// 生成充值记录
|
||||
/// </summary>
|
||||
/// <param name="orderId"></param>
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="shifts"></param>
|
||||
/// <param name="costDateTime"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="UserFriendlyException"></exception>
|
||||
/// <exception cref="VersionExceptions"></exception>
|
||||
private async Task GenerateConsumeRecordAsync(long orderId, Dictionary<CanteenSettingItemEnumType, string> settings, List<BusinessShiftMealRelationshipEntity> shifts, DateTime costDateTime)
|
||||
private async Task GenerateConsumeRecordAsync(long orderId, List<BusinessShiftMealRelationshipEntity> shifts, DateTime costDateTime)
|
||||
{
|
||||
var order = await _dbContext.Queryable<CanteenOrderEntity>().Where(x => x.Id == orderId).FirstAsync();
|
||||
var order = await DbContext.Queryable<CanteenOrderEntity>().Where(x => x.Id == orderId).FirstAsync();
|
||||
//校验
|
||||
await Verify(settings, shifts, costDateTime, order);
|
||||
await Verify(shifts, costDateTime, order);
|
||||
|
||||
var allowNoBalance = GetSetting<bool>(settings, CanteenSettingItemEnumType.AllowNoBalance);
|
||||
var allowNoBalance = await GetSettingAsync<bool>(CanteenSettingItemEnumType.AllowNoBalance);
|
||||
|
||||
await ContinueUpdateAsync(async () =>
|
||||
{
|
||||
if (!allowNoBalance)
|
||||
{
|
||||
var canteenUser = await _dbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
var canteenUser = await DbContext.Queryable<GainfoMealEntity>().Where(x => x.UserNo == order.UserNo).FirstAsync();
|
||||
//金额+-
|
||||
canteenUser.Balance += order.Amount;
|
||||
if (canteenUser.Balance < 0)
|
||||
@@ -712,7 +472,7 @@ public class OrderService : IOrderService
|
||||
throw new UserFriendlyException("余额不足,无法消费");
|
||||
}
|
||||
|
||||
var effect = await _dbContext.Updateable<GainfoMealEntity>()
|
||||
var effect = await DbContext.Updateable<GainfoMealEntity>()
|
||||
.SetColumns(x => x.Balance == canteenUser.Balance)
|
||||
.SetColumns(x => x.Version == x.Version + 1)
|
||||
.Where(x => x.UserNo == order.UserNo && x.Version == canteenUser.Version)//必须与查询时的version一致
|
||||
@@ -723,39 +483,10 @@ public class OrderService : IOrderService
|
||||
|
||||
//写入记录
|
||||
var balanceRecord = order.Adapt<BalanceRecordEntity>();
|
||||
await _dbContext.InsertAsync(balanceRecord);
|
||||
await DbContext.InsertAsync(balanceRecord);
|
||||
|
||||
}, 5);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查我的订餐是否存在,存在抛出异常
|
||||
/// </summary>
|
||||
/// <param name="bookingDate"></param>
|
||||
/// <param name="shiftType"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<GainfoEntity> CheckExistsMyBookingsAsync(DateTime bookingDate, ShiftEnumType shiftType)
|
||||
{
|
||||
var subjectId = _currentUser.GetIntSubjectId();
|
||||
var gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.IdentityUserId == subjectId).FirstAsync();
|
||||
var jinkoCode = _currentUser.GetUserClaim("jinko-code") ?? string.Empty;
|
||||
if (jinkoCode.IsPresent())
|
||||
{
|
||||
gainfo = await _dbContext.Queryable<GainfoEntity>().Where(x => x.Code == jinkoCode).FirstAsync();
|
||||
}
|
||||
|
||||
var start = bookingDate.Date.AddDays(-1);
|
||||
var end = start.AddDays(1).AddSeconds(-1);
|
||||
|
||||
var exists = await _dbContext.Queryable<CanteenOrderEntity>()
|
||||
.Where(x => x.ApplicationType == CanteenApplicaitonTypeEnumType.Booking)
|
||||
.Where(x => x.ShiftType == shiftType)
|
||||
.Where(x => x.UserNo == gainfo.No)
|
||||
.Where(x => x.CreateTime >= start && x.CreateTime <= end)
|
||||
.AnyAsync();
|
||||
|
||||
exists.ThrowIfTrue("不可重复订餐");
|
||||
|
||||
return gainfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ using Kurisu.SqlSugar;
|
||||
using SqlSugar;
|
||||
using SqlSugar.DbConvert;
|
||||
|
||||
namespace Dlhis.Entity.Basic.Entity;
|
||||
namespace Dlhis.Entity.Canteen.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// 餐补记录
|
||||
@@ -12,7 +12,7 @@ namespace Dlhis.Entity.Basic.Entity;
|
||||
public class MealSupplementRecordEntity : MealSupplementRequestRecordEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一号
|
||||
/// 唯一号(流水号)
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = false, ColumnDescription = "唯一号", UniqueGroupNameList = new[] { "idx_MealSupplementRecord_UniqueId" })]
|
||||
public override string UniqueId { get; set; }
|
||||
@@ -41,6 +41,10 @@ public class MealSupplementRecordEntity : MealSupplementRequestRecordEntity
|
||||
public bool Sync { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 餐补请求记录
|
||||
/// </summary>
|
||||
[SugarTable(TableName = "MealSupplementRequestRecord", TableDescription = "餐补请求记录")]
|
||||
public class MealSupplementRequestRecordEntity : SugarBaseEntity
|
||||
{
|
||||
@@ -57,12 +57,12 @@ public enum BalanceRecordSourceEnumType
|
||||
/// <summary>
|
||||
/// 来自本基地补贴
|
||||
/// </summary>
|
||||
[Description("本基地补贴")]
|
||||
[Description("本基地餐补")]
|
||||
LocalTenantSubsidies = 300,
|
||||
|
||||
/// <summary>
|
||||
/// 来自其他基地补贴
|
||||
/// </summary>
|
||||
[Description("其他基地补贴")]
|
||||
[Description("其他基地餐补")]
|
||||
OtherTenantSubsidies,
|
||||
}
|
||||
@@ -3,9 +3,9 @@
|
||||
namespace Dlhis.Entity.Canteen.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 就餐订单状态
|
||||
/// 餐饮订单状态
|
||||
/// </summary>
|
||||
[Description("就餐订单状态")]
|
||||
[Description("餐饮订单状态")]
|
||||
public enum CanteenOrderStatusEnumType
|
||||
{
|
||||
/// <summary>
|
||||
@@ -18,7 +18,7 @@ public enum CanteenOrderStatusEnumType
|
||||
/// 成功
|
||||
/// </summary>
|
||||
[Description("成功")]
|
||||
Successful = 1,
|
||||
Success = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 取消
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -10,4 +10,8 @@ public interface IUserApi
|
||||
[Auth]
|
||||
[Get("/api/users")]
|
||||
Task<DefaultApiResult<UserResponse>> GetUserByIdAsync(int id);
|
||||
|
||||
[Auth]
|
||||
[Post("/api/users/by-ids")]
|
||||
Task<DefaultApiResult<List<UserResponse>>> GetUserByIdsAsync(List<int> ids);
|
||||
}
|
||||
@@ -56,6 +56,13 @@ public class UsersController : ControllerBase
|
||||
return await _userService.GetUserByIdAsync(id);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpPost("by-ids")]
|
||||
public async Task<List<UserResponse>> GetUserByIdsAsync(List<int> ids)
|
||||
{
|
||||
return await _userService.GetUserByIdsAsync(ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传头像
|
||||
/// </summary>
|
||||
|
||||
@@ -15,4 +15,7 @@ public interface IUserService : IScopeDependency
|
||||
Task<UserResponse> GetUserByIdAsync(int id);
|
||||
|
||||
Task UploadUserAvatarAsync(UserAvatarUploadRequest request);
|
||||
|
||||
|
||||
Task<List<UserResponse>> GetUserByIdsAsync(List<int> ids);
|
||||
}
|
||||
|
||||
@@ -12,11 +12,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<Pagination<UserResponse>> GetPageAsync(UserPageRequest request)
|
||||
@@ -63,4 +61,10 @@ public class UserService : IUserService
|
||||
{
|
||||
var user = await _dbContext.Queryable<UserEntity>().Where(x => x.Id == request.UserNo).Select<UserResponse>().FirstAsync();
|
||||
}
|
||||
|
||||
public async Task<List<UserResponse>> GetUserByIdsAsync(List<int> ids)
|
||||
{
|
||||
var users = await _dbContext.Queryable<UserEntity>().Where(x => ids.Contains(x.Id)).Select<UserResponse>().ToListAsync();
|
||||
return users;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public class SqlSugarPack : BaseAppPack
|
||||
|
||||
return new List<ConnectionConfig>
|
||||
{
|
||||
new ConnectionConfig
|
||||
new()
|
||||
{
|
||||
ConfigId = "identity",
|
||||
|
||||
|
||||
Reference in New Issue
Block a user