feat(pricing): 新增升单检测功能- 添加升单检测API端点 /api/pricing/upgrade-check

- 实现 `checkUpgrade` 核心方法,用于检测已购与待购商品组合优惠
- 支持一口价和打包优惠的综合评估逻辑- 提供详细的请求参数与响应结果结构定义
- 更新文档说明升单检测的业务价值与使用场景- 补充关键架构变更记录与兼容性注意事项
This commit is contained in:
2025-10-11 21:09:36 +08:00
parent a5c815b6ed
commit dc4091e058

View File

@@ -82,6 +82,7 @@ com.ycwl.basic.pricing/
#### API端点 #### API端点
- `POST /api/pricing/calculate` — 执行价格计算(预览模式默认开启) - `POST /api/pricing/calculate` — 执行价格计算(预览模式默认开启)
- `GET /api/pricing/coupons/my-coupons` — 查询用户可用优惠券 - `GET /api/pricing/coupons/my-coupons` — 查询用户可用优惠券
- `POST /api/pricing/upgrade-check` — 升单检测:综合已购与待购商品,判断是否命中一口价或打包优惠
#### 计算流程 #### 计算流程
```java ```java
@@ -515,22 +516,146 @@ public class PriceCalculationResult {
- `GET /api/pricing/admin/one-price/scenic/{scenicId}` — 按景区查询启用配置 - `GET /api/pricing/admin/one-price/scenic/{scenicId}` — 按景区查询启用配置
- `GET /api/pricing/admin/one-price/check/{scenicId}` — 景区是否适用一口价 - `GET /api/pricing/admin/one-price/check/{scenicId}` — 景区是否适用一口价
## 升单检测功能 (Upgrade Detection)
### 1. 功能概述
升单检测功能是最新新增的功能,用于综合已购商品与待购商品,判断是否满足一口价或打包购买优惠条件,为用户提供购买建议。
### 2. 核心接口
#### IPriceCalculationService 升单检测方法
```java
/**
* 升单检测:综合已购与待购商品,判断是否命中一口价或打包优惠
* @param request 升单检测请求
* @return 升单检测结果
*/
UpgradeCheckResult checkUpgrade(UpgradeCheckRequest request);
```
#### API 端点
- `POST /api/pricing/upgrade-check` — 升单检测接口
### 3. 检测逻辑
#### 请求参数 (UpgradeCheckRequest)
- `scenicId`: 景区ID
- `purchasedProducts`: 已购商品列表
- `intendingProducts`: 待购商品列表
#### 检测流程
1. **商品规范化**: 对已购和待购商品进行规范化处理
2. **价格汇总**: 分别计算已购和待购商品的总价格
3. **一口价评估**: 判断合并商品是否满足一口价条件
4. **打包优惠评估**: 检测是否满足打包购买优惠条件
5. **结果汇总**: 生成升单检测结果和建议
#### 响应结果 (UpgradeCheckResult)
- `summary`: 价格汇总信息(原价、优惠价、最终价)
- `onePriceResult`: 一口价检测结果(如适用)
- `bundleResult`: 打包优惠检测结果(如适用)
- `upgradeAvailable`: 是否可升单(布尔值)
- `savingsAmount`: 升单可节省金额
### 4. 业务价值
#### 用户体验提升
- 为用户提供购买建议,提高客单价
- 自动检测最优购买组合
- 清晰展示升单优惠金额
#### 销售支持
- 促进多商品销售
- 提高打包购买和一口价利用率
- 增加用户购买决策信心
### 5. 使用场景
#### 典型场景
- 用户已购买照片,建议加购视频享受打包优惠
- 用户购买多件商品,建议升级为一口价套餐
- 用户购买数量接近打包优惠门槛,建议增加数量
#### 实现细节
```java
// 升单检测核心逻辑
@Override
public UpgradeCheckResult checkUpgrade(UpgradeCheckRequest request) {
// 1. 参数验证
if (request == null) {
throw new PriceCalculationException("升单检测请求不能为空");
}
// 2. 商品规范化
List<ProductItem> purchased = normalizeProducts(request.getPurchasedProducts());
List<ProductItem> intending = normalizeProducts(request.getIntendingProducts());
// 3. 合并商品列表
List<ProductItem> allProducts = new ArrayList<>();
allProducts.addAll(purchased);
allProducts.addAll(intending);
// 4. 价格计算
PriceDetails purchasedPrice = calculateProductsPriceWithOriginal(purchased);
PriceDetails intendingPrice = calculateProductsPriceWithOriginal(intending);
PriceDetails totalPrice = calculateProductsPrice(allProducts);
// 5. 优惠评估
UpgradeOnePriceResult onePriceResult = evaluateOnePrice(request.getScenicId(), allProducts, totalPrice);
UpgradeBundleDiscountResult bundleResult = evaluateBundleDiscount(request.getScenicId(), allProducts, totalPrice);
// 6. 结果汇总
return buildUpgradeResult(purchasedPrice, intendingPrice, onePriceResult, bundleResult);
}
```
## 测试策略 ## 测试策略
### 1. 单元测试 ### 单元测试类型
建议覆盖: - **服务层测试**:每个服务类都有对应测试类
- 价格计算核心流程与边界 - `PriceBundleServiceTest` - 套餐价格计算测试
- 优惠券/券码/一口价适用性与叠加规则 - `ReusableVoucherServiceTest` - 可重复使用券码测试
- 异常场景与异常处理器 - `VoucherTimeRangeTest` - 券码时间范围功能测试
- `VoucherPrintServiceCodeGenerationTest` - 券码生成测试
- **实体映射测试**:验证数据库映射和JSON序列化
- `PriceBundleConfigStructureTest` - 实体结构测试
- `PriceBundleConfigJsonTest` - JSON序列化测试
- `CouponSwitchFieldsMappingTest` - 字段映射测试
- **类型处理器测试**:验证自定义TypeHandler
- `BundleProductListTypeHandlerTest` - 套餐商品列表序列化测试
- **配置验证测试**:验证系统配置完整性
- `DefaultConfigValidationTest` - 验证所有ProductType的default配置
- `CodeGenerationStandaloneTest` - 独立代码生成测试
### 2. 集成测试 ### 测试执行命令
- 数据库读写与分页 ```bash
- JSON 序列化/反序列化(TypeHandler) # 运行单个测试类
- API 端点的入参/出参校验 mvn test -Dtest=VoucherTimeRangeTest
mvn test -Dtest=ReusableVoucherServiceTest
mvn test -Dtest=BundleProductListTypeHandlerTest
### 3. 配置校验 # 运行整个pricing模块测试
- 校验各 ProductType 的默认配置完整性 mvn test -Dtest="com.ycwl.basic.pricing.*Test"
- 关键枚举与配置代码路径的兼容性
# 运行特定分类的测试
mvn test -Dtest="com.ycwl.basic.pricing.service.*Test" # 服务层测试
mvn test -Dtest="com.ycwl.basic.pricing.handler.*Test" # TypeHandler测试
mvn test -Dtest="com.ycwl.basic.pricing.entity.*Test" # 实体测试
mvn test -Dtest="com.ycwl.basic.pricing.mapper.*Test" # Mapper测试
# 运行带详细报告的测试
mvn test -Dtest="com.ycwl.basic.pricing.*Test" -Dsurefire.printSummary=true
```
### 重点测试场景
- **价格计算核心流程**:验证统一优惠检测和组合逻辑
- **可重复使用券码**:验证多次使用、时间间隔、用户限制逻辑
- **时间范围控制**:验证券码有效期开始和结束时间
- **优惠叠加规则**:验证券码、优惠券、一口价的叠加逻辑
- **JSON序列化**:验证复杂对象在数据库中的存储和读取
- **分页功能**:验证PageHelper和MyBatis-Plus分页集成
- **异常处理**:验证业务异常和全局异常处理器
## 数据库设计 ## 数据库设计
@@ -568,9 +693,18 @@ CREATE INDEX idx_print_face_scenic ON voucher_print_record(face_id, scenic_id);
- 定期清理已删除的过期数据 - 定期清理已删除的过期数据
- 使用数据完整性检查 SQL 验证统计数据准确性 - 使用数据完整性检查 SQL 验证统计数据准确性
### 关键架构变更
#### 最近重要更新 (2025-09-18)
1. **新增升单检测功能** - 添加了`/api/pricing/upgrade-check`接口,支持已购和待购商品的优惠组合检测
2. **新增打包购买优惠功能** - 实现了多商品组合优惠策略,优先级100(仅次于一口价)
3. **优惠优先级调整** - 确立了"一口价 > 打包购买 > 券码 > 优惠券"的优先级顺序
4. **PrinterServiceImpl重构** - 移除对PriceRepository的依赖,统一使用IPriceCalculationService
## 兼容性与注意事项 ## 兼容性与注意事项
- 本模块使用 PageHelper(优惠券相关)与 MyBatis‑Plus(券码/一口价等)并存,请根据对应 Service/Mapper 选择分页与查询方式。 - 本模块使用 PageHelper(优惠券相关)与 MyBatis‑Plus(券码/一口价等)并存,请根据对应 Service/Mapper 选择分页与查询方式。
- 优惠优先级及叠加规则以各 Provider 与业务配置为准,避免在外层重复实现优先级判断逻辑。 - 优惠优先级及叠加规则以各 Provider 与业务配置为准,避免在外层重复实现优先级判断逻辑。
- 若扩展新的优惠类型,务必实现 `IDiscountProvider` 并在 `IDiscountDetectionService` 中完成注册(当前实现通过组件扫描自动注册并排序)。 - 若扩展新的优惠类型,务必实现 `IDiscountProvider` 并在 `IDiscountDetectionService` 中完成注册(当前实现通过组件扫描自动注册并排序)。
- 升单检测功能依赖完整的价格计算和优惠检测服务,确保相关依赖正常注入。