功能概述 商品更新记录功能用于跟踪和管理小象买菜系统中商品信息的变更历史,包括价格调整、库存变化、商品上下架等操作记录,便于审计和问题追溯。 数据库设计 商品更新记录表(product_update_log) ```sql CREATETABLEproduct_up
功能概述
商品更新记录功能用于跟踪和管理小象买菜系统中商品信息的变更历史,包括价格调整、库存变化、商品上下架等操作记录,便于审计和问题追溯。
数据库设计
商品更新记录表(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_CHANGE, STOCK_CHANGE, STATUS_CHANGE等),
old_value TEXT COMMENT 旧值(JSON格式),
new_value TEXT COMMENT 新值(JSON格式),
update_by VARCHAR(50) COMMENT 操作人,
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 更新时间,
remark VARCHAR(255) COMMENT 备注信息,
INDEX idx_product_id (product_id),
INDEX idx_update_time (update_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=商品更新记录表;
```
后端实现
1. 实体类定义
```java
@Data
public class ProductUpdateLog {
private Long id;
private Long productId;
private String updateType;
private String oldValue;
private String newValue;
private String updateBy;
private LocalDateTime updateTime;
private String remark;
}
```
2. 记录更新逻辑
在商品服务中添加更新记录的逻辑:
```java
@Service
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductUpdateLogMapper productUpdateLogMapper;
@Override
@Transactional
public void updateProductPrice(Long productId, BigDecimal newPrice, String operator) {
// 1. 获取原商品信息
Product product = productMapper.selectById(productId);
BigDecimal oldPrice = product.getPrice();
// 2. 更新商品价格
product.setPrice(newPrice);
productMapper.updateById(product);
// 3. 记录更新日志
ProductUpdateLog log = new ProductUpdateLog();
log.setProductId(productId);
log.setUpdateType("PRICE_CHANGE");
log.setOldValue(oldPrice.toString());
log.setNewValue(newPrice.toString());
log.setUpdateBy(operator);
log.setRemark("商品价格调整");
productUpdateLogMapper.insert(log);
}
// 其他更新方法类似...
}
```
3. 使用AOP统一处理更新记录(可选)
更优雅的实现方式是使用AOP统一处理:
```java
@Aspect
@Component
public class ProductUpdateLogAspect {
@Autowired
private ProductUpdateLogMapper productUpdateLogMapper;
@Pointcut("execution(* com.example.service.ProductService.update*(..)) && @annotation(com.example.annotation.LogUpdate)")
public void productUpdatePointcut() {}
@Around("productUpdatePointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法参数
Object[] args = joinPoint.getArgs();
Long productId = (Long) args[0]; // 假设第一个参数是productId
String operator = getCurrentOperator(); // 获取当前操作人
// 执行原方法
Object result = joinPoint.proceed();
// 获取方法返回值中的新值(需要根据实际返回类型调整)
// 这里简化处理,实际应根据具体方法实现
// 记录日志(实际应从数据库或缓存获取旧值)
ProductUpdateLog log = new ProductUpdateLog();
log.setProductId(productId);
log.setUpdateType(determineUpdateType(joinPoint));
log.setOldValue(getOldValueFromDB(productId)); // 需要实现
log.setNewValue(getNewValueFromResult(result)); // 需要实现
log.setUpdateBy(operator);
productUpdateLogMapper.insert(log);
return result;
}
// 其他辅助方法...
}
```
前端实现
1. 更新记录列表页面
```vue
商品更新记录
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
<script>
export default {
data() {
return {
updateLogs: [],
currentPage: 1,
pageSize: 10,
total: 0,
productId: this.$route.params.id
}
},
created() {
this.fetchUpdateLogs();
},
methods: {
fetchUpdateLogs() {
this.$api.getProductUpdateLogs({
productId: this.productId,
pageNum: this.currentPage,
pageSize: this.pageSize
}).then(response => {
this.updateLogs = response.data.list;
this.total = response.data.total;
});
},
handleSizeChange(val) {
this.pageSize = val;
this.fetchUpdateLogs();
},
handleCurrentChange(val) {
this.currentPage = val;
this.fetchUpdateLogs();
}
}
}
```
2. 更新记录详情弹窗
```vue
{{ log.updateTime }}
{{ log.updateType }}
{{ log.updateBy }}
{{ log.remark }}
{{ formatValue(log.oldValue) }}
{{ formatValue(log.newValue) }}
<script>
export default {
props: {
log: Object
},
data() {
return {
dialogVisible: false
}
},
methods: {
formatValue(value) {
try {
const obj = JSON.parse(value);
return JSON.stringify(obj, null, 2);
} catch (e) {
return value;
}
}
}
}
```
高级功能扩展
1. 差异对比功能:
- 在前端实现新旧值的差异高亮显示
- 使用diff算法对比JSON结构变化
2. 批量导出功能:
- 添加导出Excel按钮,支持按时间范围导出更新记录
3. 操作人信息增强:
- 记录操作人的IP地址、设备信息等
- 集成SSO系统获取更详细的用户信息
4. 自动回滚功能:
- 基于更新记录实现商品信息的回滚操作
5. 变更通知:
- 重要变更(如价格调整)通过企业微信/短信通知相关人员
注意事项
1. 对于频繁更新的字段(如库存),考虑异步记录更新日志或批量写入
2. 更新记录应保留足够长的时间,根据业务需求设置合理的归档策略
3. 对于敏感操作(如价格调整),应增加额外的审批流程
4. 考虑记录操作来源(如API、后台管理、定时任务等)
以上实现方案可根据实际业务需求和技术栈进行调整和优化。