From b394df082b875856884d6d02cce2a43c49ad6704 Mon Sep 17 00:00:00 2001
From: xin <1099200748@qq.com>
Date: Fri, 30 May 2025 16:44:46 +0800
Subject: [PATCH] Merge branch 'feature/pc-base' into xin
---
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java | 20
oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml | 36
oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java | 59
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryCreateRequest.java | 18
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java | 10
oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/StoreSearchDto.java | 17
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java | 16
oying-system/src/main/java/com/oying/modules/pc/common/core/constrant/Constants.java | 50
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantSimpleView.java | 22
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreView.java | 28
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java | 34
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java | 33
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java | 263 ++
oying-system/src/main/resources/config/application-dev.yml | 4
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java | 92 +
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java | 34
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryCreateRequest.java | 33
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java | 24
oying-system/src/main/java/com/oying/modules/pc/search/view/StoreSearchView.java | 27
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java | 65
oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java | 83
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreCategory.java | 70
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java | 36
oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryDtoAssembler.java | 10
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java | 52
oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductCategoryMapper.java | 22
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java | 68
oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java | 90 +
oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java | 38
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreMerchantOwnershipService.java | 12
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java | 16
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java | 75
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java | 26
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreQualificationIdGenerator.java | 15
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreCategoryMapper.java | 22
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java | 79
oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml | 108 +
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java | 73
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java | 26
oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java | 21
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java | 31
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreationCoordinator.java | 31
oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductMapper.java | 22
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java | 48
oying-system/src/main/java/com/oying/modules/pc/search/service/StoreSearchService.java | 10
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductSimpleView.java | 21
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreCategoryView.java | 25
oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java | 25
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryQueryCriteria.java | 22
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdGenerator.java | 15
oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryCustomerView.java | 16
oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreViewAssembler.java | 7
oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java | 120 +
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java | 159 +
oying-system/src/main/java/com/oying/modules/pc/category/domain/PlatformCategory.java | 72
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java | 45
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductOverviewView.java | 4
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java | 55
oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java | 135 +
oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryView.java | 33
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java | 106 +
oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreDtoAssembler.java | 7
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreLocationUpdateRequest.java | 17
oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreQualificationMapper.java | 24
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java | 9
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java | 57
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java | 141 +
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryCustomerController.java | 71
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java | 136 +
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantCreateServiceImpl.java | 59
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java | 90 +
oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java | 58
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreateService.java | 7
oying-system/src/main/java/com/oying/modules/pc/category/mapper/PlatformCategoryMapper.java | 22
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantOwnershipServiceImpl.java | 59
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreBusinessHoursRequest.java | 18
oying-system/src/main/java/com/oying/modules/pc/common/core/domain/R.java | 102 +
oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml | 60
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java | 25
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java | 24
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCategoryQueryCriteria.java | 18
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java | 67
oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml | 40
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java | 16
oying-system/src/main/resources/mapper/pc/category/PlatformCategoryMapper.xml | 34
oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java | 21
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateDto.java | 21
oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdentifierGenerator.java | 11
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCategoryService.java | 52
oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java | 100 +
oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java | 84
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantDetailsView.java | 25
oying-system/src/main/java/com/oying/modules/pc/utils/WrapperUtils.java | 18
.gitignore | 34
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java | 27
oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java | 56
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java | 60
oying-system/src/main/resources/mapper/pc/search/SearchMapper.xml | 56
oying-system/src/main/java/com/oying/modules/pc/search/service/impl/StoreSearchServiceImpl.java | 25
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java | 16
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java | 12
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java | 96 +
oying-system/src/main/java/com/oying/modules/pc/common/exception/LevelExceededException.java | 13
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java | 13
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java | 16
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java | 26
oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java | 20
oying-system/src/main/java/com/oying/modules/pc/product/service/ProductCategoryService.java | 60
oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerDetailsView.java | 24
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreStatus.java | 5
oying-system/src/main/resources/config/application.yml | 8
oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreLocation.java | 57
oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java | 51
oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductCategory.java | 52
oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java | 21
oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductCategoryServiceImpl.java | 79
oying-system/src/main/java/com/oying/modules/pc/store/view/StoreCategoryMerchantView.java | 23
oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java | 24
oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java | 43
oying-system/src/main/java/com/oying/modules/security/rest/AuthController.java | 2
120 files changed, 5,234 insertions(+), 7 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d723c67
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+*.pid
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryDtoAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryDtoAssembler.java
new file mode 100644
index 0000000..1c84e51
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryDtoAssembler.java
@@ -0,0 +1,10 @@
+package com.oying.modules.pc.category.converter;
+
+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.PlatformCategoryUpdateRequest;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PlatformCategoryDtoAssembler {
+}
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
new file mode 100644
index 0000000..8b70f78
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryViewAssembler.java
@@ -0,0 +1,25 @@
+package com.oying.modules.pc.category.converter;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.oying.modules.pc.category.domain.PlatformCategory;
+import com.oying.modules.pc.category.view.PlatformCategoryCustomerView;
+import com.oying.modules.pc.category.view.PlatformCategoryView;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PlatformCategoryViewAssembler {
+
+ public PlatformCategoryView toPlatformCategoryResponse(PlatformCategory category) {
+ PlatformCategoryView categoryView = new PlatformCategoryView();
+ 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/PlatformCategory.java b/oying-system/src/main/java/com/oying/modules/pc/category/domain/PlatformCategory.java
new file mode 100644
index 0000000..258cc2b
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/domain/PlatformCategory.java
@@ -0,0 +1,72 @@
+package com.oying.modules.pc.category.domain;
+
+import lombok.Data;
+import cn.hutool.core.bean.BeanUtil;
+import io.swagger.annotations.ApiModelProperty;
+import cn.hutool.core.bean.copier.CopyOptions;
+import java.sql.Timestamp;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+* @description /
+* @author lzp
+* @date 2025-04-28
+**/
+@Data
+@TableName("pc_platform_category")
+public class PlatformCategory implements Serializable {
+
+ @TableId(value = "category_id", type = IdType.AUTO)
+ @ApiModelProperty(value = "类目ID")
+ private Long categoryId;
+
+ @NotNull
+ @ApiModelProperty(value = "父类目ID")
+ private Long parentId;
+
+ @NotBlank
+ @ApiModelProperty(value = "类目名称")
+ private String name;
+
+ @NotNull
+ @ApiModelProperty(value = "类目层级:1-级类目 ")
+ private Integer level;
+
+ @NotNull
+ @ApiModelProperty(value = "排序权重")
+ private Integer sortWeight;
+
+ @ApiModelProperty(value = "类目图标ID")
+ private Long iconId;
+
+ @NotNull
+ @ApiModelProperty(value = "状态")
+ private Integer status;
+
+ @NotNull
+ @ApiModelProperty(value = "是否启用(0-否 1-是)")
+ private Integer active;
+
+ @ApiModelProperty(value = "创建人")
+ private Long createBy;
+
+ @NotNull
+ @ApiModelProperty(value = "创建时间")
+ private Timestamp createTime;
+
+ @ApiModelProperty(value = "修改人")
+ private Long updateBy;
+
+ @NotNull
+ @ApiModelProperty(value = "更新时间")
+ private Timestamp updateTime;
+
+ public void copy(PlatformCategory source){
+ BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryCreateRequest.java
new file mode 100644
index 0000000..e22e4e3
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryCreateRequest.java
@@ -0,0 +1,33 @@
+package com.oying.modules.pc.category.domain.dto;
+
+import cn.hutool.json.JSONUtil;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class PlatformCategoryCreateRequest {
+
+ @NotBlank
+ @ApiModelProperty(value = "类目名称", example = "超市")
+ private String name;
+
+ @ApiModelProperty(value = "排序权重", example = "1")
+ private Integer sortWeight;
+
+ @ApiModelProperty(value = "是否启用", example = "1")
+ private int active;
+
+ @ApiModelProperty(value = "上传类目图标文件ID", example = "4682827376555999")
+ private Long iconUploadFileId;
+
+ public static void main(String[] args) {
+ PlatformCategoryCreateRequest platformCategory = new PlatformCategoryCreateRequest();
+ platformCategory.setName("美食");
+ platformCategory.setSortWeight(1);
+ platformCategory.setIconUploadFileId(1L);
+ platformCategory.setActive(1);
+ System.out.println(JSONUtil.toJsonStr(platformCategory));
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryQueryCriteria.java
new file mode 100644
index 0000000..3ed3ef2
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryQueryCriteria.java
@@ -0,0 +1,22 @@
+package com.oying.modules.pc.category.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+* @author lzp
+* @date 2025-04-30
+**/
+@Data
+public class PlatformCategoryQueryCriteria{
+
+ @ApiModelProperty(value = "是否启用", example = "1")
+ private Integer active = 1;
+
+ @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/category/domain/dto/PlatformCategoryUpdateDto.java b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateDto.java
new file mode 100644
index 0000000..a8ca29d
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateDto.java
@@ -0,0 +1,21 @@
+package com.oying.modules.pc.category.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class PlatformCategoryUpdateDto {
+
+ private Long categoryId;
+
+ private String name;
+
+ private Integer sortWeight;
+
+ private Long iconUploadFileId;
+
+ private int active;
+
+}
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
new file mode 100644
index 0000000..be896e5
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/domain/dto/PlatformCategoryUpdateRequest.java
@@ -0,0 +1,24 @@
+package com.oying.modules.pc.category.domain.dto;
+
+import com.oying.modules.pc.category.domain.PlatformCategory;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class PlatformCategoryUpdateRequest {
+
+ @ApiModelProperty(value = "类目名称", example = "超市")
+ private String name;
+
+ @ApiModelProperty(value = "排序权重", example = "1")
+ private Integer sortWeight;
+
+ @ApiModelProperty(value = "上传类目图标文件ID", example = "2682827376555999239484")
+ private Long iconUploadFileId;
+
+ @ApiModelProperty(value = "是否启用", example = "1")
+ private int active;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/mapper/PlatformCategoryMapper.java b/oying-system/src/main/java/com/oying/modules/pc/category/mapper/PlatformCategoryMapper.java
new file mode 100644
index 0000000..16f289d
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/mapper/PlatformCategoryMapper.java
@@ -0,0 +1,22 @@
+package com.oying.modules.pc.category.mapper;
+
+import com.oying.modules.pc.category.domain.PlatformCategory;
+import com.oying.modules.pc.category.domain.dto.PlatformCategoryQueryCriteria;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+/**
+* @author lzp
+* @date 2025-04-30
+**/
+@Mapper
+public interface PlatformCategoryMapper extends BaseMapper<PlatformCategory> {
+
+ IPage<PlatformCategory> findAll(@Param("criteria") PlatformCategoryQueryCriteria criteria, Page<Object> page);
+
+ List<PlatformCategory> findAll(@Param("criteria") PlatformCategoryQueryCriteria criteria);
+}
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
new file mode 100644
index 0000000..2dd0278
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryAdminController.java
@@ -0,0 +1,83 @@
+package com.oying.modules.pc.category.rest;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.oying.annotation.Log;
+import com.oying.modules.pc.category.converter.PlatformCategoryViewAssembler;
+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.service.PlatformCategoryService;
+import com.oying.modules.pc.category.view.PlatformCategoryView;
+import com.oying.modules.pc.common.core.domain.R;
+import com.oying.utils.PageResult;
+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.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 java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * @author lzp
+ * @date 2025-04-28
+ **/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "平台类目")
+@RequestMapping("/api/pc/admin/platformCategory")
+public class PlatformCategoryAdminController {
+
+ private final PlatformCategoryService categoryService;
+ private final PlatformCategoryViewAssembler assembler;
+
+ @GetMapping
+ @ApiOperation("查询平台类目(支持分页)")
+ @PreAuthorize("@el.check('admin:platformCategory:list')")
+ public ResponseEntity<?> queryPlatformCategory(PlatformCategoryQueryCriteria criteria) {
+ Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
+ PageResult<PlatformCategory> pageResult = categoryService.queryAll(criteria, page);
+ List<PlatformCategoryView> responseList = Optional.ofNullable(pageResult.getContent()).orElse(new ArrayList<>()).stream().map(assembler::toPlatformCategoryResponse).collect(Collectors.toList());
+ PageResult<PlatformCategoryView> responsePageResult = new PageResult<>(responseList, pageResult.getTotalElements());
+ return ResponseEntity.ok(R.success(responsePageResult));
+ }
+
+ @PostMapping
+ @ApiOperation("新增平台类目")
+ //@PreAuthorize("@el.check('admin:platformCategory:create')")
+ public ResponseEntity<?> create(@Validated @RequestBody PlatformCategoryCreateRequest request) {
+ categoryService.create(request);
+ return ResponseEntity.status(HttpStatus.CREATED).build();
+ }
+
+ @PutMapping("/{categoryId}")
+ @ApiOperation("修改平台类目")
+ //@PreAuthorize("@el.check('admin:platformCategory:updateById')")
+ public ResponseEntity<?> updateById(@PathVariable Long categoryId,
+ @Validated @RequestBody PlatformCategoryUpdateRequest request) {
+ PlatformCategoryUpdateDto updateDto = new PlatformCategoryUpdateDto();
+ BeanUtils.copyProperties(request, updateDto);
+ updateDto.setCategoryId(categoryId);
+ categoryService.update(updateDto);
+ return ResponseEntity.noContent().build();
+ }
+
+ @DeleteMapping
+ @Log("删除平台类目")
+ @ApiOperation("删除平台类目")
+ //@PreAuthorize("@el.check('admin:platformCategory:batchDel')")
+ public ResponseEntity<?> batchDelete(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+ categoryService.deleteAll(ids);
+ 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
new file mode 100644
index 0000000..d6105be
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/rest/PlatformCategoryCustomerController.java
@@ -0,0 +1,43 @@
+package com.oying.modules.pc.category.rest;
+
+import com.oying.modules.pc.category.converter.PlatformCategoryViewAssembler;
+import com.oying.modules.pc.category.domain.PlatformCategory;
+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;
+import com.oying.modules.pc.common.core.domain.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author lzp
+ * @date 2025-04-28
+ **/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "平台类目(客户端)")
+@RequestMapping("/api/pc/customer/platformCategory")
+public class PlatformCategoryCustomerController {
+
+ private final PlatformCategoryService categoryService;
+ private final PlatformCategoryViewAssembler assembler;
+
+ @GetMapping("/list")
+ @ApiOperation("查询平台类目")
+ //@PreAuthorize("@el.check('customer:platformCategory:list')")
+ public ResponseEntity<?> queryPlatformCategory() {
+ PlatformCategoryQueryCriteria criteria = new PlatformCategoryQueryCriteria();
+ criteria.setActive(1);
+ 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
new file mode 100644
index 0000000..490df6b
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/service/PlatformCategoryService.java
@@ -0,0 +1,59 @@
+package com.oying.modules.pc.category.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+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.utils.PageResult;
+
+import java.util.List;
+
+/**
+ * 平台类目服务接口
+ *
+ * @author lzp
+ * @date 2025-04-30
+ **/
+public interface PlatformCategoryService extends IService<PlatformCategory> {
+
+ /**
+ * 查询数据分页
+ *
+ * @param criteria 条件
+ * @param page 分页参数
+ * @return PageResult
+ */
+ PageResult<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria, Page<Object> page);
+
+ /**
+ * 查询所有数据不分页
+ *
+ * @param criteria 条件参数
+ * @return List<PlatformCategoryDto>
+ */
+ List<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria);
+
+ /**
+ * 创建
+ *
+ * @param resources /
+ */
+ void create(PlatformCategoryCreateRequest resources);
+
+ /**
+ * 编辑
+ *
+ * @param resources /
+ */
+ void update(PlatformCategoryUpdateDto resources);
+
+ /**
+ * 多选删除
+ *
+ * @param ids /
+ */
+ void deleteAll(List<Long> ids);
+}
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
new file mode 100644
index 0000000..5b220a6
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/service/impl/PlatformCategoryServiceImpl.java
@@ -0,0 +1,90 @@
+package com.oying.modules.pc.category.service.impl;
+
+import cn.hutool.core.util.ObjUtil;
+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.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.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;
+
+/**
+ * 平台类目服务实现
+ *
+ * @author lzp
+ * @date 2025-04-30
+ **/
+@Service
+@RequiredArgsConstructor
+public class PlatformCategoryServiceImpl extends ServiceImpl<PlatformCategoryMapper, PlatformCategory> implements PlatformCategoryService {
+
+ private final PlatformCategoryMapper platformCategoryMapper;
+
+ @Override
+ public PageResult<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria, Page<Object> page) {
+ return PageUtil.toPage(platformCategoryMapper.findAll(criteria, page));
+ }
+
+ @Override
+ public List<PlatformCategory> queryAll(PlatformCategoryQueryCriteria criteria) {
+ return platformCategoryMapper.findAll(criteria);
+ }
+
+ @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());
+ platformCategoryCreate.setCreateBy(SecurityUtils.getCurrentUserId());
+
+ // 使用处理图标文件
+ platformCategoryMapper.insert(platformCategoryCreate);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(PlatformCategoryUpdateDto updateDto) {
+
+ 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"));
+ }
+
+ 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);
+ existingPlatformCategory.setUpdateBy(SecurityUtils.getCurrentUserId());
+ platformCategoryMapper.updateById(existingPlatformCategory);
+
+ // 使用处理图标文件
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteAll(List<Long> ids) {
+ platformCategoryMapper.deleteBatchIds(ids);
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryCustomerView.java b/oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryCustomerView.java
new file mode 100644
index 0000000..de6fcda
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryCustomerView.java
@@ -0,0 +1,16 @@
+package com.oying.modules.pc.category.view;
+
+import lombok.Data;
+
+@Data
+public class PlatformCategoryCustomerView {
+
+ private Long categoryId;
+
+ private String name;
+
+ private Integer sortWeight;
+
+ private String iconUrl;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryView.java b/oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryView.java
new file mode 100644
index 0000000..3fa48a8
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/category/view/PlatformCategoryView.java
@@ -0,0 +1,33 @@
+package com.oying.modules.pc.category.view;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+@Data
+public class PlatformCategoryView implements Serializable {
+
+ private Long categoryId;
+
+ private String name;
+
+ private Integer sort;
+
+ private String icon;
+
+ private String iconUrl;
+
+ private Integer status;
+
+ private Integer visible;
+
+ private Long createBy;
+
+ private Timestamp createTime;
+
+ private Long updateBy;
+
+ private Timestamp updateTime;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/common/core/constrant/Constants.java b/oying-system/src/main/java/com/oying/modules/pc/common/core/constrant/Constants.java
new file mode 100644
index 0000000..796bccf
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/common/core/constrant/Constants.java
@@ -0,0 +1,50 @@
+package com.oying.modules.pc.common.core.constrant;
+
+/**
+ * 通用常量信息
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+public class Constants {
+
+ /**
+ * UTF-8 字符集
+ */
+ public static final String UTF8 = "UTF-8";
+
+ /**
+ * GBK 字符集
+ */
+ public static final String GBK = "GBK";
+
+ /**
+ * www主域
+ */
+ public static final String WWW = "www.";
+
+ /**
+ * RMI 远程方法调用
+ */
+ public static final String LOOKUP_RMI = "rmi:";
+
+ /**
+ * LDAP 远程方法调用
+ */
+ public static final String LOOKUP_LDAP = "ldap:";
+
+ /**
+ * LDAPS 远程方法调用
+ */
+ public static final String LOOKUP_LDAPS = "ldaps:";
+
+ /**
+ * http请求
+ */
+ public static final String HTTP = "http://";
+
+ /**
+ * https请求
+ */
+ public static final String HTTPS = "https://";
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/common/core/domain/R.java b/oying-system/src/main/java/com/oying/modules/pc/common/core/domain/R.java
new file mode 100644
index 0000000..e85df96
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/common/core/domain/R.java
@@ -0,0 +1,102 @@
+package com.oying.modules.pc.common.core.domain;
+
+import java.io.Serializable;
+
+/**
+ * 响应信息主体
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+public class R<T> implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 成功
+ */
+ public static final int SUCCESS = 0;
+
+ /**
+ * 失败
+ */
+ public static final int FAIL = 1;
+
+ private int status;
+
+ private String message;
+
+ private T data;
+
+ public static <T> R<T> success() {
+ return restResult(null, SUCCESS, null);
+ }
+
+ public static <T> R<T> success(T data) {
+ return restResult(data, SUCCESS, null);
+ }
+
+ public static <T> R<T> success(T data, String msg) {
+ return restResult(data, SUCCESS, msg);
+ }
+
+ public static <T> R<T> fail() {
+ return restResult(null, FAIL, null);
+ }
+
+ public static <T> R<T> fail(String msg) {
+ return restResult(null, FAIL, msg);
+ }
+
+ public static <T> R<T> fail(T data) {
+ return restResult(data, FAIL, null);
+ }
+
+ public static <T> R<T> fail(T data, String msg) {
+ return restResult(data, FAIL, msg);
+ }
+
+ public static <T> R<T> fail(int code, String msg) {
+ return restResult(null, code, msg);
+ }
+
+ private static <T> R<T> restResult(T data, int code, String msg) {
+ R<T> apiResult = new R<>();
+ apiResult.setStatus(code);
+ apiResult.setData(data);
+ apiResult.setMessage(msg);
+ return apiResult;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public static <T> Boolean isError(R<T> ret) {
+ return !isSuccess(ret);
+ }
+
+ public static <T> Boolean isSuccess(R<T> ret) {
+ return R.SUCCESS == ret.getStatus();
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/common/exception/LevelExceededException.java b/oying-system/src/main/java/com/oying/modules/pc/common/exception/LevelExceededException.java
new file mode 100644
index 0000000..eff343d
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/common/exception/LevelExceededException.java
@@ -0,0 +1,13 @@
+package com.oying.modules.pc.common.exception;
+
+public class LevelExceededException extends RuntimeException {
+
+ public LevelExceededException(Integer level, Integer maxLevel) {
+ super(generateMessage(level, maxLevel));
+ }
+
+ private static String generateMessage(Integer level, Integer maxLevel) {
+ return String.format("层级 %d 超过了允许的最大层级 (%d)", level, maxLevel);
+ }
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdGenerator.java b/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdGenerator.java
new file mode 100644
index 0000000..1abed33
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdGenerator.java
@@ -0,0 +1,15 @@
+package com.oying.modules.pc.common.id;
+
+import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.util.IdUtil;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StoreIdGenerator {
+
+ private static final Snowflake snowflake = IdUtil.getSnowflake(1,1);
+
+ public static long getId() {
+ return snowflake.nextId();
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdentifierGenerator.java b/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdentifierGenerator.java
new file mode 100644
index 0000000..1e26454
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreIdentifierGenerator.java
@@ -0,0 +1,11 @@
+package com.oying.modules.pc.common.id;
+
+import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
+
+public class StoreIdentifierGenerator implements IdentifierGenerator {
+
+ @Override
+ public Number nextId(Object entity) {
+ return null;
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreQualificationIdGenerator.java b/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreQualificationIdGenerator.java
new file mode 100644
index 0000000..38b167c
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/common/id/StoreQualificationIdGenerator.java
@@ -0,0 +1,15 @@
+package com.oying.modules.pc.common.id;
+
+import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.util.IdUtil;
+import org.springframework.stereotype.Component;
+
+@Component
+public class StoreQualificationIdGenerator {
+
+ private static final Snowflake snowflake = IdUtil.getSnowflake(1,1);
+
+ public static long getId() {
+ return snowflake.nextId();
+ }
+}
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
new file mode 100644
index 0000000..9a7c28f
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/Product.java
@@ -0,0 +1,120 @@
+package com.oying.modules.pc.product.domain;
+
+import lombok.Data;
+import cn.hutool.core.bean.BeanUtil;
+import io.swagger.annotations.ApiModelProperty;
+import cn.hutool.core.bean.copier.CopyOptions;
+import java.sql.Timestamp;
+import java.math.BigDecimal;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+* @description /
+* @author lzp
+* @date 2025-04-30
+**/
+@Data
+@TableName("pc_product")
+public class Product implements Serializable {
+
+ @TableId(value = "product_id")
+ @ApiModelProperty(value = "ID")
+ private Long productId;
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺ID")
+ private Long storeId;
+
+ @NotBlank
+ @ApiModelProperty(value = "条形码")
+ private String barcode;
+
+ @NotBlank
+ @ApiModelProperty(value = "商品名称")
+ private String name;
+
+ @NotBlank
+ @ApiModelProperty(value = "商品标题")
+ private String title;
+
+ @NotNull
+ @ApiModelProperty(value = "一级分类ID")
+ private Long categoryId;
+
+ @NotNull
+ @ApiModelProperty(value = "二级分类ID")
+ private Long secondCategoryId;
+
+ @NotNull
+ @ApiModelProperty(value = "状态:1000-草稿 1001上架 1002下架")
+ private Integer status;
+
+ @NotBlank
+ @ApiModelProperty(value = "主图片")
+ private String mainImage;
+
+ @ApiModelProperty(value = "详情图片")
+ private String detailImage;
+
+ @ApiModelProperty(value = "商品描述")
+ private String description;
+
+ @NotNull
+ @ApiModelProperty(value = "销售价格")
+ private BigDecimal price;
+
+ @NotNull
+ @ApiModelProperty(value = "库存数量")
+ private Integer stockQuantity;
+
+ @NotNull
+ @ApiModelProperty(value = "起售数量")
+ private Integer minPurchaseQuantity;
+
+ @ApiModelProperty(value = "预警库存")
+ private Integer warnStock;
+
+ @ApiModelProperty(value = "重量(单位:g)")
+ private Integer weight;
+
+ @ApiModelProperty(value = "宽度(单位:厘米)")
+ private Integer width;
+
+ @ApiModelProperty(value = "长度(单位:厘米)")
+ private Integer length;
+
+ @ApiModelProperty(value = "高度(单位:厘米)")
+ private Integer height;
+
+ @NotNull
+ @ApiModelProperty(value = "是否删除")
+ private Integer deletedFlag;
+
+ @NotNull
+ @ApiModelProperty(value = "创建人")
+ private Long createBy;
+
+ @NotNull
+ @ApiModelProperty(value = "创建时间")
+ private Timestamp createTime;
+
+ @NotNull
+ @ApiModelProperty(value = "修改人")
+ private Long updateBy;
+
+ @NotNull
+ @ApiModelProperty(value = "修改时间")
+ private Timestamp updateTime;
+
+ @NotNull
+ @ApiModelProperty(value = "版本号")
+ private Long version;
+
+ 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/ProductCategory.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductCategory.java
new file mode 100644
index 0000000..b677fdc
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductCategory.java
@@ -0,0 +1,52 @@
+package com.oying.modules.pc.product.domain;
+
+import lombok.Data;
+import cn.hutool.core.bean.BeanUtil;
+import io.swagger.annotations.ApiModelProperty;
+import cn.hutool.core.bean.copier.CopyOptions;
+import java.sql.Timestamp;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+* @description /
+* @author lzp
+* @date 2025-05-13
+**/
+@Data
+@TableName("pc_product_category")
+public class ProductCategory implements Serializable {
+
+ @TableId(value = "id", type = IdType.AUTO)
+ @ApiModelProperty(value = "商品类目唯一标识")
+ private Long id;
+
+ @NotNull
+ @ApiModelProperty(value = "商品ID")
+ private Long productId;
+
+ @ApiModelProperty(value = "所属一级店铺类目ID")
+ private Long storeCategoryId;
+
+ @ApiModelProperty(value = "所属二级店铺类目ID")
+ private Long storeCategorySecondId;
+
+ @ApiModelProperty(value = "创建者")
+ private Long createBy;
+
+ @ApiModelProperty(value = "创建时间")
+ private Timestamp createTime;
+
+ @ApiModelProperty(value = "修改者")
+ private Long updateBy;
+
+ @ApiModelProperty(value = "修改时间")
+ private Timestamp updateTime;
+
+ public void copy(ProductCategory 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
new file mode 100644
index 0000000..46eede8
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCategoryQueryCriteria.java
@@ -0,0 +1,18 @@
+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
new file mode 100644
index 0000000..412ee55
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductCustomerQueryCriteria.java
@@ -0,0 +1,21 @@
+package com.oying.modules.pc.product.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author lzp
+ * @date 2025-04-30
+ **/
+@Data
+public class ProductCustomerQueryCriteria {
+
+ private Long categoryId;
+
+ @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/ProductImageCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java
new file mode 100644
index 0000000..0fb9117
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageCreateRequest.java
@@ -0,0 +1,9 @@
+package com.oying.modules.pc.product.domain.dto;
+
+public class ProductImageCreateRequest {
+
+ private Long uploadId;
+
+ private Integer type;
+
+}
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
new file mode 100644
index 0000000..bcf7d49
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelCreateRequest.java
@@ -0,0 +1,16 @@
+package com.oying.modules.pc.product.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class ProductLabelCreateRequest {
+
+ private String category;
+
+ private String labelName;
+
+ private String labelValue;
+
+ 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
new file mode 100644
index 0000000..85c8761
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantCreateRequest.java
@@ -0,0 +1,52 @@
+package com.oying.modules.pc.product.domain.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class ProductMerchantCreateRequest {
+
+ @NotBlank
+ private String barcode;
+
+ @NotBlank
+ private String name;
+
+ @NotBlank
+ private String title;
+
+ @NotNull
+ private Long categoryId;
+
+ private Long secondCategoryId;
+
+ @NotNull
+ private BigDecimal price;
+
+ @NotNull
+ private Integer stockQuantity;
+
+ private Integer minPurchaseQuantity;
+
+ private Integer warnStock;
+
+ @NotNull
+ private Integer weight;
+
+ private Integer length;
+
+ private Integer width;
+
+ private Integer height;
+
+ private Integer allowReturns;
+
+ private List<ProductImageCreateRequest> imageList;
+
+ private List<ProductLabelCreateRequest> labelList;
+
+}
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
new file mode 100644
index 0000000..734cb8f
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductMerchantUpdateRequest.java
@@ -0,0 +1,45 @@
+package com.oying.modules.pc.product.domain.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+public class ProductMerchantUpdateRequest {
+
+ private String barcode;
+
+ private String name;
+
+ private String title;
+
+ private Long categoryId;
+
+ private Long secondCategoryId;
+
+ private BigDecimal price;
+
+ private Integer stockQuantity;
+
+ private Integer minPurchaseQuantity;
+
+ private Integer warnStock;
+
+ private Integer weight;
+
+ private Integer length;
+
+ private Integer width;
+
+ private Integer height;
+
+ private Integer allowReturns;
+
+ private List<ProductImageCreateRequest> imageList;
+
+ private List<ProductLabelCreateRequest> specList;
+
+}
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
new file mode 100644
index 0000000..b89cf98
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java
@@ -0,0 +1,34 @@
+package com.oying.modules.pc.product.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author lzp
+ * @date 2025-04-30
+ **/
+@Data
+public class ProductQueryCriteria {
+
+ @ApiModelProperty(value = "搜索字段", example = "柚子")
+ private String blurry;
+
+ private Long productId;
+
+ private Long storeId;
+
+ 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;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductCategoryMapper.java b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductCategoryMapper.java
new file mode 100644
index 0000000..8fe2ade
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductCategoryMapper.java
@@ -0,0 +1,22 @@
+package com.oying.modules.pc.product.mapper;
+
+import com.oying.modules.pc.product.domain.ProductCategory;
+import com.oying.modules.pc.product.domain.dto.ProductCategoryQueryCriteria;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+/**
+* @author lzp
+* @date 2025-05-13
+**/
+@Mapper
+public interface ProductCategoryMapper extends BaseMapper<ProductCategory> {
+
+ IPage<ProductCategory> findAll(@Param("criteria") ProductCategoryQueryCriteria criteria, Page<Object> page);
+
+ List<ProductCategory> findAll(@Param("criteria") ProductCategoryQueryCriteria criteria);
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductMapper.java b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductMapper.java
new file mode 100644
index 0000000..861cd02
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductMapper.java
@@ -0,0 +1,22 @@
+package com.oying.modules.pc.product.mapper;
+
+import com.oying.modules.pc.product.domain.Product;
+import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+/**
+* @author lzp
+* @date 2025-04-30
+**/
+@Mapper
+public interface ProductMapper extends BaseMapper<Product> {
+
+ IPage<Product> findAll(@Param("criteria") ProductQueryCriteria criteria, Page<Object> page);
+
+ List<Product> findAll(@Param("criteria") ProductQueryCriteria criteria);
+}
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
new file mode 100644
index 0000000..fed2f9c
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductController.java
@@ -0,0 +1,73 @@
+package com.oying.modules.pc.product.rest;
+
+import com.oying.annotation.Log;
+import com.oying.modules.pc.common.core.domain.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.ProductQueryCriteria;
+import lombok.RequiredArgsConstructor;
+import java.util.List;
+
+import org.springframework.security.access.prepost.PreAuthorize;
+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;
+
+/**
+* @author lzp
+* @date 2025-04-30
+**/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "商品")
+@RequestMapping("/api/product")
+public class ProductController {
+
+ private final ProductService productService;
+
+ @ApiOperation("导出数据")
+ @GetMapping(value = "/download")
+ @PreAuthorize("@el.check('product:list')")
+ public void exportProduct(HttpServletResponse response, ProductQueryCriteria criteria) throws IOException {
+ productService.download(productService.queryAll(criteria), response);
+ }
+
+ @GetMapping
+ @ApiOperation("查询商品")
+ @PreAuthorize("@el.check('product:list')")
+ public R<PageResult<Product>> queryProduct(ProductQueryCriteria criteria){
+ Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
+ return R.success(productService.queryAll(criteria,page));
+ }
+
+ @PostMapping
+ @Log("新增商品")
+ @ApiOperation("新增商品")
+ @PreAuthorize("@el.check('product:add')")
+ public R<?> createProduct(@Validated @RequestBody Product resources){
+ productService.create(resources);
+ return R.success();
+ }
+
+ @PutMapping
+ @Log("修改商品")
+ @ApiOperation("修改商品")
+ @PreAuthorize("@el.check('product:edit')")
+ public R<?> updateProduct(@Validated @RequestBody Product resources){
+ productService.update(resources);
+ return R.success();
+ }
+
+ @DeleteMapping
+ @Log("删除商品")
+ @ApiOperation("删除商品")
+ @PreAuthorize("@el.check('product:del')")
+ public R<?> deleteProduct(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+ productService.deleteAll(ids);
+ return R.success();
+ }
+}
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
new file mode 100644
index 0000000..95d701d
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java
@@ -0,0 +1,84 @@
+package com.oying.modules.pc.product.rest;
+
+import cn.hutool.core.collection.ListUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.oying.modules.pc.common.core.domain.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.ProductService;
+import com.oying.modules.pc.product.view.ProductCustomerView;
+import com.oying.modules.pc.product.view.ProductMerchantSimpleView;
+import com.oying.utils.PageResult;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/*
+*
+ * @author lzp
+ * @date 2025-04-30
+ *
+*/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "商品(客户端)")
+@RequestMapping("/api/pc/customer/store/{storeId}/product")
+public class ProductCustomerController {
+
+ private final ProductService productService;
+
+ @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) {
+
+ ProductQueryCriteria criteria = new ProductQueryCriteria();
+ criteria.setStoreId(storeId);
+ criteria.setCategoryId(categoryId);
+ criteria.setSecondCategoryId(secondCategoryId);
+ criteria.setBlurry(blurry);
+ 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<ProductCustomerView> viewPageResult = new PageResult<>(
+ 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());
+ return ResponseEntity.ok(R.success(viewPageResult));
+ }
+
+ @GetMapping(value = "/{productId}/details")
+ @ApiOperation("查询商品")
+ /*@PreAuthorize("@el.check('merchant:product:byProductId')")*/
+ public ResponseEntity<?> getDetails(@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());
+ 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
new file mode 100644
index 0000000..fe7a50b
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductMerchantController.java
@@ -0,0 +1,141 @@
+package com.oying.modules.pc.product.rest;
+
+import cn.hutool.core.collection.ListUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.oying.annotation.Log;
+import com.oying.modules.pc.common.core.domain.R;
+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.domain.dto.ProductQueryCriteria;
+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 io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+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 java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * @author lzp
+ * @date 2025-04-30
+ **/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "商品(商户端)")
+@RequestMapping("/api/pc/merchant/store/{storeId}/product")
+public class ProductMerchantController {
+
+ private final ProductService productService;
+ private final ProductMerchantService productMerchantService;
+
+ @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);
+ 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);
+ return view;
+ }).collect(Collectors.toList()),
+ productPageResult.getTotalElements());
+ return ResponseEntity.ok(R.success(viewPageResult));
+ }
+
+ @GetMapping(value = "/{productId}")
+ @ApiOperation("查询商品")
+ /*@PreAuthorize("@el.check('merchant:product:byProductId') " +
+ "and @storeMerchantOwnershipService.check(#storeId)")*/
+ public ResponseEntity<?> getById(@PathVariable Long productId) {
+ return ResponseEntity.ok(R.success(productService.getById(productId)));
+ }
+
+ @GetMapping(value = "/{productId}/details")
+ @ApiOperation("查询商品详情")
+ /*@PreAuthorize("@el.check('merchant:product:byProductId') " +
+ "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());
+ }
+ return ResponseEntity.ok(R.success(view));
+ }
+
+ @PostMapping
+ @Log("新增商品")
+ @ApiOperation("新增商品")
+ //@PreAuthorize("@el.check('merchant:product:add') " +
+ // "and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> createProduct(@PathVariable Long storeId,
+ @Validated @RequestBody ProductMerchantCreateRequest request) {
+
+ productMerchantService.create(storeId, request);
+ return ResponseEntity.noContent().build();
+ }
+
+ @PutMapping(value = "/{productId}")
+ @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);
+ return ResponseEntity.noContent().build();
+ }
+
+ @DeleteMapping
+ @Log("批量删除商品")
+ @ApiOperation("批量删除商品")
+ //@PreAuthorize("@el.check('merchant:product:batchDel') " +
+ // "and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> deleteProduct(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+ productMerchantService.batchDelete(ids);
+ return ResponseEntity.noContent().build();
+ }
+
+ @PutMapping(value = "/{productId}/on")
+ @Log("上架商品")
+ @ApiOperation("上架商品")
+ /*@PreAuthorize("@el.check('merchant:product:on') " +
+ "and @storeMerchantOwnershipService.check(#storeId)")*/
+ public ResponseEntity<?> putOnShelf(@PathVariable("productId") Long productId) {
+ productMerchantService.putOnShelf(productId);
+ return ResponseEntity.noContent().build();
+ }
+
+ @PutMapping(value = "/{productId}/off")
+ @Log("下架商品")
+ @ApiOperation("下架商品")
+ /*@PreAuthorize("@el.check('merchant:product:off') " +
+ "and @storeMerchantOwnershipService.check(#storeId)")*/
+ public ResponseEntity<?> takeOffShelf(@PathVariable("productId") Long productId) {
+ productMerchantService.takeOffShelf(productId);
+ return ResponseEntity.noContent().build();
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductCategoryService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductCategoryService.java
new file mode 100644
index 0000000..8e3aa61
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductCategoryService.java
@@ -0,0 +1,60 @@
+package com.oying.modules.pc.product.service;
+
+import com.oying.modules.pc.product.domain.ProductCategory;
+import com.oying.modules.pc.product.domain.dto.ProductCategoryQueryCriteria;
+import java.util.Map;
+import java.util.List;
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.oying.utils.PageResult;
+
+/**
+* @description 服务接口
+* @author lzp
+* @date 2025-05-13
+**/
+public interface ProductCategoryService extends IService<ProductCategory> {
+
+ /**
+ * 查询数据分页
+ * @param criteria 条件
+ * @param page 分页参数
+ * @return PageResult
+ */
+ PageResult<ProductCategory> queryAll(ProductCategoryQueryCriteria criteria, Page<Object> page);
+
+ /**
+ * 查询所有数据不分页
+ * @param criteria 条件参数
+ * @return List<ProductCategoryDto>
+ */
+ List<ProductCategory> queryAll(ProductCategoryQueryCriteria criteria);
+
+ /**
+ * 创建
+ * @param resources /
+ */
+ void create(ProductCategory resources);
+
+ /**
+ * 编辑
+ * @param resources /
+ */
+ void update(ProductCategory resources);
+
+ /**
+ * 多选删除
+ * @param ids /
+ */
+ void deleteAll(List<Long> ids);
+
+ /**
+ * 导出数据
+ * @param all 待导出的数据
+ * @param response /
+ * @throws IOException /
+ */
+ void download(List<ProductCategory> all, HttpServletResponse response) throws IOException;
+}
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
new file mode 100644
index 0000000..dba1948
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductMerchantService.java
@@ -0,0 +1,16 @@
+package com.oying.modules.pc.product.service;
+
+import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest;
+import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest;
+
+import java.util.List;
+
+public interface ProductMerchantService {
+
+ void create(Long storeId, ProductMerchantCreateRequest request);
+ void update(Long storeId, 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/ProductService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java
new file mode 100644
index 0000000..a610f1d
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductService.java
@@ -0,0 +1,60 @@
+package com.oying.modules.pc.product.service;
+
+import com.oying.modules.pc.product.domain.Product;
+import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
+
+import java.util.List;
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.oying.utils.PageResult;
+
+/**
+* @description 服务接口
+* @author lzp
+* @date 2025-04-30
+**/
+public interface ProductService extends IService<Product> {
+
+ /**
+ * 查询数据分页
+ * @param criteria 条件
+ * @param page 分页参数
+ * @return PageResult
+ */
+ PageResult<Product> queryAll(ProductQueryCriteria criteria, Page<Object> page);
+
+ /**
+ * 查询所有数据不分页
+ * @param criteria 条件参数
+ * @return List<ProductDto>
+ */
+ List<Product> queryAll(ProductQueryCriteria criteria);
+
+ /**
+ * 创建
+ * @param resources /
+ */
+ void create(Product resources);
+
+ /**
+ * 编辑
+ * @param resources /
+ */
+ void update(Product resources);
+
+ /**
+ * 多选删除
+ * @param ids /
+ */
+ void deleteAll(List<Long> ids);
+
+ /**
+ * 导出数据
+ * @param all 待导出的数据
+ * @param response /
+ * @throws IOException /
+ */
+ void download(List<Product> all, HttpServletResponse response) throws IOException;
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductCategoryServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductCategoryServiceImpl.java
new file mode 100644
index 0000000..844836f
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductCategoryServiceImpl.java
@@ -0,0 +1,79 @@
+package com.oying.modules.pc.product.service.impl;
+
+import com.oying.modules.pc.product.domain.ProductCategory;
+import com.oying.utils.FileUtil;
+import lombok.RequiredArgsConstructor;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.oying.modules.pc.product.service.ProductCategoryService;
+import com.oying.modules.pc.product.domain.dto.ProductCategoryQueryCriteria;
+import com.oying.modules.pc.product.mapper.ProductCategoryMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import com.oying.utils.PageUtil;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import com.oying.utils.PageResult;
+
+/**
+* @description 服务实现
+* @author lzp
+* @date 2025-05-13
+**/
+@Service
+@RequiredArgsConstructor
+public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMapper, ProductCategory> implements ProductCategoryService {
+
+ private final ProductCategoryMapper productCategoryMapper;
+
+ @Override
+ public PageResult<ProductCategory> queryAll(ProductCategoryQueryCriteria criteria, Page<Object> page){
+ return PageUtil.toPage(productCategoryMapper.findAll(criteria, page));
+ }
+
+ @Override
+ public List<ProductCategory> queryAll(ProductCategoryQueryCriteria criteria){
+ return productCategoryMapper.findAll(criteria);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void create(ProductCategory resources) {
+ productCategoryMapper.insert(resources);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(ProductCategory resources) {
+ ProductCategory productCategory = getById(resources.getId());
+ productCategory.copy(resources);
+ productCategoryMapper.updateById(productCategory);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteAll(List<Long> ids) {
+ productCategoryMapper.deleteBatchIds(ids);
+ }
+
+ @Override
+ public void download(List<ProductCategory> all, HttpServletResponse response) throws IOException {
+ List<Map<String, Object>> list = new ArrayList<>();
+ for (ProductCategory productCategory : all) {
+ Map<String, Object> map = new LinkedHashMap<>();
+ map.put("商品ID", productCategory.getProductId());
+ map.put("所属一级店铺类目ID", productCategory.getStoreCategoryId());
+ map.put("所属二级店铺类目ID", productCategory.getStoreCategorySecondId());
+ map.put("创建者", productCategory.getCreateBy());
+ map.put("创建时间", productCategory.getCreateTime());
+ map.put("修改者", productCategory.getUpdateBy());
+ map.put("修改时间", productCategory.getUpdateTime());
+ list.add(map);
+ }
+ FileUtil.downloadExcel(list, response);
+ }
+}
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
new file mode 100644
index 0000000..c675445
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantCreateServiceImpl.java
@@ -0,0 +1,59 @@
+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
new file mode 100644
index 0000000..5a91767
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductServiceImpl.java
@@ -0,0 +1,106 @@
+package com.oying.modules.pc.product.service.impl;
+
+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.modules.pc.product.domain.Product;
+import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria;
+import com.oying.modules.pc.product.mapper.ProductMapper;
+import com.oying.modules.pc.product.service.ProductService;
+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;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author lzp
+ * @description 服务实现
+ * @date 2025-04-30
+ **/
+@Service
+@RequiredArgsConstructor
+public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
+
+ private final ProductMapper productMapper;
+
+ @Override
+ public PageResult<Product> queryAll(ProductQueryCriteria criteria, Page<Object> page) {
+ return PageUtil.toPage(productMapper.findAll(criteria, page));
+ }
+
+ @Override
+ public List<Product> queryAll(ProductQueryCriteria criteria) {
+ return productMapper.findAll(criteria);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void create(Product resources) {
+ resources.setCreateBy(SecurityUtils.getCurrentUserId());
+ productMapper.insert(resources);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(Product resources) {
+ Product product = getById(resources.getProductId());
+ product.copy(resources);
+ product.setUpdateBy(SecurityUtils.getCurrentUserId());
+ productMapper.updateById(product);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteAll(List<Long> ids) {
+ for (Long id : ids) {
+ LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>()
+ .eq(Product::getProductId, id)
+ .set(Product::getDeletedFlag, 1);
+ // set状态
+ this.update(wrapper);
+ }
+ }
+
+ @Override
+ public void download(List<Product> all, HttpServletResponse response) throws IOException {
+ List<Map<String, Object>> list = new ArrayList<>();
+ for (Product product : all) {
+ Map<String, Object> map = new LinkedHashMap<>();
+ map.put("商品编号", product.getStoreId());
+ map.put("条形码", product.getBarcode());
+ 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.getDescription());
+ map.put("销售价格", product.getPrice());
+ map.put("库存数量", product.getStockQuantity());
+ map.put("起售数量", product.getMinPurchaseQuantity());
+ map.put("预警库存", product.getWarnStock());
+ map.put("重量(单位:g)", product.getWeight());
+ map.put("宽度(单位:厘米)", product.getWidth());
+ map.put("长度(单位:厘米)", product.getLength());
+ map.put("高度(单位:厘米)", product.getHeight());
+ map.put("是否删除", product.getDeletedFlag());
+ map.put("创建人", product.getCreateBy());
+ map.put("创建时间", product.getCreateTime());
+ map.put("修改人", product.getUpdateBy());
+ map.put("修改时间", product.getUpdateTime());
+ map.put("版本号", product.getVersion());
+ list.add(map);
+ }
+ FileUtil.downloadExcel(list, response);
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerDetailsView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerDetailsView.java
new file mode 100644
index 0000000..29204b7
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerDetailsView.java
@@ -0,0 +1,24 @@
+package com.oying.modules.pc.product.view;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 简单商品vo
+ * @author lzp
+ * @date 2025-04-25
+ */
+@Data
+public class ProductCustomerDetailsView {
+
+ private Long id;
+ private String title;
+ private BigDecimal price;
+ private Integer sold;
+
+ private List<ProductImageCustomerView> mainImageList;
+ private List<ProductLabelCustomerView> labelList;
+
+}
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
new file mode 100644
index 0000000..bf2ca91
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java
@@ -0,0 +1,25 @@
+package com.oying.modules.pc.product.view;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 简单商品vo
+ * @author lzp
+ * @date 2025-04-25
+ */
+@Data
+public class ProductCustomerView {
+
+ private Long productId;
+ private String title;
+ private BigDecimal price;
+ private Double score; // 评分
+ private Integer sold; // 月销量
+
+ private List<ProductImageCustomerView> mainImageList;
+ private List<ProductLabelCustomerView> labelList;
+
+}
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
new file mode 100644
index 0000000..208cd49
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductImageCustomerView.java
@@ -0,0 +1,12 @@
+package com.oying.modules.pc.product.view;
+
+import lombok.Data;
+
+@Data
+public class ProductImageCustomerView {
+
+ private String url;
+ private Integer primaryFlag;
+ 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
new file mode 100644
index 0000000..868e975
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductLabelCustomerView.java
@@ -0,0 +1,13 @@
+package com.oying.modules.pc.product.view;
+
+import lombok.Data;
+
+@Data
+public class ProductLabelCustomerView {
+
+ private Integer categoryId;
+ private String categoryName;
+ private String labelName;
+ private String labelValue;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantDetailsView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantDetailsView.java
new file mode 100644
index 0000000..383115b
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantDetailsView.java
@@ -0,0 +1,25 @@
+package com.oying.modules.pc.product.view;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 简单商品vo
+ * @author lzp
+ * @date 2025-04-25
+ */
+@Data
+public class ProductMerchantDetailsView {
+
+ private Long productId;
+ private String name;
+ private BigDecimal price;
+ private Integer sold;
+ private Integer status;
+
+ private List<ProductImageCustomerView> mainImageList;
+ private List<ProductLabelCustomerView> labelList;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantSimpleView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantSimpleView.java
new file mode 100644
index 0000000..b558519
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantSimpleView.java
@@ -0,0 +1,22 @@
+package com.oying.modules.pc.product.view;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 简单商品vo
+ * @author lzp
+ * @date 2025-04-25
+ */
+@Data
+public class ProductMerchantSimpleView {
+
+ private Long productId;
+ private String name;
+ private BigDecimal price;
+ private Integer stockQuantity;
+ private Integer sold;
+ private Integer status;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductOverviewView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductOverviewView.java
new file mode 100644
index 0000000..01918a8
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductOverviewView.java
@@ -0,0 +1,4 @@
+package com.oying.modules.pc.product.view;
+
+public class ProductOverviewView {
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductSimpleView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductSimpleView.java
new file mode 100644
index 0000000..c7df610
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductSimpleView.java
@@ -0,0 +1,21 @@
+package com.oying.modules.pc.product.view;
+
+import java.math.BigDecimal;
+
+/**
+ * 简单商品vo
+ * @author lzp
+ * @date 2025-04-25
+ */
+public class ProductSimpleView {
+
+ private Long productId;
+ private String productTitle;
+ private String mainImage;
+ private BigDecimal price;
+ private BigDecimal originalPrice; // 原价(用于显示划线价)
+ //private Double rating; // 评分
+ //private Integer monthlySales; // 月销量
+
+
+}
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
new file mode 100644
index 0000000..723d856
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/NearbyStoreQueryCriteria.java
@@ -0,0 +1,38 @@
+package com.oying.modules.pc.search.domain.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+
+@Data
+public class NearbyStoreQueryCriteria {
+
+ @NotNull
+ private Double longitude; // 中心点经度
+
+ @NotNull
+ private Double latitude; // 中心点纬度
+
+ @Min(100)
+ @Max(5000)
+ private Integer radius = 1000; // 搜索半径(米)
+
+ private Boolean onlyOpenNow = true; // 是否只查当前营业的
+
+ @Min(1)
+ @Max(50)
+ private Integer limit = 20; // 返回数量限制
+
+ // 分页参数
+ private Integer page = 1;
+
+ private Integer size = 10;
+
+ private String blurry;
+
+ private Long status;
+
+ private Long platformCategoryId;
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/StoreSearchDto.java b/oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/StoreSearchDto.java
new file mode 100644
index 0000000..66f15c0
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/search/domain/dto/StoreSearchDto.java
@@ -0,0 +1,17 @@
+package com.oying.modules.pc.search.domain.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+public class StoreSearchDto {
+
+ // 店铺基础信息
+ private Long storeId;
+ private String storeName;
+ private String logoImage;
+ private Integer deliveryTime;
+ private Integer distance;
+
+}
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
new file mode 100644
index 0000000..e659545
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/search/rest/StoreSearchController.java
@@ -0,0 +1,58 @@
+package com.oying.modules.pc.search.rest;
+
+import cn.hutool.core.collection.CollUtil;
+import com.oying.modules.pc.common.core.domain.R;
+import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
+import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
+import com.oying.modules.pc.search.view.StoreSearchView;
+import com.oying.modules.pc.search.service.StoreSearchService;
+import com.oying.utils.PageResult;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+/**
+ * 店铺
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+@RestController
+@RequestMapping("/api/pc/search")
+@RequiredArgsConstructor
+public class StoreSearchController {
+
+ private final StoreSearchService storeSearchService;
+
+ /**
+ * 查询最近的店铺
+ */
+ @GetMapping("/near")
+ public R<PageResult<StoreSearchView>> list(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());
+ if (CollUtil.isNotEmpty(resources.getContent())) {
+ t.setContent(resources.getContent().stream().map(storeSearchDto -> {
+ StoreSearchView searchView = new StoreSearchView();
+ searchView.setStoreId(storeSearchDto.getStoreId());
+ searchView.setStoreName(storeSearchDto.getStoreName());
+ searchView.setStoreLogoUrl(""); // 获取obs
+ searchView.setDistance(storeSearchDto.getDistance());
+ searchView.setRecommendedProducts(Collections.emptyList());
+ return searchView;
+ }).collect(Collectors.toList()));
+ }
+ if (CollUtil.isEmpty(t.getContent())) {
+ t.setContent(Collections.emptyList());
+ }
+ return t;
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/search/service/StoreSearchService.java b/oying-system/src/main/java/com/oying/modules/pc/search/service/StoreSearchService.java
new file mode 100644
index 0000000..63d91d6
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/search/service/StoreSearchService.java
@@ -0,0 +1,10 @@
+package com.oying.modules.pc.search.service;
+
+import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
+import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
+import com.oying.utils.PageResult;
+
+public interface StoreSearchService {
+
+ PageResult<StoreSearchDto> findNearStores(NearbyStoreQueryCriteria criteria);
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/search/service/impl/StoreSearchServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/search/service/impl/StoreSearchServiceImpl.java
new file mode 100644
index 0000000..3c37c6a
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/search/service/impl/StoreSearchServiceImpl.java
@@ -0,0 +1,25 @@
+package com.oying.modules.pc.search.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.oying.modules.pc.search.domain.dto.NearbyStoreQueryCriteria;
+import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
+import com.oying.modules.pc.store.mapper.StoreMapper;
+import com.oying.modules.pc.search.service.StoreSearchService;
+import com.oying.utils.PageResult;
+import com.oying.utils.PageUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class StoreSearchServiceImpl implements StoreSearchService {
+
+ private final StoreMapper storeMapper;
+
+ @Override
+ public PageResult<StoreSearchDto> findNearStores(NearbyStoreQueryCriteria criteria) {
+ Page<StoreSearchDto> page = new Page<>(criteria.getPage(), criteria.getSize());
+ return PageUtil.toPage(storeMapper.queryNearStores(criteria, page));
+ }
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/search/view/StoreSearchView.java b/oying-system/src/main/java/com/oying/modules/pc/search/view/StoreSearchView.java
new file mode 100644
index 0000000..fabd856
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/search/view/StoreSearchView.java
@@ -0,0 +1,27 @@
+package com.oying.modules.pc.search.view;
+
+import com.oying.modules.pc.product.view.ProductSimpleView;
+import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
+import lombok.Data;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 搜索结果VO - 包含店铺和推荐商品
+ * @author lzp
+ * @date 2025-04-25
+ */
+@Data
+public class StoreSearchView {
+
+ // 店铺基础信息
+ private Long storeId;
+ private String storeName;
+ private String storeLogoUrl;
+ private Integer deliveryTime;
+ private Integer distance;
+
+ // 商品列表(通常3-5个推荐商品)
+ private List<ProductSimpleView> recommendedProducts;
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreDtoAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreDtoAssembler.java
new file mode 100644
index 0000000..fed4923
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreDtoAssembler.java
@@ -0,0 +1,7 @@
+package com.oying.modules.pc.store.converter;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class StoreDtoAssembler {
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreViewAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreViewAssembler.java
new file mode 100644
index 0000000..d92d697
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreViewAssembler.java
@@ -0,0 +1,7 @@
+package com.oying.modules.pc.store.converter;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class StoreViewAssembler {
+}
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
new file mode 100644
index 0000000..4542f86
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/Store.java
@@ -0,0 +1,135 @@
+package com.oying.modules.pc.store.domain;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.data.geo.Point;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalTime;
+import java.time.ZonedDateTime;
+
+/**
+ * @author lzp
+ * @date 2025-04-21
+ **/
+@Data
+@TableName("pc_store")
+public class Store implements Serializable {
+
+ @TableId(value = "store_id", type = IdType.AUTO)
+ @ApiModelProperty(value = "唯一标识")
+ private Long storeId;
+
+ @NotNull
+ @ApiModelProperty(value = "商户ID")
+ private Long merchantId;
+
+ @NotNull
+ @ApiModelProperty(value = "平台类目")
+ private Long platformCategoryId;
+
+ @NotNull
+ @ApiModelProperty(value = "店铺类型:1-自营 2-加盟 3-第三方")
+ private Integer storeType;
+
+ @ApiModelProperty(value = "店铺编码")
+ private String storeCode;
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺名称")
+ private String storeName;
+
+ @ApiModelProperty(value = "经营范围")
+ private String businessScope;
+
+ @NotNull
+ @ApiModelProperty(value = "状态:1000-草稿 1002-正常 1003-暂停营业 1004-关闭")
+ private Integer status;
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺logo图片")
+ private Long logoImageId;
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺封面图")
+ private Long coverImageId;
+
+ @ApiModelProperty(value = "店铺描述")
+ private String description;
+
+ @ApiModelProperty(value = "店铺标签,逗号分隔")
+ private String tags;
+
+ @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 provinceCode;
+
+ @ApiModelProperty(value = "市级代码")
+ private String cityCode;
+
+ @ApiModelProperty(value = "区/县级代码")
+ private String districtCode;
+
+ @ApiModelProperty(value = "详细地址")
+ private String address;
+
+ @ApiModelProperty(value = "经度")
+ private Double longitude;
+
+ @ApiModelProperty(value = "纬度")
+ private Double latitude;
+
+ @ApiModelProperty(value = "GeoHash编码")
+ private String geoHash;
+
+ @ApiModelProperty(value = "空间坐标")
+ private Point geoPoint;
+
+ @ApiModelProperty(value = "坐标系:WGS84/GCJ02/BD09/CGCS2000")
+ private String coordinateSystem;
+
+ @ApiModelProperty(value = "营业半径(米)")
+ private Integer radius;
+
+ @NotNull
+ @ApiModelProperty(value = "创建人")
+ private Long createBy;
+
+ @NotNull
+ @ApiModelProperty(value = "创建日期")
+ private ZonedDateTime createTime;
+
+ @NotNull
+ @ApiModelProperty(value = "修改人")
+ private Long updateBy;
+
+ @NotNull
+ @ApiModelProperty(value = "修改时间")
+ private ZonedDateTime updateTime;
+
+ 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/StoreCategory.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreCategory.java
new file mode 100644
index 0000000..9c68dbb
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreCategory.java
@@ -0,0 +1,70 @@
+package com.oying.modules.pc.store.domain;
+
+import lombok.Data;
+import cn.hutool.core.bean.BeanUtil;
+import io.swagger.annotations.ApiModelProperty;
+import cn.hutool.core.bean.copier.CopyOptions;
+import java.sql.Timestamp;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+* @description /
+* @author lzp
+* @date 2025-04-27
+**/
+@Data
+@TableName("pc_store_category")
+public class StoreCategory implements Serializable {
+
+ @TableId(value = "category_id")
+ @ApiModelProperty(value = "ID")
+ private Long categoryId;
+
+ @NotNull
+ @ApiModelProperty(value = "店铺ID")
+ private Long storeId;
+
+ @NotNull
+ @ApiModelProperty(value = "父ID")
+ private Long parentId;
+
+ @NotBlank
+ @ApiModelProperty(value = "类目名称")
+ private String name;
+
+ @NotNull
+ @ApiModelProperty(value = "类目层级:1-级类目 2-级类目")
+ private Integer level;
+
+ @ApiModelProperty(value = "排序权重")
+ private Integer sortWeight;
+
+ @ApiModelProperty(value = "类目图标")
+ private String iconId;
+
+ @ApiModelProperty(value = "状态(暂不使用)")
+ private Integer status;
+
+ @ApiModelProperty(value = "是否启用(0-否 1-是)")
+ private Integer active;
+
+ @ApiModelProperty(value = "创建人")
+ private Long createBy;
+
+ @ApiModelProperty(value = "创建时间")
+ private Timestamp createTime;
+
+ @ApiModelProperty(value = "更新人")
+ private Long updateBy;
+
+ @ApiModelProperty(value = "更新时间")
+ private Timestamp updateTime;
+
+ public void copy(StoreCategory source){
+ BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreLocation.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreLocation.java
new file mode 100644
index 0000000..6cd40d9
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreLocation.java
@@ -0,0 +1,57 @@
+package com.oying.modules.pc.store.domain;
+
+import lombok.Data;
+import cn.hutool.core.bean.BeanUtil;
+import io.swagger.annotations.ApiModelProperty;
+import cn.hutool.core.bean.copier.CopyOptions;
+
+import java.math.BigDecimal;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import org.springframework.data.geo.Point;
+
+/**
+* @description /
+* @author lzp
+* @date 2025-04-23
+**/
+@Data
+@TableName("store_location")
+public class StoreLocation implements Serializable {
+
+ @TableId(value = "address_id", type = IdType.AUTO)
+ @ApiModelProperty(value = "地址ID")
+ private Long locationId;
+
+ @NotNull
+ @ApiModelProperty(value = "关联的店铺ID")
+ private Long storeId;
+
+ @ApiModelProperty(value = "省份")
+ private String province;
+
+ @ApiModelProperty(value = "城市")
+ private String city;
+
+ @ApiModelProperty(value = "区县")
+ private String district;
+
+ @ApiModelProperty(value = "详细地址")
+ private String address;
+
+ @ApiModelProperty(value = "经度")
+ private BigDecimal longitude;
+
+ @ApiModelProperty(value = "纬度")
+ private BigDecimal latitude;
+
+ @ApiModelProperty(value = "空间坐标")
+ private Point getPoint;
+
+ public void copy(StoreLocation 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
new file mode 100644
index 0000000..069b7c8
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreQualification.java
@@ -0,0 +1,75 @@
+package com.oying.modules.pc.store.domain;
+
+import lombok.Data;
+import cn.hutool.core.bean.BeanUtil;
+import io.swagger.annotations.ApiModelProperty;
+import cn.hutool.core.bean.copier.CopyOptions;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.time.LocalTime;
+import java.time.ZonedDateTime;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+* @description /
+* @author lzp
+* @date 2025-04-22
+**/
+@Data
+@TableName("pc_store_qualification")
+public class StoreQualification implements Serializable {
+
+ @TableId(value = "qualification_id", type = IdType.AUTO)
+ @ApiModelProperty(value = "资质ID")
+ private Long qualificationId;
+
+ @NotNull
+ @ApiModelProperty(value = "关联的店铺ID")
+ private Long storeId;
+
+ @NotNull
+ @ApiModelProperty(value = "资质类型")
+ private Integer qualificationType;
+
+ @ApiModelProperty(value = "资质编号")
+ private String qualificationNumber;
+
+ @ApiModelProperty(value = "资质名称")
+ private String qualificationName;
+
+ @ApiModelProperty(value = "资质图片")
+ private String qualificationImageId;
+
+ @ApiModelProperty(value = "有效期开始日期")
+ private LocalTime startDate;
+
+ @ApiModelProperty(value = "有效期结束日期")
+ private LocalTime endDate;
+
+ @ApiModelProperty(value = "状态:1000-草稿 1001-有效 1002-无效")
+ private Integer status;
+
+ @NotNull
+ @ApiModelProperty(value = "创建人")
+ private Long createBy;
+
+ @NotNull
+ @ApiModelProperty(value = "创建日期")
+ private ZonedDateTime createTime;
+
+ @NotNull
+ @ApiModelProperty(value = "修改人")
+ private Long updateBy;
+
+ @NotNull
+ @ApiModelProperty(value = "修改时间")
+ private ZonedDateTime updateTime;
+
+ public void copy(StoreQualification source){
+ BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
+ }
+}
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
new file mode 100644
index 0000000..719247d
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreStatus.java
@@ -0,0 +1,5 @@
+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/StoreBusinessHoursRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreBusinessHoursRequest.java
new file mode 100644
index 0000000..a89348e
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreBusinessHoursRequest.java
@@ -0,0 +1,18 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.time.LocalTime;
+
+@Data
+public class StoreBusinessHoursRequest {
+
+ @NotNull
+ private LocalTime openTime;
+
+ @NotNull
+ private LocalTime closeTime;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryCreateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryCreateRequest.java
new file mode 100644
index 0000000..cedeb47
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryCreateRequest.java
@@ -0,0 +1,18 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class StoreCategoryCreateRequest {
+
+ private Long storeId;
+
+ private Long parentId;
+
+ private String name;
+
+ private Integer sortWeight;
+
+ private Integer active;
+
+}
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
new file mode 100644
index 0000000..46b5256
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantCreateRequest.java
@@ -0,0 +1,20 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+public class StoreCategoryMerchantCreateRequest {
+
+ private Long parentId;
+
+ @NotBlank
+ private String name;
+
+ private Integer sortWeight;
+
+ private Integer active;
+
+}
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
new file mode 100644
index 0000000..48a15fb
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryMerchantUpdateRequest.java
@@ -0,0 +1,16 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class StoreCategoryMerchantUpdateRequest {
+
+ private Long parentId;
+
+ private String name;
+
+ private Integer sortWeight;
+
+ private Integer active;
+
+}
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
new file mode 100644
index 0000000..bc8ae0a
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryQueryCriteria.java
@@ -0,0 +1,26 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author lzp
+ * @date 2025-04-27
+ **/
+@Data
+public class StoreCategoryQueryCriteria {
+
+ private Long storeId;
+
+ private Integer level;
+
+ private Boolean recursive;
+
+ private Integer active;
+
+ @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
new file mode 100644
index 0000000..fc238f6
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCategoryUpdateRequest.java
@@ -0,0 +1,20 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class StoreCategoryUpdateRequest {
+
+ private Long storeId;
+
+ private Long parentId;
+
+ private Long categoryId;
+
+ private String name;
+
+ private Integer sortWeight;
+
+ private Integer active;
+
+}
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
new file mode 100644
index 0000000..f23b372
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCreateRequest.java
@@ -0,0 +1,90 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.json.JSONUtil;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class StoreCreateRequest {
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺全称", example = "重庆永辉超市新纪元店")
+ private String storeName;
+
+ /*@NotBlank
+ @ApiModelProperty(value = "店铺简称", example = "永辉超市(新纪元店)")
+ private String storeShortName;*/
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺LOGO文件ID", example = "14567785444763247876234")
+ private Long logoUploadFileId;
+
+ /*@NotBlank
+ @ApiModelProperty(value = "店铺门户图片ID", example = "276409837458893793939")
+ private Long coverUploadFileId;*/
+
+ @NotBlank
+ @ApiModelProperty(value = "平台类目ID", example = "29784639387324848347230")
+ private Long platformCategoryId;
+ //private String businessCategory;
+
+ @NotBlank
+ @ApiModelProperty(value = "简介", example = "")
+ private String description;
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺联系电话", example = "13800000001")
+ private String contactPhone;
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺地址", example = "276409837458893793939")
+ private String address;
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺坐标经度", example = "121.505978")
+ private Double longitude;
+
+ @NotBlank
+ @ApiModelProperty(value = "店铺坐标纬度", example = "31.144515")
+ private Double latitude;
+
+ @ApiModelProperty(value = "店铺资质", example = "")
+ private List<StoreQualificationCreateRequest> qualificationList;
+
+ 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
new file mode 100644
index 0000000..765a099
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java
@@ -0,0 +1,26 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class StoreCustomerDetailDto {
+
+ private String name;
+
+ private String logoUrl;
+
+ private String description;
+
+ private String address;
+
+ private String businessHours;
+
+ private String contactPhone;
+
+ private Integer score;
+
+ private Integer deliveryDuration;
+
+ private Integer monthlySales;
+
+}
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
new file mode 100644
index 0000000..ad461f2
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerQueryCriteria.java
@@ -0,0 +1,16 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class StoreCustomerQueryCriteria {
+
+ private Long StoreId;
+
+ private Double longitude; // 中心点经度
+
+ private Double latitude; // 中心点纬度
+
+}
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
new file mode 100644
index 0000000..a273357
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreFieldUpdateRequest.java
@@ -0,0 +1,92 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.time.LocalTime;
+
+@Data
+public class StoreFieldUpdateRequest {
+
+ @NotNull
+ private Long storeId;
+
+ public interface UpdateStorePlatformCategoryGroup{}
+
+ @NotNull(groups = UpdateStorePlatformCategoryGroup.class)
+ private Long platformCategoryId;
+
+ public interface UpdateStoreNameGroup{}
+
+ @NotBlank(groups = UpdateStoreNameGroup.class)
+ private String storeName;
+
+ public interface UpdateStoreTitleGroup{}
+
+ @NotBlank(groups = UpdateStoreTitleGroup.class)
+ private String storeTitle;
+
+ public interface UpdateStoreBusinessStatusGroup {}
+
+ @NotNull(groups = UpdateStoreBusinessStatusGroup.class)
+ private Integer businessStatus;
+
+ public interface UpdateStoreLogoImageGroup{}
+
+ @NotBlank(groups = UpdateStoreLogoImageGroup.class)
+ private String logoImageUploadId;
+
+ public interface UpdateStoreCoverImageGroup{}
+
+ @NotBlank(groups = UpdateStoreCoverImageGroup.class)
+ private String coverImageUploadId;
+
+ public interface UpdateStoreDescriptionGroup{}
+
+ @NotBlank(groups = UpdateStoreDescriptionGroup.class)
+ private String description;
+
+ public interface UpdateStoreDeliveryFeeGroup{}
+
+ @NotBlank(groups = UpdateStoreDeliveryFeeGroup.class)
+ private BigDecimal deliveryFee;
+
+ public interface UpdateStoreDeliveryMinimumGroup{}
+
+ @NotBlank(groups = UpdateStoreDeliveryMinimumGroup.class)
+ private BigDecimal deliveryMinimum;
+
+ public interface UpdateStoreContactPhoneGroup{}
+
+ @NotBlank(groups = UpdateStoreContactPhoneGroup.class)
+ private String contactPhone;
+
+ public interface UpdateStoreBusinessHoursGroup{}
+
+ @NotBlank(groups = UpdateStoreBusinessHoursGroup.class)
+ private LocalTime openTime;
+
+ @NotBlank(groups = UpdateStoreBusinessHoursGroup.class)
+ private LocalTime closeTime;
+
+ public interface UpdateStoreAddressGroup{}
+
+ @NotBlank(groups = UpdateStoreAddressGroup.class)
+ private String address;
+
+ public interface UpdateStoreLocationGroup{}
+
+ @NotBlank(groups = UpdateStoreLocationGroup.class)
+ private Double longitude;
+
+ @NotBlank(groups = UpdateStoreLocationGroup.class)
+ private Double latitude;
+
+ public interface UpdateStoreRadiusGroup{}
+
+ @NotBlank(groups = UpdateStoreRadiusGroup.class)
+ private Integer radius;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreLocationUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreLocationUpdateRequest.java
new file mode 100644
index 0000000..f6555b3
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreLocationUpdateRequest.java
@@ -0,0 +1,17 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class StoreLocationUpdateRequest {
+
+ @NotNull
+ private Double longitude;
+
+ @NotNull
+ private Double latitude;
+
+}
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
new file mode 100644
index 0000000..5826de4
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationCreateRequest.java
@@ -0,0 +1,26 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import com.oying.modules.pc.store.domain.StoreQualification;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+
+@Data
+public class StoreQualificationCreateRequest {
+
+ @NotNull
+ @ApiModelProperty(value = "资质类型", example = "1001")
+ private Integer type;
+
+ /*@NotBlank
+ @ApiModelProperty(value = "资质名称", example = "营业执照")
+ private String name;*/
+
+ @NotBlank
+ @ApiModelProperty(value = "资质图片ID", example = "30975645483838730008921")
+ private String 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
new file mode 100644
index 0000000..3d0e43b
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationQueryCriteria.java
@@ -0,0 +1,24 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+* @author lzp
+* @date 2025-04-23
+**/
+@Data
+public class StoreQualificationQueryCriteria{
+
+ @ApiModelProperty(value = "店铺资质ID", example = "1")
+ private Long id;
+
+ @ApiModelProperty(value = "店铺ID", example = "1")
+ private Long storeId;
+
+ @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/StoreQualificationUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java
new file mode 100644
index 0000000..23f8369
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQualificationUpdateRequest.java
@@ -0,0 +1,27 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+
+@Data
+public class StoreQualificationUpdateRequest {
+
+ @NotBlank
+ @ApiModelProperty(value = "资质ID", example = "317640956839788210948")
+ private Long id;
+
+ @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 {
+ }
+
+}
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
new file mode 100644
index 0000000..2d86a34
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreQueryCriteria.java
@@ -0,0 +1,31 @@
+package com.oying.modules.pc.store.domain.dto;
+
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @author lzp
+ * @date 2025-04-22
+ **/
+@Data
+public class StoreQueryCriteria implements Serializable {
+
+ @ApiModelProperty(value = "商户ID", example = "1")
+ private Long merchantId;
+
+ private String storeName;
+
+ private Integer status;
+
+ @ApiModelProperty(value = "页码", example = "1")
+ private Integer page = 1;
+
+ @ApiModelProperty(value = "每页数据量", example = "10")
+ private Integer size = 10;
+
+ @ApiModelProperty(value = "偏移量", hidden = true)
+ private long offset;
+
+}
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
new file mode 100644
index 0000000..3471252
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreStatusEnum.java
@@ -0,0 +1,21 @@
+package com.oying.modules.pc.store.domain.enums;
+
+public enum StoreStatusEnum {
+
+ creating(1000, "筹备中"),
+ reviewing(2000, "审核中"),
+ business_open(3000, ""),
+ business_paused(3001, ""),
+ business_banned(3002, ""),
+ business_suspended(3003, ""),
+ closed(1001, ""),
+ deleted(1002, "");
+
+ private final int value;
+ private final String reasonPhrase;
+
+ private StoreStatusEnum(int value, String reasonPhrase) {
+ this.value = value;
+ this.reasonPhrase = reasonPhrase;
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreCategoryMapper.java b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreCategoryMapper.java
new file mode 100644
index 0000000..dd684f7
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreCategoryMapper.java
@@ -0,0 +1,22 @@
+package com.oying.modules.pc.store.mapper;
+
+import com.oying.modules.pc.store.domain.StoreCategory;
+import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+/**
+* @author lzp
+* @date 2025-04-24
+**/
+@Mapper
+public interface StoreCategoryMapper extends BaseMapper<StoreCategory> {
+
+ IPage<StoreCategory> findAll(@Param("criteria") StoreCategoryQueryCriteria criteria, Page<Object> page);
+
+ List<StoreCategory> findAll(@Param("criteria") StoreCategoryQueryCriteria criteria);
+}
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
new file mode 100644
index 0000000..15753c0
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreMapper.java
@@ -0,0 +1,34 @@
+package com.oying.modules.pc.store.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+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.StoreQueryCriteria;
+import com.oying.modules.pc.search.domain.dto.StoreSearchDto;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 店铺Mapper接口
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+@Mapper
+public interface StoreMapper extends BaseMapper<Store> {
+
+ List<Store> selectStoreList(@Param("criteria") StoreQueryCriteria criteria, Page<Store> page);
+
+ List<Store> selectStoreList(@Param("criteria") StoreQueryCriteria criteria);
+
+ Store selectStoreByMerchantId(@Param("merchantId") Long merchantId);
+
+ IPage<StoreSearchDto> queryNearStores(@Param("criteria") NearbyStoreQueryCriteria criteria, Page<StoreSearchDto> page);
+
+ IPage<StoreSearchDto> queryNearStoreWithProduct(@Param("criteria") NearbyStoreQueryCriteria criteria, Page<StoreSearchDto> page);
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreQualificationMapper.java b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreQualificationMapper.java
new file mode 100644
index 0000000..51b20df
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreQualificationMapper.java
@@ -0,0 +1,24 @@
+package com.oying.modules.pc.store.mapper;
+
+import java.util.List;
+
+import com.oying.modules.pc.store.domain.StoreQualification;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Mapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+/**
+* @author lzp
+* @date 2025-04-23
+**/
+@Mapper
+public interface StoreQualificationMapper extends BaseMapper<StoreQualification> {
+
+ IPage<StoreQualification> findAll(@Param("criteria") StoreQualificationQueryCriteria criteria, Page<Object> page);
+
+ List<StoreQualification> findAll(@Param("criteria") StoreQualificationQueryCriteria criteria);
+
+}
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
new file mode 100644
index 0000000..9e04ce0
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryController.java
@@ -0,0 +1,65 @@
+package com.oying.modules.pc.store.rest;
+
+import com.oying.annotation.Log;
+import com.oying.modules.pc.common.core.domain.R;
+import com.oying.modules.pc.store.domain.StoreCategory;
+import com.oying.modules.pc.store.service.StoreCategoryService;
+import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
+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 com.oying.utils.PageResult;
+
+/**
+* @author lzp
+* @date 2025-04-24
+**/
+@Api(tags = "商品中心:店铺类目")
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/pc/storeCategory")
+public class StoreCategoryController {
+
+ private final StoreCategoryService storeCategoryService;
+
+ @GetMapping
+ @ApiOperation("查询api/store/category")
+ public ResponseEntity<?> queryStoreCategory(StoreCategoryQueryCriteria criteria){
+ Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
+ return ResponseEntity.ok(R.success(storeCategoryService.queryAll(criteria, page)));
+ }
+
+ @PostMapping
+ @Log("新增api/store")
+ @ApiOperation("新增api/store")
+ @PreAuthorize("@el.check('storeCategory:add')")
+ public ResponseEntity<?> createStoreCategory(@Validated @RequestBody StoreCategory resources){
+ storeCategoryService.create(resources);
+ 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);
+ return ResponseEntity.noContent().build();
+ }
+
+ @DeleteMapping
+ @Log("删除api/store")
+ @ApiOperation("删除api/store")
+ @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
new file mode 100644
index 0000000..348f729
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryCustomerController.java
@@ -0,0 +1,71 @@
+package com.oying.modules.pc.store.rest;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.lang.tree.Tree;
+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.common.core.domain.R;
+import com.oying.modules.pc.store.domain.StoreCategory;
+import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
+import com.oying.modules.pc.store.service.StoreCategoryService;
+import com.oying.modules.pc.store.view.CustomerStoreCategoryView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * @author lzp
+ * @date 2025-04-24
+ **/
+@Api(tags = "店铺类目(客户端)")
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/pc/customer/store/{storeId}/category")
+public class StoreCategoryCustomerController {
+
+ private final StoreCategoryService storeCategoryService;
+
+ @GetMapping(value = "/list")
+ @ApiOperation("查询店铺类目")
+ public ResponseEntity<?> getList(@PathVariable("storeId") Long storeId,
+ @RequestParam(value = "recursive", required = false) Boolean recursive) {
+
+ StoreCategoryQueryCriteria criteria = new StoreCategoryQueryCriteria();
+ criteria.setStoreId(storeId);
+ criteria.setActive(1);
+ List<StoreCategory> categoryList = storeCategoryService.queryAll(criteria);
+
+ List<CustomerStoreCategoryView> categoryViewList = Optional.ofNullable(categoryList).orElse(ListUtil.empty()).stream().map(i -> {
+ CustomerStoreCategoryView view = new CustomerStoreCategoryView();
+ view.setCategoryId(i.getCategoryId());
+ view.setParentId(i.getParentId());
+ view.setName(i.getName());
+ view.setSortWeight(i.getSortWeight());
+ return view;
+ }).collect(Collectors.toList());
+
+ if (BooleanUtil.isFalse(recursive)) {
+ return ResponseEntity.ok(R.success(categoryViewList));
+ }
+
+ TreeNodeConfig config = new TreeNodeConfig();
+ config.setIdKey("categoryId");
+ config.setWeightKey("sortWeight");
+ //config.setDeep(3);
+
+ List<Tree<Long>> tree = TreeUtil.build(categoryViewList, 0L, config, (c, treeNode) -> {
+ treeNode.setId(c.getCategoryId());
+ treeNode.setParentId(c.getParentId());
+ treeNode.setName(c.getName());
+ treeNode.setWeight(c.getSortWeight());
+ });
+ return ResponseEntity.ok(R.success(tree));
+ }
+}
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
new file mode 100644
index 0000000..3e52c0a
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCategoryMerchantController.java
@@ -0,0 +1,136 @@
+package com.oying.modules.pc.store.rest;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.lang.tree.TreeNodeConfig;
+import cn.hutool.core.lang.tree.TreeUtil;
+import cn.hutool.core.util.BooleanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.oying.annotation.Log;
+import com.oying.modules.pc.common.core.domain.R;
+import com.oying.modules.pc.store.domain.StoreCategory;
+import com.oying.modules.pc.store.domain.dto.*;
+import com.oying.modules.pc.store.service.StoreCategoryService;
+import com.oying.modules.pc.store.view.StoreCategoryMerchantView;
+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.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 java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * @author lzp
+ * @date 2025-04-24
+ **/
+@Api(tags = "店铺类目(商户端)")
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/pc/merchant/store/{storeId}/category")
+public class StoreCategoryMerchantController {
+
+ private final StoreCategoryService storeCategoryService;
+
+ @GetMapping(value = "/list")
+ @ApiOperation("查询店铺类目")
+ //@PreAuthorize("@el.check('merchant:storeCategory:list')" +
+ // " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> getList(@PathVariable Long storeId,
+ @RequestParam(value = "recursive", required = false) Boolean recursive) {
+
+ StoreCategoryQueryCriteria criteria = new StoreCategoryQueryCriteria();
+ criteria.setStoreId(storeId);
+ List<StoreCategory> storeCategoryList = storeCategoryService.queryAll(criteria);
+ List<StoreCategoryMerchantView> viewList = Optional.ofNullable(storeCategoryList).orElse(ListUtil.empty()).stream().map(i -> {
+ StoreCategoryMerchantView view = new StoreCategoryMerchantView();
+ BeanUtils.copyProperties(i, view);
+ return view;
+ }).collect(Collectors.toList());
+
+ if (BooleanUtil.isFalse(recursive)) {
+ return ResponseEntity.ok(R.success(viewList));
+ }
+
+ TreeNodeConfig config = new TreeNodeConfig();
+ config.setIdKey("categoryId");
+ config.setWeightKey("sortWeight");
+ //config.setDeep(3);
+
+ List<Tree<Long>> tree = TreeUtil.build(viewList, 0L, config, (c, treeNode) -> {
+ treeNode.setId(c.getCategoryId());
+ treeNode.setParentId(c.getParentId());
+ treeNode.setName(c.getName());
+ treeNode.setWeight(c.getSortWeight());
+ });
+
+ return ResponseEntity.ok(R.success(tree));
+ }
+
+ @GetMapping(value = "/{categoryId}")
+ @ApiOperation("查询店铺类目")
+ //@PreAuthorize("@el.check('merchant:storeCategory:list')" +
+ // " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> getById(@PathVariable Long categoryId,
+ @RequestParam(value = "recursive", required = false) Boolean recursive) {
+
+ StoreCategory storeCategory = storeCategoryService.getById(categoryId);
+ StoreCategoryMerchantView view = new StoreCategoryMerchantView();
+ BeanUtils.copyProperties(storeCategory, view);
+
+ /*LambdaQueryWrapper<StoreCategory> wrapper = new LambdaQueryWrapper<StoreCategory>()
+ .eq(StoreCategory::getParentId, categoryId);
+ List<StoreCategory> subStoreCategoryList = storeCategoryService.list(wrapper);*/
+
+ return ResponseEntity.ok(R.success(view));
+ }
+
+ @PostMapping
+ @Log("新增店铺类目")
+ @ApiOperation("新增店铺类目")
+ //@PreAuthorize("@el.check('storeCategory:add')" +
+ // " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> createStoreCategory(@PathVariable Long storeId,
+ @Validated @RequestBody StoreCategoryMerchantCreateRequest request) {
+
+ StoreCategory resources = new StoreCategory();
+ BeanUtils.copyProperties(request, resources);
+ resources.setStoreId(storeId);
+ storeCategoryService.create(resources);
+ return ResponseEntity.status(HttpStatus.CREATED).build();
+ }
+
+ @PutMapping(value = "/{categoryId}")
+ @Log("修改店铺类目")
+ @ApiOperation("修改店铺类目")
+ //@PreAuthorize("@el.check('storeCategory:edit')" +
+ // " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateStoreCategory(@PathVariable Long storeId,
+ @PathVariable Long categoryId,
+ @Validated @RequestBody StoreCategoryMerchantUpdateRequest request) {
+
+ StoreCategory resources = new StoreCategory();
+ BeanUtils.copyProperties(request, resources);
+ resources.setCategoryId(categoryId);
+ resources.setStoreId(storeId);
+ storeCategoryService.update(resources);
+ return ResponseEntity.noContent().build();
+ }
+
+ @DeleteMapping
+ @Log("删除店铺类目")
+ @ApiOperation("删除店铺类目")
+ @PreAuthorize("@el.check('storeCategory:del')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> deleteStoreCategory(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+ storeCategoryService.deleteAll(ids);
+ return ResponseEntity.noContent().build();
+ }
+}
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
new file mode 100644
index 0000000..36a5a1d
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreController.java
@@ -0,0 +1,68 @@
+package com.oying.modules.pc.store.rest;
+
+import com.oying.modules.pc.common.core.domain.R;
+import com.oying.modules.pc.common.id.StoreIdGenerator;
+import com.oying.modules.pc.store.domain.Store;
+import com.oying.modules.pc.store.domain.dto.*;
+import com.oying.modules.pc.store.service.StoreService;
+import com.oying.utils.SecurityUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.ZonedDateTime;
+
+/**
+ * 店铺
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+@RestController
+@RequestMapping("/api/pc/store")
+@RequiredArgsConstructor
+public class StoreController {
+
+ private final StoreService storeService;
+
+ @GetMapping(value = "/page")
+ public R<?> getStoresByPage(@RequestBody StoreQueryCriteria criteria) {
+ return R.success(storeService.queryByPage(criteria));
+ }
+
+ @GetMapping(value = "/list")
+ public R<?> getStores(@RequestBody StoreQueryCriteria criteria) {
+ return R.success(storeService.queryAll(criteria));
+ }
+
+ @GetMapping(value = "/{storeId}")
+ public R<?> getStoreById(@PathVariable("storeId") Long storeId) {
+ return R.success(storeService.getById(storeId));
+ }
+
+ @GetMapping(value = "/{storeId}/details")
+ public R<?> getStoreDetailsById(@PathVariable("storeId") Long storeId) {
+ return 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());
+ store.setCreateBy(SecurityUtils.getCurrentUserId());
+ store.setCreateTime(ZonedDateTime.now());
+ storeService.save(store);
+ return R.success();
+ }
+
+ /**
+ * 修改店铺信息
+ */
+ @PostMapping(value = "/{storeId}")
+ public R<?> update(@PathVariable("storeId") Long storeId, @RequestBody Store store) {
+ store.setStoreId(storeId);
+ storeService.updateById(store);
+ return R.success();
+ }
+
+}
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
new file mode 100644
index 0000000..dbf828d
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java
@@ -0,0 +1,36 @@
+package com.oying.modules.pc.store.rest;
+
+import com.oying.modules.pc.common.core.domain.R;
+import com.oying.modules.pc.store.domain.dto.StoreCustomerDetailDto;
+import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
+import com.oying.modules.pc.store.service.StoreQueryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 店铺
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+@Api(tags = "店铺(客户端)")
+@RestController
+@RequestMapping("/api/pc/customer/store")
+@RequiredArgsConstructor
+public class StoreCustomerController {
+
+ private final StoreQueryService storeQueryService;
+
+ @GetMapping(value = "/{storeId}")
+ @ApiOperation("查询店铺")
+ public ResponseEntity<?> getCustomerStoreById(@PathVariable("storeId") Long storeId) {
+ StoreCustomerQueryCriteria criteria = new StoreCustomerQueryCriteria();
+ criteria.setStoreId(storeId);
+ StoreCustomerDetailDto detailDto = storeQueryService.getCustomerStoreDetail(criteria);
+ return ResponseEntity.ok(R.success(detailDto));
+ }
+
+}
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
new file mode 100644
index 0000000..aa332cc
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java
@@ -0,0 +1,263 @@
+package com.oying.modules.pc.store.rest;
+
+import cn.hutool.core.collection.ListUtil;
+import com.oying.modules.pc.common.core.domain.R;
+import com.oying.modules.pc.store.domain.Store;
+import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
+import com.oying.modules.pc.store.domain.dto.StoreFieldUpdateRequest;
+import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
+import com.oying.modules.pc.store.service.StoreCreateService;
+import com.oying.modules.pc.store.service.StoreService;
+import com.oying.modules.pc.store.view.StoreMerchantView;
+import com.oying.modules.pc.store.view.StoreSimpleView;
+import com.oying.utils.SecurityUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
+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 java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * 店铺
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+@Api(tags = "店铺(商户端)")
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/pc/merchant/store")
+public class StoreMerchantController {
+
+ private final StoreService storeService;
+ private final StoreCreateService storeCreateService;
+
+ @GetMapping(value = "/list")
+ @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 -> {
+ StoreSimpleView view = new StoreSimpleView();
+ view.setId(s.getStoreId());
+ view.setName(s.getStoreName());
+ view.setLogoUrl("");
+ view.setStatus(s.getStatus());
+ return view;
+ }).collect(Collectors.toList());
+ return ResponseEntity.ok(R.success(storeViewList));
+ }
+
+ @GetMapping(value = "/{storeId}")
+ @ApiOperation("查询店铺")
+ //@PreAuthorize("@el.check('merchant:store:getById')" +
+ // " and @storeMerchantOwnershipService.check(#storeId)")
+ 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));
+ }
+
+ @PostMapping
+ @ApiOperation("创建店铺")
+ //@PreAuthorize("@el.check('merchant:store:create')")
+ public ResponseEntity<?> create(@RequestBody StoreCreateRequest request) {
+ storeCreateService.create(request);
+ return ResponseEntity.status(HttpStatus.CREATED).build();
+ }
+
+ /**
+ * 修改店铺信息
+ */
+ @PostMapping(value = "/{storeId}")
+ @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);
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺LOGO
+ */
+ @PatchMapping(value = "/{storeId}/logo")
+ @ApiOperation("修改店铺LOGO")
+ //@PreAuthorize("@el.check('merchant:store:list')" +
+ // " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateLogo(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreLogoImageGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateLogo(storeId, request.getLogoImageUploadId());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺名称
+ */
+ @PatchMapping(value = "/{storeId}/name")
+ @ApiOperation("修改店铺名称")
+ //@PreAuthorize("@el.check('merchant:store:name')" +
+ // " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateName(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreNameGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateName(storeId, request.getStoreName());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺简介
+ */
+ @PatchMapping(value = "/{storeId}/description")
+ @ApiOperation("修改店铺简介")
+ //@PreAuthorize("@el.check('merchant:store:description')" +
+ // " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateDescription(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreDescriptionGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateDescription(storeId, request.getDescription());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺联系电话
+ */
+ @PatchMapping(value = "/{storeId}/contactPhone")
+ @ApiOperation("修改店铺联系电话")
+ @PreAuthorize("@el.check('merchant:store:list')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateContactPhone(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreContactPhoneGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateContactPhone(storeId, request.getContactPhone());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺地址
+ */
+ @PatchMapping(value = "/{storeId}/address")
+ @ApiOperation("修改店铺地址")
+ @PreAuthorize("@el.check('merchant:store:address')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateAddress(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreAddressGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateAddress(storeId, request.getAddress());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺坐标
+ */
+ @PatchMapping(value = "/{storeId}/location")
+ @ApiOperation("修改店铺坐标")
+ @PreAuthorize("@el.check('merchant:store:location')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateLocation(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreLocationGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateLocation(storeId, request.getLongitude(), request.getLatitude());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺配送范围
+ */
+ @PatchMapping(value = "/{storeId}/radius")
+ @ApiOperation("修改店铺配送范围")
+ @PreAuthorize("@el.check('merchant:store:radius')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateRadius(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreRadiusGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateRadius(storeId, request.getRadius());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺绑定的经营类目
+ */
+ @PatchMapping(value = "/{storeId}/platformCategory")
+ @ApiOperation("修改店铺绑定的经营类目")
+ @PreAuthorize("@el.check('merchant:store:platformCategory')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updatePlatformCategory(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStorePlatformCategoryGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updatePlatformCategory(storeId, request.getPlatformCategoryId());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改店铺营业时间
+ */
+ @PatchMapping(value = "/{storeId}/businessHours")
+ @ApiOperation("修改店铺营业时间")
+ @PreAuthorize("@el.check('merchant:store:businessHours')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateBusinessHours(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreBusinessHoursGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateBusinessHours(storeId, request.getOpenTime(), request.getCloseTime());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改起送金额
+ */
+ @PatchMapping(value = "/{storeId}/deliveryMinimum")
+ @ApiOperation("修改起送金额")
+ @PreAuthorize("@el.check('merchant:store:deliveryMinimum')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateDeliveryMinimum(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreDeliveryMinimumGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateDeliveryMinimum(storeId, request.getDeliveryMinimum());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改配送费用
+ */
+ @PatchMapping(value = "/{storeId}/deliveryFee")
+ @ApiOperation("修改配送费用")
+ @PreAuthorize("@el.check('merchant:store:deliveryFee')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> updateDeliveryFee(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreDeliveryFeeGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateDeliveryFee(storeId, request.getDeliveryFee());
+ return ResponseEntity.noContent().build();
+ }
+
+ /**
+ * 修改状态
+ */
+ @PatchMapping(value = "/{storeId}/businessStatus")
+ @ApiOperation("修改状态")
+ @PreAuthorize("@el.check('merchant:store:businessStatus')" +
+ " and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> businessStatus(@PathVariable("storeId") Long storeId,
+ @Validated(value = StoreFieldUpdateRequest.UpdateStoreBusinessStatusGroup.class)
+ @RequestBody StoreFieldUpdateRequest request) {
+ storeService.updateStatus(storeId, request.getBusinessStatus());
+ 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
new file mode 100644
index 0000000..3ae4ed7
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationController.java
@@ -0,0 +1,67 @@
+package com.oying.modules.pc.store.rest;
+
+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.domain.dto.StoreQualificationQueryCriteria;
+import com.oying.modules.pc.store.service.StoreQualificationService;
+import com.oying.utils.PageResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+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.*;
+
+import java.util.List;
+
+/**
+ * @author lzp
+ * @date 2025-04-23
+ **/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "店铺资质")
+@RequestMapping("/api/storeQualification")
+public class StoreQualificationController {
+
+ private final StoreQualificationService storeQualificationService;
+
+ @GetMapping
+ @ApiOperation("查询店铺资质")
+ @PreAuthorize("@el.check('storeQualification:list')")
+ public ResponseEntity<PageResult<StoreQualification>> queryStoreQualification(StoreQualificationQueryCriteria criteria) {
+ Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
+ return new ResponseEntity<>(storeQualificationService.queryAll(criteria, page), HttpStatus.OK);
+ }
+
+ @PostMapping
+ @Log("新增店铺资质")
+ @ApiOperation("新增店铺资质")
+ @PreAuthorize("@el.check('storeQualification:add')")
+ public ResponseEntity<Object> createStoreQualification(@Validated @RequestBody StoreQualification resources) {
+ storeQualificationService.create(resources);
+ return new ResponseEntity<>(HttpStatus.CREATED);
+ }
+
+ @PutMapping
+ @Log("修改店铺资质")
+ @ApiOperation("修改店铺资质")
+ @PreAuthorize("@el.check('storeQualification:edit')")
+ public ResponseEntity<Object> updateStoreQualification(@Validated @RequestBody StoreQualification resources) {
+ storeQualificationService.update(resources);
+ return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+ }
+
+ @DeleteMapping
+ @Log("删除店铺资质")
+ @ApiOperation("删除店铺资质")
+ @PreAuthorize("@el.check('storeQualification:del')")
+ public ResponseEntity<Object> deleteStoreQualification(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+ storeQualificationService.deleteAll(ids);
+ return new ResponseEntity<>(HttpStatus.OK);
+ }
+}
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
new file mode 100644
index 0000000..87718ea
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java
@@ -0,0 +1,55 @@
+package com.oying.modules.pc.store.rest;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjUtil;
+import com.oying.modules.pc.common.core.domain.R;
+import com.oying.modules.pc.store.domain.StoreQualification;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
+import com.oying.modules.pc.store.service.StoreQualificationService;
+import com.oying.modules.pc.store.view.CustomerStoreQualificationView;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * @author lzp
+ * @date 2025-04-23
+ *
+*/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "店铺资质(客户端)")
+@RequestMapping("/api/pc/customer/store/{storeId}/qualification")
+public class StoreQualificationCustomerController {
+
+ private final StoreQualificationService storeQualificationService;
+
+ @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()));
+ }
+ 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;
+ }).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
new file mode 100644
index 0000000..fe4d46e
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationMerchantController.java
@@ -0,0 +1,100 @@
+package com.oying.modules.pc.store.rest;
+
+import cn.hutool.core.collection.ListUtil;
+import com.oying.annotation.Log;
+import com.oying.modules.pc.common.core.domain.R;
+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 io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * @author lzp
+ * @date 2025-04-23
+ **/
+@RestController
+@RequiredArgsConstructor
+@Api(tags = "店铺资质(商户端)")
+@RequestMapping("/api/pc/merchant/store/{storeId}/qualification")
+public class StoreQualificationMerchantController {
+
+ private final StoreQualificationService storeQualificationService;
+
+ @GetMapping("/list")
+ @ApiOperation("查询店铺资质")
+ //@PreAuthorize("@el.check('merchant:storeQualification:list') " +
+ // "and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> getList(@PathVariable Long storeId) {
+ StoreQualificationQueryCriteria criteria = new StoreQualificationQueryCriteria();
+ criteria.setStoreId(storeId);
+ List<StoreQualification> storeQualificationList = storeQualificationService.queryAll(criteria);
+ List<StoreQualificationMerchantView> viewList = Optional.ofNullable(storeQualificationList).orElse(ListUtil.empty()).stream().map(i -> {
+ StoreQualificationMerchantView view = new StoreQualificationMerchantView();
+ view.setId(i.getQualificationId());
+ view.setType(i.getQualificationType());
+ view.setName(i.getQualificationName());
+ view.setImageUrl("");
+ return view;
+ }).collect(Collectors.toList());
+
+ return ResponseEntity.ok(R.success(viewList));
+ }
+
+ @PostMapping
+ @Log("新增店铺资质")
+ @ApiOperation("新增店铺资质")
+ //@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);
+ return ResponseEntity.status(HttpStatus.CREATED).build();
+ }
+
+ @PutMapping("/{qualificationId}")
+ @Log("修改店铺资质")
+ @ApiOperation("修改店铺资质")
+ //@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);
+ return ResponseEntity.noContent().build();
+ }
+
+ @DeleteMapping
+ @Log("删除店铺资质")
+ @ApiOperation("删除店铺资质")
+ //@PreAuthorize("@el.check('merchant:storeQualification:batchDel') " +
+ // "and @storeMerchantOwnershipService.check(#storeId)")
+ public ResponseEntity<?> batchDel(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
+ storeQualificationService.deleteAll(ids);
+ return ResponseEntity.noContent().build();
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCategoryService.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCategoryService.java
new file mode 100644
index 0000000..74f3947
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCategoryService.java
@@ -0,0 +1,52 @@
+package com.oying.modules.pc.store.service;
+
+import com.oying.modules.pc.store.domain.StoreCategory;
+import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
+
+import java.util.List;
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.oying.utils.PageResult;
+
+/**
+* @description 服务接口
+* @author lzp
+* @date 2025-04-24
+**/
+public interface StoreCategoryService extends IService<StoreCategory> {
+
+ /**
+ * 查询数据分页
+ * @param criteria 条件
+ * @param page 分页参数
+ * @return PageResult
+ */
+ PageResult<StoreCategory> queryAll(StoreCategoryQueryCriteria criteria, Page<Object> page);
+
+ /**
+ * 查询所有数据不分页
+ * @param criteria 条件参数
+ * @return List<StoreCategoryDto>
+ */
+ List<StoreCategory> queryAll(StoreCategoryQueryCriteria criteria);
+
+ /**
+ * 创建
+ * @param resources /
+ */
+ void create(StoreCategory resources);
+
+ /**
+ * 编辑
+ * @param resources /
+ */
+ void update(StoreCategory resources);
+
+ /**
+ * 多选删除
+ * @param ids /
+ */
+ void deleteAll(List<Long> ids);
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreateService.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreateService.java
new file mode 100644
index 0000000..7644c48
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreateService.java
@@ -0,0 +1,7 @@
+package com.oying.modules.pc.store.service;
+
+import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
+
+public interface StoreCreateService {
+ void create(StoreCreateRequest request);
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreationCoordinator.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreationCoordinator.java
new file mode 100644
index 0000000..df486f6
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreCreationCoordinator.java
@@ -0,0 +1,31 @@
+package com.oying.modules.pc.store.service;
+
+import com.oying.modules.pc.store.domain.dto.StoreCreateRequest;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class StoreCreationCoordinator {
+
+ private final StoreService storeService;
+ private final StoreQualificationService qualificationService;
+
+ // 核心方法:支持可选 qualification
+ /*@Transactional
+ public StoreFullDTO createFullStore(StoreCreateRequest request) {
+ // 1. 必选操作:store + location + staff
+ Store store = storeService.create(request.getStore());
+ StoreLocation location = locationService.create(store.getId(), request.getLocation());
+ StoreStaff staff = staffService.create(store.getId(), request.getStaff());
+
+ // 2. 可选操作:qualification(根据请求决定)
+ StoreQualification qualification = null;
+ if (request.hasQualification()) {
+ qualification = qualificationService.create(store.getId(), request.getQualification());
+ }
+
+ // 3. 返回聚合结果
+ return new StoreFullDTO(store, location, staff, qualification);
+ }*/
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreMerchantOwnershipService.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreMerchantOwnershipService.java
new file mode 100644
index 0000000..0b1abf6
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreMerchantOwnershipService.java
@@ -0,0 +1,12 @@
+package com.oying.modules.pc.store.service;
+
+import com.oying.modules.pc.store.domain.Store;
+
+public interface StoreMerchantOwnershipService {
+
+ boolean isStoreOwnedByMerchant(Long storeId, Long merchantId);
+ Store verifyAndGetStore(Long storeId, Long merchantId);
+ void verifyStoreOwnership(Long storeId, Long merchantId);
+ Boolean check(Long storeId);
+
+}
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
new file mode 100644
index 0000000..fca62cf
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java
@@ -0,0 +1,57 @@
+package com.oying.modules.pc.store.service;
+
+import java.util.List;
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.utils.PageResult;
+
+/**
+* @description 服务接口
+* @author lzp
+* @date 2025-04-27
+**/
+public interface StoreQualificationService extends IService<StoreQualification> {
+
+ /**
+ * 查询数据分页
+ * @param criteria 条件
+ * @param page 分页参数
+ * @return PageResult
+ */
+ PageResult<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria, Page<Object> page);
+
+ /**
+ * 查询所有数据不分页
+ * @param criteria 条件参数
+ * @return List<StoreQualificationDto>
+ */
+ List<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria);
+
+ /**
+ * 创建
+ * @param resources /
+ */
+ void create(StoreQualification resources);
+
+ /**
+ * 批量创建
+ * @param resources /
+ */
+ void batchCreate(List<StoreQualification> resources);
+
+ /**
+ * 编辑
+ * @param resources /
+ */
+ void update(StoreQualification resources);
+
+ /**
+ * 多选删除
+ * @param ids /
+ */
+ void deleteAll(List<Long> ids);
+}
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
new file mode 100644
index 0000000..e0c3aa0
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQueryService.java
@@ -0,0 +1,10 @@
+package com.oying.modules.pc.store.service;
+
+import com.oying.modules.pc.store.domain.dto.StoreCustomerDetailDto;
+import com.oying.modules.pc.store.domain.dto.StoreCustomerQueryCriteria;
+
+public interface StoreQueryService {
+
+ StoreCustomerDetailDto getCustomerStoreDetail(StoreCustomerQueryCriteria 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
new file mode 100644
index 0000000..8bdcc52
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreService.java
@@ -0,0 +1,56 @@
+package com.oying.modules.pc.store.service;
+
+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.utils.PageResult;
+
+import java.math.BigDecimal;
+import java.time.LocalTime;
+import java.util.List;
+
+/**
+ * 店铺基础信息Service接口
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+public interface StoreService extends IService<Store> {
+
+ PageResult<Store> queryByPage(StoreQueryCriteria criteria);
+
+ List<Store> queryAll(StoreQueryCriteria criteria);
+
+ Store getMerchantStore(Long merchantId);
+
+ boolean create(Store store);
+
+ boolean updateLogo(Long storeId, String logo);
+
+ boolean updateName(Long storeId, String storeName);
+
+ boolean updateDescription(Long storeId, String description);
+
+ boolean updateContactPhone(Long storeId, String contactPhone);
+
+ boolean updateAddress(Long storeId, String address);
+
+ boolean updateLocation(Long storeId, Double longitude, Double latitude);
+
+ boolean updateRadius(Long storeId, Integer radius);
+
+ boolean updatePlatformCategory(Long storeId, Long platformCategory);
+
+ boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime);
+
+ boolean updateDeliveryMinimum(Long storeId, BigDecimal deliveryMinimum);
+
+ boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee);
+
+ boolean updateStatus(Long storeId, Integer status);
+
+ 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
new file mode 100644
index 0000000..a994009
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCategoryServiceImpl.java
@@ -0,0 +1,96 @@
+package com.oying.modules.pc.store.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.oying.exception.EntityNotFoundException;
+import com.oying.modules.pc.common.exception.LevelExceededException;
+import com.oying.modules.pc.store.domain.StoreCategory;
+import com.oying.modules.pc.store.domain.dto.StoreCategoryQueryCriteria;
+import com.oying.modules.pc.store.mapper.StoreCategoryMapper;
+import com.oying.modules.pc.store.service.StoreCategoryService;
+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;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author lzp
+ * @date 2025-04-24
+ **/
+@Service
+@RequiredArgsConstructor
+public class StoreCategoryServiceImpl extends ServiceImpl<StoreCategoryMapper, StoreCategory> implements StoreCategoryService {
+
+ private static final int MAX_LEVEL = 2;
+
+ private final StoreCategoryMapper storeCategoryMapper;
+
+ @Override
+ public PageResult<StoreCategory> queryAll(StoreCategoryQueryCriteria criteria, Page<Object> page) {
+ return PageUtil.toPage(storeCategoryMapper.findAll(criteria, page));
+ }
+
+ @Override
+ public List<StoreCategory> queryAll(StoreCategoryQueryCriteria criteria) {
+ return storeCategoryMapper.findAll(criteria);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void create(StoreCategory resources) {
+ // 重名
+ this.calculateAndSetLevel(resources);
+ resources.setCreateBy(SecurityUtils.getCurrentUserId());
+ storeCategoryMapper.insert(resources);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(StoreCategory resources) {
+ StoreCategory storeCategory = getById(resources.getCategoryId());
+ storeCategory.copy(resources);
+ resources.setUpdateBy(SecurityUtils.getCurrentUserId());
+ storeCategoryMapper.updateById(storeCategory);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteAll(List<Long> ids) {
+ storeCategoryMapper.deleteBatchIds(ids);
+ }
+
+ /**
+ * 计算并设置类目的层级
+ */
+ private void calculateAndSetLevel(StoreCategory category) {
+
+ if (category == null) {
+ throw new IllegalArgumentException("对象不能为null");
+ }
+
+ Long parentCategoryId = category.getParentId();
+ if (parentCategoryId == null) {
+ category.setParentId(0L);
+ category.setLevel(1);
+ return;
+ }
+
+ StoreCategory parentCategory = Optional.ofNullable(getById(parentCategoryId))
+ .orElseThrow(() -> new EntityNotFoundException(StoreCategory.class, "parentId", parentCategoryId.toString()));
+
+ int currentLevel = parentCategory.getLevel() + 1;
+
+ if (currentLevel > MAX_LEVEL) {
+ throw new LevelExceededException(category.getLevel(), MAX_LEVEL);
+ }
+
+ category.setLevel(currentLevel);
+ }
+}
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
new file mode 100644
index 0000000..467ebbb
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreCreateServiceImpl.java
@@ -0,0 +1,51 @@
+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
+@RequiredArgsConstructor
+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);
+ }
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantOwnershipServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantOwnershipServiceImpl.java
new file mode 100644
index 0000000..3825e60
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreMerchantOwnershipServiceImpl.java
@@ -0,0 +1,59 @@
+package com.oying.modules.pc.store.service.impl;
+
+import com.oying.modules.pc.store.domain.Store;
+import com.oying.modules.pc.store.service.StoreMerchantOwnershipService;
+import com.oying.modules.pc.store.service.StoreService;
+import com.oying.utils.SecurityUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service("smo")
+@RequiredArgsConstructor
+public class StoreMerchantOwnershipServiceImpl implements StoreMerchantOwnershipService {
+
+ private final StoreService storeService;
+
+ /**
+ * 验证店铺是否属于商户
+ */
+ @Override
+ public boolean isStoreOwnedByMerchant(Long storeId, Long merchantId) {
+ /*if (storeId == null || merchantId == null) {
+ return false;
+ }
+ Store store = storeService.getById(storeId);
+ return Optional.ofNullable(store).map(i -> merchantId.equals(i.getMerchantId())).orElse(false);*/
+ return true;
+ }
+
+ /**
+ * 验证并获取店铺对象
+ */
+ @Override
+ public Store verifyAndGetStore(Long storeId, Long merchantId) {
+ Store store = storeService.getById(storeId);
+ return Optional.ofNullable(store).orElseThrow(() -> new AccessDeniedException("无权访问此店铺"));
+ }
+
+ /**
+ * 简单验证(不返回对象)
+ */
+ @Override
+ public void verifyStoreOwnership(Long storeId, Long merchantId) {
+ if (!isStoreOwnedByMerchant(storeId, merchantId)) {
+ throw new AccessDeniedException("无权操作此店铺");
+ }
+ }
+
+ /**
+ * PreAuthorize验证
+ */
+ @Override
+ public Boolean check(Long storeId) {
+ Long merchantId = SecurityUtils.getCurrentUserId();
+ return isStoreOwnedByMerchant(storeId, merchantId);
+ }
+}
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
new file mode 100644
index 0000000..6c380c6
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java
@@ -0,0 +1,79 @@
+package com.oying.modules.pc.store.service.impl;
+
+import cn.hutool.core.util.ObjUtil;
+import com.oying.exception.EntityExistException;
+import com.oying.modules.pc.common.id.StoreQualificationIdGenerator;
+import com.oying.modules.pc.store.domain.StoreQualification;
+import com.oying.modules.pc.store.domain.dto.StoreQualificationQueryCriteria;
+import com.oying.modules.pc.store.mapper.StoreQualificationMapper;
+import com.oying.modules.pc.store.service.StoreQualificationService;
+import com.oying.utils.*;
+import lombok.RequiredArgsConstructor;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.ZonedDateTime;
+import java.util.*;
+import java.io.IOException;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+* @description 服务实现
+* @author lzp
+* @date 2025-04-27
+**/
+@Service
+@RequiredArgsConstructor
+public class StoreQualificationServiceImpl extends ServiceImpl<StoreQualificationMapper, StoreQualification> implements StoreQualificationService {
+
+ private final StoreQualificationMapper storeQualificationMapper;
+
+ @Override
+ public PageResult<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria, Page<Object> page){
+ return PageUtil.toPage(storeQualificationMapper.findAll(criteria, page));
+ }
+
+ @Override
+ public List<StoreQualification> queryAll(StoreQualificationQueryCriteria criteria){
+ return storeQualificationMapper.findAll(criteria);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void create(StoreQualification resources) {
+ // resources.setQualificationId(StoreQualificationIdGenerator.getId());
+ resources.setCreateBy(SecurityUtils.getCurrentUserId());
+ resources.setCreateTime(ZonedDateTime.now());
+ storeQualificationMapper.insert(resources);
+ }
+
+ @Override
+ public void batchCreate(List<StoreQualification> resources) {
+ resources.forEach(i-> {
+ i.setCreateBy(SecurityUtils.getCurrentUserId());
+ i.setCreateTime(ZonedDateTime.now());
+ });
+ this.saveBatch(resources);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(StoreQualification resources) {
+ // resources.setUpdateBy();
+ Long qualificationId = resources.getQualificationId();
+ StoreQualification existingStoreQualification = this.getById(qualificationId);
+ if (ObjUtil.isEmpty(existingStoreQualification)) {
+ throw new EntityExistException(StoreQualification.class, "id", Optional.ofNullable(qualificationId).map(Object::toString).orElse("null"));
+ }
+ existingStoreQualification.copy(resources);
+ storeQualificationMapper.updateById(existingStoreQualification);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteAll(List<Long> ids) {
+ storeQualificationMapper.deleteBatchIds(ids);
+ }
+}
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
new file mode 100644
index 0000000..0514d5c
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQueryServiceImpl.java
@@ -0,0 +1,33 @@
+package com.oying.modules.pc.store.service.impl;
+
+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.service.StoreQueryService;
+import com.oying.modules.pc.store.service.StoreService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class StoreQueryServiceImpl implements StoreQueryService {
+
+ private final StoreService storeService;
+
+ @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;
+ }
+}
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
new file mode 100644
index 0000000..445170a
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreServiceImpl.java
@@ -0,0 +1,159 @@
+package com.oying.modules.pc.store.service.impl;
+
+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.modules.pc.store.domain.Store;
+import com.oying.modules.pc.store.domain.dto.StoreQueryCriteria;
+import com.oying.modules.pc.store.mapper.StoreMapper;
+import com.oying.modules.pc.store.service.StoreService;
+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 java.math.BigDecimal;
+import java.time.LocalTime;
+import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * 店铺Service业务层处理
+ *
+ * @author lzp
+ * @date 2025-04-22
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class StoreServiceImpl extends ServiceImpl<StoreMapper, Store> implements StoreService {
+
+ private final StoreMapper storeMapper;
+
+ @Override
+ public PageResult<Store> queryByPage(StoreQueryCriteria criteria) {
+ Page<Store> page = new Page<>(criteria.getPage(), criteria.getSize());
+ return PageUtil.toPage(storeMapper.selectStoreList(criteria, page));
+ }
+
+ @Override
+ public List<Store> queryAll(StoreQueryCriteria criteria) {
+ return storeMapper.selectStoreList(criteria);
+ }
+
+ @Override
+ public Store getMerchantStore(Long merchantId) {
+ return storeMapper.selectStoreByMerchantId(merchantId);
+ }
+
+ @Override
+ public boolean create(Store store) {
+ // store.setStoreId(StoreIdGenerator.getId());
+ store.setCreateBy(SecurityUtils.getCurrentUserId());
+ store.setCreateTime(ZonedDateTime.now());
+ return save(store);
+ }
+
+ @Override
+ public boolean updateLogo(Long storeId, String logo) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId).set(Store::getLogoImageId, logo);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updateName(Long storeId, String storeName) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .set(Store::getStoreName, storeName);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updateDescription(Long storeId, String description) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .set(Store::getDescription, description);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updateContactPhone(Long storeId, String contactPhone) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .set(Store::getContactPhone, contactPhone);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updateAddress(Long storeId, String address) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .set(Store::getAddress, address);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updateLocation(Long storeId, Double longitude, Double latitude) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .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)
+ .set(Store::getRadius, radius);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updatePlatformCategory(Long storeId, Long platformCategory) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .set(Store::getPlatformCategoryId, platformCategory);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updateBusinessHours(Long storeId, LocalTime openTime, LocalTime endTime) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .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)
+ .set(Store::getDeliveryMinimum, deliveryMinimum);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updateDeliveryFee(Long storeId, BigDecimal deliveryFee) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .set(Store::getDeliveryFee, deliveryFee);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean updateStatus(Long storeId, Integer status) {
+ LambdaUpdateWrapper<Store> wrapper = this.createLambdaUpdateWrapper(storeId)
+ .set(Store::getStatus, status);
+ return update(wrapper);
+ }
+
+ @Override
+ public boolean existsByIdAndMerchantId(Long storeId, Long merchantId) {
+ if (storeId == null || merchantId == null) {
+ return false;
+ }
+ Store store = getById(storeId);
+ 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());
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreCategoryView.java b/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreCategoryView.java
new file mode 100644
index 0000000..e1fd477
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreCategoryView.java
@@ -0,0 +1,25 @@
+package com.oying.modules.pc.store.view;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class CustomerStoreCategoryView {
+
+ @ApiModelProperty(value = "类目ID")
+ private Long categoryId;
+
+ @ApiModelProperty(value = "父ID")
+ private Long parentId;
+
+ @ApiModelProperty(value = "类目名称")
+ private String name;
+
+ @ApiModelProperty(value = "排序权重")
+ private Integer sortWeight;
+
+ private List<StoreCategoryMerchantView> children;
+
+}
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
new file mode 100644
index 0000000..92f9328
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreQualificationView.java
@@ -0,0 +1,21 @@
+package com.oying.modules.pc.store.view;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class CustomerStoreQualificationView {
+
+ @NotNull
+ @ApiModelProperty(value = "资质类型")
+ private Integer type;
+
+ @ApiModelProperty(value = "资质名称")
+ private String name;
+
+ @ApiModelProperty(value = "资质图片")
+ private String imageUrl;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreView.java b/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreView.java
new file mode 100644
index 0000000..b68087a
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreView.java
@@ -0,0 +1,28 @@
+package com.oying.modules.pc.store.view;
+
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+@Data
+public class CustomerStoreView {
+
+ private String name;
+
+ private String logoUrl;
+
+ private String description;
+
+ private String address;
+
+ private String businessHours;
+
+ private String contactPhone;
+
+ private Integer score;
+
+ private Integer deliveryDuration;
+
+ private Integer monthlySales;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreCategoryMerchantView.java b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreCategoryMerchantView.java
new file mode 100644
index 0000000..05d0450
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreCategoryMerchantView.java
@@ -0,0 +1,23 @@
+package com.oying.modules.pc.store.view;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class StoreCategoryMerchantView {
+
+ private Long categoryId;
+
+ private Long storeId;
+
+ private Long parentId;
+
+ private String name;
+
+ private Integer sortWeight;
+
+ private Integer active;
+
+ private List<StoreCategoryMerchantView> children;
+}
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
new file mode 100644
index 0000000..d5c970f
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreMerchantView.java
@@ -0,0 +1,48 @@
+package com.oying.modules.pc.store.view;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalTime;
+
+@Data
+public class StoreMerchantView {
+
+ @ApiModelProperty(value = "ID")
+ private Long storeId;
+
+ @ApiModelProperty(value = "平台类目")
+ private Long platformCategoryId;
+
+ @ApiModelProperty(value = "店铺名称")
+ private String storeName;
+
+ private String logoUrl;
+
+ @ApiModelProperty(value = "店铺描述")
+ private String description;
+
+ @ApiModelProperty(value = "联系电话")
+ private String contactPhone;
+
+ @ApiModelProperty(value = "营业开始时间")
+ private LocalTime openTime;
+
+ @ApiModelProperty(value = "营业结束时间")
+ private LocalTime closeTime;
+
+ @ApiModelProperty(value = "详细地址")
+ private String address;
+
+ @ApiModelProperty(value = "经度")
+ private Double longitude;
+
+ @ApiModelProperty(value = "纬度")
+ private Double latitude;
+
+ @ApiModelProperty(value = "营业半径(米)")
+ private Integer radius;
+
+ private Integer status;
+
+}
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
new file mode 100644
index 0000000..0c45390
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreQualificationMerchantView.java
@@ -0,0 +1,24 @@
+package com.oying.modules.pc.store.view;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class StoreQualificationMerchantView {
+
+ @NotNull
+ @ApiModelProperty(value = "资质ID")
+ private Long id;
+
+ @ApiModelProperty(value = "资质类型")
+ private Integer type;
+
+ @ApiModelProperty(value = "资质名称")
+ private String name;
+
+ @ApiModelProperty(value = "资质图片")
+ private String imageUrl;
+
+}
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
new file mode 100644
index 0000000..1a93719
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/store/view/StoreSimpleView.java
@@ -0,0 +1,16 @@
+package com.oying.modules.pc.store.view;
+
+import lombok.Data;
+
+@Data
+public class StoreSimpleView {
+
+ private Long id;
+
+ private String name;
+
+ private String logoUrl;
+
+ private Integer status;
+
+}
diff --git a/oying-system/src/main/java/com/oying/modules/pc/utils/WrapperUtils.java b/oying-system/src/main/java/com/oying/modules/pc/utils/WrapperUtils.java
new file mode 100644
index 0000000..304b570
--- /dev/null
+++ b/oying-system/src/main/java/com/oying/modules/pc/utils/WrapperUtils.java
@@ -0,0 +1,18 @@
+package com.oying.modules.pc.utils;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.oying.base.BaseEntity;
+
+public class WrapperUtils {
+
+ public static <T> UpdateWrapper<T> baseUpdateWrapper(Long id, Long updateBy) {
+ return new UpdateWrapper<T>()
+ .eq("id", id)
+ .set("update_by", updateBy);
+ }
+
+ public static <T extends BaseEntity> LambdaUpdateWrapper<T> getBaseLambdaUpdateWrapper(Long id, Long updateBy) {
+ return new LambdaUpdateWrapper<T>();
+ }
+}
diff --git a/oying-system/src/main/java/com/oying/modules/security/rest/AuthController.java b/oying-system/src/main/java/com/oying/modules/security/rest/AuthController.java
index d6443ee..fed5323 100644
--- a/oying-system/src/main/java/com/oying/modules/security/rest/AuthController.java
+++ b/oying-system/src/main/java/com/oying/modules/security/rest/AuthController.java
@@ -102,7 +102,7 @@
}
@ApiOperation("临时授权")
- @AnonymousPostMapping(value = "/token")
+ @AnonymousGetMapping(value = "/token")
public ResponseEntity<Object> loginTest(@RequestParam String username, HttpServletRequest request) {
// 生成令牌与第三方系统获取令牌方式
JwtUserDto jwtUser = userDetailsService.loadUserByUsername(username);
diff --git a/oying-system/src/main/resources/config/application-dev.yml b/oying-system/src/main/resources/config/application-dev.yml
index 43ed09a..3ea16c0 100644
--- a/oying-system/src/main/resources/config/application-dev.yml
+++ b/oying-system/src/main/resources/config/application-dev.yml
@@ -111,8 +111,8 @@
path: /opt/oying/file/
avatar: /opt/oying/avatar/
windows:
- path: C:\oying\file\
- avatar: C:\oying\avatar\
+ path: d:\data\oying\file\
+ avatar: d:\data\oying\avatar\
# 文件大小 /M
maxSize: 100
avatarMaxSize: 5
diff --git a/oying-system/src/main/resources/config/application.yml b/oying-system/src/main/resources/config/application.yml
index d139423..568e67d 100644
--- a/oying-system/src/main/resources/config/application.yml
+++ b/oying-system/src/main/resources/config/application.yml
@@ -33,10 +33,10 @@
redis:
#数据库索引
- database: ${REDIS_DB:1}
- host: ${REDIS_HOST:127.0.0.1}
- port: ${REDIS_PORT:6379}
- password: ${REDIS_PWD:}
+ database: 16
+ host: 192.168.28.55
+ port: 6379
+ password: qwert321
#连接超时时间
timeout: 5000
# 连接池配置
diff --git a/oying-system/src/main/resources/mapper/pc/category/PlatformCategoryMapper.xml b/oying-system/src/main/resources/mapper/pc/category/PlatformCategoryMapper.xml
new file mode 100644
index 0000000..be265d3
--- /dev/null
+++ b/oying-system/src/main/resources/mapper/pc/category/PlatformCategoryMapper.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.oying.modules.pc.category.mapper.PlatformCategoryMapper">
+ <resultMap id="BaseResultMap" type="com.oying.modules.pc.category.domain.PlatformCategory">
+ <id column="category_id" property="categoryId"/>
+ <result column="parent_id" property="parentId"/>
+ <result column="name" property="name"/>
+ <result column="level" property="level"/>
+ <result column="sort_weight" property="sortWeight"/>
+ <result column="icon_id" property="iconId"/>
+ <result column="status" property="status"/>
+ <result column="active" property="active"/>
+ <result column="create_by" property="createBy"/>
+ <result column="create_time" property="createTime"/>
+ <result column="update_by" property="updateBy"/>
+ <result column="update_time" property="updateTime"/>
+ </resultMap>
+
+ <sql id="Base_Column_List">
+ category_id, parent_id, name, level, sort_weight, icon_id, status, active, create_by, create_time, update_by, update_time
+ </sql>
+
+ <select id="findAll" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from pc_platform_category
+ <where>
+ <if test="criteria.active != null">
+ and active = #{criteria.active}
+ </if>
+ </where>
+ order by category_id desc
+ </select>
+</mapper>
\ No newline at end of file
diff --git a/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml b/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml
new file mode 100644
index 0000000..43a18b8
--- /dev/null
+++ b/oying-system/src/main/resources/mapper/pc/product/ProductMapper.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.oying.modules.pc.product.mapper.ProductMapper">
+ <resultMap id="BaseResultMap" type="com.oying.modules.pc.product.domain.Product">
+ <id column="product_id" property="productId"/>
+ <result column="store_id" property="storeId"/>
+ <result column="code" property="code"/>
+ <result column="barcode" property="barcode"/>
+ <result column="name" property="name"/>
+ <result column="title" property="title"/>
+ <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="description" property="description"/>
+ <result column="price" property="price"/>
+ <result column="stock_quantity" property="stockQuantity"/>
+ <result column="min_purchase_quantity" property="minPurchaseQuantity"/>
+ <result column="warn_stock" property="warnStock"/>
+ <result column="weight" property="weight"/>
+ <result column="width" property="width"/>
+ <result column="length" property="length"/>
+ <result column="height" property="height"/>
+ <result column="deleted_flag" property="deletedFlag"/>
+ <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
+ </sql>
+
+ <select id="findAll" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from pc_product
+ <where>
+ <if test="criteria.storeId != null">
+ and store_id = #{criteria.storeId}
+ </if>
+ <if test="criteria.categoryId != null">
+ and category_id = #{criteria.categoryId}
+ </if>
+ <if test="criteria.secondCategoryId != null">
+ and second_category_id = #{criteria.secondCategoryId}
+ </if>
+ <if test="criteria.blurry != null and criteria.blurry != ''">
+ and (name like concat('%',#{criteria.blurry},'%') or title like concat('%',#{criteria.blurry},'%'))
+ </if>
+ <if test="criteria.status != null">
+ and status = #{criteria.status}
+ </if>
+ <if test="criteria.active != null">
+ and active = #{criteria.active}
+ </if>
+ </where>
+ order by product_id desc
+ </select>
+
+</mapper>
\ No newline at end of file
diff --git a/oying-system/src/main/resources/mapper/pc/search/SearchMapper.xml b/oying-system/src/main/resources/mapper/pc/search/SearchMapper.xml
new file mode 100644
index 0000000..3c8bb8d
--- /dev/null
+++ b/oying-system/src/main/resources/mapper/pc/search/SearchMapper.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+ "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.oying.modules.pc.store.mapper.StoreMapper">
+<!--
+ <resultMap id="storeWithProductResultMap" type="com.oying.modules.pc.store.domain.Store">
+ <result property="storeId" column="store_id"/>
+ <result property="merchantId" column="merchant_id"/>
+ <result property="platformCategoryId" column="platform_category_id"/>
+ <result property="storeName" column="store_name"/>
+ <result property="description" column="description"/>
+ <result property="deliveryFee" column="delivery_fee"/>
+ <result property="deliveryMinimum" column="delivery_minimum"/>
+ <result property="contactPhone" column="contact_phone"/>
+ <collection property="products" ofType="Product">
+ <id column="product_id" property="productId"/>
+ <result column="store_id" property="storeId"/>
+ <result column="title" property="title"/>
+ <result column="status" property="status"/>
+ <result column="description" property="description"/>
+ <result column="price" property="price"/>
+ <result column="stock_quantity" property="stockQuantity"/>
+ <result column="min_purchase_quantity" property="minPurchaseQuantity"/>
+ <result column="warn_stock" property="warnStock"/>
+ <result column="weight" property="weight"/>
+ <result column="version" property="version"/>
+ </collection>
+ </resultMap>
+
+ <select id="queryNearStoreWithProduct" resultMap="storeWithProductResultMap">
+ SELECT
+ s.store_id AS storeId,
+ s.store_name AS storeName,
+ s.logo_image_id AS logoImageId,
+ ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude, s.latitude)) AS distance,
+ MATCH(s.store_name) AGAINST(#{criteria.blurry}) AS storeNameMatchScore
+ FROM pc_store s inner join pc_product p ON s.store_id = p.product_id
+ WHERE
+ ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude, s.latitude)) <= #{criteria.radius}
+ AND ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude, s.latitude)) <= s.radius
+ AND s.status = 1000
+ AND p.status in (1000, 1001, 1002)
+ AND p.deleted_flag = 0
+ AND CURRENT_TIME() BETWEEN s.open_time AND s.close_time
+ <choose>
+ <when test="criteria.blurry != null and criteria.blurry != ''">
+ AND (MATCH(s.store_name) AGAINST(#{criteria.blurry} IN NATURAL LANGUAGE MODE) OR MATCH(p.title) AGAINST(#{criteria.blurry} IN NATURAL LANGUAGE MODE))
+ </when>
+ <otherwise>
+
+ </otherwise>
+ </choose>
+ </select>-->
+
+</mapper>
\ No newline at end of file
diff --git a/oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml b/oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml
new file mode 100644
index 0000000..f79f66c
--- /dev/null
+++ b/oying-system/src/main/resources/mapper/pc/store/StoreCategoryMapper.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.oying.modules.pc.store.mapper.StoreCategoryMapper">
+ <resultMap id="BaseResultMap" type="com.oying.modules.pc.store.domain.StoreCategory">
+ <id column="category_id" property="categoryId"/>
+ <result column="parent_id" property="parentId"/>
+ <result column="name" property="name"/>
+ <result column="level" property="level"/>
+ <result column="sort_weight" property="sortWeight"/>
+ <result column="icon_id" property="iconId"/>
+ <result column="status" property="status"/>
+ <result column="active" property="active"/>
+ <result column="create_by" property="createBy"/>
+ <result column="create_time" property="createTime"/>
+ <result column="update_by" property="updateBy"/>
+ <result column="update_time" property="updateTime"/>
+ </resultMap>
+
+ <sql id="Base_Column_List">
+ category_id, parent_id, name, level, sort_weight, icon_id, status, active, create_by, create_time, update_by, update_time
+ </sql>
+
+ <select id="findAll" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from pc_store_category
+ <where>
+ <if test="criteria.storeId != null ">
+ and store_id = #{criteria.storeId}
+ </if>
+ <if test="criteria.level != null ">
+ and level = #{criteria.level}
+ </if>
+ <if test="criteria.active != null ">
+ and active = #{criteria.active}
+ </if>
+ </where>
+ order by category_id desc
+ </select>
+</mapper>
\ No newline at end of file
diff --git a/oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml b/oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml
new file mode 100644
index 0000000..564abeb
--- /dev/null
+++ b/oying-system/src/main/resources/mapper/pc/store/StoreMapper.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+ "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.oying.modules.pc.store.mapper.StoreMapper">
+
+ <resultMap id="StoreResult" type="com.oying.modules.pc.store.domain.Store">
+ <result property="storeId" column="store_id"/>
+ <result property="merchantId" column="merchant_id"/>
+ <result property="platformCategoryId" column="platform_category_id"/>
+ <result property="storeType" column="store_type"/>
+ <result property="storeCode" column="store_code"/>
+ <result property="storeName" column="store_name"/>
+ <result property="businessScope" column="business_scope"/>
+ <result property="status" column="status"/>
+ <result property="logoImageId" column="logo_image_id"/>
+ <result property="coverImageId" column="cover_image_id"/>
+ <result property="description" column="description"/>
+ <result property="tags" column="tags"/>
+ <result property="deliveryFee" column="delivery_fee"/>
+ <result property="deliveryMinimum" column="delivery_minimum"/>
+ <result property="contactPhone" column="contact_phone"/>
+ <result property="openTime" column="open_time"/>
+ <result property="closeTime" column="close_time"/>
+ <result property="address" column="address"/>
+ <result property="longitude" column="longitude"/>
+ <result property="latitude" column="latitude"/>
+ <result property="geoHash" column="geo_hash"/>
+ <result property="coordinateSystem" column="coordinate_system"/>
+ <result property="radius" column="radius"/>
+ <result property="createBy" column="create_by"/>
+ <result property="createTime" column="create_time"/>
+ <result property="updateBy" column="update_by"/>
+ <result property="updateTime" column="update_time"/>
+ </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
+ </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
+ </sql>
+
+ <select id="selectStoreList" resultMap="StoreResult">
+ <include refid="selectStoreVo"/>
+ <where>
+ <if test="criteria.merchantId != null ">and merchant_id = #{criteria.merchantId}</if>
+ <if test="criteria.storeName != null and criteria.storeName != ''">
+ and store_name like concat('%', #{criteria.storeName}, '%')
+ </if>
+ <if test="criteria.status != null ">and status = #{criteria.status}</if>
+ </where>
+ </select>
+
+ <select id="selectStoreByMerchantId" resultMap="StoreResult">
+ <include refid="selectStoreVo"/>
+ where merchant_id = #{merchantId}
+ </select>
+
+ <select id="queryNearStores" resultType="com.oying.modules.pc.search.domain.dto.StoreSearchDto">
+ SELECT
+ <trim prefix="" suffix="" suffixOverrides=",">
+ s.store_id AS storeId,
+ s.store_name AS storeName,
+ s.logo_image AS logoImage,
+ <!--<if test="criteria.longitude != null and criteria.latitude != null and criteria.radius != null">
+ ST_Distance_Sphere(
+ POINT(#{criteria.longitude}, #{criteria.latitude}),
+ POINT(s.longitude, s.latitude)
+ ) AS distance,</if>
+ <if test="criteria.blurry != null and criteria.blurry != ''">
+ MATCH(s.store_name) AGAINST(#{criteria.blurry}) AS matchScore
+ </if>-->
+ </trim>
+ 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)) <= #{criteria.radius}
+ AND ST_Distance_Sphere(POINT(#{criteria.longitude}, #{criteria.latitude}), POINT(s.longitude,
+ s.latitude)) <= 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>
+ </select>
+
+</mapper>
\ No newline at end of file
diff --git a/oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml b/oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml
new file mode 100644
index 0000000..76b3c9c
--- /dev/null
+++ b/oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.oying.modules.pc.store.mapper.StoreQualificationMapper">
+ <resultMap id="BaseResultMap" type="com.oying.modules.pc.store.domain.StoreQualification">
+ <id column="qualification_id" property="qualificationId"/>
+ <result column="store_id" property="storeId"/>
+ <result column="qualification_type" property="qualificationType"/>
+ <result column="qualification_number" property="qualificationNumber"/>
+ <result column="qualification_name" property="qualificationName"/>
+ <result column="qualification_image_id" property="qualificationImageId"/>
+ <result column="start_date" property="startDate"/>
+ <result column="end_date" property="endDate"/>
+ <result column="status" property="status"/>
+ <result column="create_by" property="createBy"/>
+ <result column="create_time" property="createTime"/>
+ <result column="update_by" property="updateBy"/>
+ <result column="update_time" property="updateTime"/>
+ </resultMap>
+
+ <sql id="Base_Column_List">
+ qualification_id, store_id, qualification_type, qualification_number, qualification_name, qualification_image_id, start_date, end_date, status,
+ create_by, create_time, update_by, update_time
+ </sql>
+
+ <select id="findAll" resultMap="BaseResultMap">
+ select
+ <include refid="Base_Column_List"/>
+ from pc_store_qualification
+ <where>
+ <if test="criteria.storeId != null">
+ and store_id = #{criteria.storeId}
+ </if>
+ </where>
+ order by qualification_id desc
+ </select>
+</mapper>
\ No newline at end of file
--
Gitblit v1.9.3