You've already forked FrameTour-BE
docs
This commit is contained in:
269
CLAUDE.md
269
CLAUDE.md
@@ -21,11 +21,20 @@ mvn spring-boot:run
|
||||
# 运行特定测试类
|
||||
mvn test -Dtest=FaceCleanerTest
|
||||
|
||||
# 运行特定测试方法
|
||||
mvn test -Dtest=FaceCleanerTest#testSpecificMethod
|
||||
|
||||
# 运行特定包的测试
|
||||
mvn test -Dtest="com.ycwl.basic.storage.adapters.*Test"
|
||||
|
||||
# 运行pricing模块测试
|
||||
mvn test -Dtest="com.ycwl.basic.pricing.*Test"
|
||||
|
||||
# 运行所有测试
|
||||
mvn test -DskipTests=false
|
||||
|
||||
# 运行测试并生成详细报告
|
||||
mvn test -DskipTests=false -Dsurefire.printSummary=true
|
||||
```
|
||||
|
||||
### 开发环境配置
|
||||
@@ -134,12 +143,15 @@ mvn test -DskipTests=false
|
||||
## 价格查询系统 (Pricing Module)
|
||||
|
||||
### 核心架构
|
||||
价格查询系统是一个独立的业务模块,位于 `com.ycwl.basic.pricing` 包中,提供商品定价、优惠券管理和价格计算功能。
|
||||
价格查询系统是一个独立的业务模块,位于 `com.ycwl.basic.pricing` 包中,提供商品定价、优惠券管理、券码管理和统一优惠检测功能。
|
||||
|
||||
#### 关键组件
|
||||
- **PriceCalculationController** (`/api/pricing/calculate`):价格计算API
|
||||
- **CouponManagementController** (`/api/pricing/admin/coupons/`):优惠券管理API
|
||||
- **PricingConfigController** (`/api/pricing/config/`):价格配置管理API
|
||||
- **PriceCalculationController** (`/api/pricing/calculate`):统一价格计算API,支持自动优惠组合
|
||||
- **CouponManagementController** (`/api/pricing/admin/coupons/`):优惠券配置和统计管理
|
||||
- **VoucherManagementController** (`/api/pricing/voucher/`):券码批次和券码管理
|
||||
- **VoucherUsageController** (`/api/pricing/voucher/usage/`):券码使用记录和统计
|
||||
- **PricingConfigController** (`/api/pricing/config/`):商品价格配置管理
|
||||
- **OnePricePurchaseController** (`/api/pricing/admin/one-price/`):一口价配置管理
|
||||
|
||||
#### 商品类型支持
|
||||
```java
|
||||
@@ -151,12 +163,16 @@ ProductType枚举定义了支持的商品类型:
|
||||
- MACHINE_PRINT: 一体机打印
|
||||
```
|
||||
|
||||
#### 价格计算流程
|
||||
1. 接收PriceCalculationRequest(包含商品列表和用户ID)
|
||||
#### 价格计算流程(统一优惠检测)
|
||||
1. 接收PriceCalculationRequest(包含商品列表、用户ID、券码等)
|
||||
2. 查找商品基础配置和分层定价
|
||||
3. 处理套餐商品(BundleProductItem)
|
||||
4. 自动应用最优优惠券
|
||||
5. 返回PriceCalculationResult(包含原价、最终价格、优惠详情)
|
||||
4. **统一优惠检测**:通过IDiscountDetectionService自动检测所有可用优惠
|
||||
- 券码优惠(VoucherDiscountProvider,优先级100)
|
||||
- 优惠券优惠(CouponDiscountProvider,优先级80)
|
||||
- 一口价优惠(OnePricePurchaseDiscountProvider,优先级60)
|
||||
5. **智能优惠组合**:按优先级和叠加规则应用最优优惠组合
|
||||
6. 返回PriceCalculationResult(包含原价、最终价格、使用的优惠详情、可用优惠列表)
|
||||
|
||||
#### 优惠券系统
|
||||
- **CouponType**: PERCENTAGE(百分比)、FIXED_AMOUNT(固定金额)
|
||||
@@ -166,15 +182,93 @@ ProductType枚举定义了支持的商品类型:
|
||||
- 时间有效期控制
|
||||
|
||||
#### 分页查询功能
|
||||
所有管理接口都支持分页查询,使用PageHelper实现:
|
||||
- 优惠券配置分页:支持按状态、名称筛选
|
||||
- 领取记录分页:支持按用户、优惠券、状态、时间范围筛选
|
||||
所有管理接口都支持分页查询:
|
||||
- **优惠券系统**:使用PageHelper实现
|
||||
- 优惠券配置分页:支持按状态、名称筛选
|
||||
- 领取记录分页:支持按用户、优惠券、状态、时间范围筛选
|
||||
- **券码系统**:使用MyBatis-Plus Page实现
|
||||
- 券码批次分页:支持按景区、批次名称、状态筛选
|
||||
- 券码列表分页:支持按批次、状态、用户筛选
|
||||
- 使用记录分页:支持按券码、用户、时间范围筛选
|
||||
|
||||
#### 统计功能
|
||||
- 基础统计:领取数、使用数、可用数
|
||||
- 详细统计:使用率、平均使用天数
|
||||
- **优惠券统计**:基础统计(领取数、使用数、可用数)、详细统计(使用率、平均使用天数)
|
||||
- **券码统计**:支持可重复使用的统计(使用率、重复使用率、平均使用次数)
|
||||
- 时间范围统计:指定时间段的整体数据分析
|
||||
|
||||
## 券码管理系统 (Voucher System)
|
||||
|
||||
### 核心特性
|
||||
券码系统支持**可重复使用**的优惠券管理,与传统优惠券系统并行工作。
|
||||
|
||||
#### 关键优势
|
||||
- **可重复使用**:支持单个券码多次使用,通过`maxUseCount`配置最大使用次数
|
||||
- **用户使用限制**:支持单个用户对券码的使用次数限制(`maxUsePerUser`)
|
||||
- **使用间隔控制**:支持设置使用时间间隔(`useIntervalHours`)
|
||||
- **时间范围控制**:支持设置券码的有效期开始和结束时间
|
||||
|
||||
#### 券码优惠类型
|
||||
```java
|
||||
public enum VoucherDiscountType {
|
||||
FREE_ALL(0, "全场免费"), // 优先级最高,且不可叠加
|
||||
REDUCE_PRICE(1, "商品降价"), // 每个商品减免固定金额
|
||||
DISCOUNT(2, "商品打折"); // 每个商品按百分比打折
|
||||
}
|
||||
```
|
||||
|
||||
#### 数据库表结构
|
||||
- **price_voucher_batch_config**:券码批次配置表,支持按景区、推客创建券码批次
|
||||
- **price_voucher_code**:券码表,每个券码全局唯一,支持同一用户在同一景区只能领取一次
|
||||
- **price_voucher_usage_record**:券码使用记录表,记录每次使用的完整信息
|
||||
- **voucher_print_record**:券码打印记录表,用于移动端打印功能
|
||||
|
||||
## 统一优惠检测系统 (Unified Discount Detection)
|
||||
|
||||
### 设计模式
|
||||
采用**策略模式**的可扩展优惠检测系统,统一管理并自动组合多种优惠类型。
|
||||
|
||||
#### 核心接口
|
||||
```java
|
||||
// 优惠提供者接口
|
||||
public interface IDiscountProvider {
|
||||
String getProviderType(); // 提供者类型
|
||||
int getPriority(); // 优先级(数字越大越高)
|
||||
List<DiscountInfo> detectAvailableDiscounts(); // 检测可用优惠
|
||||
DiscountResult applyDiscount(); // 应用优惠
|
||||
}
|
||||
|
||||
// 优惠检测服务接口
|
||||
public interface IDiscountDetectionService {
|
||||
DiscountCombinationResult calculateOptimalCombination(); // 计算最优组合
|
||||
DiscountCombinationResult previewOptimalCombination(); // 预览优惠组合
|
||||
}
|
||||
```
|
||||
|
||||
#### 优惠提供者实现(按优先级排序)
|
||||
1. **VoucherDiscountProvider** (优先级: 100)
|
||||
- 处理券码优惠逻辑
|
||||
- 支持用户主动输入券码或自动选择最优券码
|
||||
- 全场免费券码不可与其他优惠叠加
|
||||
|
||||
2. **CouponDiscountProvider** (优先级: 80)
|
||||
- 处理优惠券优惠逻辑
|
||||
- 自动选择最优优惠券
|
||||
- 可与券码叠加使用(除全场免费券码外)
|
||||
|
||||
3. **OnePricePurchaseDiscountProvider** (优先级: 60)
|
||||
- 处理一口价优惠逻辑(景区级统一价格)
|
||||
- 仅当一口价小于当前金额时产生优惠
|
||||
- 叠加性由配置`canUseCoupon/canUseVoucher`控制
|
||||
|
||||
#### 优惠应用策略
|
||||
```java
|
||||
原价 → 券码 → 优惠券 → 一口价 → 最终价格
|
||||
|
||||
特殊情况:
|
||||
- 全场免费券码:直接最终价=0,停止后续优惠
|
||||
- 一口价:可叠加性由配置 canUseCoupon / canUseVoucher 控制
|
||||
```
|
||||
|
||||
### 开发模式
|
||||
|
||||
#### 添加新商品类型
|
||||
@@ -188,15 +282,92 @@ ProductType枚举定义了支持的商品类型:
|
||||
2. 在CouponServiceImpl中实现计算逻辑
|
||||
3. 更新applicableProducts验证规则
|
||||
|
||||
#### 添加新优惠提供者(策略扩展)
|
||||
```java
|
||||
@Component
|
||||
public class FlashSaleDiscountProvider implements IDiscountProvider {
|
||||
@Override
|
||||
public String getProviderType() { return "FLASH_SALE"; }
|
||||
|
||||
@Override
|
||||
public int getPriority() { return 90; } // 介于券码和优惠券之间
|
||||
|
||||
@Override
|
||||
public List<DiscountInfo> detectAvailableDiscounts(DiscountDetectionContext context) {
|
||||
// 实现限时抢购优惠检测逻辑
|
||||
return discountInfoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscountResult applyDiscount(DiscountDetectionContext context, DiscountInfo discount) {
|
||||
// 实现优惠应用逻辑
|
||||
return discountResult;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 创建可重复使用券码批次
|
||||
```java
|
||||
VoucherBatchCreateReqV2 request = new VoucherBatchCreateReqV2();
|
||||
request.setBatchName("限时活动券码");
|
||||
request.setMaxUseCount(3); // 每个券码最多使用三次
|
||||
request.setMaxUsePerUser(2); // 每个用户最多使用两次
|
||||
request.setUseIntervalHours(12); // 使用间隔12小时
|
||||
request.setValidStartTime(startTime); // 有效期开始时间
|
||||
request.setValidEndTime(endTime); // 有效期结束时间
|
||||
```
|
||||
|
||||
#### 自定义TypeHandler使用
|
||||
项目使用自定义TypeHandler处理复杂JSON字段:
|
||||
- `BundleProductListTypeHandler`:处理套餐商品列表JSON序列化
|
||||
|
||||
### 测试策略
|
||||
- 单元测试:每个服务类都有对应测试类
|
||||
- 配置验证测试:DefaultConfigValidationTest验证default配置
|
||||
- JSON序列化测试:验证复杂对象的数据库存储
|
||||
- 分页功能测试:验证PageHelper集成
|
||||
针对pricing模块的全面测试策略:
|
||||
|
||||
#### 单元测试类型
|
||||
- **服务层测试**:每个服务类都有对应测试类
|
||||
- `PriceBundleServiceTest` - 套餐价格计算测试
|
||||
- `ReusableVoucherServiceTest` - 可重复使用券码测试
|
||||
- `VoucherTimeRangeTest` - 券码时间范围功能测试
|
||||
- `VoucherPrintServiceCodeGenerationTest` - 券码生成测试
|
||||
- **实体映射测试**:验证数据库映射和JSON序列化
|
||||
- `PriceBundleConfigStructureTest` - 实体结构测试
|
||||
- `PriceBundleConfigJsonTest` - JSON序列化测试
|
||||
- `CouponSwitchFieldsMappingTest` - 字段映射测试
|
||||
- **类型处理器测试**:验证自定义TypeHandler
|
||||
- `BundleProductListTypeHandlerTest` - 套餐商品列表序列化测试
|
||||
- **配置验证测试**:验证系统配置完整性
|
||||
- `DefaultConfigValidationTest` - 验证所有ProductType的default配置
|
||||
- `CodeGenerationStandaloneTest` - 独立代码生成测试
|
||||
|
||||
#### 测试执行命令
|
||||
```bash
|
||||
# 运行单个测试类
|
||||
mvn test -Dtest=VoucherTimeRangeTest
|
||||
mvn test -Dtest=ReusableVoucherServiceTest
|
||||
mvn test -Dtest=BundleProductListTypeHandlerTest
|
||||
|
||||
# 运行整个pricing模块测试
|
||||
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分页集成
|
||||
- **异常处理**:验证业务异常和全局异常处理器
|
||||
|
||||
## 关键架构模式
|
||||
|
||||
@@ -289,4 +460,68 @@ mvn test -Dtest="com.ycwl.basic.integration.*Test"
|
||||
logging:
|
||||
level:
|
||||
com.ycwl.basic.integration: DEBUG
|
||||
```
|
||||
|
||||
## 开发环境和调试
|
||||
|
||||
### 端口配置
|
||||
- **开发环境端口**: 8030
|
||||
- **应用名称**: zt
|
||||
|
||||
### 日志配置
|
||||
开发环境默认启用详细的集成服务日志,便于调试外部服务调用问题。
|
||||
|
||||
### CI/CD 配置
|
||||
项目使用 Jenkins 进行持续集成:
|
||||
- **JDK 版本**: OpenJDK 21
|
||||
- **构建命令**: `mvn clean package -DskipTests=true`
|
||||
- **构建产物**: 自动归档和发布 JAR 文件
|
||||
|
||||
## 重要开发约定
|
||||
|
||||
### 测试文件组织
|
||||
测试按功能模块组织,包括:
|
||||
- **适配器测试**: `*AdapterTest.java` 测试第三方集成
|
||||
- **实体测试**: 验证数据库映射和JSON序列化
|
||||
- **Mapper测试**: 验证数据访问层逻辑
|
||||
- **Handler测试**: 测试自定义TypeHandler
|
||||
|
||||
### 模块化架构
|
||||
每个业务模块(如 `pricing`、`integration`、`order`)都有完整的分层结构:
|
||||
```
|
||||
module/
|
||||
├── controller/ # REST API控制器
|
||||
├── service/ # 业务逻辑层
|
||||
├── repository/ # 数据访问抽象
|
||||
├── mapper/ # MyBatis数据映射
|
||||
├── entity/ # JPA/MyBatis实体
|
||||
├── dto/ # 数据传输对象
|
||||
├── enums/ # 枚举定义
|
||||
└── exception/ # 模块特定异常
|
||||
```
|
||||
|
||||
### 外部服务集成
|
||||
集成服务统一使用以下模式:
|
||||
- **Feign客户端**: 声明式HTTP客户端调用
|
||||
- **错误处理**: 统一的`handleResponse`模式
|
||||
- **配置管理**: 通过`IntegrationProperties`集中配置
|
||||
- **超时配置**: 连接超时5秒,读取超时10秒
|
||||
|
||||
## Windows 开发环境注意事项
|
||||
|
||||
### 路径处理
|
||||
- 项目在Windows系统上运行,注意路径分隔符使用反斜杠 `\`
|
||||
- 配置文件中的资源路径已适配Windows环境
|
||||
- 日志文件和临时文件路径会自动适配系统环境
|
||||
|
||||
### 开发工具兼容性
|
||||
- 确保使用Java 21兼容的IDE
|
||||
- Maven命令在Windows Command Prompt和PowerShell中均可使用
|
||||
- 建议使用UTF-8编码避免中文字符问题
|
||||
|
||||
### 端口占用检查
|
||||
开发时如遇端口冲突,使用以下命令检查:
|
||||
```cmd
|
||||
netstat -ano | findstr :8030
|
||||
taskkill /f /pid <PID>
|
||||
```
|
Reference in New Issue
Block a user