010-53388338

小象买菜系统:商品更新记录功能设计与多方案实现

分类:IT频道 时间:2026-01-11 16:55 浏览:33
概述
    功能概述    商品更新记录功能用于跟踪小象买菜系统中商品信息的变更历史,包括价格调整、库存变化、商品上下架等操作记录。这对于系统审计、数据分析和问题排查都非常重要。    数据库设计    商品更新记录表(product_update_log)    ```sql  CREATETABLE
内容
  
   功能概述
  
  商品更新记录功能用于跟踪小象买菜系统中商品信息的变更历史,包括价格调整、库存变化、商品上下架等操作记录。这对于系统审计、数据分析和问题排查都非常重要。
  
   数据库设计
  
   商品更新记录表(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_time DATETIME NOT NULL 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 DEFAULT CHARSET=utf8mb4 COMMENT=商品更新记录表;
  ```
  
   实现方案
  
   1. 基于AOP的实现方式(推荐)
  
  ```java
  @Aspect
  @Component
  public class ProductUpdateAspect {
  
   @Autowired
   private ProductUpdateLogService productUpdateLogService;
  
   @Autowired
   private OperatorContext operatorContext; // 假设有操作人上下文
  
   // 拦截商品服务中的更新方法
   @AfterReturning(pointcut = "execution(* com.xiaoxiang.service.ProductService.update*(..)) && args(productId,..)",
   returning = "result")
   public void afterProductUpdate(JoinPoint joinPoint, Long productId, boolean result) {
   if (!result) return;
  
   // 获取方法名判断更新类型
   String methodName = joinPoint.getSignature().getName();
   String updateType = "";
   Map oldValues = new HashMap<>();
   Map newValues = new HashMap<>();
  
   // 根据方法名确定更新类型和获取新旧值
   switch (methodName) {
   case "updatePrice":
   updateType = "price";
   // 从参数中获取新旧价格
   Object[] args = joinPoint.getArgs();
   // 假设参数顺序为productId, oldPrice, newPrice
   oldValues.put("price", args[1]);
   newValues.put("price", args[2]);
   break;
   case "updateStock":
   updateType = "stock";
   // 类似处理库存更新
   break;
   case "updateStatus":
   updateType = "status";
   // 处理上下架状态
   break;
   case "updateProductInfo":
   updateType = "info";
   // 处理商品信息更新
   break;
   default:
   return;
   }
  
   // 记录更新日志
   ProductUpdateLog log = new ProductUpdateLog();
   log.setProductId(productId);
   log.setUpdateType(updateType);
   log.setOldValue(JSON.toJSONString(oldValues));
   log.setNewValue(JSON.toJSONString(newValues));
   log.setOperatorId(operatorContext.getOperatorId());
   log.setOperatorName(operatorContext.getOperatorName());
  
   productUpdateLogService.save(log);
   }
  }
  ```
  
   2. 手动记录方式(适用于简单场景)
  
  ```java
  @Service
  public class ProductServiceImpl implements ProductService {
  
   @Autowired
   private ProductUpdateLogService productUpdateLogService;
  
   @Autowired
   private OperatorContext operatorContext;
  
   @Override
   public boolean updatePrice(Long productId, BigDecimal oldPrice, BigDecimal newPrice) {
   // 1. 执行价格更新逻辑
   boolean result = productMapper.updatePrice(productId, newPrice) > 0;
  
   // 2. 记录更新日志
   if (result) {
   ProductUpdateLog log = new ProductUpdateLog();
   log.setProductId(productId);
   log.setUpdateType("price");
   log.setOldValue(oldPrice.toString());
   log.setNewValue(newPrice.toString());
   log.setOperatorId(operatorContext.getOperatorId());
   log.setOperatorName(operatorContext.getOperatorName());
  
   productUpdateLogService.save(log);
   }
  
   return result;
   }
  
   // 其他更新方法类似...
  }
  ```
  
   3. 商品更新记录服务实现
  
  ```java
  @Service
  public class ProductUpdateLogServiceImpl implements ProductUpdateLogService {
  
   @Autowired
   private ProductUpdateLogMapper productUpdateLogMapper;
  
   @Override
   public void save(ProductUpdateLog log) {
   productUpdateLogMapper.insert(log);
   }
  
   @Override
   public List getUpdateHistory(Long productId, Date startTime, Date endTime) {
   return productUpdateLogMapper.selectByProductIdAndTimeRange(productId, startTime, endTime);
   }
  
   @Override
   public PageInfo getUpdateHistoryPage(Long productId, PageParam pageParam) {
   PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
   List logs = productUpdateLogMapper.selectByProductId(productId);
   return new PageInfo<>(logs);
   }
  }
  ```
  
   前端展示实现
  
   商品更新历史页面
  
  ```javascript
  // Vue组件示例
  export default {
   data() {
   return {
   productId: null,
   updateLogs: [],
   pagination: {
   currentPage: 1,
   pageSize: 10,
   total: 0
   }
   }
   },
   methods: {
   fetchUpdateLogs() {
   const params = {
   productId: this.productId,
   pageNum: this.pagination.currentPage,
   pageSize: this.pagination.pageSize
   };
  
   api.getProductUpdateLogs(params).then(response => {
   this.updateLogs = response.data.list;
   this.pagination.total = response.data.total;
   });
   },
   formatUpdateType(type) {
   const typeMap = {
   price: 价格调整,
   stock: 库存变更,
   status: 上下架状态,
   info: 商品信息
   };
   return typeMap[type] || type;
   },
   formatValue(value) {
   try {
   const json = JSON.parse(value);
   return Object.entries(json).map(([key, val]) => `${key}: ${val}`).join(, );
   } catch (e) {
   return value;
   }
   }
   },
   mounted() {
   this.productId = this.$route.params.productId;
   this.fetchUpdateLogs();
   }
  }
  ```
  
   模板示例
  
  ```html
  
  ```
  
   高级功能扩展
  
  1. 变更对比:在前端实现新旧值的差异高亮显示
  2. 批量导出:支持将更新记录导出为Excel
  3. 变更通知:重要变更(如价格大幅调整)自动发送通知
  4. 操作回滚:基于更新记录实现部分操作的回滚功能
  5. 数据可视化:对价格、库存等历史数据进行图表展示
  
   注意事项
  
  1. 性能考虑:高频更新的商品可能会产生大量记录,需考虑分表或归档策略
  2. 数据安全:敏感信息(如成本价)不应直接记录在日志中
  3. 一致性:确保在事务回滚时也能正确处理更新记录
  4. 存储优化:对于频繁更新的字段,可考虑单独建表或使用更高效的存储格式
  
  通过实现商品更新记录功能,小象买菜系统可以更好地追踪商品信息的变化,提高系统可维护性和数据可靠性。
评论