From f6239d1029da4c51ba3b2cec790f7399a210a3df Mon Sep 17 00:00:00 2001
From: zepengdev <lzpsmith@outlook.com>
Date: Sat, 19 Jul 2025 16:13:27 +0800
Subject: [PATCH] feat: 优化商品和店铺

---
 oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java |   34 +++++++++--
 oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantServiceImpl.java     |    3 +
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java         |    2 
 oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java          |   10 +++
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java      |   14 ++++
 oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAuditServiceImpl.java    |    9 +++
 oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java                          |    3 +
 oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAuditService.java             |    8 ++
 oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java                  |   14 ++--
 oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductAuditController.java             |    2 
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductAuditData.java             |    6 +
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreAuditData.java                 |    1 
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductRevisionRecord.java        |   18 ------
 oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml                                  |    6 +
 14 files changed, 93 insertions(+), 37 deletions(-)

diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java
index 566ea69..2c5e76f 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java
@@ -58,6 +58,9 @@
     @ApiModelProperty(value = "状态")
     private Integer status;
 
+    @ApiModelProperty(value = "上架状态")
+    private Integer shelfStatus;
+
     @NotBlank
     @ApiModelProperty(value = "主图片")
     private String mainImageId;
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductAuditData.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductAuditData.java
index 7f8f95d..d383ca0 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductAuditData.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductAuditData.java
@@ -1,5 +1,6 @@
 package com.oying.modules.pc.product.domain.dto;
 
+import com.oying.modules.pc.product.domain.Product;
 import com.oying.modules.pc.store.domain.Store;
 import com.oying.modules.pc.store.domain.dto.StoreRevisionRecord;
 import lombok.Data;
