一、功能概述
商品迭代记录功能用于跟踪和管理叮咚买菜平台上商品的变更历史,包括商品信息修改、上下架状态变化、价格调整等关键操作记录,以提升商品管理透明度和可追溯性。
二、系统架构设计
1. 数据库设计
```sql
-- 商品迭代记录表
CREATE TABLE product_iteration_log (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
product_id BIGINT NOT NULL COMMENT 商品ID,
change_type VARCHAR(50) NOT NULL COMMENT 变更类型(price/stock/status/info等),
old_value TEXT COMMENT 变更前值(JSON格式),
new_value TEXT COMMENT 变更后值(JSON格式),
change_field VARCHAR(100) COMMENT 具体变更字段,
operator_id BIGINT COMMENT 操作人ID,
operator_name VARCHAR(50) COMMENT 操作人姓名,
operation_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 操作时间,
ip_address VARCHAR(50) COMMENT 操作IP,
reason VARCHAR(255) COMMENT 变更原因,
INDEX idx_product_id (product_id),
INDEX idx_operation_time (operation_time)
);
```
2. 服务层设计
```java
// 商品迭代记录服务接口
public interface ProductIterationService {
/
* 记录商品变更
* @param productId 商品ID
* @param changeType 变更类型
* @param changeField 变更字段
* @param oldValue 旧值
* @param newValue 新值
* @param operator 操作人信息
* @param reason 变更原因
*/
void recordProductChange(Long productId, String changeType, String changeField,
String oldValue, String newValue, Operator operator, String reason);
/
* 查询商品变更历史
* @param productId 商品ID
* @param startTime 开始时间
* @param endTime 结束时间
* @param changeType 变更类型
* @param pageNum 页码
* @param pageSize 每页大小
* @return 变更记录列表
*/
Page
queryProductChanges(Long productId, Date startTime,
Date endTime, String changeType,
int pageNum, int pageSize);
}
```
三、核心功能实现
1. 变更记录拦截器实现
```java
@Aspect
@Component
public class ProductChangeAspect {
@Autowired
private ProductIterationService iterationService;
// 拦截商品服务中的修改方法
@AfterReturning(pointcut = "execution(* com.dingdong.product.service.ProductService.update*(..)) && args(product,..)",
returning = "result")
public void afterProductUpdate(JoinPoint joinPoint, Product product, Boolean result) {
if (!result) {
return;
}
Object[] args = joinPoint.getArgs();
Product oldProduct = // 从数据库获取修改前的商品信息
// 价格变更记录
if (args[0] instanceof ProductUpdateDTO dto && dto.getPrice() != null
&& !dto.getPrice().equals(oldProduct.getPrice())) {
iterationService.recordProductChange(
product.getId(),
"price",
"price",
oldProduct.getPrice().toString(),
dto.getPrice().toString(),
getOperator(),
dto.getChangeReason()
);
}
// 其他字段变更类似处理...
}
private Operator getOperator() {
// 从安全上下文中获取当前操作人信息
return SecurityContextHolder.getContext().getAuthentication() != null ?
(Operator) SecurityContextHolder.getContext().getAuthentication().getPrincipal() :
null;
}
}
```
2. 变更记录服务实现
```java
@Service
public class ProductIterationServiceImpl implements ProductIterationService {
@Autowired
private ProductIterationLogMapper iterationLogMapper;
@Override
@Transactional
public void recordProductChange(Long productId, String changeType, String changeField,
String oldValue, String newValue, Operator operator, String reason) {
ProductIterationLog log = new ProductIterationLog();
log.setProductId(productId);
log.setChangeType(changeType);
log.setChangeField(changeField);
log.setOldValue(oldValue);
log.setNewValue(newValue);
log.setOperatorId(operator != null ? operator.getId() : null);
log.setOperatorName(operator != null ? operator.getName() : "系统");
log.setReason(reason);
log.setIpAddress(getIpAddress());
iterationLogMapper.insert(log);
}
@Override
public Page queryProductChanges(Long productId, Date startTime,
Date endTime, String changeType,
int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List logs = iterationLogMapper.selectByConditions(
productId, startTime, endTime, changeType);
return new Page<>(logs);
}
private String getIpAddress() {
// 获取请求IP地址
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
return request.getRemoteAddr();
}
}
```
四、前端展示实现
1. 商品详情页变更历史标签页
```vue
商品变更历史
旧值: {{ row.oldValue }}
新值: {{ row.newValue }}
@current-change="handlePageChange"
:current-page="pagination.currentPage"
:page-size="pagination.pageSize"
layout="prev, pager, next"
:total="pagination.total">
<script>
export default {
data() {
return {
changeLogs: [],
pagination: {
currentPage: 1,
pageSize: 10,
total: 0
},
productId: this.$route.params.id
}
},
created() {
this.fetchChangeLogs();
},
methods: {
fetchChangeLogs() {
const params = {
productId: this.productId,
pageNum: this.pagination.currentPage,
pageSize: this.pagination.pageSize
};
api.getProductChangeLogs(params).then(res => {
this.changeLogs = res.data.list;
this.pagination.total = res.data.total;
});
},
handlePageChange(page) {
this.pagination.currentPage = page;
this.fetchChangeLogs();
}
}
}
<style>
.old-value {
color: f56c6c;
margin-right: 10px;
}
.new-value {
color: 67c23a;
}
```
五、关键业务场景实现
1. 商品价格变更记录
```java
// 在价格修改服务中添加记录
public boolean updateProductPrice(Long productId, BigDecimal newPrice, String changeReason) {
Product product = productMapper.selectById(productId);
if (product == null) {
throw new BusinessException("商品不存在");
}
// 记录变更前
String oldPrice = product.getPrice() != null ? product.getPrice().toString() : null;
// 执行更新
product.setPrice(newPrice);
int rows = productMapper.updateById(product);
if (rows > 0) {
// 记录变更
iterationService.recordProductChange(
productId,
"price",
"price",
oldPrice,
newPrice.toString(),
getOperator(),
changeReason
);
return true;
}
return false;
}
```
2. 商品上下架记录
```java
public boolean updateProductStatus(Long productId, Integer newStatus, String changeReason) {
Product product = productMapper.selectById(productId);
if (product == null) {
throw new BusinessException("商品不存在");
}
Integer oldStatus = product.getStatus();
product.setStatus(newStatus);
int rows = productMapper.updateById(product);
if (rows > 0) {
// 记录状态变更
iterationService.recordProductChange(
productId,
"status",
"status",
oldStatus != null ? oldStatus.toString() : null,
newStatus.toString(),
getOperator(),
changeReason
);
return true;
}
return false;
}
```
六、系统优化与扩展
1. 异步记录:对于高频变更操作,可采用消息队列异步记录变更,避免影响主流程性能
2. 变更对比:实现变更前后内容的差异高亮显示
3. 变更回滚:基于变更记录实现商品信息的回滚功能
4. 操作审计:结合安全系统,记录操作终端信息、地理位置等增强审计能力
5. 数据归档:定期将历史变更记录归档至冷存储,降低主库压力
七、测试用例示例
1. 正常场景测试:
- 修改商品价格,验证变更记录是否正确生成
- 上下架商品,验证状态变更记录
2. 异常场景测试:
- 无权限用户操作时是否记录失败
- 网络中断时变更记录是否重试或丢失
3. 性能测试:
- 高并发下变更记录的写入性能
- 历史记录查询的响应时间
通过以上实现,叮咚买菜系统可以完整记录商品全生命周期的变更历史,为商品管理、问题追溯和合规审计提供有力支持。