一 背景
AI coding已经是行业公认的开发方向,但是AIcoding如何落地,目前缺少对应的标准化的落地方案,在探索中思考到,AI擅长一些领域,如新增的逻辑功能开发,单元测试等,下面我就写一个真实的落地案例
二 执行流程
执行流程基本上分几块
- 使用claudeCode进入plan模式,plan模式是claudeCode用来规划方案的模式,原则是先规划后开发的方式
- 在plan模式上编写实施方案,并检查实施方案是否满足和准确
- 实施方案检查完成后,切换为执行模式,让claudeCode基于实施方案文档自动编写代码
- 执行单元测试,检查生成的代码是否满足要求
三 Plan模式
Claude Code的Plan Mode(计划模式)是一种“只读分析模式”,核心特点是只分析和规划,不修改任何代码。
可以把它理解为一个“安全预览”开关。开启后,Claude在执行复杂任务(如重构、添加新功能)前,会先为你制定一份详细的执行计划,等你审核批准后才会真正动手修改文件。这样能有效防止AI误改代码,尤其适合处理不熟悉的大型项目。
| 模式 | 核心特点 | 适用场景 |
|---|---|---|
| Plan Mode(计划模式) | 只读:Claude会分析代码、制定计划,但不创建、修改或删除任何文件。 | 熟悉新项目、规划复杂功能:在修改前先进行方案评审,确保思路正确,避免返工-8。 |
| Default Mode(默认模式) | 安全确认:Claude在每次修改文件或执行命令前,都会弹出提示,需要你手动点击确认。 | 日常编码:希望在AI修改代码前有机会逐条审查,确保每一步都符合预期。 |
| Auto-Accept(自动接受模式) | 高效执行:Claude会自动接受文件修改,无需你逐一确认(但执行Shell命令通常仍需确认)。 | 编写样板代码、执行简单重构:处理信任度高、风险小的任务,追求速度。 |
-
如何切换:在Claude Code的交互界面中,按
Shift+Tab快捷键即可在三种模式间循环切换。切换后,界面左下角的模式指示器会相应变化。 -
核心价值——将指令转化为计划:当你输入一个需求(例如“将用户登录从Session改为JWT”),Plan Mode下的Claude 不会直接修改代码,而是会生成一份清晰的执行步骤,比如列出需要安装的依赖、需要修改的文件以及具体的实现逻辑。
-
典型应用场景:
-
熟悉陌生代码库:接手一个新项目时,用Plan Mode分析某个模块的架构,可以放心提问,完全不用担心误操作。
-
规划高风险改动:在进行数据库迁移、核心逻辑重构等复杂任务前,先用Plan Mode生成方案并进行评审,可以大大降低风险。
-
执行plan命令进入plan模式
本次开发的场景主要是表单,表单是所有需求里面频率最高的场景,这次首先让claudeCode生成一个实施文件sendpriceconfig.md
本次需求
将需求文字描述放到此文件
# 智能出价配置 — 需求与实施方案
## 一、需求背景
针对无人报价的情况,系统已引入智能报价能力,按渠道维度配置智能出价策略,提升平台报价能力,但目前,智能出价策略的配置完全依赖后端开发人员,结合业务实际运营情况,智能出价配置调整频率高达一周多次,现有配置模式无法适配业务快速迭代的需求。
## 二、需求价值
将智能出价策略的配置能力从开发侧下放至运营侧,保障运营灵活性,优化用户体验
---
## 三、需求详情
### 1、查询
按渠道筛选,筛选全部渠道,可多选,选项用【渠道号(端口名)】显示,如:(小程序)
【查询】按钮,点击根据筛选条件查询相应内容
【重置】按钮,点击清空筛选条件并查询
### 2、列表
(1)列表展示目前配置的所有配置内容
(2)列表字段
- 渠道号
- 渠道名称
- 是否强制出价:点击直接开启或关闭
- 出价规则
- 最后修改时间:展示最后修改的时间和修改人
(3)分页:按现有组件
### 3、操作
- 新增配置:点击出现弹窗
- 编辑:点击出现弹窗
- 删除:点击出现二次确认弹窗,二次确认后删除当前配置的数据,删除后,相当于关闭该渠道的智能出价配置
### 操作日志
**1、操作日志触发条件**
- 每次点击编辑弹窗里的【确定】按钮,记录操作后的数据
- 每次点击新增配置弹窗里的【确定】按钮,记录操作后的数据
- 每次点击删除二次确认弹窗中【确定】按钮,记录操作时对应的数据
**2、操作日志字段**
- 操作时间:记录每次记录时对应的时间
- 操作人:操作人的工号
- 操作类型:包括新增配置、编辑配置、删除配置
- 操作详情:模板如下:
- 新增【900059(小程序)】渠道,强制出价:【是】;出价规则:【竞价结束前115s ,满0元,出价系数为2,默认报价为10元】
- 编辑【900059(小程序)】渠道,强制出价:【是】;出价规则:【竞价结束前115s ,满0元,出价系数为2,默认报价为10元】
- 删除【900059(小程序)】渠道,强制出价:【是】;出价规则:【竞价结束前115s ,满0元,出价系数为2,默认报价为10元】
**3、分页:按现有组件**
### 新增配置
**1、渠道**:单选下拉选项,选项内容为:yh_sales_channel.tb_sale_channel中order_type=3的所有渠道号和渠道名称
**2、是否强制出价**:问号鼠标悬殊时展示注释,文案如原型所示
- 当前编辑的渠道开启强制出价就显示开启,没有就显示关闭
- 开启或关闭时,按钮右侧文字显示开启/关闭
**3、出价规则**
- 竞价结束前x秒,范围(0,1000],仅支持正整数
- 梯度配置
- 最少配置1个梯度。新增梯度后,后方有【删除】按钮。梯度上限为10个
- 后面的梯度金额需要比上一个梯度金额大,如果不比上一个梯度金额大的话需要红字提示:梯度价要大于上一个梯度金额
- 编辑中间的梯度金额时,需要小于下一个梯度金额,如果大于下一个梯度金额话需要红字提示:梯度价要小于下一个梯度金额
- 梯度金额:默认赋值0,必填,范围[0,999999],仅支持输入0或正整数,不符合规范提示:请输入[0,999999]的整数
- 出价系数:范围(0,10],支持小数点后2位
- 默认报价:范围[0,999999],仅支持输入0或正整数
**4、【确定】按钮**:点击按钮时,判断该渠道是否已经存在配置
- 若已经存在,提示:该渠道智能出价配置已经存在
- 若不存在,新增成功,弹窗关闭,列表新增一条数据并展示
**5、【取消】按钮**:点击按钮后,弹窗关闭,填写的数据不保存
### 编辑配置
**1、渠道**:编辑时,该字段置灰,不支持修改
**2、是否强制出价**:同新增配置
**3、出价规则**:同新增配置
**4、【确定】按钮**:点击按钮时,编辑成功,弹窗关闭,数据更新
**5、【取消】按钮**:点击按钮后,弹窗关闭,填写的数据不保存
### 删除配置
- 点击列表中的"删除"按钮,出现二次确认弹窗
- 点击"确认"按钮,确认后,弹窗关闭,删除当前配置的数据
- 点击"取消"按钮,弹窗关闭,数据不变
---
四 实施方案生成
在claudeCode命令中输入,@sendpriceconfig.md,基于里面的产品需求生成实施方案,claudeCode会自动填充实施方案,执行后
## 四、实施方案
### 4.1 建表设计
#### 配置主表 `tb_ec_bid_smart_price_config`
```sql
CREATE TABLE `tb_ec_bid_smart_price_config` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`channel_id` varchar(20) NOT NULL COMMENT '渠道ID(如900059)',
`channel_name` varchar(100) NOT NULL COMMENT '渠道名称',
`force_bid` tinyint NOT NULL DEFAULT 0 COMMENT '是否强制出价: 0=关闭, 1=开启',
`bid_end_before_seconds` int NOT NULL DEFAULT 5 COMMENT '竞价结束前出价秒数, 范围(0,1000]',
`tier_config_json` varchar(2000) NOT NULL COMMENT '梯度配置JSON, 最多10个梯度',
`default_price` bigint NOT NULL DEFAULT 0 COMMENT '默认报价(分), 范围[0,99999900]',
`auto_bid_switch` tinyint NOT NULL DEFAULT 0 COMMENT '自动出价开关: 0=关闭, 1=开启',
`ext_json` varchar(500) DEFAULT NULL COMMENT '扩展字段JSON',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modify` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
`creator` varchar(50) DEFAULT NULL COMMENT '创建人',
`modifier` varchar(50) DEFAULT NULL COMMENT '修改人',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_channel_id` (`channel_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='智能出价配置表';
```
**设计要点**:
- `channel_id` 唯一键 — 每渠道仅一条配置(需求:"若已存在,提示:该渠道智能出价配置已经存在")
- `tier_config_json` 存储梯度数组:`[{"tierAmount":0,"bidCoefficient":2.0,"defaultPrice":10},{"tierAmount":1000,"bidCoefficient":1.5,"defaultPrice":5}]`
- 梯度用 JSON 列而非独立子表:最多10个梯度,始终与主配置一起读写,无需独立查询,符合现有 `ServiceFeeGradientDetail` 存 JSON 的模式
- `default_price` 以分存储,与现有竞标代码约定一致
- `force_bid` 是新概念,区别于已有的 `autoBidSwitch`
#### 操作日志表 `tb_ec_bid_smart_price_config_log`
```sql
CREATE TABLE `tb_ec_bid_smart_price_config_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`config_id` bigint DEFAULT NULL COMMENT '关联配置ID',
`operation_type` varchar(20) NOT NULL COMMENT '操作类型: 新增配置/编辑配置/删除配置',
`operation_desc` varchar(1000) NOT NULL COMMENT '操作详情',
`ext_json` varchar(500) DEFAULT NULL COMMENT '扩展字段(可存变更前后快照)',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',
`creator` varchar(50) NOT NULL COMMENT '操作人工号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='智能出价配置操作日志表';
```
---
### 4.2 实体类(MyBatis-Plus 模式)
包路径:`com.yihuan.easychange.recycle.business.recycler.bid.po.smartbidprice`
| 类名 | 表名 | 说明 |
|------|------|------|
| `SmartPriceConfigPo` | `tb_ec_bid_smart_price_config` | 配置主表PO,`@TableName` + `@TableId(IdType.AUTO)` + `@Accessors(chain=true)` |
| `SmartPriceConfigLogPo` | `tb_ec_bid_smart_price_config_log` | 操作日志PO |
梯度内部DTO(在 ec-recycle-beans 共享模块):
```java
@Data
public class BidTierConfigDTO implements Serializable {
private Integer tierAmount; // 梯度金额(元), [0,999999]
private BigDecimal bidCoefficient; // 出价系数, (0,10], 2位小数
private Integer defaultPrice; // 默认报价(元), [0,999999]
}
```
---
### 4.3 Mapper 接口
包路径:`com.yihuan.easychange.recycle.business.recycler.bid.dao.smartbidprice`
| Mapper | 继承 | 说明 |
|--------|------|------|
| `SmartPriceConfigMapper` | `BaseMapper<SmartPriceConfigPo>` | 配置主表,简单CRUD无需XML |
| `SmartPriceConfigLogMapper` | `BaseMapper<SmartPriceConfigLogPo>` | 操作日志 |
---
### 4.4 Service 层
包路径:`com.yihuan.easychange.recycle.business.recycler.bid.service.smartbidprice`
**ISmartPriceConfigService** extends `IService<SmartPriceConfigPo>`:
| 方法 | 说明 |
|------|------|
| `pageList(pageIndex, pageSize, channelIds)` | 分页查询,可按渠道筛选,按gmt_modify降序 |
| `getByChannelId(channelId)` | 根据渠道ID查配置 |
| `addConfig(configPo)` | 新增配置(校验渠道唯一性) |
| `updateConfig(configPo)` | 更新配置 |
| `deleteConfig(id, operator)` | 删除配置 + 记录日志 |
| `toggleForceBid(id, forceBid, operator)` | 开关强制出价 |
**ISmartPriceConfigLogService** extends `IService<SmartPriceConfigLogPo>`:
| 方法 | 说明 |
|------|------|
| `pageLogList(pageIndex, pageSize)` | 分页查询操作日志,按gmt_created降序 |
---
### 4.5 Dubbo 接口与实现
#### Dubbo接口(ec-recycle-beans 共享模块)
包路径:`com.yihuan.ec.recycle.bean.bid.dubboservice`
```java
public interface SmartBidPriceConfigDubboService {
PageResult<SmartBidPriceConfigDTO> getConfigList(SmartBidPriceConfigSearchDTO searchDTO);
SmartBidPriceConfigDTO getConfigByChannelId(String channelId);
Boolean addConfig(SmartBidPriceConfigCreateDTO createDTO);
Boolean updateConfig(SmartBidPriceConfigUpdateDTO updateDTO);
Boolean deleteConfig(Long id, String operator);
Boolean toggleForceBid(Long id, Integer forceBid, String operator);
PageResult<SmartBidPriceConfigLogDTO> getLogList(SmartBidPriceConfigLogSearchDTO searchDTO);
List<SaleChannelOptionDTO> getChannelOptions();
List<SmartBidPriceConfigDTO> getAllConfigs();
}
```
#### 接口详情
| 接口方法 | 请求参数 | 返回 | 说明 |
|----------|----------|------|------|
| `getConfigList` | `SmartBidPriceConfigSearchDTO`(channelIds多选, pageIndex, pageSize) | `PageResult<SmartBidPriceConfigDTO>` | 配置分页列表,按渠道筛选 |
| `getConfigByChannelId` | `String channelId` | `SmartBidPriceConfigDTO` | 单渠道配置查询 |
| `addConfig` | `SmartBidPriceConfigCreateDTO`(channelId, forceBid, bidEndBeforeSeconds, tierConfigs, defaultPrice, autoBidSwitch, creator) | `Boolean` | 新增配置,校验渠道唯一性 |
| `updateConfig` | `SmartBidPriceConfigUpdateDTO`(id, forceBid, bidEndBeforeSeconds, tierConfigs, defaultPrice, autoBidSwitch, modifier) | `Boolean` | 编辑配置,channelId不可改 |
| `deleteConfig` | `Long id, String operator` | `Boolean` | 删除配置 |
| `toggleForceBid` | `Long id, Integer forceBid, String operator` | `Boolean` | 列表内直接开关强制出价 |
| `getLogList` | `SmartBidPriceConfigLogSearchDTO`(pageIndex, pageSize) | `PageResult<SmartBidPriceConfigLogDTO>` | 操作日志分页 |
| `getChannelOptions` | 无 | `List<SaleChannelOptionDTO>` | 渠道下拉选项(order_type=3) |
| `getAllConfigs` | 无 | `List<SmartBidPriceConfigDTO>` | 全量配置(运行时读取用) |
#### DTO列表(ec-recycle-beans 共享模块)
| DTO | 说明 |
|-----|------|
| `SmartBidPriceConfigDTO` | 配置响应/列表项(含解析后的tierConfigs列表) |
| `SmartBidPriceConfigSearchDTO` | 查询条件(channelIds多选 + 分页) |
| `SmartBidPriceConfigCreateDTO` | 新增请求 |
| `SmartBidPriceConfigUpdateDTO` | 编辑请求(无channelId字段) |
| `SmartBidPriceConfigLogDTO` | 操作日志响应 |
| `SmartBidPriceConfigLogSearchDTO` | 日志查询条件(分页) |
| `SaleChannelOptionDTO` | 渠道下拉选项(displayName="900059(小程序)") |
| `BidTierConfigDTO` | 梯度配置项 |
#### Dubbo实现类
包路径:`com.yihuan.easychange.recycle.business.recycler.bid.dubbo.service.impl`
`SmartBidPriceConfigDubboServiceImpl`:
- `@Service(version = "1.0.0")` + `@Component`
- 注入 `ISmartPriceConfigService` + `ISmartPriceConfigLogService`
- PO→DTO转换:将 `tierConfigJson` 反序列化为 `List<BidTierConfigDTO>`
- DTO→PO转换:将 `List<BidTierConfigDTO>` 序列化为 `tierConfigJson`
- 每次CRUD操作后生成操作日志
- 渠道映射使用 `OfflineChannelEnum.getNameByCode()` 和 `OfflineChannelEnum.getDangHuanV3()`,不依赖 `tb_sale_channel` 表
---
### 4.6 校验规则
| 字段 | 规则 | 错误提示 |
|------|------|----------|
| `channelId` | 新增时校验唯一性 | 该渠道智能出价配置已经存在 |
| `bidEndBeforeSeconds` | (0, 1000],正整数 | 请输入(0,1000]的整数 |
| `tierConfigs` | 1~10个梯度 | — |
| `tierAmount` | [0, 999999],正整数或0 | 请输入[0,999999]的整数 |
| `tierAmount` 递增 | 后梯度金额 > 前梯度金额 | 梯度价要大于上一个梯度金额 |
| `tierAmount` 中间编辑 | 中间梯度 < 下一个梯度金额 | 梯度价要小于下一个梯度金额 |
| `bidCoefficient` | (0, 10],2位小数 | — |
| `defaultPrice` | [0, 999999],正整数或0 | 请输入[0,999999]的整数 |
---
### 4.7 迁移方案(dynamic.properties → 数据库)
#### 迁移策略:数据库优先 + Heracles回退
修改 `AutoBidPriceServiceImpl`,添加数据库读取路径:
1. `getChannelBidConfig()` → 先查数据库,若无则回退到 `AutoBidPriceDynamicConfig`
2. `getChannelBidPrice()` → 新增基于梯度的价格计算方法 `getChannelBidPriceFromTierConfig()`
3. `getChannelAutoBidSwitch()` → 先查数据库 `autoBidSwitch` 字段
4. 新增 `forceBid` 判断逻辑(需求新增概念)
#### 区间→梯度转换
旧模型:`PriceAndRatio { priceStr: "(0,1000]", ratio: 0.7 }`
新模型:`BidTierConfigDTO { tierAmount: 0, bidCoefficient: 0.7, defaultPrice: 300 }`
转换规则:`priceStr` 的下界 → `tierAmount`,`ratio` → `bidCoefficient`,`defaultPrice` 取配置全局值
#### 数据迁移步骤
1. 手动/脚本将 `dynamic.properties` 中 `bid-auto-bidPrice-config` 的7个渠道配置转为数据库INSERT语句
2. 验证数据库配置产生的出价结果与旧配置一致
3. 确认无问题后,清空 Heracles `bid-auto-bidPrice-config` 配置项
4. 移除回退代码(可选,建议保留一段时间)
---
### 4.8 product-api 服务新增接口
#### 4.8.1 概述
product-api 是运营后台的 API 网关服务,通过 Dubbo RPC 调用 bid 服务暴露的 Dubbo 接口,对外提供 HTTP REST API 供前端页面调用。
**调用模式**:Controller 层通过 `@Reference(version = "1.0.0")` 注入 `SmartBidPriceConfigDubboService`,调用 Dubbo 接口获取数据,用 `ApiResult<T>` 包装返回给前端。
#### 4.8.2 Controller 类设计
**类名**:`SmartBidPriceConfigController`
**包路径**:`com.yihuan.easychange.recycle.business.recycler.smartbidprice`
**路径前缀**:`/yihuan/smartBidPriceConfig`
```java
@Slf4j
@RestController
@RequestMapping(value = "/yihuan/smartBidPriceConfig")
public class SmartBidPriceConfigController {
@Reference(version = "1.0.0")
private SmartBidPriceConfigDubboService smartBidPriceConfigDubboService;
}
```
#### 4.8.3 接口列表
| HTTP方法 | URL | 方法名 | 说明 | Dubbo接口调用 |
|----------|-----|--------|------|---------------|
| POST | `/yihuan/smartBidPriceConfig/pageList` | `pageList` | 配置分页列表查询(支持渠道多选筛选) | `getConfigList(searchDTO)` |
| POST | `/yihuan/smartBidPriceConfig/add` | `addConfig` | 新增配置 | `addConfig(createDTO)` |
| POST | `/yihuan/smartBidPriceConfig/update` | `updateConfig` | 编辑配置 | `updateConfig(updateDTO)` |
| POST | `/yihuan/smartBidPriceConfig/delete` | `deleteConfig` | 删除配置(二次确认后调用) | `deleteConfig(id, operator)` |
| POST | `/yihuan/smartBidPriceConfig/toggleForceBid` | `toggleForceBid` | 开关强制出价(列表内直接点击) | `toggleForceBid(id, forceBid, operator)` |
| GET | `/yihuan/smartBidPriceConfig/getChannelOptions` | `getChannelOptions` | 获取渠道下拉选项(order_type=3) | `getChannelOptions()` |
| POST | `/yihuan/smartBidPriceConfig/logPageList` | `logPageList` | 操作日志分页查询 | `getLogList(searchDTO)` |
#### 4.8.4 接口详细设计
**1、配置分页列表查询**
```
POST /yihuan/smartBidPriceConfig/pageList
Request Body: {
"channelIds": ["900059", "900030"], // 可多选,可为空(查全部)
"pageIndex": 1,
"pageSize": 10
}
Response: ApiResult<PageResult<SmartBidPriceConfigDTO>>
```
**2、新增配置**
```
POST /yihuan/smartBidPriceConfig/add
Request Body: {
"channelId": "900059",
"forceBid": true,
"bidEndBeforeSeconds": 115,
"tierConfigs": [
{"tierAmount": 0, "bidCoefficient": 2.0, "defaultPrice": 10},
{"tierAmount": 500, "bidCoefficient": 1.5, "defaultPrice": 8}
],
"defaultPrice": 10, // 默认报价(分)
"autoBidSwitch": true
}
Response: ApiResult<Boolean>
说明:creator 从 SessionLocal.getUser().getUserCode() 获取操作人工号
```
**3、编辑配置**
```
POST /yihuan/smartBidPriceConfig/update
Request Body: {
"id": 1,
"forceBid": true,
"bidEndBeforeSeconds": 115,
"tierConfigs": [
{"tierAmount": 0, "bidCoefficient": 2.0, "defaultPrice": 10}
],
"defaultPrice": 10,
"autoBidSwitch": true
}
Response: ApiResult<Boolean>
说明:modifier 从 SessionLocal.getUser().getUserCode() 获取;channelId 不可修改
```
**4、删除配置**
```
POST /yihuan/smartBidPriceConfig/delete
Request Body: {
"id": 1
}
Response: ApiResult<Boolean>
说明:operator 从 SessionLocal.getUser().getUserCode() 获取;删除前需二次确认(前端控制)
```
**5、开关强制出价**
```
POST /yihuan/smartBidPriceConfig/toggleForceBid
Request Body: {
"id": 1,
"forceBid": 1 // 1=开启, 0=关闭
}
Response: ApiResult<Boolean>
说明:operator 从 SessionLocal.getUser().getUserCode() 获取
```
**6、获取渠道下拉选项**
```
GET /yihuan/smartBidPriceConfig/getChannelOptions
Response: ApiResult<List<SaleChannelOptionDTO>>
返回格式示例: [{"channelId":"900059","channelName":"小程序","displayName":"900059(小程序)"}]
```
**7、操作日志分页查询**
```
POST /yihuan/smartBidPriceConfig/logPageList
Request Body: {
"pageIndex": 1,
"pageSize": 10
}
Response: ApiResult<PageResult<SmartBidPriceConfigLogDTO>>
```
#### 4.8.5 关键实现要点
- **操作人获取**:所有写入操作(新增/编辑/删除/开关)均通过 `SessionLocal.getUser().getUserCode()` 获取当前登录用户的工号,传入 Dubbo 接口的 `creator`/`modifier`/`operator` 参数
- **响应包装**:所有接口统一返回 `ApiResult<T>`,成功返回 `ApiResult.success(data)`,失败返回 `ApiResult.fail(code, message)`
- **渠道唯一性校验**:新增配置时 Dubbo 接口内部校验 `channelId` 唯一性,若已存在返回失败,前端展示提示信息
- **二次确认**:删除操作的前端二次确认由前端控制,Controller 不做额外判断,直接调用 Dubbo 删除接口
- **校验规则**:所有字段校验在 Dubbo 服务端执行,Controller 层仅做参数非空校验(如 `id` 不能为空)
---
### 4.9 完整文件清单
#### 新建文件(ec-recycle-beans 共享模块)
| 文件 | 包 | 说明 |
|------|------|------|
| `BidTierConfigDTO.java` | `dto.smartbidprice` | 梯度配置DTO |
| `SmartBidPriceConfigDTO.java` | `dto.smartbidprice` | 配置响应DTO |
| `SmartBidPriceConfigSearchDTO.java` | `dto.smartbidprice` | 查询条件DTO |
| `SmartBidPriceConfigCreateDTO.java` | `dto.smartbidprice` | 新增请求DTO |
| `SmartBidPriceConfigUpdateDTO.java` | `dto.smartbidprice` | 编辑请求DTO |
| `SmartBidPriceConfigLogDTO.java` | `dto.smartbidprice` | 日志响应DTO |
| `SmartBidPriceConfigLogSearchDTO.java` | `dto.smartbidprice` | 日志查询DTO |
| `SaleChannelOptionDTO.java` | `dto.smartbidprice` | 渠道下拉DTO |
| `SmartBidPriceConfigDubboService.java` | `dubboservice` | Dubbo接口 |
#### 新建文件(bid 项目)
| 文件 | 包 | 说明 |
|------|------|------|
| `SmartPriceConfigPo.java` | `po.smartbidprice` | 配置PO |
| `SmartPriceConfigLogPo.java` | `po.smartbidprice` | 日志PO |
| `SmartPriceConfigMapper.java` | `dao.smartbidprice` | 配置Mapper |
| `SmartPriceConfigLogMapper.java` | `dao.smartbidprice` | 日志Mapper |
| `ISmartPriceConfigService.java` | `service.smartbidprice` | 配置Service接口 |
| `ISmartPriceConfigLogService.java` | `service.smartbidprice` | 日志Service接口 |
| `SmartPriceConfigServiceImpl.java` | `service.smartbidprice.impl` | 配置Service实现 |
| `SmartPriceConfigLogServiceImpl.java` | `service.smartbidprice.impl` | 日志Service实现 |
| `SmartBidPriceConfigDubboServiceImpl.java` | `dubbo.service.impl` | Dubbo实现 |
#### 新建文件(product-api 项目)
| 文件 | 包 | 说明 |
|------|------|------|
| `SmartBidPriceConfigController.java` | `business.recycler.smartbidprice` | 智能出价配置Controller(7个HTTP接口) |
#### 修改文件
| 文件 | 项目 | 变更 |
|------|------|------|
| `AutoBidPriceServiceImpl.java` | bid | 添加数据库优先读取路径 + Heracles回退 + 新梯度价格计算 |
| `AutoBidPriceService.java` | bid | 新增 `getSmartConfigByChannelId()` 方法签名 |
---
### 4.10 验证方案
1. **建表验证**:执行DDL,确认表结构与唯一键约束正确
2. **CRUD验证**:通过Dubbo接口逐个测试新增/编辑/删除/查询/开关操作
3. **校验验证**:测试各边界条件(渠道重复、梯度金额递增/递减、范围越界)
4. **日志验证**:每次操作后检查日志表记录的operation_type和operation_desc格式
5. **迁移验证**:对比数据库配置与原dynamic.properties配置产生的出价结果一致性
6. **回退验证**:删除数据库配置后,确认系统回退到Heracles配置正常工作
7. **HTTP接口验证**:通过product-api的HTTP接口测试完整的前端调用链路,确认接口返回格式正确、操作人信息正确获取
claudeCode通过抓取项目信息,了解项目结构,生成对应代码,这部分体现了claudeCode的上下文能力,文件名称,现有组件的使用都在计划文档里很好的生成了
五 执行实施方案
这个阶段切换plan模式到默认模式,让claudeCode执行实施方案,一般有计划说明的情况,claudeCode会很快执行完,这里面需要注意的是,数据库的脚本是由我手动去执行的,另外考虑到修改代码的安全性,这里使用默认模式,当修改代码时,claudeCode会让我每次确认下是否要修改对应代码
六 代码检查及单元测试
通过对代码的检查发现,异常的返回不是我期望的,对这一处进行了修改,单元测试的信息如下,截取部分
@Test
public void addConfigDuplicate() {
try {
SmartPriceConfigPo configPo = new SmartPriceConfigPo();
configPo.setChannelId("900053"); // 已存在
configPo.setChannelName("小小");
configPo.setForceBid(1);
configPo.setBidEndBeforeSeconds(30);
configPo.setTierConfigJson("[{"tierAmount":0,"bidCoefficient":2.0,"defaultPrice":10}]");
configPo.setDefaultPrice(1000L);
configPo.setAutoBidSwitch(0);
configPo.setCreator("testUser2");
Boolean result = smartPriceConfigService.addConfig(configPo);
log.info("重复渠道新增(不应该成功):{}", result);
} catch (RuntimeException e) {
log.info("重复渠道新增异常(预期):{}", e.getMessage());
}
}
执行单元测试,返回成功,claudeCode会自动生成参数,提升了很大的效率
七 总结
表单在开发中存在很大的场景,以往的表单开发大概需要16h,包含测试等,而现在claudeCode执行以上的过程不到3个小时,加上联调不超过6小时,对于表单场景而言,是有极大的提升,效率提升了50%以上,除此之外这个需求也不止在表单,还在读取配置的地方修改了代码,工具都准确的找到了,只是在读取配置的场景中,存在一些修改错误,需要人去检查和干预,但在表单的场景中,已经有了极大的帮助