refactor(config): 重构配置管理并优化翻译功能
- 移除 @Component 注解,改用 @EnableConfigurationProperties 在启动类中启用配置 - 将PingPong支付配置从主配置文件移至开发环境配置文件 - 添加PayPal支付配置和百度翻译配置到开发环境 - 将商品和SKU名称翻译逻辑从查询时移至创建时,提高性能 - 移除运行时翻译方法,改为数据库中存储已翻译内容 - 标记PaymentController为过时,系统已切换到PayPal支付 - 优化pom.xml配置,添加classifier属性
This commit is contained in:
@@ -1,43 +0,0 @@
|
||||
CREATE TABLE `customer_order` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`order_no` VARCHAR(64) NOT NULL UNIQUE COMMENT '订单号(全局唯一)',
|
||||
`product_id` BIGINT NOT NULL COMMENT '商品ID',
|
||||
`product_name` VARCHAR(500) NOT NULL COMMENT '商品名称',
|
||||
`sku_id` BIGINT NOT NULL COMMENT 'SKU ID',
|
||||
`sku_name` VARCHAR(500) NOT NULL COMMENT 'SKU名称/描述',
|
||||
`quantity` INT NOT NULL COMMENT '购买数量',
|
||||
`unit_price` DECIMAL(10, 2) NOT NULL COMMENT '单价',
|
||||
`total_amount` DECIMAL(10, 2) NOT NULL COMMENT '订单总金额',
|
||||
`currency` VARCHAR(3) NOT NULL COMMENT '货币代码',
|
||||
`status` VARCHAR(20) NOT NULL DEFAULT 'PENDING' COMMENT '订单状态:PENDING-待支付,PAID-已支付,SHIPPED-已发货,COMPLETED-已完成,CANCELLED-已取消',
|
||||
|
||||
-- 客户信息
|
||||
`customer_name` VARCHAR(100) NOT NULL COMMENT '客户姓名',
|
||||
`customer_phone` VARCHAR(20) NOT NULL COMMENT '客户电话',
|
||||
`customer_email` VARCHAR(100) COMMENT '客户邮箱',
|
||||
|
||||
-- 收货地址
|
||||
`shipping_name` VARCHAR(100) NOT NULL COMMENT '收货人姓名',
|
||||
`shipping_phone` VARCHAR(20) NOT NULL COMMENT '收货人电话',
|
||||
`shipping_country` VARCHAR(50) NOT NULL COMMENT '收货国家',
|
||||
`shipping_state` VARCHAR(50) COMMENT '收货州/省',
|
||||
`shipping_city` VARCHAR(50) NOT NULL COMMENT '收货城市',
|
||||
`shipping_street` VARCHAR(200) NOT NULL COMMENT '收货街道地址',
|
||||
`shipping_postcode` VARCHAR(20) COMMENT '收货邮编',
|
||||
|
||||
-- 支付信息
|
||||
`payment_order_id` BIGINT COMMENT '关联的支付订单ID',
|
||||
`payment_status` VARCHAR(20) DEFAULT 'UNPAID' COMMENT '支付状态:UNPAID-未支付,PAID-已支付,FAILED-支付失败',
|
||||
|
||||
-- 备注
|
||||
`remark` VARCHAR(500) COMMENT '订单备注',
|
||||
|
||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_order_no` (`order_no`),
|
||||
KEY `idx_product_id` (`product_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_create_time` (`create_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='客户订单表';
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<classifier>boot</classifier>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
||||
@@ -2,13 +2,12 @@ package com.mtkj.mtpay.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 阿里云OSS配置属性
|
||||
* 注意:不使用 @Component,而是通过 @EnableConfigurationProperties 在启动类中启用
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "aliyun.oss")
|
||||
public class AliyunOSSProperties {
|
||||
|
||||
|
||||
@@ -2,13 +2,12 @@ package com.mtkj.mtpay.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* PingPong支付配置属性
|
||||
* 注意:不使用 @Component,而是通过 @EnableConfigurationProperties 在启动类中启用
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "pingpong")
|
||||
public class PingPongProperties {
|
||||
|
||||
|
||||
@@ -16,11 +16,15 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* 支付控制器
|
||||
* 支付控制器(PingPong支付)
|
||||
*
|
||||
* @deprecated 系统已切换到 PayPal 支付,此控制器保留以备将来需要时使用
|
||||
* 如需重新启用,请取消注释 @RestController 和 @RequestMapping 注解
|
||||
*/
|
||||
@Deprecated
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/payment")
|
||||
// @RestController
|
||||
// @RequestMapping("/api/payment")
|
||||
@RequiredArgsConstructor
|
||||
public class PaymentController {
|
||||
|
||||
|
||||
@@ -71,8 +71,30 @@ public class CustomerOrderServiceImpl implements CustomerOrderService {
|
||||
CustomerOrder order = new CustomerOrder();
|
||||
order.setOrderNo(OrderIdGenerator.generateMerchantTransactionId());
|
||||
order.setProductId(request.getProductId());
|
||||
order.setProductName(product.getName());
|
||||
|
||||
// 根据SKU的货币代码翻译商品名称并存入订单表
|
||||
String currency = sku.getCurrency();
|
||||
String translatedProductName = product.getName(); // 默认使用原始名称
|
||||
if (currency != null && !currency.trim().isEmpty()) {
|
||||
try {
|
||||
String targetLanguage = baiduTranslatorUtils.getLanguageByCurrency(currency);
|
||||
log.debug("订单货币: {}, 推断目标语言: {}, 原始商品名称: {}",
|
||||
currency, targetLanguage, product.getName());
|
||||
String translated = baiduTranslatorUtils.getTransResult(product.getName(), targetLanguage);
|
||||
if (translated != null && !translated.equals(product.getName())) {
|
||||
translatedProductName = translated;
|
||||
log.info("商品名称翻译: {} -> {} (货币: {}, 语言: {})",
|
||||
product.getName(), translatedProductName, currency, targetLanguage);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("翻译商品名称失败,使用原始名称,商品ID: {}, 货币: {}",
|
||||
request.getProductId(), currency, e);
|
||||
}
|
||||
}
|
||||
order.setProductName(translatedProductName);
|
||||
|
||||
order.setSkuId(request.getSkuId());
|
||||
// SKU名称已在创建商品时翻译并存入数据库,直接使用即可
|
||||
order.setSkuName(sku.getSku());
|
||||
order.setQuantity(request.getQuantity());
|
||||
order.setUnitPrice(sku.getPrice());
|
||||
@@ -161,8 +183,7 @@ public class CustomerOrderServiceImpl implements CustomerOrderService {
|
||||
// 将JSON特殊字段转换为Map
|
||||
response.setShippingSpecialFields(order.getShippingSpecialFieldsMap());
|
||||
|
||||
// 翻译订单内容(商品名称和SKU名称)
|
||||
translateOrderContent(response);
|
||||
// 注意:商品名称和SKU名称已在创建时翻译并存入数据库,查询时直接返回即可
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -185,8 +206,7 @@ public class CustomerOrderServiceImpl implements CustomerOrderService {
|
||||
// 将JSON特殊字段转换为Map
|
||||
response.setShippingSpecialFields(order.getShippingSpecialFieldsMap());
|
||||
|
||||
// 翻译订单内容(商品名称和SKU名称)
|
||||
translateOrderContent(response);
|
||||
// 注意:商品名称和SKU名称已在创建时翻译并存入数据库,查询时直接返回即可
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -207,8 +227,7 @@ public class CustomerOrderServiceImpl implements CustomerOrderService {
|
||||
// 将JSON特殊字段转换为Map
|
||||
response.setShippingSpecialFields(order.getShippingSpecialFieldsMap());
|
||||
|
||||
// 翻译订单内容(商品名称和SKU名称)
|
||||
translateOrderContent(response);
|
||||
// 注意:商品名称和SKU名称已在创建时翻译并存入数据库,查询时直接返回即可
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -288,47 +307,5 @@ public class CustomerOrderServiceImpl implements CustomerOrderService {
|
||||
log.info("订单状态更新成功,订单号: {}", orderNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译订单内容(商品名称和SKU名称)
|
||||
* 根据订单的货币代码推断目标语言
|
||||
*/
|
||||
private void translateOrderContent(CustomerOrderResponseDTO orderDTO) {
|
||||
try {
|
||||
// 如果没有货币信息,不进行翻译
|
||||
String currency = orderDTO.getCurrency();
|
||||
if (currency == null || currency.trim().isEmpty()) {
|
||||
// 尝试使用支付货币
|
||||
currency = orderDTO.getPaymentCurrency();
|
||||
if (currency == null || currency.trim().isEmpty()) {
|
||||
log.debug("订单货币代码为空,跳过翻译,订单号: {}", orderDTO.getOrderNo());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String targetLanguage = baiduTranslatorUtils.getLanguageByCurrency(currency);
|
||||
log.debug("根据货币代码 {} 推断目标语言: {}, 订单号: {}", currency, targetLanguage, orderDTO.getOrderNo());
|
||||
|
||||
// 翻译商品名称
|
||||
if (orderDTO.getProductName() != null && !orderDTO.getProductName().trim().isEmpty()) {
|
||||
String translatedName = baiduTranslatorUtils.getTransResult(orderDTO.getProductName(), targetLanguage);
|
||||
if (translatedName != null && !translatedName.equals(orderDTO.getProductName())) {
|
||||
log.debug("商品名称翻译: {} -> {}, 订单号: {}", orderDTO.getProductName(), translatedName, orderDTO.getOrderNo());
|
||||
orderDTO.setProductName(translatedName);
|
||||
}
|
||||
}
|
||||
|
||||
// 翻译SKU名称
|
||||
if (orderDTO.getSkuName() != null && !orderDTO.getSkuName().trim().isEmpty()) {
|
||||
String translatedSku = baiduTranslatorUtils.getTransResult(orderDTO.getSkuName(), targetLanguage);
|
||||
if (translatedSku != null && !translatedSku.equals(orderDTO.getSkuName())) {
|
||||
log.debug("SKU名称翻译: {} -> {}, 订单号: {}", orderDTO.getSkuName(), translatedSku, orderDTO.getOrderNo());
|
||||
orderDTO.setSkuName(translatedSku);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("翻译订单内容失败,订单号: {}", orderDTO.getOrderNo(), e);
|
||||
// 翻译失败不影响订单数据返回,只记录日志
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ public class ProductServiceImpl implements ProductService {
|
||||
|
||||
// 创建商品
|
||||
MtProduct product = new MtProduct();
|
||||
// 商品名称存储原始名称(不翻译,因为一个商品可能对应多个国家/货币)
|
||||
product.setName(request.getName());
|
||||
product.setPrice(request.getPrice());
|
||||
|
||||
@@ -102,13 +103,34 @@ public class ProductServiceImpl implements ProductService {
|
||||
}
|
||||
log.debug("商品基础信息插入成功,商品ID: {}", product.getId());
|
||||
|
||||
// 创建SKU
|
||||
// 创建SKU(在存入数据库前完成翻译)
|
||||
if (request.getSkus() != null && !request.getSkus().isEmpty()) {
|
||||
log.debug("开始创建SKU,数量: {}", request.getSkus().size());
|
||||
for (CreateProductRequestDTO.CreateProductSkuDTO skuDTO : request.getSkus()) {
|
||||
MtProductSku sku = new MtProductSku();
|
||||
sku.setProductId(product.getId());
|
||||
sku.setSku(skuDTO.getSku());
|
||||
|
||||
// 根据SKU的货币代码推断目标语言并翻译SKU名称
|
||||
String currency = skuDTO.getCurrency();
|
||||
if (currency != null && !currency.trim().isEmpty()) {
|
||||
String targetLanguage = baiduTranslatorUtils.getLanguageByCurrency(currency);
|
||||
log.debug("SKU货币: {}, 推断目标语言: {}, 原始SKU名称: {}",
|
||||
currency, targetLanguage, skuDTO.getSku());
|
||||
|
||||
// 翻译SKU名称
|
||||
String originalSkuName = skuDTO.getSku();
|
||||
String translatedSkuName = baiduTranslatorUtils.getTransResult(originalSkuName, targetLanguage);
|
||||
if (translatedSkuName != null && !translatedSkuName.equals(originalSkuName)) {
|
||||
log.info("SKU名称翻译: {} -> {} (货币: {}, 语言: {})",
|
||||
originalSkuName, translatedSkuName, currency, targetLanguage);
|
||||
sku.setSku(translatedSkuName); // 存储翻译后的名称
|
||||
} else {
|
||||
sku.setSku(originalSkuName); // 翻译失败或无需翻译,使用原文
|
||||
}
|
||||
} else {
|
||||
sku.setSku(skuDTO.getSku()); // 无货币信息,使用原文
|
||||
}
|
||||
|
||||
sku.setPrice(skuDTO.getPrice());
|
||||
sku.setCurrency(skuDTO.getCurrency());
|
||||
sku.setStock(skuDTO.getStock());
|
||||
@@ -125,7 +147,7 @@ public class ProductServiceImpl implements ProductService {
|
||||
throw new BusinessException(ResultCode.SYSTEM_ERROR, "创建SKU失败");
|
||||
}
|
||||
log.debug("SKU创建成功,商品ID: {}, SKU编码: {}, SKU ID: {}",
|
||||
product.getId(), skuDTO.getSku(), sku.getId());
|
||||
product.getId(), sku.getSku(), sku.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,8 +229,8 @@ public class ProductServiceImpl implements ProductService {
|
||||
|
||||
response.setSkus(skuDTOs);
|
||||
|
||||
// 翻译功能:根据SKU的货币代码推断目标语言并翻译
|
||||
translateProductContent(response);
|
||||
// 注意:商品名称和SKU名称已在创建时翻译并存入数据库,查询时直接返回即可
|
||||
// 如果需要根据当前用户的语言再次翻译,可以在这里添加逻辑
|
||||
|
||||
log.info("获取商品详情成功,商品ID: {}, 商品名称: {}, SKU数量: {}, 主图数量: {}",
|
||||
id, product.getName(), skuDTOs.size(),
|
||||
@@ -314,8 +336,7 @@ public class ProductServiceImpl implements ProductService {
|
||||
}).collect(Collectors.toList());
|
||||
dto.setSkus(skuDTOs);
|
||||
|
||||
// 翻译功能:根据SKU的货币代码推断目标语言并翻译
|
||||
translateProductContent(dto);
|
||||
// 注意:商品名称和SKU名称已在创建时翻译并存入数据库,查询时直接返回即可
|
||||
|
||||
result.add(dto);
|
||||
}
|
||||
@@ -324,58 +345,5 @@ public class ProductServiceImpl implements ProductService {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译商品内容(商品名称和SKU名称)
|
||||
* 根据SKU的货币代码推断目标语言
|
||||
*/
|
||||
private void translateProductContent(ProductResponseDTO productDTO) {
|
||||
try {
|
||||
// 如果没有SKU,不进行翻译
|
||||
if (productDTO.getSkus() == null || productDTO.getSkus().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据第一个SKU的货币代码推断目标语言
|
||||
String firstCurrency = productDTO.getSkus().get(0).getCurrency();
|
||||
if (firstCurrency == null || firstCurrency.trim().isEmpty()) {
|
||||
log.debug("SKU货币代码为空,跳过翻译,商品ID: {}", productDTO.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
String targetLanguage = baiduTranslatorUtils.getLanguageByCurrency(firstCurrency);
|
||||
log.debug("根据货币代码 {} 推断目标语言: {}, 商品ID: {}", firstCurrency, targetLanguage, productDTO.getId());
|
||||
|
||||
// 翻译商品名称
|
||||
if (productDTO.getName() != null && !productDTO.getName().trim().isEmpty()) {
|
||||
String translatedName = baiduTranslatorUtils.getTransResult(productDTO.getName(), targetLanguage);
|
||||
if (translatedName != null && !translatedName.equals(productDTO.getName())) {
|
||||
log.debug("商品名称翻译: {} -> {}, 商品ID: {}", productDTO.getName(), translatedName, productDTO.getId());
|
||||
productDTO.setName(translatedName);
|
||||
}
|
||||
}
|
||||
|
||||
// 翻译每个SKU的名称(sku字段)
|
||||
for (ProductResponseDTO.ProductSkuResponseDTO skuDTO : productDTO.getSkus()) {
|
||||
// 如果SKU的货币与第一个不同,使用该SKU的货币推断语言
|
||||
String skuCurrency = skuDTO.getCurrency();
|
||||
String skuLanguage = targetLanguage;
|
||||
if (skuCurrency != null && !skuCurrency.equals(firstCurrency)) {
|
||||
skuLanguage = baiduTranslatorUtils.getLanguageByCurrency(skuCurrency);
|
||||
}
|
||||
|
||||
// 翻译SKU名称
|
||||
if (skuDTO.getSku() != null && !skuDTO.getSku().trim().isEmpty()) {
|
||||
String translatedSku = baiduTranslatorUtils.getTransResult(skuDTO.getSku(), skuLanguage);
|
||||
if (translatedSku != null && !translatedSku.equals(skuDTO.getSku())) {
|
||||
log.debug("SKU名称翻译: {} -> {}, SKU ID: {}", skuDTO.getSku(), translatedSku, skuDTO.getId());
|
||||
skuDTO.setSku(translatedSku);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("翻译商品内容失败,商品ID: {}", productDTO.getId(), e);
|
||||
// 翻译失败不影响商品数据返回,只记录日志
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user