功能概述
商品更新记录功能用于跟踪和管理小象买菜系统中商品信息的变更历史,包括价格调整、库存变化、商品上下架等操作记录。
数据库设计
商品更新记录表(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/status/info,
old_value TEXT COMMENT 旧值(JSON格式),
new_value TEXT COMMENT 新值(JSON格式),
update_by BIGINT COMMENT 操作人ID,
update_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 更新时间,
remark VARCHAR(255) COMMENT 备注信息,
INDEX idx_product_id (product_id),
INDEX idx_update_time (update_time)
) ENGINE=InnoDB COMMENT=商品更新记录表;
```
后端实现
1. 实体类
```java
@Data
public class ProductUpdateLog {
private Long id;
private Long productId;
private String updateType; // price, stock, status, info
private String oldValue; // JSON字符串
private String newValue; // JSON字符串
private Long updateBy;
private Date updateTime;
private String remark;
}
```
2. 服务层实现
```java
@Service
public class ProductUpdateLogService {
@Autowired
private ProductUpdateLogMapper productUpdateLogMapper;
/
* 记录商品更新
*/
public void recordUpdate(Long productId, String updateType,
String oldValue, String newValue,
Long operatorId, String remark) {
ProductUpdateLog log = new ProductUpdateLog();
log.setProductId(productId);
log.setUpdateType(updateType);
log.setOldValue(oldValue);
log.setNewValue(newValue);
log.setUpdateBy(operatorId);
log.setRemark(remark);
productUpdateLogMapper.insert(log);
}
/
* 查询商品更新记录
*/
public List
getUpdateLogsByProduct(Long productId,
Date startTime,
Date endTime) {
ProductUpdateLogExample example = new ProductUpdateLogExample();
example.createCriteria()
.andProductIdEqualTo(productId)
.andUpdateTimeBetween(startTime, endTime);
return productUpdateLogMapper.selectByExample(example);
}
}
```
3. 业务逻辑集成
在商品服务中,在执行更新操作时记录变更:
```java
@Service
public class ProductService {
@Autowired
private ProductUpdateLogService productUpdateLogService;
@Transactional
public void updateProductPrice(Long productId, BigDecimal newPrice, Long operatorId) {
// 1. 获取旧价格
Product product = productMapper.selectByPrimaryKey(productId);
BigDecimal oldPrice = product.getPrice();
// 2. 更新价格
product.setPrice(newPrice);
productMapper.updateByPrimaryKey(product);
// 3. 记录更新日志
JSONObject oldJson = new JSONObject();
oldJson.put("price", oldPrice);
JSONObject newJson = new JSONObject();
newJson.put("price", newPrice);
productUpdateLogService.recordUpdate(
productId,
"price",
oldJson.toJSONString(),
newJson.toJSONString(),
operatorId,
"调整商品价格"
);
}
}
```
前端实现
商品更新记录列表页面
```javascript
// Vue组件示例
export default {
data() {
return {
productId: this.$route.params.id,
updateLogs: [],
loading: false
}
},
created() {
this.fetchUpdateLogs();
},
methods: {
async fetchUpdateLogs() {
this.loading = true;
try {
const response = await api.get(`/products/${this.productId}/update-logs`);
this.updateLogs = response.data;
} catch (error) {
console.error(获取更新记录失败:, error);
} finally {
this.loading = false;
}
}
}
}
```
更新记录展示组件
```html
商品更新记录
{{ formatDate(row.updateTime) }}
{{ getUpdateTypeName(row.updateType) }}
{{ getOperatorName(row.updateBy) }}
查看详情
更新类型: {{ getUpdateTypeName(currentLog.updateType) }}
更新时间: {{ formatDate(currentLog.updateTime) }}
操作人: {{ getOperatorName(currentLog.updateBy) }}
备注: {{ currentLog.remark }}
变更前:
{{ formatChangeData(currentLog.oldValue) }} 变更后:
{{ formatChangeData(currentLog.newValue) }}
```
高级功能扩展
1. 变更对比可视化
```javascript
// 在showChangeDetail方法中
showChangeDetail(log) {
this.currentLog = log;
this.dialogVisible = true;
// 使用diff库对比JSON变化
const diff = jsonDiff.diff(
JSON.parse(log.oldValue),
JSON.parse(log.newValue)
);
this.diffResult = diff;
}
```
2. 自动捕获变更(使用AOP)
```java
@Aspect
@Component
public class ProductUpdateAspect {
@Autowired
private ProductUpdateLogService logService;
@Around("execution(* com.xiaoxiang.service.ProductService.update*(..))")
public Object aroundUpdate(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取方法参数
Object[] args = joinPoint.getArgs();
Long productId = (Long) args[0]; // 假设第一个参数是productId
// 执行原方法前获取旧值
Product oldProduct = productMapper.selectByPrimaryKey(productId);
// 执行原方法
Object result = joinPoint.proceed();
// 执行后获取新值
Product newProduct = productMapper.selectByPrimaryKey(productId);
// 记录变更
recordChanges(oldProduct, newProduct, getOperatorId(), getMethodName(joinPoint));
return result;
}
private void recordChanges(Product oldProduct, Product newProduct,
Long operatorId, String methodName) {
// 实现变更记录逻辑
}
}
```
部署与监控
1. 日志归档策略:设置按月分表的归档策略,保留最近6个月的详细记录
2. 性能监控:监控高频更新商品的记录写入性能
3. 数据安全:对敏感信息(如成本价)进行脱敏处理
测试用例
1. 正常流程测试:
- 更新商品价格,验证记录是否正确
- 修改库存,检查库存变更记录
2. 异常流程测试:
- 并发更新同一商品,检查记录是否完整
- 更新非存在商品,检查系统处理
3. 边界条件测试:
- 更新空值字段
- 更新超长文本字段
通过以上实现,小象买菜系统可以完整记录商品信息的变更历史,为运营分析、问题追溯和合规审计提供有力支持。