功能概述 商品更新记录功能用于跟踪和管理小象买菜系统中商品的变更历史,包括价格调整、库存变化、商品信息修改等操作,便于审计、回滚和数据分析。 数据库设计 商品更新记录表(product_update_log) ```sql CREATETABLEproduct_update
功能概述
商品更新记录功能用于跟踪和管理小象买菜系统中商品的变更历史,包括价格调整、库存变化、商品信息修改等操作,便于审计、回滚和数据分析。
数据库设计
商品更新记录表(product_update_log)
```sql
CREATE TABLE product_update_log (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 记录ID,
product_id BIGINT NOT NULL COMMENT 商品ID,
update_type VARCHAR(20) NOT NULL COMMENT 更新类型(price/stock/info),
old_value TEXT COMMENT 旧值(JSON格式),
new_value TEXT COMMENT 新值(JSON格式),
update_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 更新时间,
operator_id BIGINT COMMENT 操作人ID,
operator_name VARCHAR(50) COMMENT 操作人姓名,
remark VARCHAR(255) COMMENT 备注,
INDEX idx_product_id (product_id),
INDEX idx_update_time (update_time)
) ENGINE=InnoDB COMMENT=商品更新记录表;
```
后端实现
1. 使用AOP切面记录更新
```java
@Aspect
@Component
public class ProductUpdateAspect {
@Autowired
private ProductUpdateLogService logService;
@AfterReturning(pointcut = "execution(* com.xiaoxiang.service.ProductService.update*(..)) && args(product,..)",
returning = "result")
public void afterProductUpdate(JoinPoint joinPoint, Product product, boolean result) {
if (!result) return;
// 获取方法名判断更新类型
String methodName = joinPoint.getSignature().getName();
String updateType = "info"; // 默认信息更新
if (methodName.contains("Price")) {
updateType = "price";
} else if (methodName.contains("Stock")) {
updateType = "stock";
}
// 获取旧值(需要从数据库查询)
Product oldProduct = productService.getById(product.getId());
// 创建更新记录
ProductUpdateLog log = new ProductUpdateLog();
log.setProductId(product.getId());
log.setUpdateType(updateType);
log.setOldValue(JSON.toJSONString(oldProduct));
log.setNewValue(JSON.toJSONString(product));
log.setOperatorId(SecurityUtils.getUserId()); // 假设有获取当前用户的方法
log.setOperatorName(SecurityUtils.getUserName());
logService.save(log);
}
}
```
2. 单独的记录服务
```java
@Service
public class ProductUpdateLogService {
@Autowired
private ProductUpdateLogMapper logMapper;
public void recordUpdate(Long productId, String updateType,
Object oldValue, Object newValue,
Long operatorId, String operatorName) {
ProductUpdateLog log = new ProductUpdateLog();
log.setProductId(productId);
log.setUpdateType(updateType);
log.setOldValue(JSON.toJSONString(oldValue));
log.setNewValue(JSON.toJSONString(newValue));
log.setOperatorId(operatorId);
log.setOperatorName(operatorName);
logMapper.insert(log);
}
// 查询商品更新记录
public List
getUpdateLogs(Long productId,
Date startTime, Date endTime) {
// 实现查询逻辑
}
}
```
前端实现
1. 更新记录展示页面
```vue
商品更新记录
查看变更
更新类型: {{ currentLog.updateType }}
更新时间: {{ currentLog.updateTime }}
操作人: {{ currentLog.operatorName }}
旧值
{{ formatDiff(currentLog.oldValue) }} 新值
{{ formatDiff(currentLog.newValue) }}
<script>
export default {
data() {
return {
updateLogs: [],
dialogVisible: false,
currentLog: null
}
},
created() {
this.fetchUpdateLogs();
},
methods: {
fetchUpdateLogs() {
// 调用API获取更新记录
},
showDiff(log) {
this.currentLog = log;
this.dialogVisible = true;
},
formatDiff(jsonStr) {
try {
const obj = JSON.parse(jsonStr);
return JSON.stringify(obj, null, 2);
} catch {
return jsonStr;
}
}
}
}
<style>
.diff-container {
display: flex;
gap: 20px;
}
.diff-section {
flex: 1;
background: f5f5f5;
padding: 10px;
border-radius: 4px;
}
```
关键实现点
1. 变更类型分类:
- 价格更新(price)
- 库存更新(stock)
- 商品信息更新(info)
2. 数据存储:
- 使用JSON格式存储旧值和新值,便于扩展和解析
- 记录操作人和操作时间,便于审计
3. 性能考虑:
- 对频繁更新的字段(如库存)可以考虑异步记录
- 定期归档历史记录,避免表过大
4. 扩展功能:
- 添加变更原因字段
- 支持按商品、时间范围、操作人等条件筛选
- 添加变更通知功能(如价格变动通知)
部署与监控
1. 确保日志记录不会显著影响系统性能
2. 监控日志表增长情况,设置自动归档策略
3. 定期备份重要变更记录
这个实现方案可以根据实际业务需求进行调整和扩展,例如添加更详细的变更字段、实现更复杂的差异对比功能等。