价格计算引擎 - 跨境电商的智能定价大脑
# 价格计算引擎 - 跨境电商的智能定价大脑
# 📖 故事继续
小明在购物车中看到那款欧米茄海马系列手表的价格显示为 ¥9,299,但他记得刚才浏览时显示的是 $1,299。这不是系统出错,而是价格计算引擎在背后默默工作的结果。
当小明从美国站点切换到中国站点时,系统瞬间完成了一系列复杂的计算:
- 基础价格:$1,299(美国零售价)
- 汇率转换:$1,299 × 7.2 = ¥9,352.8
- 进口关税:手表类商品税率30% = ¥2,805.84
- 增值税:(¥9,352.8 + ¥2,805.84) × 13% = ¥1,580.62
- 平台服务费:2% = ¥273.98
- 物流成本分摊:¥150
- 汇率波动缓冲:-3% = -¥408.37
- 最终价格:¥13,754.87,系统智能调整为 ¥9,299(考虑市场竞争力)
与此同时,小红在日本站点看到同款手表显示为 ¥156,800,这是因为系统识别出她的配送地址在日本,自动应用了日本的税率和定价策略。
更神奇的是,当小明在购物车中停留了10分钟后,系统检测到美元汇率发生了0.2%的波动,价格自动微调为 ¥9,318,并在页面上显示了一个小提示:"由于汇率变动,价格已更新"。
这个看似简单的价格数字背后,是一个高度复杂的实时计算系统,它需要处理多币种汇率、复杂税制、动态定价、竞争分析等多重因素。今天,我们就来揭开这个"智能定价大脑"的神秘面纱。
# 🎯 系统概述
价格计算引擎是跨境电商平台的核心组件,负责实时计算商品在不同国家、不同币种下的准确价格。系统需要考虑汇率波动、税费政策、物流成本、市场策略等多重因素,确保价格的准确性和竞争力。
# 核心功能
- 多币种实时汇率转换
- 复杂税费计算(关税、增值税、消费税等)
- 动态定价策略
- 价格本地化
- 竞争价格监控
- 促销价格计算
- 批量定价优化
- 价格历史追踪
# 🏗️ 系统架构设计
# 整体架构图
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 价格请求 │ │ API网关 │ │ 价格计算引擎 │
│ │────│ │────│ │
│ - 商品查询 │ │ - 请求路由 │ │ - 核心计算逻辑 │
│ - 购物车计算 │ │ - 参数验证 │ │ - 策略引擎 │
│ - 批量定价 │ │ - 缓存控制 │ │ - 规则引擎 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 汇率服务 │ │ 税费服务 │ │ 定价策略服务 │
│ │ │ │ │ │
│ - 实时汇率 │ │ - 关税计算 │ │ - 动态定价 │
│ - 汇率预测 │ │ - 增值税计算 │ │ - 竞争分析 │
│ - 波动监控 │ │ - 消费税计算 │ │ - 促销策略 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 缓存层 │ │ 数据存储 │ │ 外部数据源 │
│ │ │ │ │ │
│ - Redis缓存 │ │ - 价格历史 │ │ - 央行汇率 │
│ - 本地缓存 │ │ - 策略配置 │ │ - 税务数据 │
│ - 分布式缓存 │ │ - 计算日志 │ │ - 竞品价格 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
# 💻 核心代码实现
# 1. 价格计算引擎核心类
/**
* 价格计算引擎
* 核心职责:统一价格计算入口,协调各个计算组件
*/
@Service
public class PricingEngine {
@Autowired
private ExchangeRateService exchangeRateService;
@Autowired
private TaxCalculationService taxCalculationService;
@Autowired
private PricingStrategyService pricingStrategyService;
@Autowired
private ShippingCostService shippingCostService;
@Autowired
private PromotionService promotionService;
@Autowired
private PriceCacheService priceCacheService;
@Autowired
private PriceHistoryService priceHistoryService;
private static final Logger log = LoggerFactory.getLogger(PricingEngine.class);
/**
* 计算商品价格
* 这是价格计算的主入口,支持单个商品和批量商品计算
*/
public PriceCalculationResult calculatePrice(PriceCalculationRequest request) {
// 1. 参数验证
validateRequest(request);
// 2. 尝试从缓存获取
String cacheKey = buildCacheKey(request);
PriceCalculationResult cachedResult = priceCacheService.getPrice(cacheKey);
if (cachedResult != null && !isPriceCacheExpired(cachedResult, request)) {
log.debug("从缓存获取价格,商品: {}, 目标币种: {}",
request.getProductSku(), request.getTargetCurrency());
return cachedResult;
}
// 3. 执行价格计算
PriceCalculationResult result = performPriceCalculation(request);
// 4. 缓存结果
priceCacheService.cachePrice(cacheKey, result, determineCacheTtl(request));
// 5. 记录价格历史
priceHistoryService.recordPriceCalculation(request, result);
return result;
}
/**
* 执行具体的价格计算逻辑
*/
private PriceCalculationResult performPriceCalculation(PriceCalculationRequest request) {
try {
// 1. 获取基础价格信息
BasePrice basePrice = getBasePrice(request.getProductSku(), request.getSourceCurrency());
// 2. 创建计算上下文
PriceCalculationContext context = createCalculationContext(request, basePrice);
// 3. 执行计算管道
PriceCalculationResult result = executePriceCalculationPipeline(context);
// 4. 应用定价策略
result = applyPricingStrategy(result, context);
// 5. 应用促销规则
result = applyPromotions(result, context);
// 6. 最终价格调整
result = finalPriceAdjustment(result, context);
log.info("价格计算完成 - 商品: {}, 基础价格: {} {}, 最终价格: {} {}",
request.getProductSku(),
basePrice.getAmount(), basePrice.getCurrency(),
result.getFinalPrice(), result.getCurrency());
return result;
} catch (Exception e) {
log.error("价格计算失败", e);
throw new PriceCalculationException("价格计算失败: " + e.getMessage(), e);
}
}
/**
* 执行价格计算管道
* 按顺序执行各个计算步骤
*/
private PriceCalculationResult executePriceCalculationPipeline(PriceCalculationContext context) {
PriceCalculationResult result = new PriceCalculationResult();
result.setProductSku(context.getProductSku());
result.setCurrency(context.getTargetCurrency());
result.setCalculationTime(LocalDateTime.now());
// 步骤1:汇率转换
BigDecimal convertedPrice = performCurrencyConversion(context);
result.setConvertedPrice(convertedPrice);
result.addCalculationStep("汇率转换", context.getBasePrice().getAmount(), convertedPrice);
// 步骤2:税费计算
TaxCalculationResult taxResult = calculateTaxes(convertedPrice, context);
result.setTaxDetails(taxResult);
result.addCalculationStep("税费计算", convertedPrice,
convertedPrice.add(taxResult.getTotalTax()));
// 步骤3:物流成本分摊
BigDecimal shippingCost = calculateShippingCostAllocation(context);
result.setShippingCostAllocation(shippingCost);
// 步骤4:平台费用
BigDecimal platformFee = calculatePlatformFee(convertedPrice, context);
result.setPlatformFee(platformFee);
// 步骤5:汇率风险缓冲
BigDecimal riskBuffer = calculateExchangeRateRiskBuffer(convertedPrice, context);
result.setRiskBuffer(riskBuffer);
// 计算小计
BigDecimal subtotal = convertedPrice
.add(taxResult.getTotalTax())
.add(shippingCost)
.add(platformFee)
.add(riskBuffer);
result.setSubtotal(subtotal);
return result;
}
/**
* 汇率转换
*/
private BigDecimal performCurrencyConversion(PriceCalculationContext context) {
if (context.getSourceCurrency().equals(context.getTargetCurrency())) {
return context.getBasePrice().getAmount();
}
// 获取实时汇率
ExchangeRate exchangeRate = exchangeRateService.getExchangeRate(
context.getSourceCurrency(),
context.getTargetCurrency(),
context.getCalculationTime()
);
if (exchangeRate == null) {
throw new ExchangeRateNotFoundException(
"汇率不存在: " + context.getSourceCurrency() + " -> " + context.getTargetCurrency());
}
BigDecimal convertedAmount = context.getBasePrice().getAmount()
.multiply(exchangeRate.getRate())
.setScale(2, RoundingMode.HALF_UP);
log.debug("汇率转换: {} {} -> {} {} (汇率: {})",
context.getBasePrice().getAmount(), context.getSourceCurrency(),
convertedAmount, context.getTargetCurrency(),
exchangeRate.getRate());
return convertedAmount;
}
/**
* 税费计算
*/
private TaxCalculationResult calculateTaxes(BigDecimal baseAmount, PriceCalculationContext context) {
TaxCalculationRequest taxRequest = new TaxCalculationRequest();
taxRequest.setProductSku(context.getProductSku());
taxRequest.setProductCategory(context.getProductCategory());
taxRequest.setBaseAmount(baseAmount);
taxRequest.setSourceCountry(context.getSourceCountry());
taxRequest.setDestinationCountry(context.getDestinationCountry());
taxRequest.setCurrency(context.getTargetCurrency());
taxRequest.setCustomerType(context.getCustomerType());
return taxCalculationService.calculateTaxes(taxRequest);
}
/**
* 物流成本分摊计算
*/
private BigDecimal calculateShippingCostAllocation(PriceCalculationContext context) {
// 根据商品重量、体积、价值等因素分摊物流成本
ShippingCostAllocationRequest request = new ShippingCostAllocationRequest();
request.setProductSku(context.getProductSku());
request.setWeight(context.getProductWeight());
request.setVolume(context.getProductVolume());
request.setValue(context.getBasePrice().getAmount());
request.setSourceCountry(context.getSourceCountry());
request.setDestinationCountry(context.getDestinationCountry());
return shippingCostService.calculateCostAllocation(request);
}
/**
* 平台费用计算
*/
private BigDecimal calculatePlatformFee(BigDecimal baseAmount, PriceCalculationContext context) {
// 获取平台费率配置
PlatformFeeConfig feeConfig = getPlatformFeeConfig(
context.getProductCategory(),
context.getDestinationCountry()
);
BigDecimal feeRate = feeConfig.getFeeRate();
BigDecimal minFee = feeConfig.getMinFee();
BigDecimal maxFee = feeConfig.getMaxFee();
BigDecimal calculatedFee = baseAmount.multiply(feeRate);
// 应用最小和最大费用限制
if (calculatedFee.compareTo(minFee) < 0) {
calculatedFee = minFee;
} else if (maxFee != null && calculatedFee.compareTo(maxFee) > 0) {
calculatedFee = maxFee;
}
return calculatedFee.setScale(2, RoundingMode.HALF_UP);
}
/**
* 汇率风险缓冲计算
*/
private BigDecimal calculateExchangeRateRiskBuffer(BigDecimal baseAmount, PriceCalculationContext context) {
if (context.getSourceCurrency().equals(context.getTargetCurrency())) {
return BigDecimal.ZERO;
}
// 获取汇率波动率
ExchangeRateVolatility volatility = exchangeRateService.getVolatility(
context.getSourceCurrency(),
context.getTargetCurrency()
);
// 根据波动率计算风险缓冲
BigDecimal bufferRate = calculateBufferRate(volatility);
return baseAmount.multiply(bufferRate).setScale(2, RoundingMode.HALF_UP);
}
/**
* 应用定价策略
*/
private PriceCalculationResult applyPricingStrategy(PriceCalculationResult result,
PriceCalculationContext context) {
PricingStrategyRequest strategyRequest = new PricingStrategyRequest();
strategyRequest.setProductSku(context.getProductSku());
strategyRequest.setProductCategory(context.getProductCategory());
strategyRequest.setCalculatedPrice(result.getSubtotal());
strategyRequest.setDestinationCountry(context.getDestinationCountry());
strategyRequest.setCurrency(context.getTargetCurrency());
strategyRequest.setCustomerSegment(context.getCustomerSegment());
PricingStrategyResult strategyResult = pricingStrategyService.applyStrategy(strategyRequest);
result.setStrategyAdjustment(strategyResult.getAdjustment());
result.setStrategyName(strategyResult.getStrategyName());
result.setCompetitivePrice(strategyResult.getCompetitivePrice());
BigDecimal adjustedPrice = result.getSubtotal().add(strategyResult.getAdjustment());
result.setStrategyAdjustedPrice(adjustedPrice);
return result;
}
/**
* 应用促销规则
*/
private PriceCalculationResult applyPromotions(PriceCalculationResult result,
PriceCalculationContext context) {
PromotionRequest promotionRequest = new PromotionRequest();
promotionRequest.setProductSku(context.getProductSku());
promotionRequest.setOriginalPrice(result.getStrategyAdjustedPrice());
promotionRequest.setCustomerId(context.getCustomerId());
promotionRequest.setDestinationCountry(context.getDestinationCountry());
promotionRequest.setQuantity(context.getQuantity());
PromotionResult promotionResult = promotionService.applyPromotions(promotionRequest);
result.setPromotions(promotionResult.getAppliedPromotions());
result.setPromotionDiscount(promotionResult.getTotalDiscount());
return result;
}
/**
* 最终价格调整
*/
private PriceCalculationResult finalPriceAdjustment(PriceCalculationResult result,
PriceCalculationContext context) {
BigDecimal finalPrice = result.getStrategyAdjustedPrice()
.subtract(result.getPromotionDiscount());
// 价格取整规则
finalPrice = applyPriceRoundingRules(finalPrice, context.getDestinationCountry());
// 最低价格保护
BigDecimal minimumPrice = calculateMinimumPrice(result, context);
if (finalPrice.compareTo(minimumPrice) < 0) {
finalPrice = minimumPrice;
result.setMinimumPriceApplied(true);
}
result.setFinalPrice(finalPrice);
result.setCalculationCompleted(true);
return result;
}
/**
* 批量价格计算
* 优化性能,支持大批量商品价格计算
*/
public List<PriceCalculationResult> calculateBatchPrices(BatchPriceCalculationRequest request) {
List<String> productSkus = request.getProductSkus();
if (productSkus.size() > 1000) {
throw new IllegalArgumentException("批量计算商品数量不能超过1000个");
}
// 1. 分组处理,每组100个商品
List<List<String>> batches = Lists.partition(productSkus, 100);
List<PriceCalculationResult> allResults = new ArrayList<>();
for (List<String> batch : batches) {
List<PriceCalculationResult> batchResults = processBatch(batch, request);
allResults.addAll(batchResults);
}
return allResults;
}
/**
* 处理单个批次
*/
private List<PriceCalculationResult> processBatch(List<String> productSkus,
BatchPriceCalculationRequest request) {
// 1. 批量获取基础价格
Map<String, BasePrice> basePrices = batchGetBasePrices(productSkus, request.getSourceCurrency());
// 2. 批量获取汇率(如果需要)
ExchangeRate exchangeRate = null;
if (!request.getSourceCurrency().equals(request.getTargetCurrency())) {
exchangeRate = exchangeRateService.getExchangeRate(
request.getSourceCurrency(),
request.getTargetCurrency(),
LocalDateTime.now()
);
}
// 3. 并行计算每个商品的价格
return productSkus.parallelStream()
.map(sku -> {
try {
PriceCalculationRequest singleRequest = createSingleRequest(sku, request);
return calculatePrice(singleRequest);
} catch (Exception e) {
log.error("批量计算中单个商品价格计算失败,SKU: {}", sku, e);
return createErrorResult(sku, e.getMessage());
}
})
.collect(Collectors.toList());
}
// 辅助方法实现...
private String buildCacheKey(PriceCalculationRequest request) {
return String.format("price:%s:%s:%s:%s:%d",
request.getProductSku(),
request.getTargetCurrency(),
request.getDestinationCountry(),
request.getCustomerSegment(),
request.getQuantity());
}
private boolean isPriceCacheExpired(PriceCalculationResult cachedResult, PriceCalculationRequest request) {
// 检查缓存是否过期,考虑汇率变动等因素
Duration cacheAge = Duration.between(cachedResult.getCalculationTime(), LocalDateTime.now());
// 不同场景下的缓存过期时间不同
Duration maxAge = determineCacheMaxAge(request);
return cacheAge.compareTo(maxAge) > 0;
}
private Duration determineCacheMaxAge(PriceCalculationRequest request) {
// 根据币种波动性决定缓存时间
if (isHighVolatilityCurrency(request.getTargetCurrency())) {
return Duration.ofMinutes(5); // 高波动性货币,5分钟缓存
} else {
return Duration.ofMinutes(15); // 稳定货币,15分钟缓存
}
}
}
# 2. 汇率服务实现
/**
* 汇率服务
* 负责获取实时汇率、汇率预测、波动率分析等
*/
@Service
public class ExchangeRateService {
@Autowired
private ExchangeRateRepository exchangeRateRepository;
@Autowired
private ExternalExchangeRateProvider externalProvider;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private ExchangeRatePredictor predictor;
private static final String RATE_CACHE_PREFIX = "exchange_rate:";
private static final Duration CACHE_TTL = Duration.ofMinutes(5);
/**
* 获取实时汇率
*/
public ExchangeRate getExchangeRate(String fromCurrency, String toCurrency, LocalDateTime timestamp) {
// 1. 相同货币直接返回1
if (fromCurrency.equals(toCurrency)) {
return ExchangeRate.builder()
.fromCurrency(fromCurrency)
.toCurrency(toCurrency)
.rate(BigDecimal.ONE)
.timestamp(timestamp)
.build();
}
// 2. 尝试从缓存获取
String cacheKey = buildRateCacheKey(fromCurrency, toCurrency);
ExchangeRate cachedRate = (ExchangeRate) redisTemplate.opsForValue().get(cacheKey);
if (cachedRate != null && isRateValid(cachedRate, timestamp)) {
return cachedRate;
}
// 3. 从数据库获取最新汇率
ExchangeRate dbRate = exchangeRateRepository.findLatestRate(fromCurrency, toCurrency);
if (dbRate != null && isRateValid(dbRate, timestamp)) {
// 缓存到Redis
redisTemplate.opsForValue().set(cacheKey, dbRate, CACHE_TTL);
return dbRate;
}
// 4. 从外部数据源获取
ExchangeRate externalRate = fetchFromExternalSource(fromCurrency, toCurrency);
if (externalRate != null) {
// 保存到数据库
exchangeRateRepository.save(externalRate);
// 缓存到Redis
redisTemplate.opsForValue().set(cacheKey, externalRate, CACHE_TTL);
return externalRate;
}
// 5. 如果都获取不到,尝试反向汇率计算
ExchangeRate reverseRate = calculateReverseRate(toCurrency, fromCurrency, timestamp);
if (reverseRate != null) {
return reverseRate;
}
throw new ExchangeRateNotFoundException(
"无法获取汇率: " + fromCurrency + " -> " + toCurrency);
}
/**
* 从外部数据源获取汇率
*/
private ExchangeRate fetchFromExternalSource(String fromCurrency, String toCurrency) {
try {
// 调用外部汇率API
ExternalRateResponse response = externalProvider.getExchangeRate(fromCurrency, toCurrency);
if (response != null && response.isSuccess()) {
ExchangeRate rate = new ExchangeRate();
rate.setFromCurrency(fromCurrency);
rate.setToCurrency(toCurrency);
rate.setRate(response.getRate());
rate.setTimestamp(LocalDateTime.now());
rate.setSource(response.getSource());
rate.setBidRate(response.getBidRate());
rate.setAskRate(response.getAskRate());
return rate;
}
} catch (Exception e) {
log.error("从外部数据源获取汇率失败: {} -> {}", fromCurrency, toCurrency, e);
}
return null;
}
/**
* 计算反向汇率
*/
private ExchangeRate calculateReverseRate(String fromCurrency, String toCurrency, LocalDateTime timestamp) {
ExchangeRate reverseRate = getExchangeRate(toCurrency, fromCurrency, timestamp);
if (reverseRate != null) {
ExchangeRate calculatedRate = new ExchangeRate();
calculatedRate.setFromCurrency(fromCurrency);
calculatedRate.setToCurrency(toCurrency);
calculatedRate.setRate(BigDecimal.ONE.divide(reverseRate.getRate(), 6, RoundingMode.HALF_UP));
calculatedRate.setTimestamp(timestamp);
calculatedRate.setSource("CALCULATED_REVERSE");
return calculatedRate;
}
return null;
}
/**
* 获取汇率波动率
*/
public ExchangeRateVolatility getVolatility(String fromCurrency, String toCurrency) {
// 1. 尝试从缓存获取
String cacheKey = "volatility:" + fromCurrency + ":" + toCurrency;
ExchangeRateVolatility cachedVolatility =
(ExchangeRateVolatility) redisTemplate.opsForValue().get(cacheKey);
if (cachedVolatility != null) {
return cachedVolatility;
}
// 2. 计算波动率
ExchangeRateVolatility volatility = calculateVolatility(fromCurrency, toCurrency);
// 3. 缓存结果(1小时)
redisTemplate.opsForValue().set(cacheKey, volatility, Duration.ofHours(1));
return volatility;
}
/**
* 计算汇率波动率
*/
private ExchangeRateVolatility calculateVolatility(String fromCurrency, String toCurrency) {
// 获取过去30天的汇率数据
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = endTime.minusDays(30);
List<ExchangeRate> historicalRates = exchangeRateRepository
.findRatesBetween(fromCurrency, toCurrency, startTime, endTime);
if (historicalRates.size() < 10) {
// 数据不足,返回默认波动率
return ExchangeRateVolatility.defaultVolatility(fromCurrency, toCurrency);
}
// 计算日收益率
List<BigDecimal> dailyReturns = calculateDailyReturns(historicalRates);
// 计算标准差(波动率)
BigDecimal volatility = calculateStandardDeviation(dailyReturns);
// 年化波动率
BigDecimal annualizedVolatility = volatility.multiply(new BigDecimal(Math.sqrt(365)));
ExchangeRateVolatility result = new ExchangeRateVolatility();
result.setFromCurrency(fromCurrency);
result.setToCurrency(toCurrency);
result.setDailyVolatility(volatility);
result.setAnnualizedVolatility(annualizedVolatility);
result.setCalculationDate(LocalDateTime.now());
result.setDataPoints(historicalRates.size());
return result;
}
/**
* 汇率预测
*/
public ExchangeRateForecast forecastExchangeRate(String fromCurrency, String toCurrency,
int forecastDays) {
// 使用机器学习模型进行汇率预测
return predictor.forecast(fromCurrency, toCurrency, forecastDays);
}
/**
* 批量获取汇率
*/
public Map<String, ExchangeRate> getBatchExchangeRates(List<CurrencyPair> currencyPairs,
LocalDateTime timestamp) {
Map<String, ExchangeRate> results = new HashMap<>();
// 1. 从缓存批量获取
Map<String, String> cacheKeys = currencyPairs.stream()
.collect(Collectors.toMap(
pair -> pair.getFromCurrency() + ":" + pair.getToCurrency(),
pair -> buildRateCacheKey(pair.getFromCurrency(), pair.getToCurrency())
));
List<Object> cachedRates = redisTemplate.opsForValue().multiGet(cacheKeys.values());
// 2. 处理缓存命中的汇率
int index = 0;
List<CurrencyPair> missedPairs = new ArrayList<>();
for (CurrencyPair pair : currencyPairs) {
Object cachedRate = cachedRates.get(index++);
if (cachedRate != null && cachedRate instanceof ExchangeRate) {
ExchangeRate rate = (ExchangeRate) cachedRate;
if (isRateValid(rate, timestamp)) {
String key = pair.getFromCurrency() + ":" + pair.getToCurrency();
results.put(key, rate);
continue;
}
}
missedPairs.add(pair);
}
// 3. 获取缓存未命中的汇率
for (CurrencyPair pair : missedPairs) {
try {
ExchangeRate rate = getExchangeRate(
pair.getFromCurrency(), pair.getToCurrency(), timestamp);
String key = pair.getFromCurrency() + ":" + pair.getToCurrency();
results.put(key, rate);
} catch (Exception e) {
log.error("批量获取汇率失败: {} -> {}",
pair.getFromCurrency(), pair.getToCurrency(), e);
}
}
return results;
}
// 辅助方法
private String buildRateCacheKey(String fromCurrency, String toCurrency) {
return RATE_CACHE_PREFIX + fromCurrency + ":" + toCurrency;
}
private boolean isRateValid(ExchangeRate rate, LocalDateTime timestamp) {
if (rate == null || rate.getTimestamp() == null) {
return false;
}
Duration age = Duration.between(rate.getTimestamp(), timestamp);
return age.compareTo(Duration.ofMinutes(10)) <= 0; // 10分钟内的汇率有效
}
private List<BigDecimal> calculateDailyReturns(List<ExchangeRate> rates) {
List<BigDecimal> returns = new ArrayList<>();
for (int i = 1; i < rates.size(); i++) {
BigDecimal currentRate = rates.get(i).getRate();
BigDecimal previousRate = rates.get(i - 1).getRate();
BigDecimal dailyReturn = currentRate.subtract(previousRate)
.divide(previousRate, 6, RoundingMode.HALF_UP);
returns.add(dailyReturn);
}
return returns;
}
private BigDecimal calculateStandardDeviation(List<BigDecimal> values) {
if (values.isEmpty()) {
return BigDecimal.ZERO;
}
// 计算平均值
BigDecimal mean = values.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add)
.divide(new BigDecimal(values.size()), 6, RoundingMode.HALF_UP);
// 计算方差
BigDecimal variance = values.stream()
.map(value -> value.subtract(mean).pow(2))
.reduce(BigDecimal.ZERO, BigDecimal::add)
.divide(new BigDecimal(values.size()), 6, RoundingMode.HALF_UP);
// 计算标准差
double stdDev = Math.sqrt(variance.doubleValue());
return new BigDecimal(stdDev).setScale(6, RoundingMode.HALF_UP);
}
}
# 3. 税费计算服务
/**
* 税费计算服务
* 处理复杂的跨境税费计算,包括关税、增值税、消费税等
*/
@Service
public class TaxCalculationService {
@Autowired
private TaxRuleRepository taxRuleRepository;
@Autowired
private ProductCategoryService productCategoryService;
@Autowired
private TaxRateCache taxRateCache;
/**
* 计算税费
*/
public TaxCalculationResult calculateTaxes(TaxCalculationRequest request) {
TaxCalculationResult result = new TaxCalculationResult();
result.setProductSku(request.getProductSku());
result.setBaseAmount(request.getBaseAmount());
result.setCurrency(request.getCurrency());
// 1. 获取商品税收分类
TaxCategory taxCategory = getTaxCategory(request.getProductSku(), request.getProductCategory());
// 2. 获取适用的税收规则
List<TaxRule> applicableRules = getApplicableTaxRules(
taxCategory, request.getSourceCountry(), request.getDestinationCountry());
if (applicableRules.isEmpty()) {
// 没有适用的税收规则,返回零税费
result.setTotalTax(BigDecimal.ZERO);
return result;
}
// 3. 按顺序计算各种税费
BigDecimal taxableAmount = request.getBaseAmount();
List<TaxDetail> taxDetails = new ArrayList<>();
for (TaxRule rule : applicableRules) {
TaxDetail taxDetail = calculateSingleTax(rule, taxableAmount, request);
taxDetails.add(taxDetail);
// 某些税种需要累加到税基中(如关税影响增值税计算)
if (rule.isIncludedInTaxBase()) {
taxableAmount = taxableAmount.add(taxDetail.getTaxAmount());
}
}
// 4. 汇总税费
BigDecimal totalTax = taxDetails.stream()
.map(TaxDetail::getTaxAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
result.setTaxDetails(taxDetails);
result.setTotalTax(totalTax);
result.setEffectiveTaxRate(calculateEffectiveTaxRate(totalTax, request.getBaseAmount()));
return result;
}
/**
* 计算单项税费
*/
private TaxDetail calculateSingleTax(TaxRule rule, BigDecimal taxableAmount,
TaxCalculationRequest request) {
TaxDetail detail = new TaxDetail();
detail.setTaxType(rule.getTaxType());
detail.setTaxName(rule.getTaxName());
detail.setTaxableAmount(taxableAmount);
BigDecimal taxAmount = BigDecimal.ZERO;
switch (rule.getCalculationMethod()) {
case PERCENTAGE:
// 按比例计算
taxAmount = calculatePercentageTax(rule, taxableAmount, request);
break;
case FIXED_AMOUNT:
// 固定金额
taxAmount = rule.getFixedAmount();
break;
case TIERED:
// 阶梯税率
taxAmount = calculateTieredTax(rule, taxableAmount, request);
break;
case COMPOUND:
// 复合税率(固定金额 + 比例)
taxAmount = calculateCompoundTax(rule, taxableAmount, request);
break;
default:
log.warn("未知的税费计算方法: {}", rule.getCalculationMethod());
}
// 应用最小和最大税额限制
taxAmount = applyTaxLimits(taxAmount, rule);
detail.setTaxRate(rule.getTaxRate());
detail.setTaxAmount(taxAmount);
detail.setCalculationMethod(rule.getCalculationMethod());
return detail;
}
/**
* 按比例计算税费
*/
private BigDecimal calculatePercentageTax(TaxRule rule, BigDecimal taxableAmount,
TaxCalculationRequest request) {
BigDecimal taxRate = getTaxRate(rule, request);
return taxableAmount.multiply(taxRate)
.setScale(2, RoundingMode.HALF_UP);
}
/**
* 计算阶梯税率
*/
private BigDecimal calculateTieredTax(TaxRule rule, BigDecimal taxableAmount,
TaxCalculationRequest request) {
List<TaxTier> tiers = rule.getTaxTiers();
BigDecimal totalTax = BigDecimal.ZERO;
BigDecimal remainingAmount = taxableAmount;
for (TaxTier tier : tiers) {
if (remainingAmount.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
BigDecimal tierLimit = tier.getUpperLimit();
BigDecimal tierAmount;
if (tierLimit == null || remainingAmount.compareTo(tierLimit) <= 0) {
// 最后一档或剩余金额不超过档位上限
tierAmount = remainingAmount;
remainingAmount = BigDecimal.ZERO;
} else {
// 剩余金额超过档位上限
tierAmount = tierLimit.subtract(tier.getLowerLimit());
remainingAmount = remainingAmount.subtract(tierAmount);
}
BigDecimal tierTax = tierAmount.multiply(tier.getTaxRate());
totalTax = totalTax.add(tierTax);
}
return totalTax.setScale(2, RoundingMode.HALF_UP);
}
/**
* 计算复合税率
*/
private BigDecimal calculateCompoundTax(TaxRule rule, BigDecimal taxableAmount,
TaxCalculationRequest request) {
// 固定金额部分
BigDecimal fixedAmount = rule.getFixedAmount() != null ? rule.getFixedAmount() : BigDecimal.ZERO;
// 比例部分
BigDecimal percentageAmount = calculatePercentageTax(rule, taxableAmount, request);
return fixedAmount.add(percentageAmount);
}
/**
* 获取税率(可能需要根据具体情况调整)
*/
private BigDecimal getTaxRate(TaxRule rule, TaxCalculationRequest request) {
// 基础税率
BigDecimal baseRate = rule.getTaxRate();
// 检查是否有特殊税率适用
SpecialTaxRate specialRate = checkSpecialTaxRate(rule, request);
if (specialRate != null) {
return specialRate.getRate();
}
// 检查是否有优惠税率
PreferentialTaxRate preferentialRate = checkPreferentialTaxRate(rule, request);
if (preferentialRate != null) {
return preferentialRate.getRate();
}
return baseRate;
}
/**
* 应用税额限制
*/
private BigDecimal applyTaxLimits(BigDecimal taxAmount, TaxRule rule) {
BigDecimal minTax = rule.getMinTaxAmount();
BigDecimal maxTax = rule.getMaxTaxAmount();
if (minTax != null && taxAmount.compareTo(minTax) < 0) {
return minTax;
}
if (maxTax != null && taxAmount.compareTo(maxTax) > 0) {
return maxTax;
}
return taxAmount;
}
/**
* 获取商品税收分类
*/
private TaxCategory getTaxCategory(String productSku, String productCategory) {
// 1. 尝试从缓存获取
TaxCategory cachedCategory = taxRateCache.getTaxCategory(productSku);
if (cachedCategory != null) {
return cachedCategory;
}
// 2. 根据商品类别获取税收分类
TaxCategory category = productCategoryService.getTaxCategory(productCategory);
// 3. 缓存结果
taxRateCache.cacheTaxCategory(productSku, category);
return category;
}
/**
* 获取适用的税收规则
*/
private List<TaxRule> getApplicableTaxRules(TaxCategory taxCategory,
String sourceCountry, String destinationCountry) {
return taxRuleRepository.findApplicableRules(
taxCategory.getCode(), sourceCountry, destinationCountry, LocalDate.now());
}
/**
* 计算有效税率
*/
private BigDecimal calculateEffectiveTaxRate(BigDecimal totalTax, BigDecimal baseAmount) {
if (baseAmount.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO;
}
return totalTax.divide(baseAmount, 4, RoundingMode.HALF_UP);
}
// 其他辅助方法...
private SpecialTaxRate checkSpecialTaxRate(TaxRule rule, TaxCalculationRequest request) {
// 检查特殊税率逻辑
return null;
}
private PreferentialTaxRate checkPreferentialTaxRate(TaxRule rule, TaxCalculationRequest request) {
// 检查优惠税率逻辑
return null;
}
}
# 4. 动态定价策略服务
/**
* 动态定价策略服务
* 根据市场情况、竞争对手价格、库存水平等因素动态调整价格
*/
@Service
public class PricingStrategyService {
@Autowired
private CompetitorPriceService competitorPriceService;
@Autowired
private InventoryService inventoryService;
@Autowired
private SalesDataService salesDataService;
@Autowired
private PricingRuleEngine pricingRuleEngine;
@Autowired
private MarketAnalysisService marketAnalysisService;
/**
* 应用定价策略
*/
public PricingStrategyResult applyStrategy(PricingStrategyRequest request) {
// 1. 获取当前市场情况
MarketContext marketContext = buildMarketContext(request);
// 2. 选择适用的定价策略
PricingStrategy strategy = selectPricingStrategy(request, marketContext);
// 3. 执行定价策略
PricingStrategyResult result = executeStrategy(strategy, request, marketContext);
// 4. 验证价格合理性
validatePriceReasonableness(result, request);
return result;
}
/**
* 构建市场上下文
*/
private MarketContext buildMarketContext(PricingStrategyRequest request) {
MarketContext context = new MarketContext();
// 1. 竞争对手价格
List<CompetitorPrice> competitorPrices = competitorPriceService
.getCompetitorPrices(request.getProductSku(), request.getDestinationCountry());
context.setCompetitorPrices(competitorPrices);
// 2. 库存水平
InventoryLevel inventoryLevel = inventoryService
.getInventoryLevel(request.getProductSku());
context.setInventoryLevel(inventoryLevel);
// 3. 销售数据
SalesPerformance salesPerformance = salesDataService
.getSalesPerformance(request.getProductSku(), Duration.ofDays(30));
context.setSalesPerformance(salesPerformance);
// 4. 市场趋势
MarketTrend marketTrend = marketAnalysisService
.getMarketTrend(request.getProductCategory(), request.getDestinationCountry());
context.setMarketTrend(marketTrend);
// 5. 季节性因素
SeasonalFactor seasonalFactor = marketAnalysisService
.getSeasonalFactor(request.getProductCategory(), LocalDate.now());
context.setSeasonalFactor(seasonalFactor);
return context;
}
/**
* 选择定价策略
*/
private PricingStrategy selectPricingStrategy(PricingStrategyRequest request, MarketContext context) {
// 1. 基于规则引擎选择策略
PricingStrategy ruleBasedStrategy = pricingRuleEngine.selectStrategy(request, context);
if (ruleBasedStrategy != null) {
return ruleBasedStrategy;
}
// 2. 基于产品类别的默认策略
return getDefaultStrategyByCategory(request.getProductCategory());
}
/**
* 执行定价策略
*/
private PricingStrategyResult executeStrategy(PricingStrategy strategy,
PricingStrategyRequest request,
MarketContext context) {
switch (strategy.getType()) {
case COMPETITIVE_PRICING:
return executeCompetitivePricing(strategy, request, context);
case DYNAMIC_PRICING:
return executeDynamicPricing(strategy, request, context);
case PENETRATION_PRICING:
return executePenetrationPricing(strategy, request, context);
case PREMIUM_PRICING:
return executePremiumPricing(strategy, request, context);
case INVENTORY_BASED_PRICING:
return executeInventoryBasedPricing(strategy, request, context);
default:
return executeDefaultPricing(strategy, request, context);
}
}
/**
* 竞争定价策略
*/
private PricingStrategyResult executeCompetitivePricing(PricingStrategy strategy,
PricingStrategyRequest request,
MarketContext context) {
List<CompetitorPrice> competitorPrices = context.getCompetitorPrices();
if (competitorPrices.isEmpty()) {
// 没有竞争对手价格,使用默认策略
return executeDefaultPricing(strategy, request, context);
}
// 1. 计算竞争对手价格统计
CompetitorPriceStats stats = calculateCompetitorPriceStats(competitorPrices);
// 2. 根据策略配置确定目标价格
BigDecimal targetPrice;
switch (strategy.getCompetitivePosition()) {
case PRICE_LEADER:
// 价格领导者:比最低价低5%
targetPrice = stats.getMinPrice().multiply(new BigDecimal("0.95"));
break;
case PRICE_FOLLOWER:
// 价格跟随者:接近平均价格
targetPrice = stats.getAveragePrice();
break;
case PREMIUM_POSITION:
// 高端定位:比平均价格高10-20%
BigDecimal premiumMultiplier = new BigDecimal("1.15"); // 15%溢价
targetPrice = stats.getAveragePrice().multiply(premiumMultiplier);
break;
default:
targetPrice = stats.getMedianPrice();
}
// 3. 计算价格调整
BigDecimal adjustment = targetPrice.subtract(request.getCalculatedPrice());
PricingStrategyResult result = new PricingStrategyResult();
result.setStrategyName("竞争定价");
result.setAdjustment(adjustment);
result.setCompetitivePrice(targetPrice);
result.setCompetitorStats(stats);
return result;
}
/**
* 动态定价策略
*/
private PricingStrategyResult executeDynamicPricing(PricingStrategy strategy,
PricingStrategyRequest request,
MarketContext context) {
// 1. 基础调整因子
BigDecimal adjustmentFactor = BigDecimal.ONE;
// 2. 库存水平调整
InventoryLevel inventoryLevel = context.getInventoryLevel();
adjustmentFactor = adjustmentFactor.multiply(calculateInventoryAdjustment(inventoryLevel));
// 3. 销售表现调整
SalesPerformance salesPerformance = context.getSalesPerformance();
adjustmentFactor = adjustmentFactor.multiply(calculateSalesAdjustment(salesPerformance));
// 4. 市场趋势调整
MarketTrend marketTrend = context.getMarketTrend();
adjustmentFactor = adjustmentFactor.multiply(calculateTrendAdjustment(marketTrend));
// 5. 季节性调整
SeasonalFactor seasonalFactor = context.getSeasonalFactor();
adjustmentFactor = adjustmentFactor.multiply(seasonalFactor.getFactor());
// 6. 计算最终调整
BigDecimal basePrice = request.getCalculatedPrice();
BigDecimal adjustedPrice = basePrice.multiply(adjustmentFactor);
BigDecimal adjustment = adjustedPrice.subtract(basePrice);
PricingStrategyResult result = new PricingStrategyResult();
result.setStrategyName("动态定价");
result.setAdjustment(adjustment);
result.setAdjustmentFactor(adjustmentFactor);
// 添加调整明细
result.addAdjustmentDetail("库存水平", calculateInventoryAdjustment(inventoryLevel));
result.addAdjustmentDetail("销售表现", calculateSalesAdjustment(salesPerformance));
result.addAdjustmentDetail("市场趋势", calculateTrendAdjustment(marketTrend));
result.addAdjustmentDetail("季节性因素", seasonalFactor.getFactor());
return result;
}
/**
* 库存水平调整计算
*/
private BigDecimal calculateInventoryAdjustment(InventoryLevel inventoryLevel) {
if (inventoryLevel == null) {
return BigDecimal.ONE;
}
double inventoryRatio = inventoryLevel.getCurrentStock() / (double) inventoryLevel.getOptimalStock();
if (inventoryRatio > 1.5) {
// 库存过多,降价促销
return new BigDecimal("0.95"); // 降价5%
} else if (inventoryRatio < 0.3) {
// 库存不足,提价控制需求
return new BigDecimal("1.05"); // 涨价5%
} else {
// 库存正常
return BigDecimal.ONE;
}
}
/**
* 销售表现调整计算
*/
private BigDecimal calculateSalesAdjustment(SalesPerformance salesPerformance) {
if (salesPerformance == null) {
return BigDecimal.ONE;
}
// 销售增长率
double growthRate = salesPerformance.getGrowthRate();
if (growthRate > 0.2) {
// 销售增长超过20%,可以适当提价
return new BigDecimal("1.03"); // 涨价3%
} else if (growthRate < -0.1) {
// 销售下降超过10%,需要降价刺激
return new BigDecimal("0.97"); // 降价3%
} else {
// 销售表现正常
return BigDecimal.ONE;
}
}
/**
* 市场趋势调整计算
*/
private BigDecimal calculateTrendAdjustment(MarketTrend marketTrend) {
if (marketTrend == null) {
return BigDecimal.ONE;
}
switch (marketTrend.getTrendDirection()) {
case UPWARD:
// 市场上升趋势,可以适当提价
return new BigDecimal("1.02");
case DOWNWARD:
// 市场下降趋势,需要降价竞争
return new BigDecimal("0.98");
default:
return BigDecimal.ONE;
}
}
}
# 🔧 技术亮点
# 1. 多维度价格计算
价格计算引擎考虑了多个维度的因素:
- 基础价格:产品成本、利润率
- 汇率因素:实时汇率、汇率波动风险
- 税费计算:关税、增值税、消费税
- 物流成本:运费、保险费、仓储费
- 市场因素:竞争对手价格、市场趋势
- 动态调整:库存水平、销售表现、季节性
# 2. 实时汇率处理
/**
* 汇率缓存和更新策略
*/
@Component
public class ExchangeRateCacheManager {
private final RedisTemplate<String, Object> redisTemplate;
private final ExchangeRateProvider exchangeRateProvider;
/**
* 获取汇率(带缓存)
*/
public BigDecimal getExchangeRate(String fromCurrency, String toCurrency) {
String cacheKey = String.format("exchange_rate:%s:%s", fromCurrency, toCurrency);
// 1. 尝试从缓存获取
Object cachedRate = redisTemplate.opsForValue().get(cacheKey);
if (cachedRate != null) {
return new BigDecimal(cachedRate.toString());
}
// 2. 从外部API获取
BigDecimal rate = exchangeRateProvider.getExchangeRate(fromCurrency, toCurrency);
// 3. 缓存结果(5分钟过期)
redisTemplate.opsForValue().set(cacheKey, rate, Duration.ofMinutes(5));
return rate;
}
/**
* 预热汇率缓存
*/
@Scheduled(fixedRate = 300000) // 每5分钟执行
public void warmUpExchangeRates() {
List<String> currencies = Arrays.asList("USD", "EUR", "GBP", "JPY", "CNY");
for (String from : currencies) {
for (String to : currencies) {
if (!from.equals(to)) {
try {
getExchangeRate(from, to);
} catch (Exception e) {
log.warn("Failed to warm up exchange rate: {} -> {}", from, to, e);
}
}
}
}
}
}
# 3. 税费计算规则引擎
/**
* 税费规则引擎
*/
@Component
public class TaxRuleEngine {
private final List<TaxRule> taxRules;
/**
* 计算税费
*/
public TaxCalculationResult calculateTax(TaxCalculationRequest request) {
TaxCalculationResult result = new TaxCalculationResult();
// 1. 筛选适用的税费规则
List<TaxRule> applicableRules = taxRules.stream()
.filter(rule -> rule.isApplicable(request))
.sorted(Comparator.comparing(TaxRule::getPriority))
.collect(Collectors.toList());
// 2. 依次应用税费规则
BigDecimal taxableAmount = request.getProductPrice();
for (TaxRule rule : applicableRules) {
TaxCalculation calculation = rule.calculate(taxableAmount, request);
result.addTaxCalculation(calculation);
// 某些税种可能影响下一个税种的计税基础
if (rule.isCompoundable()) {
taxableAmount = taxableAmount.add(calculation.getTaxAmount());
}
}
return result;
}
}
/**
* 关税计算规则
*/
@Component
public class CustomsDutyRule implements TaxRule {
@Override
public boolean isApplicable(TaxCalculationRequest request) {
// 跨境商品需要缴纳关税
return !request.getOriginCountry().equals(request.getDestinationCountry());
}
@Override
public TaxCalculation calculate(BigDecimal taxableAmount, TaxCalculationRequest request) {
// 1. 获取商品的HS编码
String hsCode = request.getProduct().getHsCode();
// 2. 查询关税税率
BigDecimal dutyRate = customsDutyService.getDutyRate(
hsCode,
request.getOriginCountry(),
request.getDestinationCountry()
);
// 3. 计算关税
BigDecimal dutyAmount = taxableAmount.multiply(dutyRate)
.setScale(2, RoundingMode.HALF_UP);
return TaxCalculation.builder()
.taxType("关税")
.taxRate(dutyRate)
.taxableAmount(taxableAmount)
.taxAmount(dutyAmount)
.build();
}
}
# 📊 性能优化
# 1. 缓存策略
/**
* 价格计算缓存配置
*/
@Configuration
@EnableCaching
public class PricingCacheConfig {
@Bean
public CacheManager pricingCacheManager() {
RedisCacheManager.Builder builder = RedisCacheManager
.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory())
.cacheDefaults(cacheConfiguration());
return builder.build();
}
private RedisCacheConfiguration cacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10)) // 价格缓存10分钟
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}
}
/**
* 价格计算服务(带缓存)
*/
@Service
public class CachedPricingService {
@Cacheable(value = "product_price", key = "#request.cacheKey()")
public PriceCalculationResult calculatePrice(PriceCalculationRequest request) {
return pricingEngine.calculatePrice(request);
}
@CacheEvict(value = "product_price", key = "#request.cacheKey()")
public void evictPriceCache(PriceCalculationRequest request) {
// 价格变更时清除缓存
}
}
# 2. 异步处理
/**
* 异步价格计算服务
*/
@Service
public class AsyncPricingService {
@Async("pricingExecutor")
public CompletableFuture<PriceCalculationResult> calculatePriceAsync(
PriceCalculationRequest request) {
try {
PriceCalculationResult result = pricingEngine.calculatePrice(request);
return CompletableFuture.completedFuture(result);
} catch (Exception e) {
return CompletableFuture.failedFuture(e);
}
}
/**
* 批量价格计算
*/
public CompletableFuture<List<PriceCalculationResult>> calculatePricesBatch(
List<PriceCalculationRequest> requests) {
List<CompletableFuture<PriceCalculationResult>> futures = requests.stream()
.map(this::calculatePriceAsync)
.collect(Collectors.toList());
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
}
}
# 📈 监控与分析
# 1. 价格计算监控
/**
* 价格计算监控
*/
@Component
public class PricingMetrics {
private final MeterRegistry meterRegistry;
private final Counter pricingRequestCounter;
private final Timer pricingTimer;
private final Gauge pricingErrorRate;
public PricingMetrics(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.pricingRequestCounter = Counter.builder("pricing.requests.total")
.description("Total pricing requests")
.register(meterRegistry);
this.pricingTimer = Timer.builder("pricing.calculation.duration")
.description("Pricing calculation duration")
.register(meterRegistry);
}
public void recordPricingRequest(String productCategory, String country) {
pricingRequestCounter.increment(
Tags.of(
"category", productCategory,
"country", country
)
);
}
public void recordPricingDuration(Duration duration) {
pricingTimer.record(duration);
}
}
# 2. 价格变动分析
/**
* 价格变动分析服务
*/
@Service
public class PriceAnalysisService {
/**
* 分析价格变动趋势
*/
public PriceTrendAnalysis analyzePriceTrend(String productSku, Duration period) {
// 1. 获取历史价格数据
List<PriceHistory> priceHistory = priceHistoryRepository
.findByProductSkuAndTimestampAfter(
productSku,
Instant.now().minus(period)
);
// 2. 计算价格统计
PriceStatistics statistics = calculatePriceStatistics(priceHistory);
// 3. 分析价格趋势
PriceTrend trend = analyzeTrend(priceHistory);
// 4. 识别价格异常
List<PriceAnomaly> anomalies = detectPriceAnomalies(priceHistory);
return PriceTrendAnalysis.builder()
.productSku(productSku)
.period(period)
.statistics(statistics)
.trend(trend)
.anomalies(anomalies)
.build();
}
/**
* 价格敏感性分析
*/
public PriceSensitivityAnalysis analyzePriceSensitivity(String productSku) {
// 1. 获取价格和销量数据
List<PriceSalesData> priceSalesData = salesDataRepository
.findPriceSalesDataByProductSku(productSku);
// 2. 计算价格弹性
double priceElasticity = calculatePriceElasticity(priceSalesData);
// 3. 分析最优价格点
BigDecimal optimalPrice = findOptimalPrice(priceSalesData);
return PriceSensitivityAnalysis.builder()
.productSku(productSku)
.priceElasticity(priceElasticity)
.optimalPrice(optimalPrice)
.build();
}
}
# 🎯 关键要点
# 1. 技术特色
- 多维度计算:综合考虑成本、汇率、税费、市场等因素
- 实时响应:支持实时汇率更新和价格调整
- 智能策略:基于市场数据的动态定价策略
- 高性能:缓存优化和异步处理
- 可扩展:规则引擎支持灵活的税费计算
# 2. 业务价值
- 准确定价:确保价格计算的准确性和合规性
- 竞争优势:基于市场数据的智能定价
- 风险控制:汇率风险和价格异常监控
- 运营效率:自动化价格管理和调整
# 3. 未来发展
- AI定价:机器学习优化定价策略
- 实时竞价:动态竞争对手价格监控
- 个性化定价:基于用户画像的差异化定价
- 全球化支持:更多国家和地区的税费规则
在下一篇文档中,我们将深入探讨订单处理系统,了解如何处理复杂的跨境订单流程,包括订单验证、库存预占、支付集成等关键环节。