Merge pull request #1 from xiaoliutral/zzh

fix: 微信注册保存失败提示与订单模板申报字段推导
This commit is contained in:
biybuy 2026-07-11 09:56:06 +08:00 committed by GitHub
commit 7d458cbecd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 81 additions and 23 deletions

View File

@ -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");

View File

@ -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");

View File

@ -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)

View File

@ -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<string, object> sourceValues,
string sourceColumn,

View File

@ -77,9 +77,10 @@ public static class OmsRbacRegistrationGuard
string account,
CancellationToken cancellationToken)
{
// 唯一索引不按 IsDeleted 区分,软删除账号仍会触发 Duplicate entry。
var hit = await rbacDbContext.Database
.SqlQuery<int?>(
$"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<int?>(
$"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;
}

View File

@ -100,7 +100,10 @@ public class WeChatCustomerService(
await OmsRbacRegistrationGuard.EnsureLoginIdentityAvailableAsync(rbacDbContext, phone, email, cancellationToken);
var customerRoleId = await GetCustomerRoleIdOrThrowAsync(cancellationToken);
var user = await userService.CreateAsync(new UserCreateDto
UserDto? user = null;
try
{
user = await userService.CreateAsync(new UserCreateDto
{
Name = customerName,
Account = phone,
@ -110,8 +113,6 @@ public class WeChatCustomerService(
RoleIds = []
});
try
{
await userService.AssignRolesAsync(user.Id, [customerRoleId]);
var userId = await GetRbacUserMapIdOrThrowAsync(user.Id, cancellationToken);
var entity = new Customer
@ -130,8 +131,12 @@ public class WeChatCustomerService(
await customerRepository.InsertAsync(entity);
}
catch (Exception ex)
{
if (user != null)
{
await TryRollbackRbacUserAsync(user.Id);
}
throw ex is BusinessException ? ex : OmsRbacRegistrationGuard.ToSaveBusinessException(ex);
}
}