@@ -7,7 +8,8 @@
 @Data
 public class ProductAuditData {
 
-    private Store store;
-    private StoreRevisionRecord revisionRecord;
+    private Product originalStore;
+    private Product product;
+    private ProductRevisionRecord revisionRecord;
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java
index 644f932..860b8b4 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java
@@ -21,6 +21,8 @@
 
     private Integer status;
 
+    private Integer shelfStatus;
+
     private Long categoryId;
 
     private Long secondCategoryId;
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductRevisionRecord.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductRevisionRecord.java
index ae1e04a..20770cb 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductRevisionRecord.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductRevisionRecord.java
@@ -10,23 +10,5 @@
 
 @Data
 public class ProductRevisionRecord {
-
-    @ApiModelProperty(value = "店铺ID")
-    private Long storeId;
-
-    @ApiModelProperty(value = "店铺名称")
-    private String storeName;
-
-    @ApiModelProperty(value = "资质")
-    private List<StoreQualification> qualifications = new ArrayList<>();
-    
-    @ApiModelProperty(value = "删除的资质")
-    private List<Long> deletedQualificationIds = new ArrayList<>();
-
-    @ApiModelProperty(value = "修改的资质")
-    private List<StoreQualificationUpdateRequest> updatedQualifications = new ArrayList<>();
-
-    @ApiModelProperty(value = "新增的资质")
-    private List<StoreQualification> newQualifications = new ArrayList<>();
     
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductAuditController.java b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductAuditController.java
index 04d0bc8..8530d0c 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductAuditController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductAuditController.java
@@ -54,7 +54,7 @@
         return ResponseEntity.noContent().build();
     }
 
-    @PostMapping(value = "/verdict")
+    @PutMapping(value = "/verdict")
     @ApiOperation("处理审核")
     public ResponseEntity<?> submitAuditVerdict(@RequestBody ProductAudit resources) {
         auditService.processVerdict(resources);
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java
index 149958d..a0a2299 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java
@@ -76,7 +76,7 @@
         return ResponseEntity.ok(R.success(pageResult));
     }
 
-    @GetMapping(value = "/{productId}}")
+    @GetMapping(value = "/{productId}")
     @ApiOperation("查询商品")
     // @PreAuthorize("@el.check('product:list')")
     public ResponseEntity<?> getProduct(@PathVariable Long productId) {
@@ -87,8 +87,8 @@
         return ResponseEntity.ok(R.success(product));
     }
 
-    @GetMapping(value = "/{productId}}/details")
-    @ApiOperation("查询商品")
+    @GetMapping(value = "/{productId}/details")
+    @ApiOperation("查询商品详情")
     // @PreAuthorize("@el.check('product:list')")
     public ResponseEntity<?> getProductDetails(@PathVariable Long productId) {
         Product product = productService.getById(productId);
@@ -99,16 +99,16 @@
         return ResponseEntity.ok(R.success(product));
     }
 
-    @GetMapping(value = "/{productId}}/images")
-    @ApiOperation("查询商品")
+    @GetMapping(value = "/{productId}/images")
+    @ApiOperation("查询商品图片")
     // @PreAuthorize("@el.check('product:list')")
     public ResponseEntity<?> getProductImages(@PathVariable Long productId) {
         return ResponseEntity.ok(R.success(productImageService.queryImagesByProductId(productId)));
     }
 
 
-    @GetMapping(value = "/{productId}}/labels")
-    @ApiOperation("查询商品")
+    @GetMapping(value = "/{productId}/labels")
+    @ApiOperation("查询商品标签信息")
     // @PreAuthorize("@el.check('product:list')")
     public ResponseEntity<?> getProductLabels(@PathVariable Long productId) {
         return ResponseEntity.ok(R.success(productLabelService.queryLabelsByProductId(productId)));
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java
index 800f96f..899e619 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java
@@ -124,6 +124,16 @@
         return ResponseEntity.noContent().build();
     }
 
+    @PostMapping(value = "/delete")
+    @Log("批量删除商品")
+    @ApiOperation("批量删除商品")
+    //@PreAuthorize("@el.check('merchant:product:batchDel') " +
+    //        "and @storeMerchantOwnershipService.check(#storeId)")
+    public ResponseEntity<?> delProduct(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+        productMerchantService.batchDelete(ids);
+        return ResponseEntity.noContent().build();
+    }
+
     @PutMapping(value = "/{productId}/on")
     @Log("上架商品")
     @ApiOperation("上架商品")
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAuditService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAuditService.java
index 66ce99d..909c8f3 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAuditService.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAuditService.java
@@ -43,6 +43,14 @@
     ProductAudit getByProductId(Long productId);
 
     /**
+     * 是否有待审记录
+     *
+     * @param productId 必须的参数,不能为null
+     * @return 查询到的结果
+     */
+    boolean hasPendingByStoreId(Long productId);
+
+    /**
      * 创建
      *
      * @param resources /
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAuditServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAuditServiceImpl.java
index 6713397..e21362b 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAuditServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAuditServiceImpl.java
@@ -10,6 +10,7 @@
 import com.oying.modules.pc.product.events.ProductAuditVerdictEvent;
 import com.oying.modules.pc.product.mapper.ProductAuditMapper;
 import com.oying.modules.pc.product.service.ProductAuditService;
+import com.oying.modules.pc.store.domain.StoreAudit;
 import com.oying.utils.FileUtil;
 import com.oying.utils.PageResult;
 import com.oying.utils.PageUtil;
@@ -56,6 +57,14 @@
     }
 
     @Override
+    public boolean hasPendingByStoreId(Long productId) {
+        LambdaQueryWrapper<ProductAudit> wrapper = new LambdaQueryWrapper<ProductAudit>()
+                .eq(ProductAudit::getProductId, productId)
+                .eq(ProductAudit::getStatus, AuditStatusEnum.PENDING.getValue());
+        return productAuditMapper.selectCount(wrapper) > 0;
+    }
+
+    @Override
     @Transactional(rollbackFor = Exception.class)
     public void create(ProductAudit resources) {
         productAuditMapper.insert(resources);
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java
index 583047a..24ed038 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java
@@ -2,6 +2,7 @@
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjUtil;
+import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.oying.exception.BadRequestException;
 import com.oying.exception.EntityNotFoundException;
@@ -12,6 +13,7 @@
 import com.oying.modules.pc.product.domain.ProductAudit;
 import com.oying.modules.pc.product.domain.ProductImage;
 import com.oying.modules.pc.product.domain.ProductLabel;
+import com.oying.modules.pc.product.domain.dto.ProductAuditData;
 import com.oying.modules.pc.product.domain.dto.ProductImageCreateRequest;
 import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest;
 import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest;
@@ -76,7 +78,7 @@
     @Transactional(rollbackFor = Exception.class)
     public void update(ProductMerchantUpdateRequest request) {
         Product existingProduct = this.findOrThrow(request.getProductId());
-        this.validateApprovedStatus(existingProduct.getStatus());
+        this.validateApprovedStatus(existingProduct.getShelfStatus());
         this.processImagesUpdate(request);
         this.processLabelsUpdate(request);
         BeanUtils.copyProperties(request, existingProduct);
@@ -87,7 +89,7 @@
     @Transactional(rollbackFor = Exception.class)
     public void updateImages(ProductMerchantUpdateRequest request) {
         Product existingProduct = this.findOrThrow(request.getProductId());
-        this.validateApprovedStatus(existingProduct.getStatus());
+        this.validateApprovedStatus(existingProduct.getShelfStatus());
         this.findOrThrow(request.getProductId());
         this.processImagesUpdate(request);
     }
@@ -96,7 +98,7 @@
     @Transactional(rollbackFor = Exception.class)
     public void updateLabels(ProductMerchantUpdateRequest request) {
         Product existingProduct = this.findOrThrow(request.getProductId());
-        this.validateApprovedStatus(existingProduct.getStatus());
+        this.validateApprovedStatus(existingProduct.getShelfStatus());
         this.findOrThrow(request.getProductId());
         this.processImagesUpdate(request);
     }
@@ -109,10 +111,22 @@
 
     @Override
     public void putOnShelf(Long productId) {
+        Product existingProduct = productService.getById(productId);
+        if (ProductStatusEnum.AVAILABLE.getValue().equals(existingProduct.getShelfStatus())) {
+            throw new BadRequestException("商品已上架");
+        }
+
+        if (productAuditService.hasPendingByStoreId(productId)) {
+            throw new BadRequestException("已在审核中");
+        }
+
         ProductAudit audit = new ProductAudit();
         audit.setProductId(productId);
         audit.setType(ProductChangeTypeEnum.PUT_ON_SHELF.name());
         audit.setStatus(AuditStatusEnum.PENDING.getValue());
+        ProductAuditData auditData = new ProductAuditData();
+        auditData.setOriginalStore(existingProduct);
+        audit.setData(JSON.toJSONString(auditData));
         productAuditService.create(audit);
         LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
                 .eq(Product::getProductId, productId)
@@ -122,9 +136,14 @@
 
     @Override
     public void takeOffShelf(Long productId) {
+        Product existingProduct = productService.getById(productId);
+        if (ProductStatusEnum.NO_AVAILABLE.getValue().equals(existingProduct.getShelfStatus())) {
+            return;
+        }
         LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
                 .eq(Product::getProductId, productId)
-                .set(Product::getStatus, ProductStatusEnum.NO_AVAILABLE.getValue());
+                .set(Product::getStatus, ProductStatusEnum.NO_AVAILABLE.getValue())
+                .set(Product::getShelfStatus, ProductStatusEnum.NO_AVAILABLE.getValue());
         productService.update(wrapper);
     }
 
@@ -179,11 +198,14 @@
 
     private void handlePutOnShelfAuditEvent(ProductAudit audit) {
         AuditStatusEnum auditStatus = AuditStatusEnum.get(audit.getStatus());
+        Product existingProduct = productService.getById(audit.getProductId());
         if (AuditStatusEnum.APPROVED.equals(auditStatus)) {
-            Product existingProduct = productService.getById(audit.getProductId());
+            existingProduct.setStatus(ProductStatusEnum.AVAILABLE.getValue());
+            existingProduct.setShelfStatus(ProductStatusEnum.AVAILABLE.getValue());
+        } else {
             existingProduct.setStatus(auditStatus.getValue());
-            productService.updateById(existingProduct);
         }
+        productService.updateById(existingProduct);
     }
 
     private void validateApprovedStatus(Integer status) {
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreAuditData.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreAuditData.java
index d60c325..47fe004 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreAuditData.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreAuditData.java
@@ -6,6 +6,7 @@
 @Data
 public class StoreAuditData {
 
+    private Store originalStore;
     private Store store;
     private StoreRevisionRecord revisionRecord;
 
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java
index d193a8e..6eefbd2 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java
@@ -126,10 +126,20 @@
     @DeleteMapping
     @Log("删除店铺类目")
     @ApiOperation("删除店铺类目")
-    @PreAuthorize("@el.check('storeCategory:del')" +
-            " and @storeMerchantOwnershipService.check(#storeId)")
+    /*@PreAuthorize("@el.check('storeCategory:del')" +
+            " and @storeMerchantOwnershipService.check(#storeId)")*/
     public ResponseEntity<?> deleteStoreCategory(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
         storeCategoryService.deleteAll(ids);
         return ResponseEntity.noContent().build();
     }
+
+    @PostMapping(value = "/delete")
+    @Log("删除店铺类目")
+    @ApiOperation("删除店铺类目")
+    /*@PreAuthorize("@el.check('storeCategory:del')" +
+            " and @storeMerchantOwnershipService.check(#storeId)")*/
+    public ResponseEntity<?> delStoreCategory(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+        storeCategoryService.deleteAll(ids);
+        return ResponseEntity.noContent().build();
+    }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantServiceImpl.java
index f3ce233..1915403 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantServiceImpl.java
@@ -65,6 +65,8 @@
             BeanUtil.copyProperties(request, existingStore, CopyOptions.create().setIgnoreNullValue(true));
             storeService.update(existingStore, true);
         } else if (AuditStatusEnum.APPROVED.equals(existingStatus)) {
+            Store originalStore = new Store();
+            BeanUtil.copyProperties(existingStore, originalStore, CopyOptions.create().setIgnoreNullValue(true));
             Store newStore = new Store();
             newStore.setQualifications(ListUtil.of());
             BeanUtil.copyProperties(request, newStore, CopyOptions.create().setIgnoreNullValue(true));
@@ -95,6 +97,7 @@
             StoreRevisionRecord revisionRecord = new StoreRevisionRecord();
             BeanUtil.copyProperties(request, revisionRecord, CopyOptions.create().setIgnoreNullValue(true));
             StoreAuditData auditData = new StoreAuditData();
+            auditData.setOriginalStore(originalStore);
             auditData.setStore(newStore);
             auditData.setRevisionRecord(revisionRecord);
             this.createLatestModification(request.getStoreId(), StoreChangeTypeEnum.STORE_UPDATE, auditData);
diff --git a/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml b/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml
index 209639f..ee5bc4f 100644
--- a/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml
+++ b/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml
@@ -11,6 +11,7 @@
         <result column="category_id" property="categoryId"/>
         <result column="second_category_id" property="secondCategoryId"/>
         <result column="status" property="status"/>
+        <result column="shelf_status" property="shelfStatus"/>
         <result column="main_image_id" property="mainImageId"/>
         <result column="main_image_Url" property="mainImageUrl"/>
         <result column="description" property="description"/>
@@ -33,7 +34,7 @@
     </resultMap>
 
     <sql id="Base_Column_List">
-        product_id, store_id, code, barcode, name, title, category_id, second_category_id, status, main_image_id, main_image_url, description, price, stock_quantity, min_purchase_quantity, warn_stock, weight, width, length, height, returns, self_pickup, deleted_flag, create_by, create_time, update_by, update_time, version
+        product_id, store_id, code, barcode, name, title, category_id, second_category_id, status, shelf_status, main_image_id, main_image_url, description, price, stock_quantity, min_purchase_quantity, warn_stock, weight, width, length, height, returns, self_pickup, deleted_flag, create_by, create_time, update_by, update_time, version
     </sql>
 
     <select id="findAll" resultMap="BaseResultMap">
@@ -56,6 +57,9 @@
             <if test="criteria.status != null">
                 and status = #{criteria.status}
             </if>
+            <if test="criteria.shelfStatus != null">
+                and shelf_status = #{criteria.shelfStatus}
+            </if>
             <if test="criteria.active != null">
                 and active = #{criteria.active}
             </if>

--
Gitblit v1.9.3