diff --git a/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs b/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs
index f802eece..86e9a5c6 100644
--- a/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs
+++ b/Src/Dlhis.Canteen/Order/Controllers/OrdersController.cs
@@ -34,12 +34,12 @@ public class OrdersController : ControllerBase
}
///
- /// 添加充值消费订单
+ /// 添加充值/消费订单
///
///
///
[HttpPost]
- public async Task AddAsync(OrderAddRequest request)
+ public async Task AddAsync(OrderAddRequest request)
{
return await _orderService.AddAsync(request);
}
diff --git a/Src/Dlhis.Canteen/Order/Request/ConsumeRequest.cs b/Src/Dlhis.Canteen/Order/Request/ConsumeRequest.cs
new file mode 100644
index 00000000..87159bb6
--- /dev/null
+++ b/Src/Dlhis.Canteen/Order/Request/ConsumeRequest.cs
@@ -0,0 +1,41 @@
+using Dlhis.Entity.Canteen.Enums;
+
+namespace Dlhis.Canteen.Order.Request;
+
+public class ConsumeRequest
+{
+ ///
+ /// 是否离线数据
+ ///
+ public bool IsOffline { get; set; }
+
+ ///
+ /// 消费机器唯一信息
+ ///
+ public string DeviceUniqueNo { get; set; }
+
+ ///
+ /// 第三方订单号
+ ///
+ public string ThirdNo { get; set; }
+
+ ///
+ /// 档案号/QrCode/学工号
+ ///
+ public string UserUniqueNo { get; set; }
+
+ ///
+ /// 来源
+ ///
+ public BalanceRecordSourceEnumType Source { get; set; }
+
+ ///
+ /// 金额
+ ///
+ public decimal Amount { get; set; }
+
+ ///
+ /// 产生时间
+ ///
+ public DateTime CostDateTime { get; set; }
+}
diff --git a/Src/Dlhis.Canteen/Order/Request/OrderAddRequest.cs b/Src/Dlhis.Canteen/Order/Request/OrderAddRequest.cs
index 72c26956..9b8ff088 100644
--- a/Src/Dlhis.Canteen/Order/Request/OrderAddRequest.cs
+++ b/Src/Dlhis.Canteen/Order/Request/OrderAddRequest.cs
@@ -1,9 +1,10 @@
using System.ComponentModel.DataAnnotations;
using Dlhis.Entity.Canteen.Enums;
+using Kurisu.AspNetCore.Utils.Extensions;
namespace Dlhis.Canteen.Order.Request;
-public class OrderAddRequest
+public class OrderAddRequest : IValidatableObject
{
///
/// 是否离线数据
@@ -23,6 +24,7 @@ public class OrderAddRequest
///
/// 档案号/QrCode/学工号
///
+ [Required(ErrorMessage = "人员档案号/QrCode/学工号不能为空")]
public string UserUniqueNo { get; set; }
///
@@ -44,7 +46,41 @@ public class OrderAddRequest
public decimal Amount { get; set; }
///
- /// 消费时间,由机器提供,否则获取当前时间
+ /// 产生时间
///
- public DateTime CostDateTime { get; set; } = DateTime.Now;
+ public DateTime? CostDateTime { get; set; }
+
+
+ public IEnumerable Validate(ValidationContext validationContext)
+ {
+ //处理金额
+ Amount = Type == BalanceRecordTypeEnumType.In ? Math.Abs(Amount) : -Math.Abs(Amount);
+
+ if (Type == BalanceRecordTypeEnumType.Out)
+ {
+ //处理消费类型
+ if ((int)Source >= (int)BalanceRecordSourceEnumType.Wechat)
+ {
+ yield return new ValidationResult($"不支持来源{Source.GetDescription()}", new[] { nameof(Source) });
+ }
+
+ //在线就以API时间为准
+ if (!IsOffline)
+ {
+ CostDateTime = DateTime.Now;
+ }
+
+ if (DeviceUniqueNo.IsEmpty())
+ {
+ yield return new ValidationResult("设备唯一号不能为空", new[] { nameof(DeviceUniqueNo) });
+ }
+ }
+ else if (Type == BalanceRecordTypeEnumType.In)
+ {
+ if ((int)Source < (int)BalanceRecordSourceEnumType.Wechat)
+ {
+ yield return new ValidationResult($"不支持来源{Source.GetDescription()}", new[] { nameof(Source) });
+ }
+ }
+ }
}
diff --git a/Src/Dlhis.Canteen/Order/Request/RechargeRequest.cs b/Src/Dlhis.Canteen/Order/Request/RechargeRequest.cs
new file mode 100644
index 00000000..0d4c8a7a
--- /dev/null
+++ b/Src/Dlhis.Canteen/Order/Request/RechargeRequest.cs
@@ -0,0 +1,34 @@
+using Dlhis.Entity.Canteen.Enums;
+using System.ComponentModel.DataAnnotations;
+
+namespace Dlhis.Canteen.Order.Request;
+
+public class RechargeRequest
+{
+ ///
+ /// 第三方订单号
+ ///
+ public string ThirdNo { get; set; }
+
+ ///
+ /// 档案号/QrCode/学工号
+ ///
+ public string UserUniqueNo { get; set; }
+
+ ///
+ /// 来源
+ ///
+ [EnumDataType(typeof(BalanceRecordSourceEnumType))]
+ public BalanceRecordSourceEnumType Source { get; set; }
+
+ ///
+ /// 金额
+ ///
+ [Range(0.01, double.MaxValue)]
+ public decimal Amount { get; set; }
+
+ ///
+ /// 产生时间
+ ///
+ public DateTime CostDateTime { get; set; } = DateTime.Now;
+}
diff --git a/Src/Dlhis.Canteen/Order/Response/BalanceRecordResponse.cs b/Src/Dlhis.Canteen/Order/Response/BalanceRecordResponse.cs
index 054ba498..4f684d96 100644
--- a/Src/Dlhis.Canteen/Order/Response/BalanceRecordResponse.cs
+++ b/Src/Dlhis.Canteen/Order/Response/BalanceRecordResponse.cs
@@ -109,4 +109,9 @@ public class BalanceRecordResponse
/// 数据状态描述
///
public string StatusDesc => Status.GetDescription();
+
+ ///
+ /// 记录产生时间
+ ///
+ public DateTime CostDateTime { get; set; }
}
diff --git a/Src/Dlhis.Canteen/Order/Response/BalanceRecordUserResponse.cs b/Src/Dlhis.Canteen/Order/Response/BalanceRecordUserResponse.cs
index 70ae969d..1ab529aa 100644
--- a/Src/Dlhis.Canteen/Order/Response/BalanceRecordUserResponse.cs
+++ b/Src/Dlhis.Canteen/Order/Response/BalanceRecordUserResponse.cs
@@ -44,4 +44,9 @@ public class BalanceRecordUserResponse
/// 数据状态描述
///
public string StatusDesc => Status.GetDescription();
+
+ ///
+ /// 记录产生日期
+ ///
+ public DateTime CostDateTime { get; set; }
}
diff --git a/Src/Dlhis.Canteen/Order/Response/OrderConsumeResponse.cs b/Src/Dlhis.Canteen/Order/Response/OrderResultResponse.cs
similarity index 94%
rename from Src/Dlhis.Canteen/Order/Response/OrderConsumeResponse.cs
rename to Src/Dlhis.Canteen/Order/Response/OrderResultResponse.cs
index 969483d8..69418e4d 100644
--- a/Src/Dlhis.Canteen/Order/Response/OrderConsumeResponse.cs
+++ b/Src/Dlhis.Canteen/Order/Response/OrderResultResponse.cs
@@ -1,6 +1,6 @@
namespace Dlhis.Canteen.Order.Response;
-public class OrderConsumeResponse
+public class OrderResultResponse
{
///
/// 用户工号
diff --git a/Src/Dlhis.Canteen/Order/Services/IOrderService.cs b/Src/Dlhis.Canteen/Order/Services/IOrderService.cs
index c7e53edb..b30a7e27 100644
--- a/Src/Dlhis.Canteen/Order/Services/IOrderService.cs
+++ b/Src/Dlhis.Canteen/Order/Services/IOrderService.cs
@@ -8,5 +8,5 @@ public interface IOrderService : IScopeDependency
{
Task> GetPageAsync(OrderPageRequest request);
- Task AddAsync(OrderAddRequest request);
+ Task AddAsync(OrderAddRequest request);
}
diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs
index 2ebfb3d2..552c7ae1 100644
--- a/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs
+++ b/Src/Dlhis.Canteen/Order/Services/Implements/BalanceService.cs
@@ -56,6 +56,7 @@ public class BalanceService : IBalanceService
DepartmentName = department.Name,
BusinessPlaceName = bplace.Name,
BusinessShiftName = bshift.Name,
+ CostDateTime = record.CreateTime // todo
})
.ToPageListAsync(request);
@@ -121,6 +122,7 @@ public class BalanceService : IBalanceService
DepartmentName = department.Name,
BusinessPlaceName = bplace.Name,
BusinessShiftName = bshift.Name,
+ CostDateTime = record.CreateTime // todo
})
.ToPageListAsync(request);
@@ -151,6 +153,7 @@ public class BalanceService : IBalanceService
No = record.No,
BusinessPlaceName = bplace.Name,
BusinessShiftName = bshift.Name,
+ CostDateTime = record.CreateTime // todo
})
.ToPageListAsync(request);
diff --git a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs
index 234abb59..44aaa029 100644
--- a/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs
+++ b/Src/Dlhis.Canteen/Order/Services/Implements/OrderService.cs
@@ -24,7 +24,9 @@ public class OrderService : IOrderService
private readonly ICanteenSettingService _canteenSettingService;
private readonly ILogger _logger;
- public OrderService(IDbContext dbContext, ICanteenSettingService canteenSettingService, ILogger logger)
+ public OrderService(IDbContext dbContext,
+ ICanteenSettingService canteenSettingService,
+ ILogger logger)
{
_dbContext = dbContext;
_canteenSettingService = canteenSettingService;
@@ -41,40 +43,73 @@ public class OrderService : IOrderService
}
[IgnoreTenant]
- public async Task AddAsync(OrderAddRequest request)
+ public async Task AddAsync(OrderAddRequest request)
+ {
+ //根据档案号
+ var canteenUserExists = await _dbContext.Queryable()
+ .Where(x => x.UserNo == request.UserUniqueNo || x.UserCode == request.UserUniqueNo)
+ .AnyAsync();
+ canteenUserExists.ThrowIfFalse($"就餐用户{request.UserUniqueNo}不存在,无法操作");
+
+ var gainfo = await _dbContext.Queryable()
+ .Where(x => x.No == request.UserUniqueNo || x.Code == request.UserUniqueNo)
+ .FirstAsync();
+ gainfo.ThrowIfNull($"用户{request.UserUniqueNo}不存在,无法操作");
+
+ //消费
+ if (request.Type == BalanceRecordTypeEnumType.Out)
+ {
+ await ConsumeAsync(request.Adapt(), gainfo);
+ }
+ //充值
+ else
+ {
+ await RechargeAsync(request.Adapt(), gainfo);
+ }
+
+ //获取人员余额
+ return await _dbContext.Queryable()
+ .LeftJoin((ga, department) => ga.DepartmentNo == department.No)
+ .LeftJoin((ga, department, mealUser) => ga.No == mealUser.UserNo)
+ .Where(ga => ga.Id == gainfo.Id)
+ .Select((ga, department, mealUser) => new OrderResultResponse
+ {
+ UserCode = ga.Code,
+ UserName = ga.Name,
+ DepartmentNo = ga.DepartmentNo,
+ DepartmentName = department.Name,
+ Balance = mealUser.Balance
+ })
+ .SingleAsync();
+ }
+
+ ///
+ /// 消费
+ ///
+ ///
+ ///
+ ///
+ private async Task ConsumeAsync(ConsumeRequest request, GainfoEntity gainfo)
{
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();
registry.ThrowIfNull("设备尚未注册");
-
var businessPlace = await _dbContext.Queryable().Where(x => x.Code == registry.BusinessPlaceCode).FirstAsync();
businessPlace.ThrowIfNull("营业点尚未设置");
- var shifts = await _dbContext.Queryable().Where(x => x.BusinessPlaceCode == registry.BusinessPlaceCode).ToListAsync();
- //todo
+ //获取当前消费餐次
+ var shifts = await _dbContext.Queryable().Where(x => x.BusinessPlaceCode == businessPlace.Code).ToListAsync();
+ //todo
var shift = shifts.FirstOrDefault(x => new TimePeriod()
{
Start = x.Start,
- End = x.End,
+ End = x.End
}.IsPresent1(request.CostDateTime));
- //根据档案号
- var canteenUser = await _dbContext.Queryable()
- .Where(x => x.UserNo == request.UserUniqueNo || x.UserCode == request.UserUniqueNo)
- .FirstAsync();
-
- canteenUser.ThrowIfNull($"{request.DeviceUniqueNo}不存在,无法就餐");
-
- var gafinfo = await _dbContext.Queryable()
- .Where(x => x.No == canteenUser.UserNo)
- .FirstAsync();
-
- var settings = await _canteenSettingService.GetUserSettingAsync(gafinfo.No);
+ var settings = await _canteenSettingService.GetUserSettingAsync(request.UserUniqueNo);
var switchTime = GetSetting(settings, CanteenSettingItemEnumType.BusinessSwitchTime);
- //金额处理
- request.Amount = request.Type == BalanceRecordTypeEnumType.In ? Math.Abs(request.Amount) : -Math.Abs(request.Amount);
var shiftTimePeriod = new TimePeriod()
{
@@ -82,7 +117,7 @@ public class OrderService : IOrderService
End = shift?.End
};
- //成本日期 todo 优化
+ //计算成本日期 todo 优化
var costDate = DateTime.Now;
if (shift == null)
{
@@ -106,136 +141,141 @@ public class OrderService : IOrderService
{
RequestJson = request.ToJson(),
ThirdNo = request.ThirdNo,
- Type = request.Type.Value,
- Name = gafinfo.Name,
+ Type = BalanceRecordTypeEnumType.Out,
+ Name = gainfo.Name,
Source = request.Source,
- UserNo = canteenUser.UserNo,
- UserCode = canteenUser.UserCode,
+ UserNo = gainfo.No,
+ UserCode = gainfo.Code,
Amount = request.Amount,
BusinessPlaceCode = businessPlace.Code,
BusinessShiftCode = shift?.Code,
CostDate = costDate.Date,
- CostId = canteenUser.CostId,
- DepartmentNo = gafinfo.DepartmentNo,
- DeviceInfo = device.Code.ToString(),
+ CostId = gainfo.CostId,
+ DepartmentNo = gainfo.DepartmentNo,
+ DeviceInfo = request.DeviceUniqueNo,
No = "O" + SnowFlakeHelper.Instance.NextId(),
SubsidiesFromMonth = DateTime.Now.ToString("yyyyMM"),
IsOffline = request.IsOffline,
IsCostCrossTenant = GetSetting(settings, CanteenSettingItemEnumType.AllowCrossTenant),
- OriginTenantId = canteenUser.TenantId,//人员可能跨基地消费
+ OriginTenantId = gainfo.Werks,//人员可能跨基地消费
//餐别异常处理
Status = shift == null ? BalanceRecordStatusEnumType.Doubtful : BalanceRecordStatusEnumType.Valid,
- OrderStatus = CanteenOrderStatusEnumType.Wait,
- //设备才能标识当前消费的基地
- TenantId = device.TenantId,
- //默认为admin
- CreatedBy = 1,
- CreateTime = DateTime.Now,
- ModifiedBy = 1,
- ModifiedTime = DateTime.Now,
+ OrderStatus = CanteenOrderStatusEnumType.Wait,
+
+ CostDateTime = request.CostDateTime,
+
+ //标识当前消费的基地
+ TenantId = businessPlace.TenantId,
};
- var id = await _dbContext.InsertReturnIdentityAsync(order);
- var result = await _dbContext.UseTransactionAsync(async () =>
+ var orderId = await _dbContext.InsertReturnIdentityAsync(order);
+ //await _dbContext.Client.Ado.BeginTranAsync();
+ try
{
- try
- {
- var r = await GenerateChargeRecordAsync(id, settings, shifts, request.CostDateTime);
- return r;
- }
- catch (Exception)
- {
- throw;
- }
- finally
- {
- //订单消费成功
- order.OrderStatus = CanteenOrderStatusEnumType.Successful;
- await _dbContext.UpdateAsync(order);
- }
- });
+ await GenerateConsumeRecordAsync(orderId, settings, shifts, request.CostDateTime);
+ order.OrderStatus = CanteenOrderStatusEnumType.Successful;
- if (!result.IsSuccess)
- {
- throw new UserFriendlyException(result.ErrorMessage);
+ //await _dbContext.Client.Ado.CommitTranAsync();
}
-
- return result.Data;
- }
-
- public async Task GenerateChargeRecordAsync(long orderId,
- Dictionary settings,
- List shifts,
- DateTime costDateTime)
- {
- var order = await _dbContext.Queryable().Where(x => x.Id == orderId).FirstAsync();
-
- //校验
- await Verify(settings, shifts, costDateTime, order);
-
-
- return await ContinueUpdateAsync(async () =>
+ catch (Exception)
{
- var canteenUser = await _dbContext.Queryable().Where(x => x.UserNo == order.UserNo).FirstAsync();
- //金额+-
- canteenUser.Balance += order.Amount;
-
- if (order.Type == BalanceRecordTypeEnumType.Out)
- {
- if (canteenUser.Balance < 0)
- {
- throw new UserFriendlyException("余额不足,无法消费");
- }
- }
-
- 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("更新版本冲突");
-
- //写入消费记录
- var balanceRecord = order.Adapt();
- await _dbContext.InsertAsync(balanceRecord);
-
- return await _dbContext.Queryable()
- .LeftJoin((ga, department) => ga.DepartmentNo == department.No)
- .LeftJoin((ga, department, mealUser) => ga.No == mealUser.UserNo)
- .Select((ga, department, mealUser) => new OrderConsumeResponse
- {
- UserCode = ga.Code,
- UserName = ga.Name,
- DepartmentNo = ga.DepartmentNo,
- DepartmentName = department.Name,
- Balance = mealUser.Balance
- })
- .FirstAsync();
- }, 5);
+ order.OrderStatus = CanteenOrderStatusEnumType.Failure;
+ //await _dbContext.Client.Ado.RollbackTranAsync();
+ throw;
+ }
+ finally
+ {
+ await _dbContext.UpdateAsync(order);
+ }
}
+ ///
+ /// 充值
+ ///
+ ///
+ ///
+ ///
+ private async Task RechargeAsync(RechargeRequest request, GainfoEntity gainfo)
+ {
+ var settings = await _canteenSettingService.GetUserSettingAsync(request.UserUniqueNo);
+
+ var order = new CanteenOrderEntity
+ {
+ RequestJson = request.ToJson(),
+ ThirdNo = request.ThirdNo,
+ Type = BalanceRecordTypeEnumType.Out,
+ Name = gainfo.Name,
+ Source = request.Source,
+ UserNo = gainfo.No,
+ UserCode = gainfo.Code,
+ Amount = request.Amount,
+ BusinessPlaceCode = Guid.Empty,
+ BusinessShiftCode = null,
+ CostDate = DateTime.Now.Date,
+ CostId = gainfo.CostId,
+ DepartmentNo = gainfo.DepartmentNo,
+ DeviceInfo = string.Empty,
+
+ No = "O" + SnowFlakeHelper.Instance.NextId(),
+ SubsidiesFromMonth = DateTime.Now.ToString("yyyyMM"),
+ IsOffline = false,
+ IsCostCrossTenant = GetSetting(settings, CanteenSettingItemEnumType.AllowCrossTenant),
+
+ OriginTenantId = gainfo.Werks,//人员可能跨基地消费
+
+ Status = BalanceRecordStatusEnumType.Valid,
+
+ OrderStatus = CanteenOrderStatusEnumType.Wait,
+
+ CostDateTime = request.CostDateTime,
+
+ //标识当前消费的基地
+ TenantId = gainfo.Werks,
+ };
+
+ var orderId = await _dbContext.InsertReturnIdentityAsync(order);
+ try
+ {
+ await GenerateRechargeRecordAsync(orderId);
+ order.OrderStatus = CanteenOrderStatusEnumType.Successful;
+ }
+ catch (Exception)
+ {
+ order.OrderStatus = CanteenOrderStatusEnumType.Failure;
+ throw;
+ }
+ finally
+ {
+ await _dbContext.UpdateAsync(order);
+ }
+ }
+
+
+
+
//******************************************************* help methods ************************************************************/
+
///
- /// 设备并发更新
+ /// 设备并发更新 需要抛出VersionExceptions
///
///
///
- ///
+ /// 并发冲突处理次数
///
///
- private async Task ContinueUpdateAsync(Func> func, int retry)
+ private async Task ContinueUpdateAsync(Func func, int retry)
{
for (int i = 0; i < retry; i++)
{
try
{
- return await func();
+ await func();
+ return;
}
catch (Exception ex) when (ex is VersionExceptions)
{
@@ -247,7 +287,7 @@ public class OrderService : IOrderService
}
}
- throw new UserFriendlyException("消费失败,请重试");
+ throw new UserFriendlyException("操作失败,请重试");
}
@@ -270,7 +310,6 @@ public class OrderService : IOrderService
}
-
///
/// 验证参数
///
@@ -342,4 +381,80 @@ public class OrderService : IOrderService
}
}
}
+
+
+ ///
+ /// 生成消费记录
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task GenerateRechargeRecordAsync(long orderId)
+ {
+ 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();
+ //金额+-
+ canteenUser.Balance += order.Amount;
+
+ 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("更新版本冲突");
+
+ //写入记录
+ var balanceRecord = order.Adapt();
+ await _dbContext.InsertAsync(balanceRecord);
+
+ }, 5);
+ }
+
+ ///
+ /// 生成充值记录
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task GenerateConsumeRecordAsync(long orderId,
+ Dictionary settings,
+ List shifts,
+ DateTime costDateTime)
+ {
+ var order = await _dbContext.Queryable().Where(x => x.Id == orderId).FirstAsync();
+ //校验
+ await Verify(settings, shifts, costDateTime, order);
+
+ await ContinueUpdateAsync(async () =>
+ {
+ var canteenUser = await _dbContext.Queryable().Where(x => x.UserNo == order.UserNo).FirstAsync();
+ //金额+-
+ canteenUser.Balance += order.Amount;
+ if (canteenUser.Balance < 0)
+ {
+ throw new UserFriendlyException("余额不足,无法消费");
+ }
+
+ 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("更新版本冲突");
+
+ //写入记录
+ var balanceRecord = order.Adapt();
+ await _dbContext.InsertAsync(balanceRecord);
+ }, 5);
+ }
}