diff --git a/src/Oms.Application/Dtos/Orders/OrderDownstreamWeightImportInput.cs b/src/Oms.Application/Dtos/Orders/OrderDownstreamWeightImportInput.cs
new file mode 100644
index 0000000..d767903
--- /dev/null
+++ b/src/Oms.Application/Dtos/Orders/OrderDownstreamWeightImportInput.cs
@@ -0,0 +1,14 @@
+using Microsoft.AspNetCore.Http;
+
+namespace Oms.Application.Dtos.Orders;
+
+///
+/// 对账件重尺(downstream)Excel 导入入参。
+///
+public class OrderDownstreamWeightImportInput
+{
+ ///
+ /// Excel 文件。
+ ///
+ public IFormFile File { get; set; } = null!;
+}
diff --git a/src/Oms.Application/Dtos/Orders/OrderDownstreamWeightImportOutput.cs b/src/Oms.Application/Dtos/Orders/OrderDownstreamWeightImportOutput.cs
new file mode 100644
index 0000000..b5eca33
--- /dev/null
+++ b/src/Oms.Application/Dtos/Orders/OrderDownstreamWeightImportOutput.cs
@@ -0,0 +1,25 @@
+namespace Oms.Application.Dtos.Orders;
+
+///
+/// 对账件重尺导入结果。
+///
+public class OrderDownstreamWeightImportOutput
+{
+ public int SuccessCount { get; set; }
+
+ public int FailCount { get; set; }
+
+ public List Failures { get; set; } = [];
+}
+
+///
+/// 导入失败行。
+///
+public class OrderDownstreamWeightImportFailRow
+{
+ public int RowNumber { get; set; }
+
+ public string? WaybillNo { get; set; }
+
+ public string Reason { get; set; } = string.Empty;
+}
diff --git a/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs b/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs
index 4f0296f..7e2245d 100644
--- a/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs
+++ b/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs
@@ -256,11 +256,85 @@ public partial class OrderService
public async Task RerunInboundBillingAsync(OrderActionInput input)
{
var order = await GetOrderOrThrowAsync(input.Id);
+ EnsureReceivableMutable(order);
await ProcessInboundBillingForBatchAsync(order.Id);
order = await GetOrderOrThrowAsync(input.Id);
return (await MapOrderOutputsAsync([order])).First();
}
+ ///
+ /// 下载对账件重尺(downstream)导入模板。导入后只重算应付,不改应收。
+ ///
+ [HttpGet("/order/weight/downstream-import-template")]
+ public async Task DownloadDownstreamWeightImportTemplateAsync()
+ {
+ var bytes = await OrderDownstreamWeightImportHelper.BuildTemplateBytesAsync();
+ return new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+ {
+ FileDownloadName = OrderDownstreamWeightImportHelper.TemplateFileName
+ };
+ }
+
+ ///
+ /// 导入对账件重尺:写入 Type=downstream,锁定当前渠道重算应付;不改应收。
+ ///
+ [HttpPost("/order/weight/downstream-import")]
+ public async Task ImportDownstreamWeightsAsync(
+ [FromForm] OrderDownstreamWeightImportInput input)
+ {
+ if (input.File == null || input.File.Length == 0)
+ {
+ throw new BusinessException("请上传 Excel 文件");
+ }
+
+ await using var stream = input.File.OpenReadStream();
+ List<(int RowNumber, OrderDownstreamWeightImportRow Row)> parsedRows;
+ try
+ {
+ parsedRows = await OrderDownstreamWeightImportHelper.ParseImportRowsAsync(stream);
+ }
+ catch (Exception ex)
+ {
+ throw new BusinessException($"Excel 解析失败:{ex.Message}");
+ }
+
+ if (parsedRows.Count == 0)
+ {
+ throw new BusinessException("Excel 中无有效数据行");
+ }
+
+ if (parsedRows.Count > OrderDownstreamWeightImportHelper.MaxRows)
+ {
+ throw new BusinessException(
+ $"单次最多导入 {OrderDownstreamWeightImportHelper.MaxRows} 行,当前 {parsedRows.Count} 行");
+ }
+
+ var output = new OrderDownstreamWeightImportOutput();
+ foreach (var (rowNumber, row) in parsedRows)
+ {
+ try
+ {
+ OrderDownstreamWeightImportHelper.ValidateRow(row);
+ await ApplyDownstreamWeightAndRecalculatePayableAsync(row);
+ output.SuccessCount++;
+ }
+ catch (Exception ex)
+ {
+ output.FailCount++;
+ output.Failures.Add(new OrderDownstreamWeightImportFailRow
+ {
+ RowNumber = rowNumber,
+ WaybillNo = row.WaybillNo,
+ Reason = ex is BusinessException or InvalidOperationException
+ ? ex.Message
+ : $"导入失败:{ex.Message}"
+ });
+ }
+ }
+
+ return output;
+ }
+
///
/// 查询排货过程:优先返回快照;无快照或 live=true 时按当前规则现算(不落库)。
///
@@ -701,7 +775,121 @@ public partial class OrderService
private async Task RecalculatePayableCoreAsync(Order order)
{
- await ReallocateCoreAsync(order, scheme: null, serviceChannelId: null, enforceReallocateGate: false);
+ // 已有渠道时锁定渠道只重算金额,避免「重算应付」误换渠道清下游单号。
+ await ReallocateCoreAsync(
+ order,
+ scheme: null,
+ serviceChannelId: null,
+ enforceReallocateGate: false,
+ lockCurrentChannel: true);
+ }
+
+ ///
+ /// 写入对账件重尺并锁定当前渠道重算应付(不改应收)。
+ ///
+ private async Task ApplyDownstreamWeightAndRecalculatePayableAsync(OrderDownstreamWeightImportRow row)
+ {
+ var order = await OrderRepository.GetByWaybillNoAsync(row.WaybillNo!.Trim());
+ if (order == null)
+ {
+ throw new BusinessException("未找到对应订单,请检查单号");
+ }
+
+ if (string.IsNullOrWhiteSpace(order.ChannelCode))
+ {
+ throw new BusinessException("订单未确认服务渠道,无法按对账重量重算应付");
+ }
+
+ if (string.IsNullOrWhiteSpace(order.ProductCode))
+ {
+ throw new BusinessException("订单未绑定销售产品,无法重算应付");
+ }
+
+ var product = await SalesProductRepository.GetByProductCodeAsync(order.ProductCode.Trim());
+ if (product == null)
+ {
+ throw new BusinessException("销售产品不存在");
+ }
+
+ var weights = (await OrderRepository.GetWeightsByOrderIdsAsync([order.Id]))
+ .OrderBy(x => x.Id)
+ .ToList();
+ var downstream = weights.FirstOrDefault(x =>
+ string.Equals(x.Type, OrderWeightTypeCodes.Downstream, StringComparison.OrdinalIgnoreCase));
+ if (downstream == null)
+ {
+ throw new BusinessException("订单缺少下游件重尺记录");
+ }
+
+ // 尺寸可选:未填则沿用下游已有,仍缺则回落收货→发货→预报。
+ var length = row.Length ?? downstream.Length;
+ var width = row.Width ?? downstream.Width;
+ var height = row.Height ?? downstream.Height;
+ if (length is not > 0 || width is not > 0 || height is not > 0)
+ {
+ FillDimensionsFromFallback(weights, ref length, ref width, ref height);
+ }
+
+ if (length is not > 0 || width is not > 0 || height is not > 0)
+ {
+ throw new BusinessException("件重尺尺寸不完整,请在 Excel 填写长/宽/高,或先完善订单收货/发货尺寸");
+ }
+
+ ApplyMeasuredDimensions(downstream, length.Value, width.Value, height.Value, row.ActualWeight!.Value);
+
+ var snapshotBinding = await ResolveSnapshotBindingFromOrderAsync(product, order);
+ await ApplyChargeableWeightAsync(product, snapshotBinding.Rules, downstream);
+ await OrderRepository.ReplaceWeightsAsync(order.Id, weights);
+
+ await ReallocateCoreAsync(
+ order,
+ scheme: null,
+ serviceChannelId: null,
+ enforceReallocateGate: false,
+ lockCurrentChannel: true,
+ preferDownstreamWeight: true);
+ }
+
+ private static void FillDimensionsFromFallback(
+ IReadOnlyList weights,
+ ref decimal? length,
+ ref decimal? width,
+ ref decimal? height)
+ {
+ foreach (var type in new[]
+ {
+ OrderWeightTypeCodes.Receive,
+ OrderWeightTypeCodes.Ship,
+ OrderWeightTypeCodes.Forecast
+ })
+ {
+ var src = weights.FirstOrDefault(x =>
+ string.Equals(x.Type, type, StringComparison.OrdinalIgnoreCase));
+ if (src == null)
+ {
+ continue;
+ }
+
+ if (length is not > 0)
+ {
+ length = src.Length;
+ }
+
+ if (width is not > 0)
+ {
+ width = src.Width;
+ }
+
+ if (height is not > 0)
+ {
+ height = src.Height;
+ }
+
+ if (length is > 0 && width is > 0 && height is > 0)
+ {
+ return;
+ }
+ }
}
///
@@ -711,7 +899,9 @@ public partial class OrderService
Order order,
string? scheme,
int? serviceChannelId,
- bool enforceReallocateGate = true)
+ bool enforceReallocateGate = true,
+ bool lockCurrentChannel = false,
+ bool preferDownstreamWeight = false)
{
string? schemeOverride = null;
int? forceChannelId = null;
@@ -723,6 +913,18 @@ public partial class OrderService
? AllocationSchemeCodes.Designated
: normalizedScheme;
}
+ else if (lockCurrentChannel && !string.IsNullOrWhiteSpace(order.ChannelCode))
+ {
+ var channel = await ServiceChannelRepository.FirstOrDefaultAsync(x =>
+ x.ChannelCode == order.ChannelCode.Trim());
+ if (channel == null)
+ {
+ throw new BusinessException("订单服务渠道不存在,无法重算应付");
+ }
+
+ forceChannelId = channel.Id;
+ schemeOverride = AllocationSchemeCodes.Designated;
+ }
if (string.IsNullOrWhiteSpace(order.ProductCode))
{
@@ -736,13 +938,18 @@ public partial class OrderService
}
var weights = await OrderRepository.GetWeightsByOrderIdsAsync([order.Id]);
- var weightRow = ResolvePayableWeightRow(order, weights);
+ var weightRow = preferDownstreamWeight
+ ? weights.FirstOrDefault(x =>
+ string.Equals(x.Type, OrderWeightTypeCodes.Downstream, StringComparison.OrdinalIgnoreCase))
+ ?? throw new BusinessException("缺少件重尺类型 downstream")
+ : ResolvePayableWeightRow(order, weights);
if (!weightRow.ChargeableWeight.HasValue || weightRow.ChargeableWeight <= 0)
{
throw new BusinessException("计费重无效,请先完善件重尺");
}
// 重新排货:产品规则/分区与渠道买价均取当前有效发布,避免沿用下单时旧快照。
+ // 对账重算 / 普通重算应付:沿用订单快照绑定(分区等),买价仍由排货评估取当前有效发布。
var snapshotBinding = enforceReallocateGate
? await ResolveSnapshotBindingAsync(product, DateTime.Now)
: await ResolveSnapshotBindingFromOrderAsync(product, order);
@@ -753,6 +960,11 @@ public partial class OrderService
snapshotBinding);
var (_, chargingStage) = ResolveReceivableBillingStage(order);
+ // 对账件重尺导入:费用阶段记 outbound(终稿成本),与入库应收阶段解耦。
+ if (preferDownstreamWeight)
+ {
+ chargingStage = OrderFeeChargingStageCodes.Outbound;
+ }
await ConfirmServiceChannelAndPayableAsync(
order,
@@ -823,11 +1035,12 @@ public partial class OrderService
var weightType = chargingStage switch
{
OrderFeeChargingStageCodes.Inbound => OrderWeightTypeCodes.Receive,
- _ => OrderWeightTypeCodes.Downstream
+ OrderFeeChargingStageCodes.Outbound => OrderWeightTypeCodes.Ship,
+ _ => OrderWeightTypeCodes.Forecast
};
- return weights.FirstOrDefault(x => x.Type == weightType)
- ?? weights.FirstOrDefault(x => x.Type == OrderWeightTypeCodes.Downstream)
+ return weights.FirstOrDefault(x =>
+ string.Equals(x.Type, weightType, StringComparison.OrdinalIgnoreCase))
?? throw new BusinessException($"缺少件重尺类型 {weightType}");
}
diff --git a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
index 974c13e..10f9c5d 100644
--- a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
+++ b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
@@ -774,7 +774,8 @@ public partial class OrderService
{
if (replaceExistingReceivable)
{
- await OrderRepository.DeleteReceivableFeesByStageAsync(order.Id, chargingStage);
+ // 有效应收只保留一套:清空全部阶段后再写入当前阶段,避免预报+入库叠算。
+ await OrderRepository.DeleteReceivableFeesAsync(order.Id);
}
await OrderRepository.UpsertFeesAsync(order.Id, fees);
diff --git a/src/Oms.Application/Shared/OrderDownstreamWeightImportHelper.cs b/src/Oms.Application/Shared/OrderDownstreamWeightImportHelper.cs
new file mode 100644
index 0000000..c16a2f7
--- /dev/null
+++ b/src/Oms.Application/Shared/OrderDownstreamWeightImportHelper.cs
@@ -0,0 +1,251 @@
+using System.Globalization;
+using MiniExcelLibs;
+using Oms.Application.Dtos.Orders;
+
+namespace Oms.Application.Shared;
+
+///
+/// 对账件重尺(downstream)Excel 模板与解析。
+/// 仅写入下游对账重量,触发应付重算;不改应收。
+///
+public static class OrderDownstreamWeightImportHelper
+{
+ public const int MaxRows = 2000;
+
+ private static readonly Dictionary HeaderAliases = new(StringComparer.OrdinalIgnoreCase)
+ {
+ ["运单号"] = "WaybillNo",
+ ["单号"] = "WaybillNo",
+ ["服务商单号"] = "WaybillNo",
+ ["WaybillNo"] = "WaybillNo",
+ ["waybillNo"] = "WaybillNo",
+ ["ServiceNo"] = "WaybillNo",
+ ["serviceNo"] = "WaybillNo",
+ ["长"] = "Length",
+ ["长度"] = "Length",
+ ["Length"] = "Length",
+ ["length"] = "Length",
+ ["宽"] = "Width",
+ ["宽度"] = "Width",
+ ["Width"] = "Width",
+ ["width"] = "Width",
+ ["高"] = "Height",
+ ["高度"] = "Height",
+ ["Height"] = "Height",
+ ["height"] = "Height",
+ ["实重"] = "ActualWeight",
+ ["重量"] = "ActualWeight",
+ ["ActualWeight"] = "ActualWeight",
+ ["actualWeight"] = "ActualWeight",
+ ["Weight"] = "ActualWeight",
+ ["weight"] = "ActualWeight",
+ };
+
+ public static async Task BuildTemplateBytesAsync()
+ {
+ var rows = new List>
+ {
+ new()
+ {
+ ["运单号"] = "OMS202601010001",
+ ["长"] = 30,
+ ["宽"] = 20,
+ ["高"] = 10,
+ ["实重"] = 1.25
+ }
+ };
+
+ await using var stream = new MemoryStream();
+ await MiniExcel.SaveAsAsync(stream, rows);
+ return stream.ToArray();
+ }
+
+ public static string TemplateFileName => "对账件重尺导入模板.xlsx";
+
+ public static async Task> ParseImportRowsAsync(
+ Stream fileStream)
+ {
+ var rows = await MiniExcel.QueryAsync(fileStream, useHeaderRow: true);
+ var result = new List<(int RowNumber, OrderDownstreamWeightImportRow Row)>();
+ var rowNumber = 1;
+
+ foreach (var row in rows)
+ {
+ rowNumber++;
+ if (row is not IDictionary rowDict)
+ {
+ continue;
+ }
+
+ if (IsEmptyRow(rowDict))
+ {
+ continue;
+ }
+
+ try
+ {
+ result.Add((rowNumber, ParseRow(rowDict)));
+ }
+ catch (InvalidOperationException ex)
+ {
+ result.Add((rowNumber, new OrderDownstreamWeightImportRow
+ {
+ WaybillNo = TryPeekWaybillNo(rowDict),
+ ParseError = ex.Message
+ }));
+ }
+ }
+
+ return result;
+ }
+
+ public static void ValidateRow(OrderDownstreamWeightImportRow row)
+ {
+ if (!string.IsNullOrWhiteSpace(row.ParseError))
+ {
+ throw new InvalidOperationException(row.ParseError);
+ }
+
+ if (string.IsNullOrWhiteSpace(row.WaybillNo))
+ {
+ throw new InvalidOperationException("运单号不能为空");
+ }
+
+ row.WaybillNo = row.WaybillNo.Trim();
+ if (row.WaybillNo.Length > 64)
+ {
+ throw new InvalidOperationException("运单号不可超过64个字符");
+ }
+
+ if (!row.ActualWeight.HasValue || row.ActualWeight.Value <= 0)
+ {
+ throw new InvalidOperationException("实重必须大于0");
+ }
+
+ ValidateOptionalDimension(row.Length, "长");
+ ValidateOptionalDimension(row.Width, "宽");
+ ValidateOptionalDimension(row.Height, "高");
+
+ var hasAnyDim = row.Length.HasValue || row.Width.HasValue || row.Height.HasValue;
+ var hasAllDim = row.Length.HasValue && row.Width.HasValue && row.Height.HasValue;
+ if (hasAnyDim && !hasAllDim)
+ {
+ throw new InvalidOperationException("长/宽/高需同时填写或全部留空(留空则沿用订单已有尺寸)");
+ }
+ }
+
+ private static string? TryPeekWaybillNo(IDictionary rowDict)
+ {
+ foreach (var (header, value) in rowDict)
+ {
+ if (string.IsNullOrWhiteSpace(header))
+ {
+ continue;
+ }
+
+ if (HeaderAliases.TryGetValue(header.Trim(), out var field)
+ && string.Equals(field, "WaybillNo", StringComparison.OrdinalIgnoreCase))
+ {
+ return NormalizeCell(value);
+ }
+ }
+
+ return null;
+ }
+
+ private static void ValidateOptionalDimension(decimal? value, string label)
+ {
+ if (!value.HasValue)
+ {
+ return;
+ }
+
+ if (value.Value <= 0)
+ {
+ throw new InvalidOperationException($"{label}必须大于0");
+ }
+ }
+
+ private static OrderDownstreamWeightImportRow ParseRow(IDictionary rowDict)
+ {
+ var mapped = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ foreach (var (header, value) in rowDict)
+ {
+ if (string.IsNullOrWhiteSpace(header))
+ {
+ continue;
+ }
+
+ if (!HeaderAliases.TryGetValue(header.Trim(), out var field))
+ {
+ continue;
+ }
+
+ mapped[field] = NormalizeCell(value);
+ }
+
+ return new OrderDownstreamWeightImportRow
+ {
+ WaybillNo = mapped.GetValueOrDefault("WaybillNo"),
+ Length = ParseDecimal(mapped.GetValueOrDefault("Length")),
+ Width = ParseDecimal(mapped.GetValueOrDefault("Width")),
+ Height = ParseDecimal(mapped.GetValueOrDefault("Height")),
+ ActualWeight = ParseDecimal(mapped.GetValueOrDefault("ActualWeight"))
+ };
+ }
+
+ private static decimal? ParseDecimal(string? text)
+ {
+ if (string.IsNullOrWhiteSpace(text))
+ {
+ return null;
+ }
+
+ if (decimal.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out var value))
+ {
+ return value;
+ }
+
+ if (decimal.TryParse(text, NumberStyles.Any, CultureInfo.GetCultureInfo("zh-CN"), out value))
+ {
+ return value;
+ }
+
+ throw new InvalidOperationException($"数值格式无效:{text}");
+ }
+
+ private static string? NormalizeCell(object? value)
+ {
+ if (value is null)
+ {
+ return null;
+ }
+
+ var text = Convert.ToString(value, CultureInfo.InvariantCulture)?.Trim();
+ return string.IsNullOrWhiteSpace(text) ? null : text;
+ }
+
+ private static bool IsEmptyRow(IDictionary rowDict) =>
+ rowDict.Values.All(value => string.IsNullOrWhiteSpace(NormalizeCell(value)));
+}
+
+///
+/// 对账件重尺导入行。
+///
+public sealed class OrderDownstreamWeightImportRow
+{
+ public string? WaybillNo { get; set; }
+
+ public decimal? Length { get; set; }
+
+ public decimal? Width { get; set; }
+
+ public decimal? Height { get; set; }
+
+ public decimal? ActualWeight { get; set; }
+
+ ///
+ /// Excel 单元格解析错误(校验阶段直接抛出)。
+ ///
+ public string? ParseError { get; set; }
+}
diff --git a/src/Oms.SqlSugarCore/Orders/OrderRepository.cs b/src/Oms.SqlSugarCore/Orders/OrderRepository.cs
index c50a52f..b7d0884 100644
--- a/src/Oms.SqlSugarCore/Orders/OrderRepository.cs
+++ b/src/Oms.SqlSugarCore/Orders/OrderRepository.cs
@@ -996,6 +996,7 @@ public class OrderRepository : OmsSqlSugarRepository, IOrderRepository, I
fee.OrderId = orderId;
var existingList = await db.Queryable()
.Where(x => x.OrderId == orderId
+ && !x.IsDeleted
&& x.Type == fee.Type
&& x.CostItem == fee.CostItem
&& x.ChargingStage == fee.ChargingStage)
@@ -1004,6 +1005,7 @@ public class OrderRepository : OmsSqlSugarRepository, IOrderRepository, I
var existing = existingList.FirstOrDefault();
if (existing == null)
{
+ fee.IsDeleted = false;
await db.Insertable(fee).ExecuteCommandAsync(cancellationToken);
continue;
}
@@ -1013,6 +1015,7 @@ public class OrderRepository : OmsSqlSugarRepository, IOrderRepository, I
existing.PriceNo = fee.PriceNo;
existing.PriceEffectiveTime = fee.PriceEffectiveTime;
existing.DownstreamProvider = fee.DownstreamProvider;
+ existing.IsDeleted = false;
existing.UpdateTime = DateTime.Now;
await db.Updateable(existing).ExecuteCommandAsync(cancellationToken);
}
@@ -1021,36 +1024,46 @@ public class OrderRepository : OmsSqlSugarRepository, IOrderRepository, I
public async Task DeleteReceivableFeesAsync(int orderId, CancellationToken cancellationToken = default)
{
var db = await GetDbContextAsync(cancellationToken);
- await db.Deleteable()
- .Where(x => x.OrderId == orderId && x.Type == OrderFeeTypeCodes.Receivable)
+ await db.Updateable()
+ .SetColumns(x => new OrderFee { IsDeleted = true, UpdateTime = DateTime.Now })
+ .Where(x => x.OrderId == orderId
+ && x.Type == OrderFeeTypeCodes.Receivable
+ && !x.IsDeleted)
.ExecuteCommandAsync(cancellationToken);
}
public async Task DeleteReceivableFeesByStageAsync(int orderId, string chargingStage, CancellationToken cancellationToken = default)
{
var db = await GetDbContextAsync(cancellationToken);
- await db.Deleteable()
+ await db.Updateable()
+ .SetColumns(x => new OrderFee { IsDeleted = true, UpdateTime = DateTime.Now })
.Where(x => x.OrderId == orderId
&& x.Type == OrderFeeTypeCodes.Receivable
- && x.ChargingStage == chargingStage)
+ && x.ChargingStage == chargingStage
+ && !x.IsDeleted)
.ExecuteCommandAsync(cancellationToken);
}
public async Task DeletePayableFeesAsync(int orderId, CancellationToken cancellationToken = default)
{
var db = await GetDbContextAsync(cancellationToken);
- await db.Deleteable()
- .Where(x => x.OrderId == orderId && x.Type == OrderFeeTypeCodes.Payable)
+ await db.Updateable()
+ .SetColumns(x => new OrderFee { IsDeleted = true, UpdateTime = DateTime.Now })
+ .Where(x => x.OrderId == orderId
+ && x.Type == OrderFeeTypeCodes.Payable
+ && !x.IsDeleted)
.ExecuteCommandAsync(cancellationToken);
}
public async Task DeletePayableFeesByStageAsync(int orderId, string chargingStage, CancellationToken cancellationToken = default)
{
var db = await GetDbContextAsync(cancellationToken);
- await db.Deleteable()
+ await db.Updateable()
+ .SetColumns(x => new OrderFee { IsDeleted = true, UpdateTime = DateTime.Now })
.Where(x => x.OrderId == orderId
&& x.Type == OrderFeeTypeCodes.Payable
- && x.ChargingStage == chargingStage)
+ && x.ChargingStage == chargingStage
+ && !x.IsDeleted)
.ExecuteCommandAsync(cancellationToken);
}
@@ -1078,7 +1091,7 @@ public class OrderRepository : OmsSqlSugarRepository, IOrderRepository, I
var db = await GetDbContextAsync(cancellationToken);
return await db.Queryable()
- .Where(x => ids.Contains(x.OrderId))
+ .Where(x => ids.Contains(x.OrderId) && !x.IsDeleted)
.ToListAsync(cancellationToken);
}