一、系统设计目标
1. 实现商品信息的全生命周期管理
2. 记录商品从上架到下架的完整变更历史
3. 支持商品信息的版本对比和回滚
4. 提供商品迭代数据的统计和分析
二、核心功能模块设计
1. 商品基础信息管理
- 商品ID、名称、分类、规格等基础信息
- 商品状态管理(待上架、已上架、已下架、售罄等)
- 商品价格体系(原价、促销价、会员价等)
2. 商品迭代记录模块
- 变更类型定义:
- 新增商品
- 修改商品信息(价格、库存、描述等)
- 上下架操作
- 删除商品(软删除)
- 记录字段:
- 变更ID
- 商品ID
- 变更类型
- 变更前内容(JSON格式)
- 变更后内容(JSON格式)
- 变更人
- 变更时间
- 变更原因/备注
3. 版本对比与回滚
- 支持查看任意两个版本之间的差异
- 支持将商品回滚到指定历史版本
- 回滚操作本身也会生成迭代记录
三、技术实现方案
1. 数据库设计
```sql
-- 商品主表
CREATE TABLE product (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
category_id BIGINT,
status TINYINT DEFAULT 0 COMMENT 0-待上架,1-已上架,2-已下架,
create_time DATETIME,
update_time DATETIME,
-- 其他基础字段...
UNIQUE KEY (name, category_id) -- 防止重复商品
);
-- 商品迭代记录表
CREATE TABLE product_history (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
product_id BIGINT NOT NULL,
change_type TINYINT NOT NULL COMMENT 1-新增,2-修改,3-上下架,4-删除,
old_data TEXT COMMENT 变更前数据(JSON),
new_data TEXT COMMENT 变更后数据(JSON),
operator VARCHAR(50) NOT NULL,
change_time DATETIME NOT NULL,
remark VARCHAR(500),
INDEX idx_product_id (product_id),
INDEX idx_change_time (change_time)
);
```
2. 关键代码实现
```java
// 商品服务类
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Autowired
private ProductHistoryRepository historyRepository;
// 更新商品信息
@Transactional
public Product updateProduct(Long productId, ProductUpdateDTO updateDTO, String operator) {
// 1. 获取当前商品信息
Product current = productRepository.findById(productId)
.orElseThrow(() -> new RuntimeException("商品不存在"));
// 2. 记录变更前数据
ProductHistory history = new ProductHistory();
history.setProductId(productId);
history.setChangeType(2); // 修改类型
history.setOldData(objectMapper.writeValueAsString(current));
history.setOperator(operator);
history.setChangeTime(LocalDateTime.now());
// 3. 更新商品
BeanUtils.copyProperties(updateDTO, current,
"id", "createTime", "version"); // 忽略ID和创建时间等字段
current.setUpdateTime(LocalDateTime.now());
Product updated = productRepository.save(current);
// 4. 记录变更后数据
history.setNewData(objectMapper.writeValueAsString(updated));
historyRepository.save(history);
return updated;
}
// 获取商品变更历史
public List
getProductHistory(Long productId) {
return historyRepository.findByProductIdOrderByChangeTimeDesc(productId);
}
// 版本对比
public Map compareVersions(Long productId, Long historyId1, Long historyId2) {
// 实现逻辑...
}
}
```
3. 前端展示方案
1. 商品详情页:
- 显示当前商品信息
- 添加"查看变更历史"按钮
2. 变更历史列表页:
- 按时间倒序展示所有变更记录
- 每条记录显示变更类型、操作人、时间、变更摘要
- 提供"查看详情"按钮查看完整变更内容
3. 版本对比视图:
- 左侧显示旧版本,右侧显示新版本
- 差异部分高亮显示
- 支持滑动对比
四、高级功能扩展
1. 自动化变更检测
- 使用AOP切面自动捕获商品服务的修改操作
- 自动生成变更记录,减少手动操作
```java
@Aspect
@Component
public class ProductChangeAspect {
@Autowired
private ProductHistoryRepository historyRepository;
@Autowired
private ObjectMapper objectMapper;
@Around("execution(* com.dingdong.service.ProductService.update*(..))")
public Object aroundUpdate(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法参数
Object[] args = joinPoint.getArgs();
Long productId = (Long) args[0];
String operator = "system"; // 实际应从上下文获取
// 执行原方法前获取当前状态
Product current = productRepository.findById(productId).orElse(null);
// 执行原方法
Object result = joinPoint.proceed();
// 执行后获取新状态
Product updated = productRepository.findById(productId).orElse(null);
// 记录变更
if (current != null && updated != null) {
ProductHistory history = new ProductHistory();
history.setProductId(productId);
history.setChangeType(2); // 修改
history.setOldData(objectMapper.writeValueAsString(current));
history.setNewData(objectMapper.writeValueAsString(updated));
history.setOperator(operator);
history.setChangeTime(LocalDateTime.now());
historyRepository.save(history);
}
return result;
}
}
```
2. 变更影响分析
- 分析商品变更对订单、库存、促销活动的影响
- 提供变更前的数据验证和预警
3. 审批流程集成
- 重要商品变更(如价格调整)需要审批
- 审批流程状态也记录在迭代历史中
五、部署与监控
1. 数据归档策略:
- 定期将超过1年的历史记录归档到冷存储
- 提供数据恢复工具
2. 监控指标:
- 商品变更频率
- 变更操作成功率
- 回滚操作次数
3. 告警机制:
- 异常频繁变更告警
- 关键字段变更告警(如价格大幅调整)
六、实施路线图
1. 第一阶段(1个月):
- 完成基础商品管理和迭代记录功能
- 实现手动记录变更
2. 第二阶段(1个月):
- 开发版本对比和回滚功能
- 实现AOP自动记录变更
3. 第三阶段(1个月):
- 开发变更影响分析
- 集成审批流程
- 完善监控和告警
该方案能够全面记录叮咚买菜系统中商品的迭代过程,为商品运营提供有力的数据支持,同时满足合规审计需求。