From a7d2a73c1b35af72c7d43ea8cfcfc9c1cda2b5f2 Mon Sep 17 00:00:00 2001
From: zepengdev <lzpsmith@outlook.com>
Date: Tue, 17 Jun 2025 16:00:42 +0800
Subject: [PATCH] feat(product): 优化商品图片功能 refactor(store): 重构店铺-商户关联 fix(api): 标准化接口字段

---
 oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java             |   18 
 oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java              |  110 ++
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java |    2 
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryCustomerController.java          |    3 
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java          |    6 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java                 |   61 -
 oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java                   |    8 
 oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java            |    8 
 oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java                     |    7 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java |    4 
 oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java                            |    5 
 oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java            |   59 +
 oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml                                      |   15 
 oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java                    |   40 +
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java                  |   59 
 oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java           |   24 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java            |   24 
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java             |    6 
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java             |   49 +
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java    |    2 
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java                  |   71 +
 oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml                                  |    6 
 oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java       |    4 
 oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java              |    6 
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java                  |   61 +
 oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java           |   10 
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java     |   14 
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java                          |   64 +
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java     |   31 
 oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java   |   62 +
 oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java              |   46 
 oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java          |    2 
 oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java                          |   71 ++
 oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java                     |    4 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java         |   18 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java    |   10 
 oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java                          |   34 
 oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java    |   94 ++
 oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml                                          |   43 +
 oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java                      |  120 ++
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java             |    8 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java                  |   32 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java                 |   37 +
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java        |   10 
 oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java                        |   24 
 oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java               |   16 
 oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java    |    2 
 oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java         |    5 
 oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java               |   16 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java         |   37 +
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java    |    7 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java         |    4 
 oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java                              |   28 
 oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java                 |  195 +++++-
 oying-tools/src/main/java/com/oying/utils/ObsUtils.java                                                  |   11 
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java     |   25 
 oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java     |   20 
 /dev/null                                                                                                |    5 
 oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java                                  |   42 +
 oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java           |   31 
 oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java             |    7 
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java     |   25 
 oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java   |    3 
 oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java    |    3 
 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java        |    9 
 65 files changed, 1,401 insertions(+), 482 deletions(-)

diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java
index 6f2552a..123cde5 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java
@@ -12,14 +12,12 @@
     public PlatformCategoryAdminView toPlatformCategoryResponse(PlatformCategory category) {
         PlatformCategoryAdminView categoryView = new PlatformCategoryAdminView();
         BeanUtil.copyProperties(category, categoryView);
-        categoryView.setIconUrl("");
         return categoryView;
     }
 
     public PlatformCategoryCustomerView toCustomerPlatformCategoryResponse(PlatformCategory category) {
         PlatformCategoryCustomerView categoryView = new PlatformCategoryCustomerView();
         BeanUtil.copyProperties(category, categoryView);
-        categoryView.setIconUrl("");
         return categoryView;
     }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java
