010-53388338

标题:小象买菜系统商品更新记录:功能、实现与扩展详解

分类:IT频道 时间:2026-03-03 02:35 浏览:11
概述
    功能概述    商品更新记录功能用于跟踪小象买菜系统中商品信息的变更历史,包括价格调整、库存变化、商品上下架等操作,便于管理员审计和问题追溯。    数据库设计    商品更新记录表(product_update_log)    ```sql  CREATETABLE`product_upd
内容
  
   功能概述
  
  商品更新记录功能用于跟踪小象买菜系统中商品信息的变更历史,包括价格调整、库存变化、商品上下架等操作,便于管理员审计和问题追溯。
  
   数据库设计
  
   商品更新记录表(product_update_log)
  
  ```sql
  CREATE TABLE `product_update_log` (
   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID,
   `product_id` bigint(20) NOT NULL COMMENT 商品ID,
   `update_type` varchar(20) NOT NULL COMMENT 更新类型(price/stock/status/info),
   `old_value` text COMMENT 旧值(JSON格式),
   `new_value` text NOT NULL COMMENT 新值(JSON格式),
   `operator_id` bigint(20) DEFAULT NULL COMMENT 操作人ID,
   `operator_name` varchar(50) DEFAULT NULL COMMENT 操作人姓名,
   `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 更新时间,
   `ip_address` varchar(50) DEFAULT NULL COMMENT 操作IP,
   `remark` varchar(255) DEFAULT NULL COMMENT 备注,
   PRIMARY KEY (`id`),
   KEY `idx_product_id` (`product_id`),
   KEY `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; // price/stock/status/info
   private String oldValue; // JSON格式
   private String newValue; // JSON格式
   private Long operatorId;
   private String operatorName;
   private LocalDateTime updateTime;
   private String ipAddress;
   private String remark;
  }
  ```
  
   2. 创建更新记录Mapper接口
  
  ```java
  @Mapper
  public interface ProductUpdateLogMapper {
   int insert(ProductUpdateLog log);
  
   List selectByProductId(@Param("productId") Long productId);
  
   List selectByTimeRange(@Param("startTime") LocalDateTime startTime,
   @Param("endTime") LocalDateTime endTime);
  }
  ```
  
   3. 创建更新记录服务类
  
  ```java
  @Service
  public class ProductUpdateLogService {
  
   @Autowired
   private ProductUpdateLogMapper logMapper;
  
   /
   * 记录商品更新
   */
   public void recordUpdate(Long productId, String updateType,
   String oldValue, String newValue,
   Long operatorId, String operatorName,
   String ipAddress, String remark) {
   ProductUpdateLog log = new ProductUpdateLog();
   log.setProductId(productId);
   log.setUpdateType(updateType);
   log.setOldValue(oldValue);
   log.setNewValue(newValue);
   log.setOperatorId(operatorId);
   log.setOperatorName(operatorName);
   log.setIpAddress(ipAddress);
   log.setRemark(remark);
   logMapper.insert(log);
   }
  
   /
   * 查询商品更新记录
   */
   public List getUpdateLogs(Long productId) {
   return logMapper.selectByProductId(productId);
   }
  
   /
   * 查询时间范围内的更新记录
   */
   public List getUpdateLogsByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
   return logMapper.selectByTimeRange(startTime, endTime);
   }
  }
  ```
  
   4. 在商品服务中集成更新记录
  
  ```java
  @Service
  public class ProductService {
  
   @Autowired
   private ProductUpdateLogService logService;
  
   // 更新商品价格示例
   @Transactional
   public boolean updatePrice(Long productId, BigDecimal newPrice,
   Long operatorId, String operatorName, String ip) {
   // 1. 获取旧价格
   Product product = productMapper.selectById(productId);
   BigDecimal oldPrice = product.getPrice();
  
   // 2. 更新价格
   product.setPrice(newPrice);
   int result = productMapper.updateById(product);
  
   // 3. 记录更新日志
   if (result > 0) {
   JSONObject oldValue = new JSONObject();
   oldValue.put("price", oldPrice);
  
   JSONObject newValue = new JSONObject();
   newValue.put("price", newPrice);
  
   logService.recordUpdate(productId, "price",
   oldValue.toJSONString(),
   newValue.toJSONString(),
   operatorId, operatorName, ip, "价格调整");
   }
  
   return result > 0;
   }
  
   // 其他更新操作类似...
  }
  ```
  
   前端实现
  
   1. 商品更新记录列表页面
  
  ```vue
  
  
  <script>
  export default {
   data() {
   return {
   updateLogs: []
   }
   },
   created() {
   this.fetchUpdateLogs();
   },
   methods: {
   fetchUpdateLogs() {
   const productId = this.$route.params.productId;
   this.$api.get(`/product/update-logs/${productId}`).then(response => {
   this.updateLogs = response.data;
   });
   },
   getPriceFromJson(jsonStr) {
   try {
   const obj = JSON.parse(jsonStr);
   return obj.price;
   } catch (e) {
   return jsonStr;
   }
   },
   getStockFromJson(jsonStr) {
   try {
   const obj = JSON.parse(jsonStr);
   return obj.stock;
   } catch (e) {
   return jsonStr;
   }
   }
   }
  }
  
  ```
  
   2. 商品详情页添加更新记录入口
  
  ```vue
  
  
  <script>
  export default {
   methods: {
   viewUpdateLogs() {
   this.$router.push({
   name: ProductUpdateLogs,
   params: { productId: this.product.id }
   });
   }
   }
  }
  
  ```
  
   高级功能扩展
  
   1. 更新记录对比视图
  
  可以开发一个对比视图,直观展示变更前后的差异:
  
  ```vue
  
  
  <script>
  export default {
   props: {
   oldValue: String,
   newValue: String
   },
   computed: {
   formattedOldValue() {
   return this.formatJson(this.oldValue);
   },
   formattedNewValue() {
   return this.formatJson(this.newValue);
   }
   },
   methods: {
   formatJson(jsonStr) {
   try {
   const obj = JSON.parse(jsonStr);
   return JSON.stringify(obj, null, 2);
   } catch (e) {
   return jsonStr;
   }
   }
   }
  }
  
  
  <style scoped>
  .diff-container {
   display: flex;
   gap: 20px;
  }
  .diff-section {
   flex: 1;
   border: 1px solid   eee;
   padding: 10px;
   border-radius: 4px;
  }
  pre {
   background:   f5f5f5;
   padding: 10px;
   border-radius: 4px;
   overflow-x: auto;
  }
  
  ```
  
   2. 更新记录导出功能
  
  ```java
  @RestController
  @RequestMapping("/product/update-logs")
  public class ProductUpdateLogController {
  
   @Autowired
   private ProductUpdateLogService logService;
  
   @GetMapping("/export/{productId}")
   public void exportUpdateLogs(@PathVariable Long productId, HttpServletResponse response) {
   List logs = logService.getUpdateLogs(productId);
  
   // 设置响应头
   response.setContentType("application/vnd.ms-excel");
   response.setCharacterEncoding("utf-8");
   String fileName = URLEncoder.encode("商品更新记录", "UTF-8").replaceAll("\\+", "%20");
   response.setHeader("Content-disposition", "attachment;filename*=utf-8" + fileName + ".xlsx");
  
   // 创建Excel工作簿
   try (XSSFWorkbook workbook = new XSSFWorkbook()) {
   XSSFSheet sheet = workbook.createSheet("更新记录");
  
   // 创建表头
   Row headerRow = sheet.createRow(0);
   String[] headers = {"更新时间", "更新类型", "操作人", "操作IP", "变更前", "变更后", "备注"};
   for (int i = 0; i < headers.length; i++) {
   Cell cell = headerRow.createCell(i);
   cell.setCellValue(headers[i]);
   }
  
   // 填充数据
   for (int i = 0; i < logs.size(); i++) {
   ProductUpdateLog log = logs.get(i);
   Row row = sheet.createRow(i + 1);
  
   row.createCell(0).setCellValue(log.getUpdateTime().toString());
   row.createCell(1).setCellValue(log.getUpdateType());
   row.createCell(2).setCellValue(log.getOperatorName());
   row.createCell(3).setCellValue(log.getIpAddress());
   row.createCell(4).setCellValue(log.getOldValue());
   row.createCell(5).setCellValue(log.getNewValue());
   row.createCell(6).setCellValue(log.getRemark());
   }
  
   // 写入响应流
   try (OutputStream out = response.getOutputStream()) {
   workbook.write(out);
   }
   } catch (IOException e) {
   throw new RuntimeException("导出失败", e);
   }
   }
  }
  ```
  
   注意事项
  
  1. 性能考虑:对于高频更新的商品,更新记录可能会快速增长,考虑定期归档或分表存储
  2. 数据安全:敏感信息如成本价等不应记录在更新日志中
  3. 存储优化:对于频繁变更的字段,可以考虑只记录变更部分而非整个对象
  4. 审计要求:根据业务需求,可能需要保留更新记录一定年限
  5. 并发控制:在高并发场景下,确保更新记录的原子性
  
  通过以上实现,小象买菜系统可以完整记录商品信息的变更历史,为运营分析和问题排查提供有力支持。
评论
  • 下一篇

  • Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 8192 bytes) in /www/wwwroot/www.sjwxsc.com/config/function.php on line 274