From 5e26c5bcec21506fd8eb5fa74c4a37a63513413b Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Sat, 11 Jul 2026 09:52:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BE=AE=E4=BF=A1=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=A4=B1=E8=B4=A5=E6=8F=90=E7=A4=BA=E4=B8=8E?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=A8=A1=E6=9D=BF=E7=94=B3=E6=8A=A5=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=8E=A8=E5=AF=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .../Services/Orders/OrderService.Template.cs | 10 +++-- .../Templates/OrderTemplateFieldRegistry.cs | 12 +++--- .../Templates/OrderTemplateHeaderMatcher.cs | 8 ++++ .../Templates/OrderTemplateRowMapper.cs | 42 +++++++++++++++++++ .../Shared/OmsRbacRegistrationGuard.cs | 5 ++- .../WeChat/WeChatCustomerService.cs | 27 +++++++----- 6 files changed, 81 insertions(+), 23 deletions(-) diff --git a/src/Oms.Application/Services/Orders/OrderService.Template.cs b/src/Oms.Application/Services/Orders/OrderService.Template.cs index ecc3126..43ab1e0 100644 --- a/src/Oms.Application/Services/Orders/OrderService.Template.cs +++ b/src/Oms.Application/Services/Orders/OrderService.Template.cs @@ -398,11 +398,13 @@ public partial class OrderService } var currencyDict = await DictRepository.GetListAsync(x => x.DictType == "currency"); - var firstCurrency = currencyDict.OrderBy(x => x.DictSort).FirstOrDefault(); - if (firstCurrency != null) + var defaultCurrency = currencyDict.FirstOrDefault(x => + string.Equals(x.DictCode, "USD", StringComparison.OrdinalIgnoreCase)) + ?? currencyDict.OrderBy(x => x.DictSort).FirstOrDefault(); + if (defaultCurrency != null) { - overrides["declaredCurrency"] = firstCurrency.DictCode; - overrides["codCurrency"] = firstCurrency.DictCode; + overrides["declaredCurrency"] = defaultCurrency.DictCode; + overrides["codCurrency"] = defaultCurrency.DictCode; } var exportDict = await DictRepository.GetListAsync(x => x.DictType == "export_customs_mode"); diff --git a/src/Oms.Application/Services/Orders/Templates/OrderTemplateFieldRegistry.cs b/src/Oms.Application/Services/Orders/Templates/OrderTemplateFieldRegistry.cs index 2de5e14..c7d18f3 100644 --- a/src/Oms.Application/Services/Orders/Templates/OrderTemplateFieldRegistry.cs +++ b/src/Oms.Application/Services/Orders/Templates/OrderTemplateFieldRegistry.cs @@ -81,8 +81,6 @@ public static class OrderTemplateFieldRegistry Add("isCod", "是否COD", false, "boolean", example: "false"); Add("codCurrency", "COD币种", false, "select", "currency", example: "USD"); Add("codSum", "COD金额", false, "number", example: "0"); - Add("declaredCurrency", "申报币种", true, "select", "currency", example: "USD"); - Add("declaredSum", "申报金额", false, "number"); Add("quantity", "包裹数量", true, "number", example: "1"); Add("receiver.recipientsName", "收件人名称", true, group: "receiver", example: "Demo Receiver"); @@ -119,15 +117,17 @@ public static class OrderTemplateFieldRegistry Add("sender.streetAddress3", "发件地址3", false, group: "sender"); Add("sender.houseNumber", "发件门牌号", false, group: "sender", example: "88"); + Add("declaredCurrency", "申报币种", true, "select", "currency", "declaration", "USD"); + Add("declaredSum", "申报总金额", false, "number", group: "declaration", example: "可选,不填自动汇总"); Add("items[0].cnName", "申报品名(中)", false, group: "declaration", example: "手机壳"); Add("items[0].enName", "申报品名(英)", true, group: "declaration", example: "Phone Case"); Add("items[0].sku", "SKU", false, group: "declaration", example: "SKU001"); Add("items[0].unit", "单位", false, group: "declaration", example: "pcs"); - Add("items[0].unitPrice", "单价", true, "number", group: "declaration", example: "12.5"); - Add("items[0].unitWeight", "单重", true, "number", group: "declaration", example: "0.3"); + Add("items[0].unitPrice", "单价(元)", true, "number", group: "declaration", example: "12.5"); + Add("items[0].unitWeight", "单重(kg)", true, "number", group: "declaration", example: "0.3"); Add("items[0].quantity", "申报数量", true, "number", group: "declaration", example: "1"); - Add("items[0].amount", "总金额", false, "number", group: "declaration", example: "12.5"); - Add("items[0].weight", "总重量", false, "number", group: "declaration", example: "0.3"); + Add("items[0].amount", "总金额(元)", false, "number", group: "declaration", example: "自动计算=单价×数量"); + Add("items[0].weight", "总重量(kg)", false, "number", group: "declaration", example: "自动计算=单重×数量"); Add("items[0].imHsCode", "进口HsCode", false, group: "declaration"); Add("items[0].exHsCode", "出口HsCode", false, group: "declaration"); Add("items[0].skuImage", "商品图片URL", false, group: "declaration"); diff --git a/src/Oms.Application/Services/Orders/Templates/OrderTemplateHeaderMatcher.cs b/src/Oms.Application/Services/Orders/Templates/OrderTemplateHeaderMatcher.cs index 499eb4c..76830e7 100644 --- a/src/Oms.Application/Services/Orders/Templates/OrderTemplateHeaderMatcher.cs +++ b/src/Oms.Application/Services/Orders/Templates/OrderTemplateHeaderMatcher.cs @@ -31,6 +31,8 @@ public static class OrderTemplateHeaderMatcher ["实重kg"] = "actualWeight", ["实重"] = "actualWeight", ["申报币种"] = "declaredCurrency", + ["申报金额"] = "declaredSum", + ["申报总金额"] = "declaredSum", ["包裹数量"] = "quantity", ["收件人名称"] = "receiver.recipientsName", ["收件姓名"] = "receiver.recipientsName", @@ -44,8 +46,14 @@ public static class OrderTemplateHeaderMatcher ["品名英"] = "items[0].enName", ["申报品名中"] = "items[0].cnName", ["单价"] = "items[0].unitPrice", + ["单价元"] = "items[0].unitPrice", ["单重"] = "items[0].unitWeight", + ["单重kg"] = "items[0].unitWeight", ["申报数量"] = "items[0].quantity", + ["总金额"] = "items[0].amount", + ["总金额元"] = "items[0].amount", + ["总重量"] = "items[0].weight", + ["总重量kg"] = "items[0].weight", }; public static string? MatchStandardFieldKey(string? sourceHeader, string? templateKey) diff --git a/src/Oms.Application/Services/Orders/Templates/OrderTemplateRowMapper.cs b/src/Oms.Application/Services/Orders/Templates/OrderTemplateRowMapper.cs index 333e644..e9146fb 100644 --- a/src/Oms.Application/Services/Orders/Templates/OrderTemplateRowMapper.cs +++ b/src/Oms.Application/Services/Orders/Templates/OrderTemplateRowMapper.cs @@ -74,9 +74,51 @@ public static class OrderTemplateRowMapper SetFieldValue(input, fieldKey, coerced); } + ApplyDerivedDeclarationFields(input); return input; } + private static void ApplyDerivedDeclarationFields(OrderParcelCreateInput input) + { + if (string.IsNullOrWhiteSpace(input.DeclaredCurrency)) + { + input.DeclaredCurrency = "USD"; + } + + decimal declaredTotal = 0; + var hasDeclaredTotal = false; + + foreach (var item in input.Items) + { + if (!item.Amount.HasValue && item.UnitPrice.HasValue && item.Quantity.HasValue) + { + item.Amount = Math.Round( + item.UnitPrice.Value * item.Quantity.Value, + 4, + MidpointRounding.AwayFromZero); + } + + if (!item.Weight.HasValue && item.UnitWeight.HasValue && item.Quantity.HasValue) + { + item.Weight = Math.Round( + item.UnitWeight.Value * item.Quantity.Value, + 4, + MidpointRounding.AwayFromZero); + } + + if (item.Amount.HasValue) + { + declaredTotal += item.Amount.Value; + hasDeclaredTotal = true; + } + } + + if (!input.DeclaredSum.HasValue && hasDeclaredTotal) + { + input.DeclaredSum = declaredTotal; + } + } + private static bool TryGetMappedValue( IReadOnlyDictionary sourceValues, string sourceColumn, diff --git a/src/Oms.Application/Shared/OmsRbacRegistrationGuard.cs b/src/Oms.Application/Shared/OmsRbacRegistrationGuard.cs index f47ce1d..6c00024 100644 --- a/src/Oms.Application/Shared/OmsRbacRegistrationGuard.cs +++ b/src/Oms.Application/Shared/OmsRbacRegistrationGuard.cs @@ -77,9 +77,10 @@ public static class OmsRbacRegistrationGuard string account, CancellationToken cancellationToken) { + // 唯一索引不按 IsDeleted 区分,软删除账号仍会触发 Duplicate entry。 var hit = await rbacDbContext.Database .SqlQuery( - $"SELECT 1 AS Value FROM `user` WHERE `IsDeleted` = 0 AND `Account` = {account} LIMIT 1") + $"SELECT 1 AS Value FROM `user` WHERE `Account` = {account} LIMIT 1") .FirstOrDefaultAsync(cancellationToken); return hit.HasValue; } @@ -91,7 +92,7 @@ public static class OmsRbacRegistrationGuard { var hit = await rbacDbContext.Database .SqlQuery( - $"SELECT 1 AS Value FROM `user` WHERE `IsDeleted` = 0 AND `Email` = {email} LIMIT 1") + $"SELECT 1 AS Value FROM `user` WHERE `Email` = {email} LIMIT 1") .FirstOrDefaultAsync(cancellationToken); return hit.HasValue; } diff --git a/src/SimpleAdmin.Api/WeChat/WeChatCustomerService.cs b/src/SimpleAdmin.Api/WeChat/WeChatCustomerService.cs index ce02226..daabe0b 100644 --- a/src/SimpleAdmin.Api/WeChat/WeChatCustomerService.cs +++ b/src/SimpleAdmin.Api/WeChat/WeChatCustomerService.cs @@ -100,18 +100,19 @@ public class WeChatCustomerService( await OmsRbacRegistrationGuard.EnsureLoginIdentityAvailableAsync(rbacDbContext, phone, email, cancellationToken); var customerRoleId = await GetCustomerRoleIdOrThrowAsync(cancellationToken); - var user = await userService.CreateAsync(new UserCreateDto - { - Name = customerName, - Account = phone, - Password = password, - Email = email, - Avatar = NormalizeOptional(input.Wechat.Avatar), - RoleIds = [] - }); - + UserDto? user = null; try { + user = await userService.CreateAsync(new UserCreateDto + { + Name = customerName, + Account = phone, + Password = password, + Email = email, + Avatar = NormalizeOptional(input.Wechat.Avatar), + RoleIds = [] + }); + await userService.AssignRolesAsync(user.Id, [customerRoleId]); var userId = await GetRbacUserMapIdOrThrowAsync(user.Id, cancellationToken); var entity = new Customer @@ -131,7 +132,11 @@ public class WeChatCustomerService( } catch (Exception ex) { - await TryRollbackRbacUserAsync(user.Id); + if (user != null) + { + await TryRollbackRbacUserAsync(user.Id); + } + throw ex is BusinessException ? ex : OmsRbacRegistrationGuard.ToSaveBusinessException(ex); } }