index be896e5..8ff7ac6 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java
@@ -9,6 +9,9 @@
 @Data
 public class PlatformCategoryUpdateRequest {
 
+    @ApiModelProperty(value = "类目ID")
+    private Long categoryId;
+
     @ApiModelProperty(value = "类目名称", example = "超市")
     private String name;
 
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java b/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java
index 3dba34a..a840d1a 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java
@@ -1,5 +1,6 @@
 package com.oying.modules.pc.category.rest;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.oying.annotation.Log;
 import com.oying.modules.pc.category.converter.PlatformCategoryViewAssembler;
@@ -16,6 +17,7 @@
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -65,9 +67,9 @@
     //@PreAuthorize("@el.check('admin:platformCategory:updateById')")
     public ResponseEntity<?> updateById(@PathVariable Long categoryId,
                        @Validated @RequestBody PlatformCategoryUpdateRequest request) {
+        request.setCategoryId(ObjectUtils.defaultIfNull(request.getCategoryId(), categoryId));
         PlatformCategoryUpdateDto updateDto = new PlatformCategoryUpdateDto();
         BeanUtils.copyProperties(request, updateDto);
-        updateDto.setCategoryId(categoryId);
         categoryService.update(updateDto);
         return ResponseEntity.noContent().build();
     }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java b/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java
index fff0767..ef2292b 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java
@@ -2,6 +2,7 @@
 
 import com.oying.modules.pc.category.converter.PlatformCategoryViewAssembler;
 import com.oying.modules.pc.category.domain.PlatformCategory;
+import com.oying.modules.pc.category.domain.enums.PlatformCategoryEnum;
 import com.oying.modules.pc.category.view.PlatformCategoryCustomerView;
 import com.oying.modules.pc.category.domain.dto.PlatformCategoryQueryCriteria;
 import com.oying.modules.pc.category.service.PlatformCategoryService;
@@ -35,7 +36,7 @@
     //@PreAuthorize("@el.check('customer:platformCategory:list')")
     public ResponseEntity<?> queryPlatformCategory() {
         PlatformCategoryQueryCriteria criteria = new PlatformCategoryQueryCriteria();
-        criteria.setActive(1);
+        criteria.setActive(PlatformCategoryEnum.YES.getValue());
         List<PlatformCategory> platformCategoryList = categoryService.queryAll(criteria);
         List<PlatformCategoryCustomerView> responseList = platformCategoryList.stream().map(assembler::toCustomerPlatformCategoryResponse).collect(Collectors.toList());
         return ResponseEntity.ok(R.success(responseList));
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java b/oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java
index 490df6b..1e31261 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java
@@ -37,6 +37,14 @@
     List<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria);
 
     /**
+     * 查询
+     *
+     * @param ids /
+     * @return List<PlatformCategory>
+     */
+    List<PlatformCategory> queryBatchIds(List<Long> ids);
+
+    /**
      * 创建
      *
      * @param resources /
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java
index 7e74136..0424129 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java
@@ -1,26 +1,35 @@
 package com.oying.modules.pc.category.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.util.ObjUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.oying.exception.EntityExistException;
-import com.oying.modules.pc.category.converter.PlatformCategoryDtoAssembler;
+import com.oying.exception.EntityNotFoundException;
+import com.oying.modules.pc.category.converter.PlatformCategoryAssembler;
 import com.oying.modules.pc.category.domain.PlatformCategory;
 import com.oying.modules.pc.category.domain.dto.PlatformCategoryCreateRequest;
 import com.oying.modules.pc.category.domain.dto.PlatformCategoryQueryCriteria;
 import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateDto;
-import com.oying.modules.pc.category.domain.dto.PlatformCategoryUpdateRequest;
 import com.oying.modules.pc.category.mapper.PlatformCategoryMapper;
 import com.oying.modules.pc.category.service.PlatformCategoryService;
+import com.oying.modules.pc.common.ValueUpdate;
+import com.oying.modules.pc.store.domain.StoreQualification;
+import com.oying.modules.pc.utils.ImageUtils;
+import com.oying.service.BucketStorageService;
 import com.oying.utils.PageResult;
 import com.oying.utils.PageUtil;
-import com.oying.utils.SecurityUtils;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * 平台类目服务实现
@@ -33,6 +42,7 @@
 public class PlatformCategoryServiceImpl extends ServiceImpl<PlatformCategoryMapper, PlatformCategory> implements PlatformCategoryService {
 
     private final PlatformCategoryMapper platformCategoryMapper;
+    private final BucketStorageService bucketStorageService;
 
     @Override
     public PageResult<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria, Page<Object> page) {
@@ -45,17 +55,16 @@
     }
 
     @Override
+    public List<PlatformCategory> queryBatchIds(List<Long> ids) {
+        LambdaQueryWrapper<PlatformCategory> wrapper = new LambdaQueryWrapper<>();
+        wrapper.in(PlatformCategory::getCategoryId, ids);
+        return platformCategoryMapper.selectList(wrapper);
+    }
+
+    @Override
     @Transactional(rollbackFor = Exception.class)
     public void create(PlatformCategoryCreateRequest request) {
-
-        PlatformCategory platformCategoryCreate = new PlatformCategory();
-        platformCategoryCreate.setName(request.getName());
-        platformCategoryCreate.setSortWeight(request.getSortWeight());
-        platformCategoryCreate.setIconId(request.getIconUploadFileId());
-        platformCategoryCreate.setActive(request.getActive());
-
-        // 使用处理图标文件
-        platformCategoryMapper.insert(platformCategoryCreate);
+        platformCategoryMapper.insert(PlatformCategoryAssembler.to(request));
     }
 
     @Override
@@ -65,24 +74,35 @@
         Long categoryId = updateDto.getCategoryId();
         PlatformCategory existingPlatformCategory = this.getById(categoryId);
         if (ObjUtil.isEmpty(existingPlatformCategory)) {
-            throw new EntityExistException(PlatformCategory.class, "categoryId", Optional.ofNullable(categoryId).map(Object::toString).orElse("null"));
+            throw new EntityNotFoundException(PlatformCategory.class, "categoryId", Optional.ofNullable(categoryId).map(Object::toString).orElse("null"));
         }
 
-        PlatformCategory platformCategoryUpdate = new PlatformCategory();
-        platformCategoryUpdate.setCategoryId(updateDto.getCategoryId());
-        platformCategoryUpdate.setName(updateDto.getName());
-        platformCategoryUpdate.setSortWeight(updateDto.getSortWeight());
-        platformCategoryUpdate.setIconId(updateDto.getIconUploadFileId());
-        platformCategoryUpdate.setActive(updateDto.getActive());
-        existingPlatformCategory.copy(platformCategoryUpdate);
+        // 新的类目数据
+        PlatformCategory newPlatformCategory = PlatformCategoryAssembler.to(updateDto);
+        // 记录图片值的变更
+        ValueUpdate<Long> iconValueUpdate = new ValueUpdate<>(newPlatformCategory.getIconId(), existingPlatformCategory.getIconId());
+        // 填充新的数据
+        existingPlatformCategory.copy(newPlatformCategory);
         platformCategoryMapper.updateById(existingPlatformCategory);
+        // 删除旧图片原纪录
+        if (iconValueUpdate.isChangeAndOldValueNotEmpty()) {
+            bucketStorageService.deleteAll(ListUtil.toList(iconValueUpdate.getOldValue()));
+        }
 
-        // 使用处理图标文件
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void deleteAll(List<Long> ids) {
+        List<PlatformCategory> existingPlatformCategories = this.queryBatchIds(ids);
+        if (CollectionUtil.isEmpty(existingPlatformCategories)) {
+            throw new EntityNotFoundException(PlatformCategory.class, "platformCategoryIds", ids.toString());
+        }
         platformCategoryMapper.deleteBatchIds(ids);
+        List<Long> storageIds = existingPlatformCategories.stream().map(PlatformCategory::getIconId).collect(Collectors.toList());
+        // 删除旧图片原记录
+        if (CollectionUtil.isNotEmpty(storageIds)) {
+            bucketStorageService.deleteAll(storageIds);
+        }
     }
 }
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 eca49de..2fe6124 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
@@ -2,6 +2,8 @@
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.bean.copier.CopyOptions;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.oying.base.BaseEntity;
@@ -13,6 +15,7 @@
 import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
 * @author lzp
@@ -23,7 +26,7 @@
 @TableName("pc_product")
 public class Product extends BaseEntity implements Serializable {
 
-    @TableId(value = "product_id")
+    @TableId(value = "product_id", type = IdType.AUTO)
     @ApiModelProperty(value = "ID")
     private Long productId;
 
@@ -52,15 +55,16 @@
     private Long secondCategoryId;
 
     @NotNull
-    @ApiModelProperty(value = "状态:1000-草稿 1001上架 1002下架")
+    @ApiModelProperty(value = "状态")
     private Integer status;
 
     @NotBlank
     @ApiModelProperty(value = "主图片")
-    private String mainImage;
+    private String mainImageId;
 
-    @ApiModelProperty(value = "详情图片")
-    private String detailImage;
+    @NotBlank
+    @ApiModelProperty(value = "主图地址")
+    private String mainImageUrl;
 
     @ApiModelProperty(value = "商品描述")
     private String description;
@@ -92,6 +96,12 @@
     @ApiModelProperty(value = "高度(单位:厘米)")
     private Integer height;
 
+    @ApiModelProperty(value = "是否支持退货")
+    private Integer returns;
+
+    @ApiModelProperty(value = "是否支持自提")
+    private Integer selfPickup;
+
     @NotNull
     @ApiModelProperty(value = "是否删除")
     private Integer deletedFlag;
@@ -100,6 +110,14 @@
     @ApiModelProperty(value = "版本号")
     private Long version;
 
+    @TableField(exist = false)
+    @ApiModelProperty(value = "图片")
+    private List<ProductImage> images;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "标签")
+    private List<ProductLabel> labels;
+
     public void copy(Product source){
         BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
     }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCategoryQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCategoryQueryCriteria.java
deleted file mode 100644
index 46eede8..0000000
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCategoryQueryCriteria.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.oying.modules.pc.product.domain.dto;
-
-import lombok.Data;
-import io.swagger.annotations.ApiModelProperty;
-
-/**
-* @author lzp
-* @date 2025-05-13
-**/
-@Data
-public class ProductCategoryQueryCriteria{
-
-    @ApiModelProperty(value = "页码", example = "1")
-    private Integer page = 1;
-
-    @ApiModelProperty(value = "每页数据量", example = "10")
-    private Integer size = 10;
-}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java
index 412ee55..de0724c 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java
@@ -1,7 +1,13 @@
 package com.oying.modules.pc.product.domain.dto;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
 
 /**
  * @author lzp
@@ -10,8 +16,27 @@
 @Data
 public class ProductCustomerQueryCriteria {
 
+    @ApiModelProperty(value = "搜索字段", example = "柚子")
+    private String blurry;
+
+    @ApiModelProperty(value = "ID")
+    private Long productId;
+
+    @ApiModelProperty(value = "店铺ID")
+    private Long storeId;
+
+    @ApiModelProperty(value = "一级分类ID")
     private Long categoryId;
 
+    @ApiModelProperty(value = "二级分类ID")
+    private Long secondCategoryId;
+
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "是否删除")
+    private Integer deletedFlag;
+
     @ApiModelProperty(value = "页码", example = "1")
     private Integer page = 1;
 
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java
index 0fb9117..a5d91f3 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java
@@ -1,9 +1,14 @@
 package com.oying.modules.pc.product.domain.dto;
 
+import lombok.Data;
+
+@Data
 public class ProductImageCreateRequest {
 
-    private Long uploadId;
+    private Long productId;
 
-    private Integer type;
+    private Long uploadFileId;
+
+    private String imageType;
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java
index bcf7d49..b65de1f 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java
@@ -1,16 +1,24 @@
 package com.oying.modules.pc.product.domain.dto;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 @Data
 public class ProductLabelCreateRequest {
 
-    private String category;
+    @ApiModelProperty(value = "商品ID")
+    private Long productId;
 
+    @ApiModelProperty(value = "分类名称")
+    private String categoryName;
+
+    @ApiModelProperty(value = "标签名称")
     private String labelName;
 
+    @ApiModelProperty(value = "标签值")
     private String labelValue;
 
+    @ApiModelProperty(value = "单位")
     private String unit;
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java
index 85c8761..0f6dd58 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java
@@ -1,14 +1,18 @@
 package com.oying.modules.pc.product.domain.dto;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 
 @Data
 public class ProductMerchantCreateRequest {
+
+    private Long storeId;
 
     @NotBlank
     private String barcode;
@@ -43,10 +47,14 @@
 
     private Integer height;
 
-    private Integer allowReturns;
+    @ApiModelProperty(value = "是否支持退货")
+    private Integer returns;
 
-    private List<ProductImageCreateRequest> imageList;
+    @ApiModelProperty(value = "是否支持自提")
+    private Integer selfPickup;
 
-    private List<ProductLabelCreateRequest> labelList;
+    private List<ProductImageCreateRequest> images = new ArrayList<>();
+
+    private List<ProductLabelCreateRequest> labels = new ArrayList<>();
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java
index 734cb8f..371ff04 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java
@@ -1,14 +1,17 @@
 package com.oying.modules.pc.product.domain.dto;
 
+import com.oying.modules.pc.product.domain.ProductLabel;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 
 @Data
 public class ProductMerchantUpdateRequest {
+
+    private Long productId;
 
     private String barcode;
 
@@ -36,10 +39,22 @@
 
     private Integer height;
 
-    private Integer allowReturns;
+    @ApiModelProperty(value = "是否支持退货")
+    private Integer returns;
 
-    private List<ProductImageCreateRequest> imageList;
+    @ApiModelProperty(value = "是否支持自提")
+    private Integer selfPickup;
 
-    private List<ProductLabelCreateRequest> specList;
+    private List<Long> deletedImageIds = new ArrayList<>();
+
+    private List<ProductImageUpdateRequest> updatedImages = new ArrayList<>();
+
+    private List<ProductImageCreateRequest> newImages = new ArrayList<>();
+
+    private List<Long> deletedLabelIds = new ArrayList<>();
+
+    private List<ProductLabel> updatedLabels = new ArrayList<>();
+
+    private List<ProductLabel> newLabels = new ArrayList<>();
 
 }
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 b89cf98..c0db31f 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
@@ -17,18 +17,20 @@
 
     private Long storeId;
 
+    private String barcode;
+
     private Integer status;
 
     private Long categoryId;
 
     private Long secondCategoryId;
 
-    private Integer active;
-
     @ApiModelProperty(value = "页码", example = "1")
     private Integer page = 1;
 
     @ApiModelProperty(value = "每页数据量", example = "10")
     private Integer size = 10;
 
+    private Integer limit;
+
 }
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 6d47589..7f42839 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
@@ -1,73 +1,133 @@
 package com.oying.modules.pc.product.rest;
 
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.oying.annotation.Log;
-import com.oying.utils.R;
 import com.oying.modules.pc.product.domain.Product;
-import com.oying.modules.pc.product.service.ProductService;
+import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest;
+import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest;
 import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
+import com.oying.modules.pc.product.service.ProductAdminService;
+import com.oying.modules.pc.product.service.ProductImageService;
+import com.oying.modules.pc.product.service.ProductLabelService;
+import com.oying.modules.pc.product.service.ProductService;
+import com.oying.utils.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
-import java.util.List;
-
-import org.springframework.security.access.prepost.PreAuthorize;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.http.ResponseEntity;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-import io.swagger.annotations.*;
-import java.io.IOException;
+
 import javax.servlet.http.HttpServletResponse;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.oying.utils.PageResult;
+import java.io.IOException;
+import java.util.List;
 
 /**
-* @author lzp
-* @date 2025-04-30
-**/
+ * @author lzp
+ * @date 2025-04-30
+ **/
 @RestController
 @RequiredArgsConstructor
 @Api(tags = "商品")
-@RequestMapping("/api/product")
+@RequestMapping("/api/pc/product")
 public class ProductController {
 
     private final ProductService productService;
+    private final ProductAdminService productAdminService;
+    private final ProductImageService productImageService;
+    private final ProductLabelService productLabelService;
 
     @ApiOperation("导出数据")
     @GetMapping(value = "/download")
-    @PreAuthorize("@el.check('product:list')")
+    // @PreAuthorize("@el.check('product:list')")
     public void exportProduct(HttpServletResponse response, ProductQueryCriteria criteria) throws IOException {
         productService.download(productService.queryAll(criteria), response);
     }
 
-    @GetMapping
+    @GetMapping(value = "/list")
     @ApiOperation("查询商品")
-    @PreAuthorize("@el.check('product:list')")
-    public R<PageResult<Product>> queryProduct(ProductQueryCriteria criteria){
+    // @PreAuthorize("@el.check('product:list')")
+    public ResponseEntity<?> getProducts(ProductQueryCriteria criteria) {
+        return ResponseEntity.ok(R.success(productService.queryAll(criteria)));
+    }
+
+    @GetMapping(value = "/page")
+    @ApiOperation("查询商品")
+    // @PreAuthorize("@el.check('product:list')")
+    public ResponseEntity<?> getProductsByPage(ProductQueryCriteria criteria) {
         Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
-        return R.success(productService.queryAll(criteria,page));
+        return ResponseEntity.ok(R.success(productService.queryAll(criteria, page)));
+    }
+
+    @GetMapping(value = "/{productId}}")
+    @ApiOperation("查询商品")
+    // @PreAuthorize("@el.check('product:list')")
+    public ResponseEntity<?> getProduct(@PathVariable Long productId) {
+        Product product = productService.getById(productId);
+        if (ObjectUtil.isNotEmpty(product)) {
+            product.setLabels(productLabelService.queryLabelsByProductId(productId));
+        }
+        return ResponseEntity.ok(R.success(product));
+    }
+
+    @GetMapping(value = "/{productId}}/details")
+    @ApiOperation("查询商品")
+    // @PreAuthorize("@el.check('product:list')")
+    public ResponseEntity<?> getProductDetails(@PathVariable Long productId) {
+        Product product = productService.getById(productId);
+        if (ObjectUtil.isNotEmpty(product)) {
+            product.setImages(productImageService.queryImagesByProductId(productId));
+            product.setLabels(productLabelService.queryLabelsByProductId(productId));
+        }
+        return ResponseEntity.ok(R.success(product));
+    }
+
+    @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("查询商品")
+    // @PreAuthorize("@el.check('product:list')")
+    public ResponseEntity<?> getProductLabels(@PathVariable Long productId) {
+        return ResponseEntity.ok(R.success(productLabelService.queryLabelsByProductId(productId)));
     }
 
     @PostMapping
     @Log("新增商品")
     @ApiOperation("新增商品")
-    @PreAuthorize("@el.check('product:add')")
-    public R<?> createProduct(@Validated @RequestBody Product resources){
-        productService.create(resources);
-        return R.success();
+    //@PreAuthorize("@el.check('merchant:product:add')")
+    public ResponseEntity<?> createProduct(@PathVariable Long storeId,
+                                           @Validated @RequestBody ProductMerchantCreateRequest request) {
+        request.setStoreId(ObjectUtils.defaultIfNull(request.getStoreId(), storeId));
+        productAdminService.create(request);
+        return ResponseEntity.noContent().build();
     }
 
     @PutMapping
     @Log("修改商品")
     @ApiOperation("修改商品")
-    @PreAuthorize("@el.check('product:edit')")
-    public R<?> updateProduct(@Validated @RequestBody Product resources){
-        productService.update(resources);
-        return R.success();
+    // @PreAuthorize("@el.check('product:edit')")
+    public ResponseEntity<?> updateProduct(@PathVariable Long productId,
+                                           @Validated @RequestBody ProductMerchantUpdateRequest request) {
+        request.setProductId(ObjectUtils.defaultIfNull(request.getProductId(), productId));
+        productAdminService.update(request);
+        return ResponseEntity.noContent().build();
     }
 
     @DeleteMapping
     @Log("删除商品")
     @ApiOperation("删除商品")
-    @PreAuthorize("@el.check('product:del')")
-    public R<?> deleteProduct(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
-        productService.deleteAll(ids);
-        return R.success();
+    // @PreAuthorize("@el.check('product:del')")
+    public ResponseEntity<?> deleteProduct(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+        productAdminService.delete(ids);
+        return ResponseEntity.noContent().build();
     }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java
index c778cf8..fae7204 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java
@@ -1,13 +1,20 @@
 package com.oying.modules.pc.product.rest;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
 import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.oying.utils.R;
 import com.oying.modules.pc.product.domain.Product;
 import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
+import com.oying.modules.pc.product.service.ProductImageService;
+import com.oying.modules.pc.product.service.ProductLabelService;
 import com.oying.modules.pc.product.service.ProductService;
 import com.oying.modules.pc.product.view.ProductCustomerView;
+import com.oying.modules.pc.product.view.ProductImageCustomerView;
+import com.oying.modules.pc.product.view.ProductLabelCustomerView;
 import com.oying.utils.PageResult;
+import com.oying.utils.R;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
@@ -20,11 +27,11 @@
 import java.util.stream.Collectors;
 
 /*
-*
+ *
  * @author lzp
  * @date 2025-04-30
  *
-*/
+ */
 @RestController
 @RequiredArgsConstructor
 @Api(tags = "商品(客户端)")
@@ -32,14 +39,16 @@
 public class ProductCustomerController {
 
     private final ProductService productService;
+    private final ProductImageService productImageService;
+    private final ProductLabelService productLabelService;
 
     @GetMapping(value = "/page")
     @ApiOperation("根据商品名称模糊匹配店铺内的商品")
     /*@PreAuthorize("@el.check('merchant:product:page')")*/
-    public ResponseEntity<?> query(@PathVariable Long storeId,
-                                   @RequestParam(value = "categoryId", required = false) Long categoryId,
-                                   @RequestParam(value = "secondCategoryId", required = false) Long secondCategoryId,
-                                   @RequestParam(value = "blurry", required = false) String blurry) {
+    public ResponseEntity<?> getProductsByPage(@PathVariable Long storeId,
+                                               @RequestParam(value = "categoryId", required = false) Long categoryId,
+                                               @RequestParam(value = "secondCategoryId", required = false) Long secondCategoryId,
+                                               @RequestParam(value = "blurry", required = false) String blurry) {
 
         ProductQueryCriteria criteria = new ProductQueryCriteria();
         criteria.setStoreId(storeId);
@@ -55,8 +64,6 @@
                 productList.stream().map(i -> {
                     ProductCustomerView view = new ProductCustomerView();
                     BeanUtils.copyProperties(i, view);
-                    view.setScore(5.0D);
-                    view.setSold(0);
                     return view;
                 }).collect(Collectors.toList()),
                 productPageResult.getTotalElements());
@@ -66,16 +73,21 @@
     @GetMapping(value = "/{productId}/details")
     @ApiOperation("查询商品")
     /*@PreAuthorize("@el.check('merchant:product:byProductId')")*/
-    public ResponseEntity<?> getDetails(@PathVariable Long productId) {
+    public ResponseEntity<?> getProductDetails(@PathVariable Long productId) {
         Product product = productService.getById(productId);
         ProductCustomerView customerView = new ProductCustomerView();
-        customerView.setProductId(product.getProductId());
-        customerView.setTitle(product.getTitle());
-        customerView.setPrice(product.getPrice());
-        customerView.setScore(5.0D);
-        customerView.setSold(0);
-        customerView.setLabelList(ListUtil.empty());
-        customerView.setMainImageList(ListUtil.empty());
+        if (ObjUtil.isNotEmpty(product)) {
+            customerView.setImages(productImageService.queryImagesByProductId(productId).stream().map(i -> {
+                ProductImageCustomerView imageCustomerView = new ProductImageCustomerView();
+                BeanUtil.copyProperties(i, imageCustomerView, CopyOptions.create().setIgnoreNullValue(true));
+                return imageCustomerView;
+            }).collect(Collectors.toList()));
+            customerView.setLabels(productLabelService.queryLabelsByProductId(productId).stream().map(i -> {
+                ProductLabelCustomerView labelCustomerView = new ProductLabelCustomerView();
+                BeanUtil.copyProperties(i, labelCustomerView, CopyOptions.create().setIgnoreNullValue(true));
+                return labelCustomerView;
+            }).collect(Collectors.toList()));
+        }
         return ResponseEntity.ok(R.success(customerView));
     }
 
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 cf88760..800f96f 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
@@ -1,23 +1,29 @@
 package com.oying.modules.pc.product.rest;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.oying.annotation.Log;
-import com.oying.utils.R;
 import com.oying.modules.pc.product.domain.Product;
+import com.oying.modules.pc.product.domain.ProductLabel;
+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;
 import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
+import com.oying.modules.pc.product.service.ProductImageService;
+import com.oying.modules.pc.product.service.ProductLabelService;
 import com.oying.modules.pc.product.service.ProductMerchantService;
 import com.oying.modules.pc.product.service.ProductService;
-import com.oying.modules.pc.product.view.ProductMerchantDetailsView;
 import com.oying.modules.pc.product.view.ProductMerchantSimpleView;
 import com.oying.utils.PageResult;
+import com.oying.utils.R;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
-import org.springframework.beans.BeanUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -36,24 +42,27 @@
 @RequestMapping("/api/pc/merchant/store/{storeId}/product")
 public class ProductMerchantController {
 
+    private final int MAX_IMAGES = 5;
+    private final int MAX_LABELS = 10;
+
     private final ProductService productService;
     private final ProductMerchantService productMerchantService;
+    private final ProductImageService productImageService;
+    private final ProductLabelService productLabelService;
 
     @GetMapping(value = "/page")
     @ApiOperation("获取指定商户店铺的商品列表(支持分页)")
     /*@PreAuthorize("@el.check('merchant:product:page') " +
             "and @storeMerchantOwnershipService.check(#storeId)")*/
-    public ResponseEntity<?> query(@PathVariable Long storeId,
-                                   ProductQueryCriteria criteria) {
-
-        criteria.setStoreId(storeId);
+    public ResponseEntity<?> getProductsByPage(@PathVariable Long storeId, ProductQueryCriteria criteria) {
+        criteria.setStoreId(ObjectUtils.defaultIfNull(criteria.getStoreId(), storeId));
         Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
         PageResult<Product> productPageResult = productService.queryAll(criteria, page);
         List<Product> productList = Optional.ofNullable(productPageResult.getContent()).orElse(ListUtil.empty());
         PageResult<ProductMerchantSimpleView> viewPageResult = new PageResult<>(
                 productList.stream().map(i -> {
                     ProductMerchantSimpleView view = new ProductMerchantSimpleView();
-                    BeanUtils.copyProperties(i, view);
+                    BeanUtil.copyProperties(i, view);
                     return view;
                 }).collect(Collectors.toList()),
                 productPageResult.getTotalElements());
@@ -64,7 +73,7 @@
     @ApiOperation("查询商品")
     /*@PreAuthorize("@el.check('merchant:product:byProductId') " +
             "and @storeMerchantOwnershipService.check(#storeId)")*/
-    public ResponseEntity<?> getById(@PathVariable Long productId) {
+    public ResponseEntity<?> getProductById(@PathVariable Long productId) {
         return ResponseEntity.ok(R.success(productService.getById(productId)));
     }
 
@@ -74,14 +83,11 @@
             "and @storeMerchantOwnershipService.check(#storeId)")*/
     public ResponseEntity<?> getDetailsById(@PathVariable Long productId) {
         Product product = productService.getById(productId);
-        ProductMerchantDetailsView view = null;
-        if (product != null) {
-            view = new ProductMerchantDetailsView();
-            BeanUtils.copyProperties(product, view);
-            view.setMainImageList(ListUtil.empty());
-            view.setLabelList(ListUtil.empty());
+        if (ObjUtil.isNotEmpty(product)) {
+            product.setImages(productImageService.queryImagesByProductId(productId));
+            product.setLabels(productLabelService.queryLabelsByProductId(productId));
         }
-        return ResponseEntity.ok(R.success(view));
+        return ResponseEntity.ok(R.success(product));
     }
 
     @PostMapping
@@ -91,20 +97,20 @@
     //        "and @storeMerchantOwnershipService.check(#storeId)")
     public ResponseEntity<?> createProduct(@PathVariable Long storeId,
                                            @Validated @RequestBody ProductMerchantCreateRequest request) {
-
-        productMerchantService.create(storeId, request);
-        return ResponseEntity.noContent().build();
+        request.setStoreId(ObjectUtils.defaultIfNull(request.getStoreId(), storeId));
+        productMerchantService.create(request);
+        return ResponseEntity.status(HttpStatus.CREATED).build();
     }
 
     @PutMapping(value = "/{productId}")
-    @Log("修改商品")
+    //@Log("修改商品")
     @ApiOperation("修改商品")
     /*@PreAuthorize("@el.check('merchant:product:edit') " +
             "and @storeMerchantOwnershipService.check(#storeId)")*/
     public ResponseEntity<?> updateProduct(@PathVariable Long productId,
                                            @Validated @RequestBody ProductMerchantUpdateRequest request) {
-
-        productMerchantService.update(productId, request);
+        request.setProductId(ObjectUtils.defaultIfNull(request.getProductId(), productId));
+        productMerchantService.update(request);
         return ResponseEntity.noContent().build();
     }
 
@@ -137,4 +143,64 @@
         productMerchantService.takeOffShelf(productId);
         return ResponseEntity.noContent().build();
     }
+
+    @PostMapping(value = "/{productId}/images")
+    @Log("添加商品图片")
+    @ApiOperation("添加商品图片")
+    public ResponseEntity<?> batchAddImage(@PathVariable("productId") Long productId,
+                                           @RequestBody List<ProductImageCreateRequest> requests) {
+        requests = requests.stream().peek(i -> i.setProductId(Optional.ofNullable(i.getProductId()).orElse(productId)))
+                .collect(Collectors.toList());
+        productImageService.batchCreate(requests);
+        return ResponseEntity.status(HttpStatus.CREATED).build();
+    }
+
+    @PutMapping(value = "/{productId}/images/change")
+    @Log("商品图片变更")
+    @ApiOperation("商品图片变更")
+    public ResponseEntity<?> updateImage(@PathVariable("productId") Long productId,
+                                           @RequestBody ProductMerchantUpdateRequest request) {
+        request.setProductId(ObjectUtils.defaultIfNull(request.getProductId(), productId));
+        productMerchantService.updateImages(request);
+        return ResponseEntity.noContent().build();
+    }
+
+    @DeleteMapping(value = "/{productId}/images")
+    @Log("删除商品图片")
+    @ApiOperation("添加商品图片")
+    public ResponseEntity<?> deleteImage(@PathVariable("productId") Long productId,
+                                         @RequestBody List<Long> ids) {
+        productImageService.deleteAll(ids);
+        return ResponseEntity.noContent().build();
+    }
+
+    @PostMapping(value = "/{productId}/labels")
+    @Log("添加商品标签")
+    @ApiOperation("添加商品标签")
+    public ResponseEntity<?> batchAddLabel(@PathVariable("productId") Long productId,
+                                           @RequestBody List<ProductLabel> requests) {
+        requests = requests.stream().peek(i -> i.setProductId(Optional.ofNullable(i.getProductId()).orElse(productId)))
+                .collect(Collectors.toList());
+        productLabelService.batchCreate(requests);
+        return ResponseEntity.status(HttpStatus.CREATED).build();
+    }
+
+    @PutMapping(value = "/{productId}/labels/change")
+    @Log("标签变更")
+    @ApiOperation("标签变更")
+    public ResponseEntity<?> updateLabels(@PathVariable("productId") Long productId,
+                                         @RequestBody ProductMerchantUpdateRequest request) {
+        request.setProductId(ObjectUtils.defaultIfNull(request.getProductId(), productId));
+        productMerchantService.updateLabels(request);
+        return ResponseEntity.noContent().build();
+    }
+
+    @DeleteMapping(value = "/{productId}/labels")
+    @Log("删除商品标签")
+    @ApiOperation("添加商品标签")
+    public ResponseEntity<?> deleteLabel(@PathVariable("productId") Long productId,
+                                         @RequestBody List<Long> ids) {
+        productLabelService.deleteAll(ids);
+        return ResponseEntity.noContent().build();
+    }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java
index dba1948..be935ff 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java
@@ -7,8 +7,10 @@
 
 public interface ProductMerchantService {
 
-    void create(Long storeId, ProductMerchantCreateRequest request);
-    void update(Long storeId, ProductMerchantUpdateRequest request);
+    void create(ProductMerchantCreateRequest request);
+    void update(ProductMerchantUpdateRequest request);
+    void updateImages(ProductMerchantUpdateRequest request);
+    void updateLabels(ProductMerchantUpdateRequest request);
     void batchDelete(List<Long> ids);
     void putOnShelf(Long productId);
     void takeOffShelf(Long productId);
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantCreateServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantCreateServiceImpl.java
deleted file mode 100644
index c675445..0000000
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantCreateServiceImpl.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.oying.modules.pc.product.service.impl;
-
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.oying.modules.pc.product.domain.Product;
-import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest;
-import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest;
-import com.oying.modules.pc.product.service.ProductMerchantService;
-import com.oying.modules.pc.product.service.ProductService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.beans.BeanUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-
-@Service
-@RequiredArgsConstructor
-public class ProductMerchantCreateServiceImpl implements ProductMerchantService {
-
-    private final ProductService productService;
-
-    @Override
-    public void create(Long storeId, ProductMerchantCreateRequest request) {
-        Product product = new Product();
-        BeanUtils.copyProperties(request, product);
-        product.setStoreId(storeId);
-        productService.create(product);
-    }
-
-    @Override
-    public void update(Long productId, ProductMerchantUpdateRequest request) {
-        Product product = new Product();
-        BeanUtils.copyProperties(request, product);
-        product.setProductId(productId);
-        productService.update(product);
-    }
-
-    @Transactional
-    @Override
-    public void batchDelete(List<Long> ids) {
-        productService.deleteAll(ids);
-    }
-
-    @Override
-    public void putOnShelf(Long productId) {
-        LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
-                .eq(Product::getProductId, productId)
-                .set(Product::getStatus, 1001);
-        productService.update(wrapper);
-    }
-
-    @Override
-    public void takeOffShelf(Long productId) {
-        LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
-                .eq(Product::getProductId, productId)
-                .set(Product::getStatus, 1002);
-        productService.update(wrapper);
-    }
-}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java
index 8be214d..879e105 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java
@@ -10,7 +10,6 @@
 import com.oying.utils.FileUtil;
 import com.oying.utils.PageResult;
 import com.oying.utils.PageUtil;
-import com.oying.utils.SecurityUtils;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -79,9 +78,9 @@
             map.put("商品名称", product.getName());
             map.put("商品标题", product.getTitle());
             map.put("分类ID", product.getCategoryId());
-            map.put("状态:1000-草稿 1001上架 1002下架", product.getStatus());
-            map.put("主图片", product.getMainImage());
-            map.put("详情图片", product.getDetailImage());
+            map.put("状态", product.getStatus());
+            map.put("主图片", product.getMainImageId());
+            map.put("主图地址", product.getMainImageUrl());
             map.put("商品描述", product.getDescription());
             map.put("销售价格", product.getPrice());
             map.put("库存数量", product.getStockQuantity());
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java
index bf2ca91..521debc 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java
@@ -1,8 +1,14 @@
 package com.oying.modules.pc.product.view;
 
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.collection.ListUtil;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -13,13 +19,33 @@
 @Data
 public class ProductCustomerView {
 
-    private Long productId;
-    private String title;
-    private BigDecimal price;
-    private Double score;           // 评分
-    private Integer sold;    // 月销量
+    //private Integer sold;    // 月销量
 
-    private List<ProductImageCustomerView> mainImageList;
-    private List<ProductLabelCustomerView> labelList;
+    @ApiModelProperty(value = "ID")
+    private Long productId;
+
+    @ApiModelProperty(value = "店铺ID")
+    private Long storeId;
+
+    @ApiModelProperty(value = "商品标题")
+    private String title;
+
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "主图地址")
+    private String mainImageUrl;
+
+    @ApiModelProperty(value = "商品描述")
+    private String description;
+
+    @ApiModelProperty(value = "销售价格")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "月销售量")
+    private Integer monthlySales = 0;
+
+    private List<ProductImageCustomerView> images = new ArrayList<>();
+    private List<ProductLabelCustomerView> labels = new ArrayList<>();
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java
index 208cd49..9fdf935 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java
@@ -1,12 +1,24 @@
 package com.oying.modules.pc.product.view;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 @Data
 public class ProductImageCustomerView {
 
-    private String url;
-    private Integer primaryFlag;
+    @ApiModelProperty(value = "商品图片ID")
+    private Long imageId;
+
+    @ApiModelProperty(value = "商品ID")
+    private Long productId;
+
+    @ApiModelProperty(value = "图片类型")
+    private String imageType;
+
+    @ApiModelProperty(value = "图片地址")
+    private String imageUrl;
+
+    @ApiModelProperty(value = "排序权重")
     private Integer sortWeight;
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java
index 868e975..41c733c 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java
@@ -1,13 +1,27 @@
 package com.oying.modules.pc.product.view;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 @Data
 public class ProductLabelCustomerView {
 
-    private Integer categoryId;
+    @ApiModelProperty(value = "标签ID")
+    private Long labelId;
+
+    @ApiModelProperty(value = "商品ID")
+    private Long productId;
+
+    @ApiModelProperty(value = "分类名称")
     private String categoryName;
+
+    @ApiModelProperty(value = "标签名称")
     private String labelName;
+
+    @ApiModelProperty(value = "标签值")
     private String labelValue;
 
+    @ApiModelProperty(value = "单位")
+    private String unit;
+
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java
index 723d856..5aa2774 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java
@@ -16,7 +16,7 @@
     private Double latitude;  // 中心点纬度
 
     @Min(100)
-    @Max(5000)
+    @Max(10000)
     private Integer radius = 1000; // 搜索半径(米)
 
     private Boolean onlyOpenNow = true; // 是否只查当前营业的
diff --git a/oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java b/oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java
index 557a76e..77049f1 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java
@@ -36,6 +36,14 @@
         return R.success(toStoreSearchVo(storeSearchService.findNearStores(criteria)));
     }
 
+    /**
+     * 查询最近的店铺
+     */
+    @GetMapping("/find")
+    public R<PageResult<StoreSearchView>> find(NearbyStoreQueryCriteria criteria) {
+        return R.success(toStoreSearchVo(storeSearchService.findNearStores(criteria)));
+    }
+
     private PageResult<StoreSearchView> toStoreSearchVo(PageResult<StoreSearchDto> resources) {
         PageResult<StoreSearchView> t = new PageResult<>();
         t.setTotalElements(resources.getTotalElements());
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java
index db9261d..461c7cb 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java
@@ -3,11 +3,12 @@
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.bean.copier.CopyOptions;
 import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.oying.base.BaseEntity;
+import com.oying.modules.pc.product.domain.Product;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
 import lombok.Getter;
 import lombok.Setter;
 import org.springframework.data.geo.Point;
@@ -17,6 +18,7 @@
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.LocalTime;
+import java.util.List;
 
 /**
  * @author lzp
@@ -28,7 +30,7 @@
 public class Store extends BaseEntity implements Serializable {
 
     @TableId(value = "store_id", type = IdType.AUTO)
-    @ApiModelProperty(value = "唯一标识")
+    @ApiModelProperty(value = "店铺ID")
     private Long storeId;
 
     @NotNull
@@ -54,20 +56,20 @@
     private String businessScope;
 
     @NotNull
-    @ApiModelProperty(value = "状态:1000-草稿  1002-正常  1003-暂停营业 1004-关闭")
+    @ApiModelProperty(value = "状态")
     private Integer status;
 
     @ApiModelProperty(value = "店铺logo图片")
     private Long logoImageId;
 
     @ApiModelProperty(value = "店铺logo图片Url")
-    private Long logoImageUrl;
+    private String logoImageUrl;
 
     @ApiModelProperty(value = "店铺封面图")
     private Long coverImageId;
 
     @ApiModelProperty(value = "店铺封面图Url")
-    private Long coverImageUrl;
+    private String coverImageUrl;
 
     @ApiModelProperty(value = "店铺描述")
     private String description;
@@ -120,6 +122,36 @@
     @ApiModelProperty(value = "营业半径(米)")
     private Integer radius;
 
+    @ApiModelProperty(value = "是否支持退货")
+    private Integer returns;
+
+    @ApiModelProperty(value = "是否支持自提")
+    private Integer selfPickup;
+
+    @NotNull
+    @ApiModelProperty(value = "版本号")
+    private Long version;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "评分")
+    private Double score = 0d;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "配送距离")
+    private Integer deliveryDuration = 0;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "月销售量")
+    private Integer monthlySales = 0;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "资质")
+    private List<StoreQualification> qualifications;
+
+    @TableField(exist = false)
+    @ApiModelProperty(value = "商品")
+    private List<Product> products;
+
     public void copy(Store source) {
         BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
     }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java
index ab2c65a..0f851d5 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java
@@ -42,7 +42,7 @@
     private String qualificationName;
 
     @ApiModelProperty(value = "资质图片")
-    private String qualificationImageId;
+    private Long qualificationImageId;
 
     @ApiModelProperty(value = "资质图片")
     private String qualificationImageUrl;
@@ -53,7 +53,7 @@
     @ApiModelProperty(value = "有效期结束日期")
     private LocalTime endDate;
 
-    @ApiModelProperty(value = "状态:1000-草稿 1001-有效 1002-无效")
+    @ApiModelProperty(value = "状态")
     private Integer status;
 
     public void copy(StoreQualification source){
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreStatus.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreStatus.java
deleted file mode 100644
index 719247d..0000000
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreStatus.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.oying.modules.pc.store.domain;
-
-public class StoreStatus {
-
-}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java
index 46b5256..aec02b7 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java
@@ -8,6 +8,8 @@
 @Data
 public class StoreCategoryMerchantCreateRequest {
 
+    private Long storeId;
+
     private Long parentId;
 
     @NotBlank
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java
index 48a15fb..f9dcea9 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java
@@ -1,10 +1,14 @@
 package com.oying.modules.pc.store.domain.dto;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 @Data
 public class StoreCategoryMerchantUpdateRequest {
 
+    @ApiModelProperty(value = "ID")
+    private Long categoryId;
+
     private Long parentId;
 
     private String name;
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java
index bc8ae0a..c17c621 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java
@@ -3,6 +3,9 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
 /**
  * @author lzp
  * @date 2025-04-27
@@ -10,17 +13,28 @@
 @Data
 public class StoreCategoryQueryCriteria {
 
+    @ApiModelProperty(value = "模糊查询")
+    private String blurry;
+
+    @ApiModelProperty(value = "ID")
+    private Long categoryId;
+
+    @ApiModelProperty(value = "店铺ID")
     private Long storeId;
 
+    @ApiModelProperty(value = "类目层级:1-级类目 2-级类目")
     private Integer level;
 
-    private Boolean recursive;
-
+    @ApiModelProperty(value = "是否启用(0-否 1-是)")
     private Integer active;
+
+    @ApiModelProperty(value = "递归处理")
+    private Boolean recursive;
 
     @ApiModelProperty(value = "页码", example = "1")
     private Integer page = 1;
 
     @ApiModelProperty(value = "每页数据量", example = "10")
     private Integer size = 10;
+
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java
index fc238f6..cbc8fe4 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java
@@ -5,11 +5,11 @@
 @Data
 public class StoreCategoryUpdateRequest {
 
+    private Long categoryId;
+
     private Long storeId;
 
     private Long parentId;
-
-    private Long categoryId;
 
     private String name;
 
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java
index f23b372..011205f 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java
@@ -6,6 +6,8 @@
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalTime;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -20,71 +22,56 @@
     @ApiModelProperty(value = "店铺简称", example = "永辉超市(新纪元店)")
     private String storeShortName;*/
 
-    @NotBlank
+    @NotNull
     @ApiModelProperty(value = "店铺LOGO文件ID", example = "14567785444763247876234")
     private Long logoUploadFileId;
 
-    /*@NotBlank
     @ApiModelProperty(value = "店铺门户图片ID", example = "276409837458893793939")
-    private Long coverUploadFileId;*/
+    private Long coverUploadFileId;
 
     @NotBlank
     @ApiModelProperty(value = "平台类目ID", example = "29784639387324848347230")
     private Long platformCategoryId;
-    //private String businessCategory;
 
-    @NotBlank
-    @ApiModelProperty(value = "简介", example = "")
+    @ApiModelProperty(value = "简介", example = " ")
     private String description;
 
     @NotBlank
     @ApiModelProperty(value = "店铺联系电话", example = "13800000001")
     private String contactPhone;
 
+    @ApiModelProperty(value = "营业开始时间", example = "08:00")
+    private LocalTime openTime;
+
+    @ApiModelProperty(value = "营业结束时间", example = "22:00")
+    private LocalTime closeTime;
+
     @NotBlank
     @ApiModelProperty(value = "店铺地址", example = "276409837458893793939")
     private String address;
 
-    @NotBlank
+    @NotNull
     @ApiModelProperty(value = "店铺坐标经度", example = "121.505978")
     private Double longitude;
 
-    @NotBlank
+    @NotNull
     @ApiModelProperty(value = "店铺坐标纬度", example = "31.144515")
     private Double latitude;
 
-    @ApiModelProperty(value = "店铺资质", example = "")
-    private List<StoreQualificationCreateRequest> qualificationList;
+    @ApiModelProperty(value = "营业半径(米)")
+    private Integer radius;
+
+    @ApiModelProperty(value = "是否支持退货")
+    private Integer returns;
+
+    @ApiModelProperty(value = "是否支持自提")
+    private Integer selfPickup;
+
+    @ApiModelProperty(value = "店铺资质", example = "[]")
+    private List<StoreQualificationCreateRequest> qualificationList = new ArrayList<>();
 
     public boolean hasQualificationList() {
         return CollUtil.isNotEmpty(this.qualificationList);
-    }
-
-    public static void main(String[] args) {
-        StoreCreateRequest request = new StoreCreateRequest();
-        request.setStoreName("上海三林小学");
-        request.setLogoUploadFileId(1L);
-        request.setDescription("");
-        // request.setCoverUploadFileId(1L);
-        request.setPlatformCategoryId(1L);
-        request.setContactPhone("13599873421");
-        request.setAddress("上海");
-        request.setLongitude(121.505978D);
-        request.setLatitude(31.144515D);
-
-        List<StoreQualificationCreateRequest> qualificationList = new ArrayList<>();
-        StoreQualificationCreateRequest sq1 = new StoreQualificationCreateRequest();
-        sq1.setType(10001);
-        // sq1.setName("营业执照");
-        sq1.setImageUploadFileId("");
-        qualificationList.add(sq1);
-        StoreQualificationCreateRequest sq2 = new StoreQualificationCreateRequest();
-        sq2.setType(10002);
-        // sq2.setName("许可证");
-        sq2.setImageUploadFileId("");
-        qualificationList.add(sq2);
-        request.setQualificationList(qualificationList);
-        System.out.println(JSONUtil.toJsonStr(request));
     }
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java
index 765a099..b94cdd0 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java
@@ -5,9 +5,11 @@
 @Data
 public class StoreCustomerDetailDto {
 
-    private String name;
+    private String storeName;
 
-    private String logoUrl;
+    private String logoImageUrl;
+
+    private String coverImageUrl;
 
     private String description;
 
@@ -17,7 +19,7 @@
 
     private String contactPhone;
 
-    private Integer score;
+    private Double score;
 
     private Integer deliveryDuration;
 
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java
index ad461f2..ab71edf 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java
@@ -1,16 +1,49 @@
 package com.oying.modules.pc.store.domain.dto;
 
+import com.oying.utils.StringUtils;
 import lombok.Data;
+import org.springframework.util.DigestUtils;
 
-import javax.validation.constraints.NotNull;
+import java.util.StringJoiner;
 
 @Data
 public class StoreCustomerQueryCriteria {
 
-    private Long StoreId;
+    private Long storeId;
+
+    private Long platformCategoryId;
+
+    private String blurry;
 
     private Double longitude; // 中心点经度
 
     private Double latitude;  // 中心点纬度
 
+    private Integer radius = 10000; // 搜索半径(米)
+
+    private Integer limit = 20; // 返回数量限制
+
+    private Integer page = 1;
+
+    private Integer size = 10;
+
+    public String buildConditionCacheKey() {
+        StringJoiner baseKeyJoiner = new StringJoiner("|");
+        if (platformCategoryId != null) {
+            baseKeyJoiner.add("platformCategoryId=" + platformCategoryId);
+        }
+        if (StringUtils.isNotEmpty(blurry)) {
+            baseKeyJoiner.add("blurry=" + blurry);
+        }
+        if (longitude != null && latitude != null) {
+            baseKeyJoiner.add("longitude=" + longitude);
+            baseKeyJoiner.add("latitude=" + latitude);
+        }
+        if (StringUtils.isNotEmpty(blurry)) {
+            baseKeyJoiner.add("radius=" + radius);
+        }
+        // 使用MD5或SHA缩短键长度
+        return "store:search:page:" + DigestUtils.md5DigestAsHex(baseKeyJoiner.toString().getBytes());
+    }
+
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java
index a273357..848330e 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java
@@ -1,5 +1,6 @@
 package com.oying.modules.pc.store.domain.dto;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
@@ -50,12 +51,12 @@
 
     public interface UpdateStoreDeliveryFeeGroup{}
 
-    @NotBlank(groups = UpdateStoreDeliveryFeeGroup.class)
+    @NotNull(groups = UpdateStoreDeliveryFeeGroup.class)
     private BigDecimal deliveryFee;
 
     public interface UpdateStoreDeliveryMinimumGroup{}
 
-    @NotBlank(groups = UpdateStoreDeliveryMinimumGroup.class)
+    @NotNull(groups = UpdateStoreDeliveryMinimumGroup.class)
     private BigDecimal deliveryMinimum;
 
     public interface UpdateStoreContactPhoneGroup{}
@@ -65,10 +66,10 @@
 
     public interface UpdateStoreBusinessHoursGroup{}
 
-    @NotBlank(groups = UpdateStoreBusinessHoursGroup.class)
+    @NotNull(groups = UpdateStoreBusinessHoursGroup.class)
     private LocalTime openTime;
 
-    @NotBlank(groups = UpdateStoreBusinessHoursGroup.class)
+    @NotNull(groups = UpdateStoreBusinessHoursGroup.class)
     private LocalTime closeTime;
 
     public interface UpdateStoreAddressGroup{}
@@ -78,15 +79,24 @@
 
     public interface UpdateStoreLocationGroup{}
 
-    @NotBlank(groups = UpdateStoreLocationGroup.class)
+    @NotNull(groups = UpdateStoreLocationGroup.class)
     private Double longitude;
 
-    @NotBlank(groups = UpdateStoreLocationGroup.class)
+    @NotNull(groups = UpdateStoreLocationGroup.class)
     private Double latitude;
 
     public interface UpdateStoreRadiusGroup{}
 
-    @NotBlank(groups = UpdateStoreRadiusGroup.class)
+    @NotNull(groups = UpdateStoreRadiusGroup.class)
     private Integer radius;
 
+    @ApiModelProperty(value = "是否支持退货")
+    private Integer returns;
+
+    @ApiModelProperty(value = "是否支持自提")
+    private Integer selfPickup;
+
+    @ApiModelProperty(value = "版本号")
+    private Long version;
+
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java
index 5826de4..528d75e 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java
@@ -11,7 +11,9 @@
 @Data
 public class StoreQualificationCreateRequest {
 
-    @NotNull
+    @ApiModelProperty(value = "关联的店铺ID")
+    private Long storeId;
+
     @ApiModelProperty(value = "资质类型", example = "1001")
     private Integer type;
 
@@ -19,8 +21,7 @@
     @ApiModelProperty(value = "资质名称", example = "营业执照")
     private String name;*/
 
-    @NotBlank
     @ApiModelProperty(value = "资质图片ID", example = "30975645483838730008921")
-    private String imageUploadFileId;
+    private Long imageUploadFileId;
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java
index 3d0e43b..482fc36 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java
@@ -11,7 +11,7 @@
 public class StoreQualificationQueryCriteria{
 
     @ApiModelProperty(value = "店铺资质ID", example = "1")
-    private Long id;
+    private Long qualificationId;
 
     @ApiModelProperty(value = "店铺ID", example = "1")
     private Long storeId;
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java
index 23f8369..a5c7308 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java
@@ -9,19 +9,13 @@
 @Data
 public class StoreQualificationUpdateRequest {
 
-    @NotBlank
     @ApiModelProperty(value = "资质ID", example = "317640956839788210948")
-    private Long id;
+    private Long qualificationId;
 
-    @NotBlank(groups = {UpdateGroup.class})
     @ApiModelProperty(value = "资质类型", example = "1001")
     private Integer type;
 
-    @NotBlank(groups = {UpdateGroup.class})
     @ApiModelProperty(value = "资质图片ID", example = "30975645483838730008921")
-    private String imageUploadFileId;
-
-    public interface UpdateGroup {
-    }
+    private Long imageUploadFileId;
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java
index 2d86a34..ad86796 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java
@@ -1,9 +1,12 @@
 package com.oying.modules.pc.store.domain.dto;
 
+import com.oying.utils.StringUtils;
 import lombok.Data;
 import io.swagger.annotations.ApiModelProperty;
+import org.springframework.util.DigestUtils;
 
 import java.io.Serializable;
+import java.util.StringJoiner;
 
 /**
  * @author lzp
@@ -19,13 +22,43 @@
 
     private Integer status;
 
+    private Long storeId;
+
+    private Long platformCategoryId;
+
+    private String blurry;
+
+    private Double longitude; // 中心点经度
+
+    private Double latitude;  // 中心点纬度
+
+    private Integer radius = 10000; // 搜索半径(米)
+
+    private Integer limit = 20; // 返回数量限制
+
     @ApiModelProperty(value = "页码", example = "1")
     private Integer page = 1;
 
     @ApiModelProperty(value = "每页数据量", example = "10")
     private Integer size = 10;
 
-    @ApiModelProperty(value = "偏移量", hidden = true)
-    private long offset;
+    public String buildConditionCacheKey() {
+        StringJoiner baseKeyJoiner = new StringJoiner("|");
+        if (platformCategoryId != null) {
+            baseKeyJoiner.add("platformCategoryId=" + platformCategoryId);
+        }
+        if (StringUtils.isNotEmpty(blurry)) {
+            baseKeyJoiner.add("blurry=" + blurry);
+        }
+        if (longitude != null && latitude != null) {
+            baseKeyJoiner.add("longitude=" + longitude);
+            baseKeyJoiner.add("latitude=" + latitude);
+        }
+        if (StringUtils.isNotEmpty(blurry)) {
+            baseKeyJoiner.add("radius=" + radius);
+        }
+        // 使用MD5或SHA缩短键长度
+        return "store:search:page:" + DigestUtils.md5DigestAsHex(baseKeyJoiner.toString().getBytes());
+    }
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java
index 3471252..46706d8 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java
@@ -1,21 +1,33 @@
 package com.oying.modules.pc.store.domain.enums;
 
+import lombok.Getter;
+
+@Getter
 public enum StoreStatusEnum {
 
-    creating(1000, "筹备中"),
-    reviewing(2000, "审核中"),
-    business_open(3000, ""),
-    business_paused(3001, ""),
-    business_banned(3002, ""),
-    business_suspended(3003, ""),
-    closed(1001, ""),
-    deleted(1002, "");
+    DRAFT(1000, "创建中"),
+    PENDING(1001, "待审核"),
+    UNDER_REVIEW(1002, "审核中"),
+    REJECTED(1003, "拒绝"),
+    APPROVED(1004, "同意"),
+    COMING_SOON(2100, "即将开业"),
+    OPEN(2101, "营业中"),
+    CLOSED(2102, "停止营业");
 
-    private final int value;
+    private final Integer value;
     private final String reasonPhrase;
 
-    private StoreStatusEnum(int value, String reasonPhrase) {
+    StoreStatusEnum(Integer value, String reasonPhrase) {
         this.value = value;
         this.reasonPhrase = reasonPhrase;
     }
+
+    public static StoreStatusEnum get(Integer code) {
+        for (StoreStatusEnum value : values()) {
+            if (value.value.equals(code)) {
+                return value;
+            }
+        }
+        return null;
+    }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java
index 15753c0..b535f17 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java
@@ -5,6 +5,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.oying.modules.pc.store.domain.Store;
 import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
 import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
 import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
 import org.apache.ibatis.annotations.Mapper;
@@ -31,4 +32,8 @@
 
     IPage<StoreSearchDto> queryNearStoreWithProduct(@Param("criteria") NearbyStoreQueryCriteria criteria, Page<StoreSearchDto> page);
 
+    List<Long> queryStoreIds(@Param("criteria") StoreQueryCriteria criteria);
+
+    List<Store> queryUserStores(@Param("userId") Long userId);
+
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java
index 65462c7..6fcd434 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java
@@ -1,25 +1,29 @@
 package com.oying.modules.pc.store.rest;
 
-import com.oying.annotation.Log;
-import com.oying.utils.R;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.oying.modules.pc.store.domain.StoreCategory;
-import com.oying.modules.pc.store.service.StoreCategoryService;
+import com.oying.modules.pc.store.domain.dto.StoreCategoryCreateRequest;
 import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreCategoryUpdateRequest;
+import com.oying.modules.pc.store.service.StoreCategoryService;
+import com.oying.utils.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
 import lombok.RequiredArgsConstructor;
-import java.util.List;
-
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
-import io.swagger.annotations.*;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import java.util.List;
 
 /**
-* @author lzp
-* @date 2025-04-24
-**/
+ * @author lzp
+ * @date 2025-04-24
+ **/
 @Api(tags = "商品中心:店铺类目")
 @RestController
 @RequiredArgsConstructor
@@ -28,35 +32,48 @@
 
     private final StoreCategoryService storeCategoryService;
 
-    @GetMapping
-    @ApiOperation("查询api/store/category")
-    public ResponseEntity<?> queryStoreCategory(StoreCategoryQueryCriteria criteria){
+    @GetMapping(value = "/list")
+    @ApiOperation("查询")
+    public ResponseEntity<?> getStoreCategories(StoreCategoryQueryCriteria criteria) {
+        return ResponseEntity.ok(R.success(storeCategoryService.queryAll(criteria)));
+    }
+
+    @GetMapping(value = "/page")
+    @ApiOperation("查询")
+    public ResponseEntity<?> getStoreCategoriesByPage(StoreCategoryQueryCriteria criteria) {
         Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
         return ResponseEntity.ok(R.success(storeCategoryService.queryAll(criteria, page)));
     }
 
+    @GetMapping(value = "/{categoryId}")
+    @ApiOperation("查询")
+    public ResponseEntity<?> getStoreCategory(@PathVariable Long categoryId) {
+        return ResponseEntity.ok(R.success(storeCategoryService.getById(categoryId)));
+    }
+
     @PostMapping
-    @Log("新增api/store")
-    @ApiOperation("新增api/store")
-    @PreAuthorize("@el.check('storeCategory:add')")
-    public ResponseEntity<?> createStoreCategory(@Validated @RequestBody StoreCategory resources){
-        storeCategoryService.create(resources);
+    @ApiOperation("新增")
+    // @PreAuthorize("@el.check('storeCategory:add')")
+    public ResponseEntity<?> createStoreCategory(@Validated @RequestBody StoreCategoryCreateRequest request) {
+        StoreCategory storeCategory = new StoreCategory();
+        BeanUtil.copyProperties(request, storeCategory, CopyOptions.create().setIgnoreNullValue(true));
+        storeCategoryService.create(storeCategory);
         return ResponseEntity.status(HttpStatus.CREATED).build();
     }
 
     @PutMapping
-    @Log("修改api/store")
-    @ApiOperation("修改api/store")
-    @PreAuthorize("@el.check('storeCategory:edit')")
-    public ResponseEntity<?> updateStoreCategory(@Validated @RequestBody StoreCategory resources){
-        storeCategoryService.update(resources);
+    @ApiOperation("修改")
+    // @PreAuthorize("@el.check('storeCategory:edit')")
+    public ResponseEntity<?> updateStoreCategory(@Validated @RequestBody StoreCategoryUpdateRequest request) {
+        StoreCategory storeCategory = new StoreCategory();
+        BeanUtil.copyProperties(request, storeCategory, CopyOptions.create().setIgnoreNullValue(true));
+        storeCategoryService.update(storeCategory);
         return ResponseEntity.noContent().build();
     }
 
     @DeleteMapping
-    @Log("删除api/store")
-    @ApiOperation("删除api/store")
-    @PreAuthorize("@el.check('storeCategory:del')")
+    @ApiOperation("删除")
+    // @PreAuthorize("@el.check('storeCategory:del')")
     public ResponseEntity<?> deleteStoreCategory(@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/rest/StoreCategoryCustomerController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryCustomerController.java
index deb8507..f395f4c 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryCustomerController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryCustomerController.java
@@ -5,6 +5,7 @@
 import cn.hutool.core.lang.tree.TreeNodeConfig;
 import cn.hutool.core.lang.tree.TreeUtil;
 import cn.hutool.core.util.BooleanUtil;
+import com.oying.modules.pc.store.domain.enums.StoreCategoryEnum;
 import com.oying.utils.R;
 import com.oying.modules.pc.store.domain.StoreCategory;
 import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
@@ -39,7 +40,7 @@
 
         StoreCategoryQueryCriteria criteria = new StoreCategoryQueryCriteria();
         criteria.setStoreId(storeId);
-        criteria.setActive(1);
+        criteria.setActive(StoreCategoryEnum.YES.getValue());
         List<StoreCategory> categoryList = storeCategoryService.queryAll(criteria);
 
         List<CustomerStoreCategoryView> categoryViewList = Optional.ofNullable(categoryList).orElse(ListUtil.empty()).stream().map(i -> {
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 f576684..d193a8e 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
@@ -42,8 +42,8 @@
     @ApiOperation("查询店铺类目")
     //@PreAuthorize("@el.check('merchant:storeCategory:list')" +
     //        " and @storeMerchantOwnershipService.check(#storeId)")
-    public ResponseEntity<?> getList(@PathVariable Long storeId,
-                                     @RequestParam(value = "recursive", required = false) Boolean recursive) {
+    public ResponseEntity<?> getStoreCategories(@PathVariable Long storeId,
+                                                @RequestParam(value = "recursive", required = false) Boolean recursive) {
 
         StoreCategoryQueryCriteria criteria = new StoreCategoryQueryCriteria();
         criteria.setStoreId(storeId);
@@ -77,7 +77,7 @@
     @ApiOperation("查询店铺类目")
     //@PreAuthorize("@el.check('merchant:storeCategory:list')" +
     //        " and @storeMerchantOwnershipService.check(#storeId)")
-    public ResponseEntity<?> getById(@PathVariable Long categoryId,
+    public ResponseEntity<?> getStoreCategoryById(@PathVariable Long categoryId,
                                      @RequestParam(value = "recursive", required = false) Boolean recursive) {
 
         StoreCategory storeCategory = storeCategoryService.getById(categoryId);
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java
index 81082e4..a81be6f 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java
@@ -1,15 +1,21 @@
 package com.oying.modules.pc.store.rest;
 
-import com.oying.utils.R;
-import com.oying.modules.pc.common.id.StoreIdGenerator;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.oying.modules.pc.store.domain.Store;
-import com.oying.modules.pc.store.domain.dto.*;
+import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
+import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreUpdateRequest;
 import com.oying.modules.pc.store.service.StoreService;
-import com.oying.utils.SecurityUtils;
+import com.oying.utils.R;
+import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
-import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.Optional;
 
 /**
  * 店铺
@@ -24,43 +30,43 @@
 
     private final StoreService storeService;
 
-    @GetMapping(value = "/page")
-    public R<?> getStoresByPage(StoreQueryCriteria criteria) {
-        return R.success(storeService.queryByPage(criteria));
+    @GetMapping(value = "/list")
+    @ApiOperation("查询所有店铺")
+    public ResponseEntity<?> getStores(StoreQueryCriteria criteria) {
+        List<Store> storeList = Optional.ofNullable(storeService.queryAll(criteria)).orElse(ListUtil.empty());
+        return ResponseEntity.ok(R.success(storeList));
     }
 
-    @GetMapping(value = "/list")
-    public R<?> getStores(StoreQueryCriteria criteria) {
-        return R.success(storeService.queryAll(criteria));
+    @GetMapping(value = "/page")
+    @ApiOperation("查询所有店铺")
+    public ResponseEntity<?> getStoresByPage(StoreQueryCriteria criteria) {
+        return ResponseEntity.ok(R.success(storeService.queryByPage(criteria)));
     }
 
     @GetMapping(value = "/{storeId}")
-    public R<?> getStoreById(@PathVariable("storeId") Long storeId) {
-        return R.success(storeService.getById(storeId));
+    @ApiOperation("查询店铺")
+    public ResponseEntity<?> getStoreById(@PathVariable Long storeId) {
+        return ResponseEntity.ok(R.success(storeService.getById(storeId)));
     }
 
     @GetMapping(value = "/{storeId}/details")
-    public R<?> getStoreDetailsById(@PathVariable("storeId") Long storeId) {
-        return R.success(storeService.getById(storeId));
+    public ResponseEntity<?> getStoreDetailsById(@PathVariable("storeId") Long storeId) {
+        return ResponseEntity.ok(R.success(storeService.getById(storeId)));
     }
 
-    @PostMapping(value = "/createEmpty")
-    public R<?> createEmpty(@RequestBody StoreCreateRequest request) {
-        Store store = new Store();
-        store.setStoreId(StoreIdGenerator.getId());
-        store.setMerchantId(SecurityUtils.getCurrentUserId());
-        storeService.save(store);
-        return R.success();
+    @PostMapping
+    @ApiOperation("创建店铺")
+    public ResponseEntity<?> create(@RequestBody StoreCreateRequest request) {
+        storeService.create(request);
+        return ResponseEntity.status(HttpStatus.CREATED).build();
     }
 
-    /**
-     * 修改店铺信息
-     */
     @PostMapping(value = "/{storeId}")
-    public R<?> update(@PathVariable("storeId") Long storeId, @RequestBody Store store) {
-        store.setStoreId(storeId);
-        storeService.updateById(store);
-        return R.success();
+    @ApiOperation("修改店铺")
+    public ResponseEntity<?> update(@PathVariable("storeId") Long storeId, @RequestBody StoreUpdateRequest request) {
+        request.setStoreId(ObjectUtil.defaultIfNull(request.getStoreId(), storeId));
+        storeService.update(request);
+        return ResponseEntity.noContent().build();
     }
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java
index 0dfd954..04dd21d 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java
@@ -1,14 +1,31 @@
 package com.oying.modules.pc.store.rest;
 
-import com.oying.utils.R;
+import com.oying.modules.pc.product.domain.Product;
+import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
+import com.oying.modules.pc.product.domain.enums.ProductStatusEnum;
+import com.oying.modules.pc.product.service.ProductService;
+import com.oying.modules.pc.store.domain.Store;
+import com.oying.modules.pc.store.domain.StoreQualification;
 import com.oying.modules.pc.store.domain.dto.StoreCustomerDetailDto;
-import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
+import com.oying.modules.pc.store.service.StoreQualificationService;
 import com.oying.modules.pc.store.service.StoreQueryService;
+import com.oying.modules.pc.store.service.StoreService;
+import com.oying.modules.pc.utils.BusinessHoursUtils;
+import com.oying.utils.PageResult;
+import com.oying.utils.R;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
 
 /**
  * 店铺
@@ -22,15 +39,45 @@
 @RequiredArgsConstructor
 public class StoreCustomerController {
 
+    private final StoreService storeService;
     private final StoreQueryService storeQueryService;
+    private final StoreQualificationService storeQualificationService;
+    private final ProductService productService;
+
+    @GetMapping(value = "/page")
+    @ApiOperation("查询店铺")
+    public ResponseEntity<?> getStoresByPage(StoreQueryCriteria criteria) {
+        PageResult<Store> pagedStores = storeQueryService.findPagedStores(criteria);
+        List<Store> stores = pagedStores.getContent();
+        for (Store store : stores) {
+            store.setProducts(this.getProductsByStoreId(store.getStoreId()));
+        }
+        return ResponseEntity.ok(R.success(stores));
+    }
 
     @GetMapping(value = "/{storeId}")
     @ApiOperation("查询店铺")
-    public ResponseEntity<?> getCustomerStoreById(@PathVariable("storeId") Long storeId) {
-        StoreCustomerQueryCriteria criteria = new StoreCustomerQueryCriteria();
+    public ResponseEntity<?> getStoreDetailsById(@PathVariable("storeId") Long storeId) {
+        Store store = storeService.getById(storeId);
+        //store.setQualifications(this.getQualificationsByStoreId(store.getStoreId()));
+        StoreCustomerDetailDto storeDto = new StoreCustomerDetailDto();
+        BeanUtils.copyProperties(store, storeDto);
+        storeDto.setBusinessHours(BusinessHoursUtils.formatBusinessHours(store.getOpenTime(), store.getCloseTime()));
+        return ResponseEntity.ok(R.success(storeDto));
+    }
+
+    private List<StoreQualification> getQualificationsByStoreId(Long storeId) {
+        StoreQualificationQueryCriteria criteria = new StoreQualificationQueryCriteria();
         criteria.setStoreId(storeId);
-        StoreCustomerDetailDto detailDto = storeQueryService.getCustomerStoreDetail(criteria);
-        return ResponseEntity.ok(R.success(detailDto));
+        return storeQualificationService.queryAll(criteria);
+    }
+
+    private List<Product> getProductsByStoreId(Long storeId) {
+        ProductQueryCriteria criteria = new ProductQueryCriteria();
+        criteria.setStoreId(storeId);
+        criteria.setStatus(ProductStatusEnum.AVAILABLE.getValue());
+        criteria.setLimit(3);
+        return productService.queryAll(criteria);
     }
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java
index 6e5d928..e1eee0a 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java
@@ -1,6 +1,10 @@
 package com.oying.modules.pc.store.rest;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
 import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.oying.modules.pc.store.domain.dto.StoreUpdateRequest;
 import com.oying.utils.R;
 import com.oying.modules.pc.store.domain.Store;
 import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
@@ -44,16 +48,18 @@
     @ApiOperation("查询所有店铺")
     //@PreAuthorize("@el.check('merchant:store:list')")
     public ResponseEntity<?> getList() {
-        StoreQueryCriteria criteria = new StoreQueryCriteria();
-        criteria.setMerchantId(SecurityUtils.getCurrentUserId());
-        //criteria.setStatus();
-        List<Store> storeList = Optional.ofNullable(storeService.queryAll(criteria)).orElse(ListUtil.empty());
-        List<StoreSimpleView> storeViewList = storeList.stream().map(s -> {
+        List<Store> stores = Optional.ofNullable(storeService.queryUserStores(SecurityUtils.getCurrentUserId())).orElse(ListUtil.empty());
+        return ResponseEntity.ok(R.success(stores));
+    }
+
+    @GetMapping(value = "/simple-list")
+    @ApiOperation("查询所有店铺")
+    //@PreAuthorize("@el.check('merchant:store:list')")
+    public ResponseEntity<?> getSimpleStores() {
+        List<Store> stores = Optional.ofNullable(storeService.queryUserStores(SecurityUtils.getCurrentUserId())).orElse(ListUtil.empty());
+        List<StoreSimpleView> storeViewList = stores.stream().map(i -> {
             StoreSimpleView view = new StoreSimpleView();
-            view.setId(s.getStoreId());
-            view.setName(s.getStoreName());
-            view.setLogoUrl("");
-            view.setStatus(s.getStatus());
+            BeanUtil.copyProperties(i, view, CopyOptions.create().setIgnoreNullValue(true));
             return view;
         }).collect(Collectors.toList());
         return ResponseEntity.ok(R.success(storeViewList));
@@ -61,13 +67,11 @@
 
     @GetMapping(value = "/{storeId}")
     @ApiOperation("查询店铺")
-    //@PreAuthorize("@el.check('merchant:store:getById')" +
-    //             " and @storeMerchantOwnershipService.check(#storeId)")
+    //@PreAuthorize("@el.check('merchant:store:getById')")
     public ResponseEntity<?> getById(@PathVariable Long storeId) {
         Store store = storeService.getById(storeId);
         StoreMerchantView view = new StoreMerchantView();
         BeanUtils.copyProperties(store, view);
-        view.setLogoUrl("");
         return ResponseEntity.ok(R.success(view));
     }
 
@@ -86,10 +90,9 @@
     @ApiOperation("修改店铺")
     //@PreAuthorize("@el.check('merchant:store:update')" +
     //        " and @storeMerchantOwnershipService.check(#storeId)")
-    public ResponseEntity<?> update(@PathVariable("storeId") Long storeId,
-                       @RequestBody Store store) {
-        store.setStoreId(storeId);
-        storeService.updateById(store);
+    public ResponseEntity<?> update(@PathVariable("storeId") Long storeId, @RequestBody StoreUpdateRequest request) {
+        request.setStoreId(ObjectUtil.defaultIfNull(request.getStoreId(), storeId));
+        storeService.update(request);
         return ResponseEntity.noContent().build();
     }
 
@@ -103,7 +106,7 @@
     public ResponseEntity<?> updateLogo(@PathVariable("storeId") Long storeId,
                            @Validated(value = StoreFieldUpdateRequest.UpdateStoreLogoImageGroup.class)
                            @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateLogo(storeId, request.getLogoImageUploadId());
+        storeService.updateLogo(storeId, request.getLogoImageUploadId(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -117,7 +120,7 @@
     public ResponseEntity<?> updateName(@PathVariable("storeId") Long storeId,
                            @Validated(value = StoreFieldUpdateRequest.UpdateStoreNameGroup.class)
                            @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateName(storeId, request.getStoreName());
+        storeService.updateName(storeId, request.getStoreName(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -131,7 +134,7 @@
     public ResponseEntity<?> updateDescription(@PathVariable("storeId") Long storeId,
                                   @Validated(value = StoreFieldUpdateRequest.UpdateStoreDescriptionGroup.class)
                                   @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateDescription(storeId, request.getDescription());
+        storeService.updateDescription(storeId, request.getDescription(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -145,7 +148,7 @@
     public ResponseEntity<?> updateContactPhone(@PathVariable("storeId") Long storeId,
                                    @Validated(value = StoreFieldUpdateRequest.UpdateStoreContactPhoneGroup.class)
                                    @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateContactPhone(storeId, request.getContactPhone());
+        storeService.updateContactPhone(storeId, request.getContactPhone(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -159,7 +162,7 @@
     public ResponseEntity<?> updateAddress(@PathVariable("storeId") Long storeId,
                               @Validated(value = StoreFieldUpdateRequest.UpdateStoreAddressGroup.class)
                               @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateAddress(storeId, request.getAddress());
+        storeService.updateAddress(storeId, request.getAddress(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -173,7 +176,7 @@
     public ResponseEntity<?> updateLocation(@PathVariable("storeId") Long storeId,
                                @Validated(value = StoreFieldUpdateRequest.UpdateStoreLocationGroup.class)
                                @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateLocation(storeId, request.getLongitude(), request.getLatitude());
+        storeService.updateLocation(storeId, request.getLongitude(), request.getLatitude(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -187,7 +190,7 @@
     public ResponseEntity<?> updateRadius(@PathVariable("storeId") Long storeId,
                              @Validated(value = StoreFieldUpdateRequest.UpdateStoreRadiusGroup.class)
                              @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateRadius(storeId, request.getRadius());
+        storeService.updateRadius(storeId, request.getRadius(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -201,7 +204,7 @@
     public ResponseEntity<?> updatePlatformCategory(@PathVariable("storeId") Long storeId,
                                        @Validated(value = StoreFieldUpdateRequest.UpdateStorePlatformCategoryGroup.class)
                                        @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updatePlatformCategory(storeId, request.getPlatformCategoryId());
+        storeService.updatePlatformCategory(storeId, request.getPlatformCategoryId(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -215,7 +218,7 @@
     public ResponseEntity<?> updateBusinessHours(@PathVariable("storeId") Long storeId,
                                     @Validated(value = StoreFieldUpdateRequest.UpdateStoreBusinessHoursGroup.class)
                                     @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateBusinessHours(storeId, request.getOpenTime(), request.getCloseTime());
+        storeService.updateBusinessHours(storeId, request.getOpenTime(), request.getCloseTime(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -229,7 +232,7 @@
     public ResponseEntity<?> updateDeliveryMinimum(@PathVariable("storeId") Long storeId,
                                       @Validated(value = StoreFieldUpdateRequest.UpdateStoreDeliveryMinimumGroup.class)
                                       @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateDeliveryMinimum(storeId, request.getDeliveryMinimum());
+        storeService.updateDeliveryMinimum(storeId, request.getDeliveryMinimum(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -243,7 +246,7 @@
     public ResponseEntity<?> updateDeliveryFee(@PathVariable("storeId") Long storeId,
                                   @Validated(value = StoreFieldUpdateRequest.UpdateStoreDeliveryFeeGroup.class)
                                   @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateDeliveryFee(storeId, request.getDeliveryFee());
+        storeService.updateDeliveryFee(storeId, request.getDeliveryFee(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 
@@ -257,7 +260,7 @@
     public ResponseEntity<?> businessStatus(@PathVariable("storeId") Long storeId,
                                @Validated(value = StoreFieldUpdateRequest.UpdateStoreBusinessStatusGroup.class)
                                @RequestBody StoreFieldUpdateRequest request) {
-        storeService.updateStatus(storeId, request.getBusinessStatus());
+        storeService.updateStatus(storeId, request.getBusinessStatus(), request.getVersion());
         return ResponseEntity.noContent().build();
     }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java
index 2d5cff5..0c3eaff 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java
@@ -2,8 +2,10 @@
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.oying.annotation.Log;
-import com.oying.modules.pc.store.domain.StoreQualification;
+import com.oying.modules.pc.store.converter.StoreQualificationAssembler;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationCreateRequest;
 import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationUpdateRequest;
 import com.oying.modules.pc.store.service.StoreQualificationService;
 import com.oying.utils.R;
 import io.swagger.annotations.Api;
@@ -12,7 +14,6 @@
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -25,43 +26,57 @@
 @RestController
 @RequiredArgsConstructor
 @Api(tags = "店铺资质")
-@RequestMapping("/api/storeQualification")
+@RequestMapping("/api/pc/storeQualification")
 public class StoreQualificationController {
 
     private final StoreQualificationService storeQualificationService;
 
-    @GetMapping
+    @GetMapping(value = "/list")
     @ApiOperation("查询店铺资质")
-    @PreAuthorize("@el.check('storeQualification:list')")
-    public ResponseEntity<Object> queryStoreQualification(StoreQualificationQueryCriteria criteria) {
+    // @PreAuthorize("@el.check('storeQualification:list')")
+    public ResponseEntity<?> getStoreQualifications(StoreQualificationQueryCriteria criteria) {
+        return ResponseEntity.ok(R.success(storeQualificationService.queryAll(criteria)));
+    }
+
+    @GetMapping(value = "/page")
+    @ApiOperation("查询店铺资质")
+    // @PreAuthorize("@el.check('storeQualification:list')")
+    public ResponseEntity<?> getStoreQualificationsByPage(StoreQualificationQueryCriteria criteria) {
         Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
-        return new ResponseEntity<>(R.success(storeQualificationService.queryAll(criteria, page)), HttpStatus.OK);
+        return ResponseEntity.ok(R.success(storeQualificationService.queryAll(criteria, page)));
+    }
+
+    @GetMapping(value = "/{qualificationId}")
+    @ApiOperation("查询店铺资质")
+    // @PreAuthorize("@el.check('storeQualification:list')")
+    public ResponseEntity<?> getStoreQualificationById(@PathVariable Long qualificationId) {
+        return ResponseEntity.ok(R.success(storeQualificationService.getById(qualificationId)));
     }
 
     @PostMapping
     @Log("新增店铺资质")
     @ApiOperation("新增店铺资质")
-    @PreAuthorize("@el.check('storeQualification:add')")
-    public ResponseEntity<Object> createStoreQualification(@Validated @RequestBody StoreQualification resources) {
-        storeQualificationService.create(resources);
-        return new ResponseEntity<>(R.success(),HttpStatus.CREATED);
+    // @PreAuthorize("@el.check('storeQualification:add')")
+    public ResponseEntity<Object> createStoreQualification(@Validated @RequestBody StoreQualificationCreateRequest request) {
+        storeQualificationService.create(StoreQualificationAssembler.to(request));
+        return ResponseEntity.status(HttpStatus.CREATED).build();
     }
 
     @PutMapping
     @Log("修改店铺资质")
     @ApiOperation("修改店铺资质")
-    @PreAuthorize("@el.check('storeQualification:edit')")
-    public ResponseEntity<Object> updateStoreQualification(@Validated @RequestBody StoreQualification resources) {
-        storeQualificationService.update(resources);
-        return new ResponseEntity<>(R.success(),HttpStatus.NO_CONTENT);
+    // @PreAuthorize("@el.check('storeQualification:edit')")
+    public ResponseEntity<Object> updateStoreQualification(@Validated @RequestBody StoreQualificationUpdateRequest request) {
+        storeQualificationService.update(request);
+        return ResponseEntity.noContent().build();
     }
 
     @DeleteMapping
     @Log("删除店铺资质")
     @ApiOperation("删除店铺资质")
-    @PreAuthorize("@el.check('storeQualification:del')")
+    // @PreAuthorize("@el.check('storeQualification:del')")
     public ResponseEntity<Object> deleteStoreQualification(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
         storeQualificationService.deleteAll(ids);
-        return new ResponseEntity<>(R.success(),HttpStatus.OK);
+        return ResponseEntity.noContent().build();
     }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java
index 7d24181..fae5612 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java
@@ -34,20 +34,18 @@
     @GetMapping("/list")
     @ApiOperation("查询店铺资质")
     //@PreAuthorize("@el.check('customer:storeQualification:list')")
-    public ResponseEntity<?> getList(@PathVariable Long storeId) {
-        if (ObjUtil.isEmpty(storeId)) {
-            return ResponseEntity.ok(R.success(ListUtil.empty()));
-        }
+    public ResponseEntity<?> getQualifications(@PathVariable Long storeId) {
         StoreQualificationQueryCriteria criteria = new StoreQualificationQueryCriteria();
         criteria.setStoreId(storeId);
         List<StoreQualification> qualificationList = storeQualificationService.queryAll(criteria);
-        List<CustomerStoreQualificationView> viewList = Optional.ofNullable(qualificationList).orElse(ListUtil.empty()).stream().map(i -> {
-            CustomerStoreQualificationView view = new CustomerStoreQualificationView();
-            BeanUtils.copyProperties(i, view);
-            view.setType(i.getQualificationType());
-            view.setName(i.getQualificationName());
-            view.setImageUrl("");
-            return view;
+        List<CustomerStoreQualificationView> viewList = Optional.ofNullable(qualificationList).orElse(ListUtil.empty())
+                .stream().map(i -> {
+                    CustomerStoreQualificationView view = new CustomerStoreQualificationView();
+                    BeanUtils.copyProperties(i, view);
+                    view.setType(i.getQualificationType());
+                    view.setName(i.getQualificationName());
+                    view.setImageUrl(i.getQualificationImageUrl());
+                    return view;
         }).collect(Collectors.toList());
         return ResponseEntity.ok(R.success(viewList));
     }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java
index 6bae2fa..aa31e18 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java
@@ -1,14 +1,17 @@
 package com.oying.modules.pc.store.rest;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
 import cn.hutool.core.collection.ListUtil;
 import com.oying.annotation.Log;
-import com.oying.utils.R;
+import com.oying.modules.pc.store.converter.StoreQualificationAssembler;
 import com.oying.modules.pc.store.domain.StoreQualification;
 import com.oying.modules.pc.store.domain.dto.StoreQualificationCreateRequest;
 import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
 import com.oying.modules.pc.store.domain.dto.StoreQualificationUpdateRequest;
 import com.oying.modules.pc.store.service.StoreQualificationService;
 import com.oying.modules.pc.store.view.StoreQualificationMerchantView;
+import com.oying.utils.R;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -44,10 +47,11 @@
         List<StoreQualification> storeQualificationList = storeQualificationService.queryAll(criteria);
         List<StoreQualificationMerchantView> viewList = Optional.ofNullable(storeQualificationList).orElse(ListUtil.empty()).stream().map(i -> {
             StoreQualificationMerchantView view = new StoreQualificationMerchantView();
+            BeanUtil.copyProperties(i, view, CopyOptions.create().setIgnoreNullValue(true));
             view.setId(i.getQualificationId());
             view.setType(i.getQualificationType());
             view.setName(i.getQualificationName());
-            view.setImageUrl("");
+            view.setImageUrl(i.getQualificationImageUrl());
             return view;
         }).collect(Collectors.toList());
 
@@ -60,13 +64,9 @@
     //@PreAuthorize("@el.check('merchant:storeQualification:add') " +
     //        "and @storeMerchantOwnershipService.check(#storeId)")
     public ResponseEntity<?> create(@PathVariable Long storeId,
-                                         @Validated @RequestBody StoreQualificationCreateRequest request) {
-
-        StoreQualification resources = new StoreQualification();
-        resources.setStoreId(storeId);
-        resources.setQualificationType(request.getType());
-        resources.setQualificationImageId(request.getImageUploadFileId());
-        storeQualificationService.create(resources);
+                                    @Validated @RequestBody StoreQualificationCreateRequest request) {
+        request.setStoreId(Optional.ofNullable(request.getStoreId()).orElse(storeId));
+        storeQualificationService.create(StoreQualificationAssembler.to(request));
         return ResponseEntity.status(HttpStatus.CREATED).build();
     }
 
@@ -76,15 +76,10 @@
     //@PreAuthorize("@el.check('merchant:storeQualification:edit') " +
     //        "and @storeMerchantOwnershipService.check(#storeId)")
     public ResponseEntity<?> update(@PathVariable Long storeId,
-                                         @PathVariable Long qualificationId,
-                                         @Validated @RequestBody StoreQualificationUpdateRequest request) {
-
-        StoreQualification resources = new StoreQualification();
-        resources.setQualificationId(qualificationId);
-        resources.setStoreId(storeId);
-        resources.setQualificationType(request.getType());
-        resources.setQualificationImageId(request.getImageUploadFileId());
-        storeQualificationService.update(resources);
+                                    @PathVariable Long qualificationId,
+                                    @Validated @RequestBody StoreQualificationUpdateRequest request) {
+        request.setQualificationId(Optional.ofNullable(request.getQualificationId()).orElse(qualificationId));
+        storeQualificationService.update(request);
         return ResponseEntity.noContent().build();
     }
 
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java
index fca62cf..08b6ff7 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java
@@ -7,6 +7,7 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.oying.modules.pc.store.domain.StoreQualification;
 import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationUpdateRequest;
 import com.oying.utils.PageResult;
 
 /**
@@ -32,6 +33,13 @@
     List<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria);
 
     /**
+     * 查询
+     * @param ids 条件参数
+     * @return List<StoreQualification>
+     */
+    List<StoreQualification> queryBatchIds(List<Long> ids);
+
+    /**
     * 创建
     * @param resources /
     */
@@ -45,9 +53,15 @@
 
     /**
     * 编辑
-    * @param resources /
+    * @param request /
     */
-    void update(StoreQualification resources);
+    void update(StoreQualificationUpdateRequest request);
+
+    /**
+     * 编辑
+     * @param requests /
+     */
+    void batchUpdate(List<StoreQualificationUpdateRequest> requests);
 
     /**
     * 多选删除
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java
index e0c3aa0..b06f1b4 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java
@@ -1,10 +1,15 @@
 package com.oying.modules.pc.store.service;
 
+import com.oying.modules.pc.store.domain.Store;
 import com.oying.modules.pc.store.domain.dto.StoreCustomerDetailDto;
 import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
+import com.oying.utils.PageResult;
+
+import java.util.List;
 
 public interface StoreQueryService {
 
-    StoreCustomerDetailDto getCustomerStoreDetail(StoreCustomerQueryCriteria criteria);
+    PageResult<Store> findPagedStores(StoreQueryCriteria criteria);
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java
index 8bdcc52..d56cbfc 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java
@@ -3,9 +3,7 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.oying.modules.pc.store.domain.Store;
 import com.oying.modules.pc.store.domain.StoreCategory;
-import com.oying.modules.pc.store.domain.dto.StoreBusinessHoursRequest;
-import com.oying.modules.pc.store.domain.dto.StoreLocationUpdateRequest;
-import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.*;
 import com.oying.utils.PageResult;
 
 import java.math.BigDecimal;
@@ -26,31 +24,35 @@
 
     Store getMerchantStore(Long merchantId);
 
-    boolean create(Store store);
+    List<Store> queryUserStores(Long userId);
 
-    boolean updateLogo(Long storeId, String logo);
+    boolean create(StoreCreateRequest request);
 
-    boolean updateName(Long storeId, String storeName);
+    boolean update(StoreUpdateRequest request);
 
-    boolean updateDescription(Long storeId, String description);
+    boolean updateLogo(Long storeId, String logo, Long version);
 
-    boolean updateContactPhone(Long storeId, String contactPhone);
+    boolean updateName(Long storeId, String storeName, Long version);
 
-    boolean updateAddress(Long storeId, String address);
+    boolean updateDescription(Long storeId, String description, Long version);
 
-    boolean updateLocation(Long storeId, Double longitude, Double latitude);
+    boolean updateContactPhone(Long storeId, String contactPhone, Long version);
 
-    boolean updateRadius(Long storeId, Integer radius);
+    boolean updateAddress(Long storeId, String address, Long version);
 
-    boolean updatePlatformCategory(Long storeId, Long platformCategory);
+    boolean updateLocation(Long storeId, Double longitude, Double latitude, Long version);
 
-    boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime);
+    boolean updateRadius(Long storeId, Integer radius, Long version);
 
-    boolean updateDeliveryMinimum(Long storeId, BigDecimal deliveryMinimum);
+    boolean updatePlatformCategory(Long storeId, Long platformCategory, Long version);
 
-    boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee);
+    boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime, Long version);
 
-    boolean updateStatus(Long storeId, Integer status);
+    boolean updateDeliveryMinimum(Long storeId, BigDecimal deliveryMinimum, Long version);
+
+    boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee, Long version);
+
+    boolean updateStatus(Long storeId, Integer status, Long version);
 
     boolean existsByIdAndMerchantId(Long storeId, Long merchantId);
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java
index 7f875f2..0176e44 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java
@@ -45,7 +45,6 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void create(StoreCategory resources) {
-        // 重名
         this.calculateAndSetLevel(resources);
         storeCategoryMapper.insert(resources);
     }
@@ -68,10 +67,6 @@
      * 计算并设置类目的层级
      */
     private void calculateAndSetLevel(StoreCategory category) {
-
-        if (category == null) {
-            throw new IllegalArgumentException("对象不能为null");
-        }
 
         Long parentCategoryId = category.getParentId();
         if (parentCategoryId == null) {
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java
index 467ebbb..9ed3aa1 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java
@@ -1,20 +1,12 @@
 package com.oying.modules.pc.store.service.impl;
 
-import com.oying.modules.pc.store.domain.Store;
-import com.oying.modules.pc.store.domain.StoreQualification;
 import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
 import com.oying.modules.pc.store.service.StoreCreateService;
-import com.oying.modules.pc.store.service.StoreQualificationService;
 import com.oying.modules.pc.store.service.StoreService;
-import com.oying.utils.SecurityUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -22,30 +14,9 @@
 public class StoreCreateServiceImpl implements StoreCreateService {
 
     private final StoreService storeService;
-    private final StoreQualificationService storeQualificationService;
 
     @Transactional(rollbackFor = Exception.class)
     public void create(StoreCreateRequest request) {
-        Store store = new Store();
-        BeanUtils.copyProperties(request, store);
-        store.setMerchantId(SecurityUtils.getCurrentUserId());
-        store.setLogoImageId(request.getLogoUploadFileId());
-        // store.setCoverImage(request.getCoverUploadFileId());
-        storeService.create(store);
-        if (request.hasQualificationList()) {
-            List<StoreQualification> storeQualificationList = request.getQualificationList()
-                    .stream()
-                    .map(i -> {
-                        StoreQualification qualification = new StoreQualification();
-                        qualification.setStoreId(store.getStoreId());
-                        qualification.setQualificationType(i.getType());
-                        qualification.setQualificationName("");
-                        qualification.setQualificationImageId(i.getImageUploadFileId());
-                        return qualification;
-                    })
-                    .collect(Collectors.toList());
-            storeQualificationList.forEach(i -> i.setStoreId(store.getStoreId()));
-            storeQualificationService.batchCreate(storeQualificationList);
-        }
+        storeService.create(request);
     }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java
index dc415a8..2307d9a 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java
@@ -1,13 +1,21 @@
 package com.oying.modules.pc.store.service.impl;
 
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 import com.oying.exception.EntityExistException;
+import com.oying.exception.EntityNotFoundException;
+import com.oying.modules.pc.common.ValueUpdate;
+import com.oying.modules.pc.store.converter.StoreQualificationAssembler;
 import com.oying.modules.pc.store.domain.StoreQualification;
 import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationUpdateRequest;
 import com.oying.modules.pc.store.mapper.StoreQualificationMapper;
 import com.oying.modules.pc.store.service.StoreQualificationService;
+import com.oying.service.BucketStorageService;
 import com.oying.utils.PageResult;
 import com.oying.utils.PageUtil;
 import lombok.RequiredArgsConstructor;
@@ -15,33 +23,42 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
-* @description 服务实现
-* @author lzp
-* @date 2025-04-27
-**/
+ * @author lzp
+ * @description 服务实现
+ * @date 2025-04-27
+ **/
 @Service
 @RequiredArgsConstructor
 public class StoreQualificationServiceImpl extends ServiceImpl<StoreQualificationMapper, StoreQualification> implements StoreQualificationService {
 
     private final StoreQualificationMapper storeQualificationMapper;
+    private final BucketStorageService bucketStorageService;
 
     @Override
-    public PageResult<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria, Page<Object> page){
+    public PageResult<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria, Page<Object> page) {
         return PageUtil.toPage(storeQualificationMapper.findAll(criteria, page));
     }
 
     @Override
-    public List<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria){
+    public List<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria) {
         return storeQualificationMapper.findAll(criteria);
+    }
+
+    @Override
+    public List<StoreQualification> queryBatchIds(List<Long> ids) {
+        LambdaQueryWrapper<StoreQualification> wrapper = new LambdaQueryWrapper<>();
+        wrapper.in(StoreQualification::getQualificationId, ids);
+        return storeQualificationMapper.selectList(wrapper);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void create(StoreQualification resources) {
-        // resources.setQualificationId(StoreQualificationIdGenerator.getId());
         storeQualificationMapper.insert(resources);
     }
 
@@ -52,20 +69,73 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void update(StoreQualification resources) {
-        // resources.setUpdateBy();
-        Long qualificationId = resources.getQualificationId();
+    public void update(StoreQualificationUpdateRequest request) {
+
+        Long qualificationId = request.getQualificationId();
         StoreQualification existingStoreQualification = this.getById(qualificationId);
         if (ObjUtil.isEmpty(existingStoreQualification)) {
-            throw new EntityExistException(StoreQualification.class, "id", Optional.ofNullable(qualificationId).map(Object::toString).orElse("null"));
+            throw new EntityNotFoundException(StoreQualification.class, "qualificationId", Optional.ofNullable(qualificationId).map(Object::toString).orElse("null"));
         }
-        existingStoreQualification.copy(resources);
+
+        // 新的资质数据
+        StoreQualification newStoreQualification = StoreQualificationAssembler.to(request);
+        // 记录图片值的变更
+        ValueUpdate<Long> imageValueUpdate = new ValueUpdate<>(newStoreQualification.getQualificationImageId(), existingStoreQualification.getQualificationImageId());
+        // 填充新的数据
+        existingStoreQualification.copy(newStoreQualification);
         storeQualificationMapper.updateById(existingStoreQualification);
+        // 删除旧图片原纪录
+        if (imageValueUpdate.isChangeAndOldValueNotEmpty()) {
+            bucketStorageService.deleteAll(Lists.newArrayList(imageValueUpdate.getOldValue()));
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void batchUpdate(List<StoreQualificationUpdateRequest> requests) {
+
+        List<Long> updateIds = requests.stream().map(StoreQualificationUpdateRequest::getQualificationId).collect(Collectors.toList());
+        List<StoreQualification> existingStoreQualifications = this.queryBatchIds(updateIds);
+        if (CollectionUtil.isEmpty(existingStoreQualifications)) {
+            throw new EntityNotFoundException(StoreQualification.class, "qualificationIds", updateIds.toString());
+        }
+
+        Map<Long, StoreQualificationUpdateRequest> requestMap = requests.stream().collect(Collectors.toMap(
+                StoreQualificationUpdateRequest::getQualificationId,
+                storeQualificationUpdateRequest -> storeQualificationUpdateRequest
+        ));
+
+        // 提取需要删除的图片原纪录ID
+        List<Long> deleteBucketStorageIds = existingStoreQualifications.stream().filter(i -> {
+            Long newCloudStorageId = requestMap.get(i.getQualificationId()).getImageUploadFileId();
+            return ValueUpdate.isChangeAndOldValueNotEmpty(newCloudStorageId, i.getQualificationImageId());
+        }).map(StoreQualification::getQualificationImageId).collect(Collectors.toList());
+
+        // 填充新的数据
+        for (StoreQualification existingStoreQualification : existingStoreQualifications) {
+            StoreQualification newStoreQualification = StoreQualificationAssembler.to(requestMap.get(existingStoreQualification.getQualificationId()));
+            existingStoreQualification.copy(newStoreQualification);
+        }
+
+        this.updateBatchById(existingStoreQualifications);
+        // 删除旧图片原记录
+        if (CollectionUtil.isNotEmpty(deleteBucketStorageIds)) {
+            bucketStorageService.deleteAll(deleteBucketStorageIds);
+        }
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void deleteAll(List<Long> ids) {
+        List<StoreQualification> existingStoreQualifications = this.queryBatchIds(ids);
+        if (CollectionUtil.isEmpty(existingStoreQualifications)) {
+            throw new EntityNotFoundException(StoreQualification.class, "qualificationIds", ids.toString());
+        }
         storeQualificationMapper.deleteBatchIds(ids);
+        // 删除旧图片原记录
+        List<Long> bucketStorageIds = existingStoreQualifications.stream().map(StoreQualification::getQualificationImageId).collect(Collectors.toList());
+        if (CollectionUtil.isNotEmpty(bucketStorageIds)) {
+            bucketStorageService.deleteAll(bucketStorageIds);
+        }
     }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java
index 0514d5c..a50b69c 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java
@@ -1,33 +1,64 @@
 package com.oying.modules.pc.store.service.impl;
 
+import cn.hutool.core.util.NumberUtil;
 import com.oying.modules.pc.store.domain.Store;
-import com.oying.modules.pc.store.domain.dto.StoreCustomerDetailDto;
-import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
+import com.oying.modules.pc.store.mapper.StoreMapper;
 import com.oying.modules.pc.store.service.StoreQueryService;
 import com.oying.modules.pc.store.service.StoreService;
+import com.oying.utils.PageResult;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.BeanUtils;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
 @RequiredArgsConstructor
 public class StoreQueryServiceImpl implements StoreQueryService {
 
+    private final RedisTemplate<Object, Object> redisTemplate;
     private final StoreService storeService;
+    private final StoreMapper storeMapper;
 
     @Override
-    public StoreCustomerDetailDto getCustomerStoreDetail(StoreCustomerQueryCriteria criteria) {
-        Store store = storeService.getById(criteria.getStoreId());
-        StoreCustomerDetailDto storeDto = new StoreCustomerDetailDto();
-        BeanUtils.copyProperties(store, storeDto);
-        storeDto.setName(store.getStoreName());
-        storeDto.setLogoUrl("");
-        storeDto.setBusinessHours("");
-        storeDto.setDeliveryDuration(0);
-        storeDto.setMonthlySales(0);
-        storeDto.setScore(0);
-        return storeDto;
+    public PageResult<Store> findPagedStores(StoreQueryCriteria criteria) {
+
+        PageResult<Store> page = new PageResult<>();
+
+        // 1. 检查ZSET是否存在
+        String setKey = criteria.buildConditionCacheKey();
+        Long total = redisTemplate.opsForZSet().size(setKey);
+        if (total == null || total == 0) {
+            // 初始化缓存
+            List<Long> ids = storeMapper.queryStoreIds(criteria);
+            for (Long id : ids) {
+                redisTemplate.opsForZSet().add(setKey, 1, id);
+            }
+            // 设置缓存过期时间
+            redisTemplate.expire(setKey, 30, TimeUnit.MINUTES);
+            total = (long) ids.size();
+        }
+
+        // 2. 从ZSET获取分页ID
+        Long offset = NumberUtil.mul(criteria.getPage(), criteria.getSize()).longValue();
+        long end = NumberUtil.add(offset, criteria.getSize()).longValue();
+        Set<Long> storeIds = Optional.ofNullable(redisTemplate.opsForZSet()
+                        .range(setKey, offset, end - 1)).orElse(Collections.emptySet())
+                .stream().map(i-> (Long) i).collect(Collectors.toSet());
+
+        // 3. 获取详情数据
+        List<Store> stores = storeService.listByIds(storeIds);
+
+        page.setContent(stores);
+        page.setTotalElements(total);
+        return page;
     }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
index 69597a5..f7fbfb4 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
@@ -1,24 +1,44 @@
 package com.oying.modules.pc.store.service.impl;
 
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.oying.exception.EntityExistException;
+import com.oying.exception.EntityNotFoundException;
+import com.oying.modules.pc.common.ValueUpdate;
+import com.oying.modules.pc.store.converter.StoreAssembler;
+import com.oying.modules.pc.store.converter.StoreQualificationAssembler;
 import com.oying.modules.pc.store.domain.Store;
+import com.oying.modules.pc.store.domain.StoreQualification;
+import com.oying.modules.pc.store.domain.StoreUser;
+import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationCreateRequest;
 import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
+import com.oying.modules.pc.store.domain.dto.StoreUpdateRequest;
 import com.oying.modules.pc.store.mapper.StoreMapper;
+import com.oying.modules.pc.store.mapper.StoreUserMapper;
+import com.oying.modules.pc.store.service.StoreQualificationService;
 import com.oying.modules.pc.store.service.StoreService;
+import com.oying.service.BucketStorageService;
 import com.oying.utils.PageResult;
 import com.oying.utils.PageUtil;
 import com.oying.utils.SecurityUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.time.LocalTime;
-import java.time.ZonedDateTime;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * 店铺Service业务层处理
@@ -32,6 +52,9 @@
 public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements StoreService {
 
     private final StoreMapper storeMapper;
+    private final StoreUserMapper storeUserMapper;
+    private final StoreQualificationService qualificationService;
+    private final BucketStorageService bucketStorageService;
 
     @Override
     public PageResult<Store> queryByPage(StoreQueryCriteria criteria) {
@@ -50,92 +73,126 @@
     }
 
     @Override
-    public boolean create(Store store) {
-        // store.setStoreId(StoreIdGenerator.getId());
-        return save(store);
+    public List<Store> queryUserStores(Long userId) {
+        return storeMapper.queryUserStores(userId);
     }
 
     @Override
-    public boolean updateLogo(Long storeId, String logo) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId).set(Store::getLogoImageId, logo);
+    @Transactional(rollbackFor = Exception.class)
+    public boolean create(StoreCreateRequest request) {
+        Store store = StoreAssembler.to(request);
+        storeMapper.insert(store);
+        this.processQualificationCreate(store, request.getQualificationList());
+        this.bindUser(store.getStoreId());
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean update(StoreUpdateRequest request) {
+        Store existingStore = this.findOrThrow(request);
+        this.processImagesUpdate(request, existingStore);
+        this.processQualificationUpdate(request);
+        existingStore.copy(StoreAssembler.to(request));
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(existingStore.getStoreId(), existingStore.getVersion());
+        return this.update(existingStore, wrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean updateLogo(Long storeId, String logo, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
+                .set(Store::getLogoImageId, logo);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateName(Long storeId, String storeName) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateName(Long storeId, String storeName, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getStoreName, storeName);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateDescription(Long storeId, String description) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateDescription(Long storeId, String description, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getDescription, description);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateContactPhone(Long storeId, String contactPhone) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateContactPhone(Long storeId, String contactPhone, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getContactPhone, contactPhone);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateAddress(Long storeId, String address) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateAddress(Long storeId, String address, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getAddress, address);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateLocation(Long storeId, Double longitude, Double latitude) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateLocation(Long storeId, Double longitude, Double latitude, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getLongitude, longitude)
                 .set(Store::getLatitude, latitude);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateRadius(Long storeId, Integer radius) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateRadius(Long storeId, Integer radius, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getRadius, radius);
         return update(wrapper);
     }
 
     @Override
-    public boolean updatePlatformCategory(Long storeId, Long platformCategory) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updatePlatformCategory(Long storeId, Long platformCategory, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getPlatformCategoryId, platformCategory);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getOpenTime, openTime)
                 .set(Store::getCloseTime, endTime);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateDeliveryMinimum(Long storeId, BigDecimal deliveryMinimum) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateDeliveryMinimum(Long storeId, BigDecimal deliveryMinimum, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getDeliveryMinimum, deliveryMinimum);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getDeliveryFee, deliveryFee);
         return update(wrapper);
     }
 
     @Override
-    public boolean updateStatus(Long storeId, Integer status) {
-        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+    public boolean updateStatus(Long storeId, Integer status, Long version) {
+        Store existingStore = this.findOrThrow(storeId, version);
+        LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId, existingStore.getVersion())
                 .set(Store::getStatus, status);
         return update(wrapper);
     }
@@ -149,9 +206,83 @@
         return Optional.ofNullable(store).map(i -> merchantId.equals(i.getMerchantId())).orElse(false);
     }
 
-    private LambdaUpdateWrapper<Store> createLambdaUpdateWrapper(Long storeId) {
-        return new LambdaUpdateWrapper<Store>()
-                .eq(Store::getStoreId, storeId)
-                .set(Store::getUpdateBy, SecurityUtils.getCurrentUserId());
+    private void processQualificationCreate(Store store, List<StoreQualificationCreateRequest> qualificationRequests) {
+        if (CollectionUtil.isNotEmpty(qualificationRequests)) {
+            List<StoreQualification> storeQualificationList = qualificationRequests.stream().map(i -> {
+                i.setStoreId(store.getStoreId());
+                return StoreQualificationAssembler.to(i);
+            }).collect(Collectors.toList());
+            storeQualificationList.forEach(i -> i.setStoreId(store.getStoreId()));
+            qualificationService.batchCreate(storeQualificationList);
+        }
+    }
+
+    private void bindUser(Long storeId) {
+        StoreUser storeUser = new StoreUser();
+        storeUser.setStoreId(storeId);
+        storeUser.setUserId(SecurityUtils.getCurrentUserId());
+        storeUser.setRoleType("");
+        storeUser.setPermissions("");
+        storeUserMapper.insert(storeUser);
+    }
+
+    private LambdaUpdateWrapper<Store> createLambdaUpdateWrapper(Long storeId, Long version) {
+        Objects.requireNonNull(storeId, String.format("方法 '%s' 调用失败:参数 'storeId'(店铺ID)不能为 null", "createLambdaUpdateWrapper"));
+        LambdaUpdateWrapper<Store> updateWrapper =  new LambdaUpdateWrapper<>();
+        updateWrapper.eq(Store::getStoreId, storeId);
+        if (ObjUtil.isNotEmpty(version)) {
+            updateWrapper.eq(Store::getVersion, version);
+            updateWrapper.set(Store::getVersion, version + 1);
+        }
+        updateWrapper.set(Store::getUpdateBy, SecurityUtils.getCurrentUserId());
+        return updateWrapper;
+    }
+
+    private Store findOrThrow(StoreUpdateRequest request) {
+        return this.findOrThrow(request.getStoreId(), request.getVersion());
+    }
+
+    private Store findOrThrow(Long storeId, Long version) {
+        Objects.requireNonNull(storeId, String.format("方法 '%s' 调用失败:参数 'storeId'(店铺ID)不能为 null", "findOrThrow"));
+        LambdaQueryWrapper<Store> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(Store::getStoreId, storeId);
+        if (ObjUtil.isNotEmpty(version)) {
+            wrapper.eq(Store::getVersion, version);
+        }
+        Store existingStore = storeMapper.selectOne(wrapper);
+        if (ObjUtil.isEmpty(existingStore)) {
+            throw new EntityNotFoundException(Store.class, "storeId", storeId.toString());
+        }
+        return existingStore;
+    }
+
+    private List<Long> getDeleteImageIds(List<ValueUpdate<Long>> imageValues) {
+        List<Long> deleteImageIds = new ArrayList<>();
+        for (ValueUpdate<Long> imageValue : imageValues) {
+            if (imageValue.isChangeAndOldValueNotEmpty()) {
+                deleteImageIds.add(imageValue.getOldValue());
+            }
+        }
+        return deleteImageIds;
+    }
+
+    private void processImagesUpdate(StoreUpdateRequest request, Store existingStore) {
+        List<ValueUpdate<Long>> imageValues = ListUtil.toList(
+                new ValueUpdate<>(request.getLogoImageId(), existingStore.getLogoImageId()),
+                new ValueUpdate<>(request.getCoverImageId(), existingStore.getCoverImageId())
+        );
+        bucketStorageService.deleteAll(this.getDeleteImageIds(imageValues));
+    }
+
+    private void processQualificationUpdate(StoreUpdateRequest request) {
+        if (CollectionUtil.isNotEmpty(request.getDeletedQualificationIds())) {
+            qualificationService.deleteAll(request.getDeletedQualificationIds());
+        }
+        if (CollectionUtil.isNotEmpty(request.getUpdatedQualifications())) {
+            qualificationService.batchUpdate(request.getUpdatedQualifications());
+        }
+        if (CollectionUtil.isNotEmpty(request.getNewQualifications())) {
+            qualificationService.batchCreate(request.getNewQualifications());
+        }
     }
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java b/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java
index 92f9328..a261e85 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java
@@ -8,7 +8,6 @@
 @Data
 public class CustomerStoreQualificationView {
 
-    @NotNull
     @ApiModelProperty(value = "资质类型")
     private Integer type;
 
@@ -18,4 +17,13 @@
     @ApiModelProperty(value = "资质图片")
     private String imageUrl;
 
+    @ApiModelProperty(value = "资质类型")
+    private Integer qualificationType;
+
+    @ApiModelProperty(value = "资质名称")
+    private String qualificationName;
+
+    @ApiModelProperty(value = "资质图片")
+    private String qualificationImageUrl;
+
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java
index d5c970f..cb84e75 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java
@@ -17,7 +17,20 @@
     @ApiModelProperty(value = "店铺名称")
     private String storeName;
 
-    private String logoUrl;
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "店铺logo图片")
+    private Long logoImageId;
+
+    @ApiModelProperty(value = "店铺logo图片Url")
+    private String logoImageUrl;
+
+    @ApiModelProperty(value = "店铺封面图")
+    private Long coverImageId;
+
+    @ApiModelProperty(value = "店铺封面图Url")
+    private String coverImageUrl;
 
     @ApiModelProperty(value = "店铺描述")
     private String description;
@@ -43,6 +56,13 @@
     @ApiModelProperty(value = "营业半径(米)")
     private Integer radius;
 
-    private Integer status;
+    @ApiModelProperty(value = "是否支持退货")
+    private Integer returns;
+
+    @ApiModelProperty(value = "是否支持自提")
+    private Integer selfPickup;
+
+    @ApiModelProperty(value = "版本号")
+    private Long version;
 
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java
index 0c45390..10f5159 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java
@@ -1,9 +1,12 @@
 package com.oying.modules.pc.store.view;
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
+import java.time.LocalTime;
 
 @Data
 public class StoreQualificationMerchantView {
@@ -21,4 +24,25 @@
     @ApiModelProperty(value = "资质图片")
     private String imageUrl;
 
+    @ApiModelProperty(value = "关联的店铺ID")
+    private Long storeId;
+
+    @ApiModelProperty(value = "资质ID")
+    private Long qualificationId;
+
+    @ApiModelProperty(value = "资质类型")
+    private Integer qualificationType;
+
+    @ApiModelProperty(value = "资质名称")
+    private String qualificationName;
+
+    @ApiModelProperty(value = "资质图片")
+    private Long qualificationImageId;
+
+    @ApiModelProperty(value = "资质图片")
+    private String qualificationImageUrl;
+
+    @ApiModelProperty(value = "状态")
+    private Integer status;
+
 }
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java
index 1a93719..8f8c764 100644
--- a/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java
@@ -1,16 +1,81 @@
 package com.oying.modules.pc.store.view;
 
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalTime;
 
 @Data
 public class StoreSimpleView {
 
-    private Long id;
+    @ApiModelProperty(value = "店铺ID")
+    private Long storeId;
 
-    private String name;
+    @ApiModelProperty(value = "商户ID")
+    private Long merchantId;
 
-    private String logoUrl;
+    @ApiModelProperty(value = "平台类目")
+    private Long platformCategoryId;
 
+    @ApiModelProperty(value = "店铺类型:1-自营 2-加盟 3-第三方")
+    private Integer storeType;
+
+    @ApiModelProperty(value = "店铺名称")
+    private String storeName;
+
+    @ApiModelProperty(value = "状态")
     private Integer status;
 
+    @ApiModelProperty(value = "店铺logo图片")
+    private Long logoImageId;
+
+    @ApiModelProperty(value = "店铺logo图片Url")
+    private String logoImageUrl;
+
+    @ApiModelProperty(value = "店铺封面图")
+    private Long coverImageId;
+
+    @ApiModelProperty(value = "店铺封面图Url")
+    private String coverImageUrl;
+
+    @ApiModelProperty(value = "店铺描述")
+    private String description;
+
+    @ApiModelProperty(value = "配送费用")
+    private BigDecimal deliveryFee;
+
+    @ApiModelProperty(value = "起送金额")
+    private BigDecimal deliveryMinimum;
+
+    @ApiModelProperty(value = "联系电话")
+    private String contactPhone;
+
+    @ApiModelProperty(value = "营业开始时间")
+    private LocalTime openTime;
+
+    @ApiModelProperty(value = "营业结束时间")
+    private LocalTime closeTime;
+
+    @ApiModelProperty(value = "市级代码")
+    private String cityCode;
+
+    @ApiModelProperty(value = "详细地址")
+    private String address;
+
+    @ApiModelProperty(value = "经度")
+    private Double longitude;
+
+    @ApiModelProperty(value = "纬度")
+    private Double latitude;
+
+    @ApiModelProperty(value = "营业半径(米)")
+    private Integer radius;
+
+    @ApiModelProperty(value = "是否支持退货")
+    private Integer returns;
+
+    @ApiModelProperty(value = "是否支持自提")
+    private Integer selfPickup;
+
 }
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 43a18b8..924119b 100644
--- a/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml
+++ b/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml
@@ -11,8 +11,8 @@
         <result column="category_id" property="categoryId"/>
         <result column="second_category_id" property="secondCategoryId"/>
         <result column="status" property="status"/>
-        <result column="main_image" property="mainImage"/>
-        <result column="detail_image" property="detailImage"/>
+        <result column="main_image_id" property="mainImageId"/>
+        <result column="main_image_Url" property="mainImageUrl"/>
         <result column="description" property="description"/>
         <result column="price" property="price"/>
         <result column="stock_quantity" property="stockQuantity"/>
@@ -22,12 +22,18 @@
         <result column="width" property="width"/>
         <result column="length" property="length"/>
         <result column="height" property="height"/>
+        <result column="returns" property="returns"/>
+        <result column="self_pickup" property="selfPickup"/>
         <result column="deleted_flag" property="deletedFlag"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
         <result column="version" property="version"/>
     </resultMap>
 
     <sql id="Base_Column_List">
-        product_id, store_id, code, barcode, name, title, category_id, second_category_id, status, main_image, detail_image, description, price, stock_quantity, min_purchase_quantity, warn_stock, weight, width, length, height, 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, 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">
@@ -54,6 +60,9 @@
                 and active = #{criteria.active}
             </if>
         </where>
+        <if test="criteria.limit != null">
+            limit #{criteria.limit}
+        </if>
         order by product_id desc
     </select>
 
diff --git a/oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml b/oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml
index f79f66c..4c1901d 100644
--- a/oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml
+++ b/oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml
@@ -25,9 +25,15 @@
         <include refid="Base_Column_List"/>
         from pc_store_category
         <where>
+            <if test="criteria.categoryId != null ">
+                and category_id = #{criteria.categoryId}
+            </if>
             <if test="criteria.storeId != null ">
                 and store_id = #{criteria.storeId}
             </if>
+            <if test="criteria.blurry != null and criteria.blurry != ''">
+                and name like concat('%',#{criteria.blurry},'%')
+            </if>
             <if test="criteria.level != null ">
                 and level = #{criteria.level}
             </if>
diff --git a/oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml b/oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml
index 564abeb..25f5a00 100644
--- a/oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml
+++ b/oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml
@@ -28,23 +28,26 @@
         <result property="geoHash" column="geo_hash"/>
         <result property="coordinateSystem" column="coordinate_system"/>
         <result property="radius" column="radius"/>
+        <result column="returns" property="returns"/>
+        <result column="self_pickup" property="selfPickup"/>
         <result property="createBy" column="create_by"/>
         <result property="createTime" column="create_time"/>
         <result property="updateBy" column="update_by"/>
         <result property="updateTime" column="update_time"/>
+        <result column="version" property="version"/>
     </resultMap>
 
     <sql id="store_column_list">
         store_id, merchant_id, platform_category_id, store_type, store_code, store_name, business_scope, status, logo_image_id,
         cover_image_id, description, tags, delivery_fee, delivery_minimum, contact_phone, open_time, close_time,
-        address, longitude, latitude, geo_hash, geo_point, coordinate_system, radius, create_by, create_time, update_by, update_time
+        address, longitude, latitude, geo_hash, geo_point, coordinate_system, radius, returns, self_pickup, create_by, create_time, update_by, update_time, version
     </sql>
 
     <sql id="selectStoreVo">
         select
         store_id, merchant_id, platform_category_id, store_type, store_code, store_name, business_scope, status, logo_image_id,
         cover_image_id, description, tags, delivery_fee, delivery_minimum, contact_phone, open_time, close_time,
-        address, longitude, latitude, geo_hash, geo_point, coordinate_system, radius, create_by, create_time, update_by, update_time from pc_store
+        address, longitude, latitude, geo_hash, geo_point, coordinate_system, radius, returns, self_pickup, create_by, create_time, update_by, update_time, version from pc_store
     </sql>
 
     <select id="selectStoreList" resultMap="StoreResult">
@@ -105,4 +108,40 @@
         </where>
     </select>
 
+    <select id="queryStoreIds" resultType="java.lang.Long">
+        SELECT s.store_id AS storeId
+        FROM pc_store s
+        <where>
+            <!-- 位置条件 -->
+            <if test="criteria.longitude != null and criteria.latitude != null and criteria.radius != null">
+                AND ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude,
+                s.latitude)) &lt;= #{criteria.radius}
+                AND ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude,
+                s.latitude)) &lt;= s.radius
+            </if>
+
+            <!-- 店铺名称模糊查询 AND s.name LIKE CONCAT('%', #{criteria.blurry}, '%') -->
+            <if test="criteria.blurry != null and criteria.blurry != ''">
+                AND MATCH(s.store_name) AGAINST(#{criteria.blurry} IN NATURAL LANGUAGE MODE)
+            </if>
+
+            <!-- 营业状态 -->
+            <if test="criteria.status != null">
+                AND s.status = #{criteria.status}
+            </if>
+
+            <!-- 类目ID -->
+            <if test="criteria.platformCategoryId != null">
+                AND s.platform_category_id = #{criteria.platformCategoryId}
+            </if>
+        </where>
+        LIMIT 1000
+    </select>
+
+    <select id="queryUserStores" parameterType="java.lang.Long" resultMap="StoreResult">
+        SELECT s.*
+        FROM sys_user_store u INNER JOIN pc_store s ON u.store_id = s.store_id
+        WHERE u.user_id = #{userId}
+    </select>
+
 </mapper>
\ No newline at end of file
diff --git a/oying-tools/src/main/java/com/oying/utils/ObsUtils.java b/oying-tools/src/main/java/com/oying/utils/ObsUtils.java
index 23c45fe..9b98a33 100644
--- a/oying-tools/src/main/java/com/oying/utils/ObsUtils.java
+++ b/oying-tools/src/main/java/com/oying/utils/ObsUtils.java
@@ -124,4 +124,15 @@
         // 删除指定的对象
         obsClient.deleteObject(properties.getBucket(), objectKey);
     }
+
+    public static String getPublicObjectUrl(ObsProperties properties, String objectKey) {
+        return getPublicObjectUrl(properties.getBucket(), properties.getEndpoint(), objectKey);
+    }
+
+    public static String getPublicObjectUrl(String bucketName, String endpoint, String objectKey) {
+        // 移除objectKey开头可能存在的文件分割符('/')
+        String cleanObjectKey = objectKey.startsWith("/") ? objectKey.substring(1) : objectKey;
+        // 标准URL格式
+        return String.format("https://%s.%s/%s", bucketName, endpoint.replaceAll("^https?://", ""), cleanObjectKey);
+    }
 }

--
Gitblit v1.9.3