From 6e0a83c55db4bae4d23a4c281946bda1d610f678 Mon Sep 17 00:00:00 2001 From: zepengdev <lzpsmith@outlook.com> Date: Sat, 14 Jun 2025 12:32:31 +0800 Subject: [PATCH] 补充前次提交的遗漏内容,前次提交SHA:a6f4dd --- oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java | 7 oying-system/src/main/java/com/oying/modules/pc/utils/ImageUtils.java | 31 oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryAssembler.java | 28 oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java | 7 oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml | 8 oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java | 32 oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java | 62 + oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreQualificationAssembler.java | 32 oying-system/src/main/java/com/oying/modules/pc/product/converter/ProductLabelAssembler.java | 26 oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductImageMapper.java | 24 oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductImage.java | 52 + oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductLabelServiceImpl.java | 133 ++++ oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java | 103 +++ oying-system/src/main/java/com/oying/modules/pc/product/view/ProductMerchantSimpleView.java | 69 ++ oying-system/src/main/java/com/oying/modules/pc/product/view/ProductSimpleView.java | 76 ++ oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreCategoryEnum.java | 28 oying-system/src/main/java/com/oying/modules/pc/store/view/CustomerStoreView.java | 65 + oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageUpdateRequest.java | 16 oying-system/src/main/java/com/oying/modules/pc/product/service/ProductLabelService.java | 86 ++ oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductImageServiceImpl.java | 173 +++++ oying-system/src/main/resources/mapper/pc/product/ProductLabelMapper.xml | 28 oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductLabel.java | 49 + oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java | 33 + oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java | 16 oying-system/src/main/java/com/oying/modules/pc/utils/BusinessHoursUtils.java | 42 + oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java | 149 ++++ oying-system/src/main/resources/mapper/pc/product/ProductImageMapper.xml | 30 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelQueryCriteria.java | 18 oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java | 2 oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreUserMapper.java | 18 oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductLabelMapper.java | 22 oying-system/src/main/java/com/oying/modules/pc/product/service/ProductImageService.java | 98 ++ oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java | 6 oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAdminService.java | 14 oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAdminServiceImpl.java | 115 +++ oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java | 25 oying-system/src/main/java/com/oying/modules/pc/common/ValueUpdate.java | 37 + oying-system/src/main/java/com/oying/modules/pc/category/domain/enums/PlatformCategoryEnum.java | 28 oying-system/src/main/java/com/oying/modules/pc/product/converter/ProductImageAssembler.java | 38 + oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreUser.java | 39 + oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageQueryCriteria.java | 30 oying-system/src/main/java/com/oying/modules/pc/product/domain/enums/ProductStatusEnum.java | 33 + oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java | 3 43 files changed, 1,894 insertions(+), 37 deletions(-) diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryAssembler.java new file mode 100644 index 0000000..556e545 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/category/converter/PlatformCategoryAssembler.java @@ -0,0 +1,28 @@ +package com.oying.modules.pc.category.converter; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +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.PlatformCategoryUpdateDto; +import com.oying.modules.pc.utils.ImageUtils; + +public class PlatformCategoryAssembler { + + public static PlatformCategory to(PlatformCategoryCreateRequest request) { + PlatformCategory platformCategory = new PlatformCategory(); + BeanUtil.copyProperties(request, platformCategory, CopyOptions.create().setIgnoreNullValue(true)); + platformCategory.setIconId(request.getIconUploadFileId()); + platformCategory.setIconUrl(ImageUtils.getPublicObjectUrl(request.getIconUploadFileId())); + return platformCategory; + } + + public static PlatformCategory to(PlatformCategoryUpdateDto updateDto) { + PlatformCategory platformCategory = new PlatformCategory(); + BeanUtil.copyProperties(updateDto, platformCategory, CopyOptions.create().setIgnoreNullValue(true)); + platformCategory.setIconId(updateDto.getIconUploadFileId()); + platformCategory.setIconUrl(ImageUtils.getPublicObjectUrl(updateDto.getIconUploadFileId())); + return platformCategory; + } + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/category/domain/enums/PlatformCategoryEnum.java b/oying-system/src/main/java/com/oying/modules/pc/category/domain/enums/PlatformCategoryEnum.java new file mode 100644 index 0000000..7c5f9fd --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/category/domain/enums/PlatformCategoryEnum.java @@ -0,0 +1,28 @@ +package com.oying.modules.pc.category.domain.enums; + +import lombok.Getter; + +@Getter +public enum PlatformCategoryEnum { + + NOT(0, "已禁用"), + YES(1, "已启用"); + + private final Integer value; + private final String reasonPhrase; + + PlatformCategoryEnum(int value, String reasonPhrase) { + this.value = value; + this.reasonPhrase = reasonPhrase; + } + + public static PlatformCategoryEnum get(Integer code) { + for (PlatformCategoryEnum value : values()) { + if (value.value.equals(code)) { + return value; + } + } + return null; + } + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/common/ValueUpdate.java b/oying-system/src/main/java/com/oying/modules/pc/common/ValueUpdate.java new file mode 100644 index 0000000..01a8cdd --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/common/ValueUpdate.java @@ -0,0 +1,37 @@ +package com.oying.modules.pc.common; + +import cn.hutool.core.util.ObjUtil; +import lombok.Data; + +/** + * 用于封装字段值的变化记录,支持泛型比较逻辑 + * @param <T> + */ +@Data +public class ValueUpdate<T> { + + private final T newValue; + private final T oldValue; + + public ValueUpdate(T newValue, T oldValue) { + this.newValue = newValue; + this.oldValue = oldValue; + } + + public boolean isChange() { + return isChange(newValue, oldValue); + } + + public boolean isChangeAndOldValueNotEmpty() { + return isChangeAndOldValueNotEmpty(newValue, oldValue); + } + + public static <T> boolean isChange(T newValue, T oldValue) { + return ObjUtil.isNotEmpty(newValue) && !newValue.equals(oldValue); + } + + public static <T> boolean isChangeAndOldValueNotEmpty(T newValue, T oldValue) { + return ObjUtil.isNotEmpty(oldValue) && isChange(newValue, oldValue); + } + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/converter/ProductImageAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/product/converter/ProductImageAssembler.java new file mode 100644 index 0000000..a08a39b --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/converter/ProductImageAssembler.java @@ -0,0 +1,38 @@ +package com.oying.modules.pc.product.converter; + +import cn.hutool.core.collection.ListUtil; +import com.oying.modules.pc.product.domain.ProductImage; +import com.oying.modules.pc.product.domain.dto.ProductImageCreateRequest; +import com.oying.modules.pc.product.domain.dto.ProductImageUpdateRequest; +import com.oying.modules.pc.utils.ImageUtils; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class ProductImageAssembler { + + public static ProductImage to(ProductImageCreateRequest request) { + ProductImage productImage = new ProductImage(); + productImage.setProductId(request.getProductId()); + productImage.setImageType(Optional.ofNullable(request.getImageType()).orElse("main")); + productImage.setCloudStorageId(request.getUploadFileId()); + productImage.setImageUrl(ImageUtils.getPublicObjectUrl(request.getUploadFileId())); + return productImage; + } + + public static List<ProductImage> toProducts(List<ProductImageCreateRequest> requests) { + return Optional.ofNullable(requests).orElse(ListUtil.empty()).stream().map(ProductImageAssembler::to).collect(Collectors.toList()); + } + + public static ProductImage to(ProductImageUpdateRequest request) { + ProductImage productImage = new ProductImage(); + productImage.setImageId(request.getImageId()); + productImage.setProductId(request.getProductId()); + productImage.setImageType(request.getImageType()); + productImage.setCloudStorageId(request.getUploadFileId()); + productImage.setImageUrl(ImageUtils.getPublicObjectUrl(request.getUploadFileId())); + return productImage; + } + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/converter/ProductLabelAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/product/converter/ProductLabelAssembler.java new file mode 100644 index 0000000..5752275 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/converter/ProductLabelAssembler.java @@ -0,0 +1,26 @@ +package com.oying.modules.pc.product.converter; + +import cn.hutool.core.collection.ListUtil; +import com.oying.modules.pc.product.domain.ProductImage; +import com.oying.modules.pc.product.domain.ProductLabel; +import com.oying.modules.pc.product.domain.dto.ProductImageCreateRequest; +import com.oying.modules.pc.product.domain.dto.ProductImageUpdateRequest; +import com.oying.modules.pc.product.domain.dto.ProductLabelCreateRequest; +import com.oying.modules.pc.utils.ImageUtils; + +import java.util.List; +import java.util.Optional; + +public class ProductLabelAssembler { + + public static ProductLabel to(ProductLabelCreateRequest request) { + ProductLabel productLabel = new ProductLabel(); + productLabel.setProductId(request.getProductId()); + productLabel.setCategoryName(request.getCategoryName()); + productLabel.setLabelName(request.getLabelName()); + productLabel.setLabelValue(request.getLabelValue()); + productLabel.setUnit(request.getUnit()); + return productLabel; + } + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductImage.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductImage.java new file mode 100644 index 0000000..a0fe7a5 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductImage.java @@ -0,0 +1,52 @@ +package com.oying.modules.pc.product.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.oying.base.BaseEntity; +import lombok.Getter; +import lombok.Setter; +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-05-28 +**/ +@Getter +@Setter +@TableName("pc_product_image") +public class ProductImage extends BaseEntity implements Serializable { + + @TableId(value = "image_id", type = IdType.AUTO) + @ApiModelProperty(value = "商品图片ID") + private Long imageId; + + @NotNull + @ApiModelProperty(value = "商品ID") + private Long productId; + + @NotNull + @ApiModelProperty(value = "桶ID") + private Long cloudStorageId; + + @NotBlank + @ApiModelProperty(value = "图片类型") + private String imageType; + + @ApiModelProperty(value = "图片地址") + private String imageUrl; + + @ApiModelProperty(value = "排序权重") + private Integer sortWeight; + + public void copy(ProductImage source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductLabel.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductLabel.java new file mode 100644 index 0000000..5c16d89 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/ProductLabel.java @@ -0,0 +1,49 @@ +package com.oying.modules.pc.product.domain; + +import com.oying.base.BaseEntity; +import lombok.Getter; +import lombok.Setter; +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-28 +**/ +@Getter +@Setter +@TableName("pc_product_label") +public class ProductLabel extends BaseEntity implements Serializable { + + @TableId(value = "label_id", type = IdType.AUTO) + @ApiModelProperty(value = "标签ID") + private Long labelId; + + @NotNull + @ApiModelProperty(value = "商品ID") + private Long productId; + + @ApiModelProperty(value = "分类名称") + private String categoryName; + + @ApiModelProperty(value = "标签名称") + private String labelName; + + @ApiModelProperty(value = "标签值") + private String labelValue; + + @ApiModelProperty(value = "单位") + private String unit; + + public void copy(ProductLabel source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageQueryCriteria.java new file mode 100644 index 0000000..6feb0a8 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageQueryCriteria.java @@ -0,0 +1,30 @@ +package com.oying.modules.pc.product.domain.dto; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** +* @author lzp +* @date 2025-05-28 +**/ +@Data +public class ProductImageQueryCriteria{ + + @ApiModelProperty(value = "商品图片ID") + private Long imageId; + + @ApiModelProperty(value = "商品ID") + private Long productId; + + @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/ProductImageUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageUpdateRequest.java new file mode 100644 index 0000000..edab129 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductImageUpdateRequest.java @@ -0,0 +1,16 @@ +package com.oying.modules.pc.product.domain.dto; + +import lombok.Data; + +@Data +public class ProductImageUpdateRequest { + + private Long imageId; + + private Long productId; + + private Long uploadFileId; + + private String imageType; + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelQueryCriteria.java new file mode 100644 index 0000000..f13cacc --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductLabelQueryCriteria.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-28 +**/ +@Data +public class ProductLabelQueryCriteria{ + + @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/ProductQueryCriteria.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java index c0db31f..644f932 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java +++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/dto/ProductQueryCriteria.java @@ -25,6 +25,8 @@ private Long secondCategoryId; + private Integer active; + @ApiModelProperty(value = "页码", example = "1") private Integer page = 1; diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/domain/enums/ProductStatusEnum.java b/oying-system/src/main/java/com/oying/modules/pc/product/domain/enums/ProductStatusEnum.java new file mode 100644 index 0000000..1972d20 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/domain/enums/ProductStatusEnum.java @@ -0,0 +1,33 @@ +package com.oying.modules.pc.product.domain.enums; + +import lombok.Getter; + +@Getter +public enum ProductStatusEnum { + + DRAFT(1000, "创建中"), + PENDING(1001, "待审核"), + UNDER_REVIEW(1002, "审核中"), + REJECTED(1003, "拒绝"), + APPROVED(1004, "同意"), + AVAILABLE(2100, "在售"), + NO_AVAILABLE(2101, "停售"), + BANNED(3000, "禁止售卖"); + + private final Integer value; + private final String reasonPhrase; + + ProductStatusEnum(int value, String reasonPhrase) { + this.value = value; + this.reasonPhrase = reasonPhrase; + } + + public static ProductStatusEnum get(Integer code) { + for (ProductStatusEnum value : values()) { + if (value.value.equals(code)) { + return value; + } + } + return null; + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductImageMapper.java b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductImageMapper.java new file mode 100644 index 0000000..6d7fae9 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductImageMapper.java @@ -0,0 +1,24 @@ +package com.oying.modules.pc.product.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.product.domain.ProductImage; +import com.oying.modules.pc.product.domain.dto.ProductImageQueryCriteria; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author lzp + * @date 2025-05-28 + **/ +@Mapper +public interface ProductImageMapper extends BaseMapper<ProductImage> { + + IPage<ProductImage> findAll(@Param("criteria") ProductImageQueryCriteria criteria, Page<Object> page); + + List<ProductImage> findAll(@Param("criteria") ProductImageQueryCriteria criteria); + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductLabelMapper.java b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductLabelMapper.java new file mode 100644 index 0000000..aba5026 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/mapper/ProductLabelMapper.java @@ -0,0 +1,22 @@ +package com.oying.modules.pc.product.mapper; + +import com.oying.modules.pc.product.domain.ProductLabel; +import com.oying.modules.pc.product.domain.dto.ProductLabelQueryCriteria; +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-28 +**/ +@Mapper +public interface ProductLabelMapper extends BaseMapper<ProductLabel> { + + IPage<ProductLabel> findAll(@Param("criteria") ProductLabelQueryCriteria criteria, Page<Object> page); + + List<ProductLabel> findAll(@Param("criteria") ProductLabelQueryCriteria criteria); +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java index fae7204..38a2427 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java +++ b/oying-system/src/main/java/com/oying/modules/pc/product/rest/ProductCustomerController.java @@ -63,7 +63,7 @@ PageResult<ProductCustomerView> viewPageResult = new PageResult<>( productList.stream().map(i -> { ProductCustomerView view = new ProductCustomerView(); - BeanUtils.copyProperties(i, view); + BeanUtil.copyProperties(i, view); return view; }).collect(Collectors.toList()), productPageResult.getTotalElements()); @@ -76,6 +76,7 @@ public ResponseEntity<?> getProductDetails(@PathVariable Long productId) { Product product = productService.getById(productId); ProductCustomerView customerView = new ProductCustomerView(); + BeanUtil.copyProperties(product, customerView); if (ObjUtil.isNotEmpty(product)) { customerView.setImages(productImageService.queryImagesByProductId(productId).stream().map(i -> { ProductImageCustomerView imageCustomerView = new ProductImageCustomerView(); diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAdminService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAdminService.java new file mode 100644 index 0000000..5a5ab3c --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductAdminService.java @@ -0,0 +1,14 @@ +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 ProductAdminService { + + void create(ProductMerchantCreateRequest request); + void update(ProductMerchantUpdateRequest request); + void delete(List<Long> ids); + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductImageService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductImageService.java new file mode 100644 index 0000000..8086b5a --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductImageService.java @@ -0,0 +1,98 @@ +package com.oying.modules.pc.product.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.oying.modules.pc.product.domain.ProductImage; +import com.oying.modules.pc.product.domain.dto.ProductImageCreateRequest; +import com.oying.modules.pc.product.domain.dto.ProductImageQueryCriteria; +import com.oying.modules.pc.product.domain.dto.ProductImageUpdateRequest; +import com.oying.utils.PageResult; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * @author lzp + * @description 服务接口 + * @date 2025-05-28 + **/ +public interface ProductImageService extends IService<ProductImage> { + + /** + * 查询数据分页 + * + * @param criteria 条件 + * @param page 分页参数 + * @return PageResult + */ + PageResult<ProductImage> queryAll(ProductImageQueryCriteria criteria, Page<Object> page); + + /** + * 查询所有数据不分页 + * + * @param criteria 条件参数 + * @return List<ProductImageDto> + */ + List<ProductImage> queryAll(ProductImageQueryCriteria criteria); + + /** + * 查询多条ID关联数据 + * + * @param ids / + * @return List<ProductImage> + */ + List<ProductImage> queryBatchIds(List<Long> ids); + + /** + * 查询商品的所有图片 + * + * @param productId / + * @return List<ProductImage> + */ + List<ProductImage> queryImagesByProductId(Long productId); + + /** + * 创建 + * + * @param request / + */ + void create(ProductImageCreateRequest request); + + /** + * 批量创建 + * + * @param requests / + */ + void batchCreate(List<ProductImageCreateRequest> requests); + + /** + * 编辑 + * + * @param request / + */ + void update(ProductImageUpdateRequest request); + + /** + * 编辑 + * + * @param requests / + */ + void batchUpdate(List<ProductImageUpdateRequest> requests); + + /** + * 多选删除 + * + * @param ids / + */ + void deleteAll(List<Long> ids); + + /** + * 导出数据 + * + * @param all 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List<ProductImage> all, HttpServletResponse response) throws IOException; +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductLabelService.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductLabelService.java new file mode 100644 index 0000000..555b399 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/ProductLabelService.java @@ -0,0 +1,86 @@ +package com.oying.modules.pc.product.service; + +import com.oying.modules.pc.product.domain.ProductLabel; +import com.oying.modules.pc.product.domain.dto.ProductLabelQueryCriteria; +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-28 +**/ +public interface ProductLabelService extends IService<ProductLabel> { + + /** + * 查询数据分页 + * @param criteria 条件 + * @param page 分页参数 + * @return PageResult + */ + PageResult<ProductLabel> queryAll(ProductLabelQueryCriteria criteria, Page<Object> page); + + /** + * 查询所有数据不分页 + * @param criteria 条件参数 + * @return List<ProductLabel> + */ + List<ProductLabel> queryAll(ProductLabelQueryCriteria criteria); + + /** + * 查询 + * @param ids / + * @return List<ProductLabel> + */ + List<ProductLabel> queryBatchIds(List<Long> ids); + + /** + * 查询商品的所有标签 + * @param productId / + * @return List<ProductLabel> + */ + List<ProductLabel> queryLabelsByProductId(Long productId); + + /** + * 创建 + * @param resources / + */ + void create(ProductLabel resources); + + /** + * 批量创建 + * @param resources / + */ + void batchCreate(List<ProductLabel> resources); + + /** + * 编辑 + * @param resources / + */ + void update(ProductLabel resources); + + /** + * 编辑 + * @param resources / + */ + void batchUpdate(List<ProductLabel> resources); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(List<Long> ids); + + /** + * 导出数据 + * @param all 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List<ProductLabel> all, HttpServletResponse response) throws IOException; +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAdminServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAdminServiceImpl.java new file mode 100644 index 0000000..aada193 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductAdminServiceImpl.java @@ -0,0 +1,115 @@ +package com.oying.modules.pc.product.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjUtil; +import com.oying.exception.EntityExistException; +import com.oying.exception.EntityNotFoundException; +import com.oying.modules.pc.product.converter.ProductImageAssembler; +import com.oying.modules.pc.product.converter.ProductLabelAssembler; +import com.oying.modules.pc.product.domain.Product; +import com.oying.modules.pc.product.domain.ProductImage; +import com.oying.modules.pc.product.domain.ProductLabel; +import com.oying.modules.pc.product.domain.dto.ProductImageCreateRequest; +import com.oying.modules.pc.product.domain.dto.ProductMerchantCreateRequest; +import com.oying.modules.pc.product.domain.dto.ProductMerchantUpdateRequest; +import com.oying.modules.pc.product.domain.enums.ProductStatusEnum; +import com.oying.modules.pc.product.service.ProductAdminService; +import com.oying.modules.pc.product.service.ProductImageService; +import com.oying.modules.pc.product.service.ProductLabelService; +import com.oying.modules.pc.product.service.ProductService; +import com.oying.modules.pc.utils.ImageUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ProductAdminServiceImpl implements ProductAdminService { + + private final ProductService productService; + private final ProductImageService productImageService; + private final ProductLabelService productLabelService; + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(ProductMerchantCreateRequest request) { + Product product = new Product(); + BeanUtils.copyProperties(request, product); + request.getImages().stream().findFirst().map(ProductImageCreateRequest::getUploadFileId) + .ifPresent(id -> { + product.setMainImageId(id.toString()); + product.setMainImageUrl(ImageUtils.getPublicObjectUrl(id)); + }); + product.setStatus(ProductStatusEnum.DRAFT.getValue()); + productService.create(product); + + List<ProductImage> productImages = request.getImages().stream().map(i -> { + i.setProductId(product.getProductId()); + return ProductImageAssembler.to(i); + }).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(productImages)) { + productImageService.saveBatch(productImages); + } + + List<ProductLabel> productLabels = request.getLabels().stream().map(i -> { + i.setProductId(product.getProductId()); + return ProductLabelAssembler.to(i); + }).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(productLabels)) { + productLabelService.saveBatch(productLabels); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ProductMerchantUpdateRequest request) { + Product existingProduct = this.findOrThrow(request.getProductId()); + this.processImagesUpdate(request); + this.processLabelsUpdate(request); + BeanUtils.copyProperties(request, existingProduct); + productService.update(existingProduct); + } + + @Transactional + @Override + public void delete(List<Long> ids) { + productService.deleteAll(ids); + } + + private Product findOrThrow(Long productId) { + Product existingProduct = productService.getById(productId); + if (ObjUtil.isEmpty(existingProduct)) { + throw new EntityNotFoundException(Product.class, "id", Optional.ofNullable(productId).map(Object::toString).orElse("null")); + } + return existingProduct; + } + + private void processImagesUpdate(ProductMerchantUpdateRequest request) { + if (CollectionUtil.isNotEmpty(request.getDeletedImageIds())) { + productImageService.deleteAll(request.getDeletedImageIds()); + } + if (CollectionUtil.isNotEmpty(request.getUpdatedImages())) { + productImageService.batchUpdate(request.getUpdatedImages()); + } + if (CollectionUtil.isNotEmpty(request.getNewImages())) { + productImageService.batchCreate(request.getNewImages()); + } + } + + private void processLabelsUpdate(ProductMerchantUpdateRequest request) { + if (CollectionUtil.isNotEmpty(request.getDeletedLabelIds())) { + productLabelService.deleteAll(request.getDeletedLabelIds()); + } + if (CollectionUtil.isNotEmpty(request.getUpdatedLabels())) { + productLabelService.batchUpdate(request.getUpdatedLabels()); + } + if (CollectionUtil.isNotEmpty(request.getNewLabels())) { + productLabelService.batchCreate(request.getNewLabels()); + } + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductImageServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductImageServiceImpl.java new file mode 100644 index 0000000..6117247 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductImageServiceImpl.java @@ -0,0 +1,173 @@ +package com.oying.modules.pc.product.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ObjUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.oying.exception.EntityExistException; +import com.oying.exception.EntityNotFoundException; +import com.oying.modules.pc.common.ValueUpdate; +import com.oying.modules.pc.product.converter.ProductImageAssembler; +import com.oying.modules.pc.product.domain.ProductImage; +import com.oying.modules.pc.product.domain.dto.ProductImageCreateRequest; +import com.oying.modules.pc.product.domain.dto.ProductImageQueryCriteria; +import com.oying.modules.pc.product.domain.dto.ProductImageUpdateRequest; +import com.oying.modules.pc.product.mapper.ProductImageMapper; +import com.oying.modules.pc.product.service.ProductImageService; +import com.oying.modules.pc.store.domain.StoreQualification; +import com.oying.service.BucketStorageService; +import com.oying.utils.FileUtil; +import com.oying.utils.PageResult; +import com.oying.utils.PageUtil; +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.*; +import java.util.stream.Collectors; + +/** + * @author lzp + * @description 服务实现 + * @date 2025-05-28 + **/ +@Service +@RequiredArgsConstructor +public class ProductImageServiceImpl extends ServiceImpl<ProductImageMapper, ProductImage> implements ProductImageService { + + private final ProductImageMapper productImageMapper; + private final BucketStorageService bucketStorageService; + + @Override + public PageResult<ProductImage> queryAll(ProductImageQueryCriteria criteria, Page<Object> page) { + return PageUtil.toPage(productImageMapper.findAll(criteria, page)); + } + + @Override + public List<ProductImage> queryAll(ProductImageQueryCriteria criteria) { + return productImageMapper.findAll(criteria); + } + + @Override + public List<ProductImage> queryBatchIds(List<Long> ids) { + LambdaQueryWrapper<ProductImage> lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.in(ProductImage::getImageId, ids); + return productImageMapper.selectList(lambdaQueryWrapper); + } + + @Override + public List<ProductImage> queryImagesByProductId(Long productId) { + if (productId == null) { + return ListUtil.empty(); + } + LambdaQueryWrapper<ProductImage> wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ProductImage::getProductId, productId); + return productImageMapper.selectList(wrapper); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(ProductImageCreateRequest request) { + productImageMapper.insert(ProductImageAssembler.to(request)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void batchCreate(List<ProductImageCreateRequest> requests) { + this.saveBatch(ProductImageAssembler.toProducts(requests)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ProductImageUpdateRequest request) { + + Long updatedImageId = request.getImageId(); + ProductImage existingProductImage = this.getById(updatedImageId); + if (ObjUtil.isEmpty(existingProductImage)) { + throw new EntityNotFoundException(ProductImage.class, "imageId", Optional.ofNullable(updatedImageId).map(Object::toString).orElse("null")); + } + + // 新的图片数据 + ProductImage newProductImage = ProductImageAssembler.to(request); + // 新的图片数据 + ValueUpdate<Long> cloudStorageUpdate = new ValueUpdate<>(newProductImage.getCloudStorageId(), existingProductImage.getCloudStorageId()); + // 填充新的数据 + existingProductImage.copy(newProductImage); + productImageMapper.updateById(existingProductImage); + // 删除旧图片原纪录 + if (cloudStorageUpdate.isChangeAndOldValueNotEmpty()) { + bucketStorageService.deleteAll(ListUtil.toList(cloudStorageUpdate.getOldValue())); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void batchUpdate(List<ProductImageUpdateRequest> requests) { + + List<Long> updatedIds = requests.stream().map(ProductImageUpdateRequest::getImageId).collect(Collectors.toList()); + List<ProductImage> existingProductImages = this.queryBatchIds(updatedIds); + if (CollectionUtil.isEmpty(existingProductImages)) { + throw new EntityNotFoundException(ProductImage.class, "imageIds", updatedIds.toString()); + } + + Map<Long, ProductImageUpdateRequest> requestMap = requests.stream().collect(Collectors.toMap( + ProductImageUpdateRequest::getImageId, + productImageUpdateRequest -> productImageUpdateRequest + ) + ); + + List<Long> deleteCloudStorageIds = existingProductImages.stream().filter(i -> { + Long newCloudStorageId = requestMap.get(i.getImageId()).getUploadFileId(); + return ValueUpdate.isChangeAndOldValueNotEmpty(newCloudStorageId, i.getCloudStorageId()); + }).map(ProductImage::getImageId).collect(Collectors.toList()); + + // 填充新的数据 + for (ProductImage existingProductImage : existingProductImages) { + ProductImage newProductImage = ProductImageAssembler.to(requestMap.get(existingProductImage.getImageId())); + existingProductImage.copy(newProductImage); + } + this.updateBatchById(existingProductImages); + // 删除旧图片原纪录 + if (CollectionUtil.isNotEmpty(deleteCloudStorageIds)) { + bucketStorageService.deleteAll(deleteCloudStorageIds); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAll(List<Long> ids) { + List<ProductImage> existingProductImages = this.queryBatchIds(ids); + if (CollectionUtil.isEmpty(existingProductImages)) { + throw new EntityNotFoundException(ProductImage.class, "productImageIds", ids.toString()); + } + productImageMapper.deleteBatchIds(ids); + // 删除图片原纪录 + List<Long> deleteCloudStorageIds = existingProductImages.stream().map(ProductImage::getCloudStorageId).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(deleteCloudStorageIds)) { + bucketStorageService.deleteAll(deleteCloudStorageIds); + } + } + + @Override + public void download(List<ProductImage> all, HttpServletResponse response) throws IOException { + List<Map<String, Object>> list = new ArrayList<>(); + for (ProductImage productImage : all) { + Map<String, Object> map = new LinkedHashMap<>(); + map.put("商品ID", productImage.getProductId()); + map.put("桶ID", productImage.getCloudStorageId()); + map.put("图片key", productImage.getImageType()); + map.put("图片地址", productImage.getImageUrl()); + map.put("排序权重", productImage.getSortWeight()); + map.put("创建人", productImage.getCreateBy()); + map.put("创建日期", productImage.getCreateTime()); + map.put("修改人", productImage.getUpdateBy()); + map.put("修改时间", productImage.getUpdateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductLabelServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductLabelServiceImpl.java new file mode 100644 index 0000000..5b0048a --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductLabelServiceImpl.java @@ -0,0 +1,133 @@ +package com.oying.modules.pc.product.service.impl; + +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ObjUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.oying.exception.EntityExistException; +import com.oying.exception.EntityNotFoundException; +import com.oying.modules.pc.product.domain.ProductLabel; +import com.oying.modules.pc.product.domain.dto.ProductLabelQueryCriteria; +import com.oying.modules.pc.product.mapper.ProductLabelMapper; +import com.oying.modules.pc.product.service.ProductLabelService; +import com.oying.utils.FileUtil; +import com.oying.utils.PageResult; +import com.oying.utils.PageUtil; +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; +import java.util.stream.Collectors; + +/** + * @author lzp + * @description 服务实现 + * @date 2025-05-28 + **/ +@Service +@RequiredArgsConstructor +public class ProductLabelServiceImpl extends ServiceImpl<ProductLabelMapper, ProductLabel> implements ProductLabelService { + + private final ProductLabelMapper productLabelMapper; + + @Override + public PageResult<ProductLabel> queryAll(ProductLabelQueryCriteria criteria, Page<Object> page) { + return PageUtil.toPage(productLabelMapper.findAll(criteria, page)); + } + + @Override + public List<ProductLabel> queryAll(ProductLabelQueryCriteria criteria) { + return productLabelMapper.findAll(criteria); + } + + @Override + public List<ProductLabel> queryBatchIds(List<Long> ids) { + LambdaQueryWrapper<ProductLabel> wrapper = new LambdaQueryWrapper<>(); + wrapper.in(ProductLabel::getLabelId, ids); + return productLabelMapper.selectList(wrapper); + } + + @Override + public List<ProductLabel> queryLabelsByProductId(Long productId) { + if (productId == null) { + return ListUtil.empty(); + } + LambdaQueryWrapper<ProductLabel> wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(ProductLabel::getProductId, productId); + return productLabelMapper.selectList(wrapper); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(ProductLabel resources) { + productLabelMapper.insert(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void batchCreate(List<ProductLabel> resources) { + this.saveBatch(resources); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ProductLabel resources) { + ProductLabel productLabel = getById(resources.getLabelId()); + productLabel.copy(resources); + productLabelMapper.updateById(productLabel); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void batchUpdate(List<ProductLabel> resources) { + + List<Long> updateIds = resources.stream().map(ProductLabel::getLabelId).collect(Collectors.toList()); + List<ProductLabel> existingProductLabels = this.queryBatchIds(updateIds); + if (ObjUtil.isEmpty(existingProductLabels)) { + throw new EntityNotFoundException(ProductLabel.class, "labelId", updateIds.toString()); + } + + Map<Long, ProductLabel> longProductLabelMap = resources.stream() + .collect(Collectors.toMap( + ProductLabel::getLabelId, + productLabel -> productLabel) + ); + + for (ProductLabel existingProductLabel : existingProductLabels) { + existingProductLabel.copy(longProductLabelMap.get(existingProductLabel.getLabelId())); + } + + this.updateBatchById(existingProductLabels); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteAll(List<Long> ids) { + productLabelMapper.deleteBatchIds(ids); + } + + @Override + public void download(List<ProductLabel> all, HttpServletResponse response) throws IOException { + List<Map<String, Object>> list = new ArrayList<>(); + for (ProductLabel productLabel : all) { + Map<String, Object> map = new LinkedHashMap<>(); + map.put("商品ID", productLabel.getProductId()); + map.put(" categoryName", productLabel.getCategoryName()); + map.put("标签名称", productLabel.getLabelName()); + map.put("标签值", productLabel.getLabelValue()); + map.put("创建人", productLabel.getCreateBy()); + map.put("创建时间", productLabel.getCreateTime()); + map.put("修改人", productLabel.getUpdateBy()); + map.put("修改时间", productLabel.getUpdateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java new file mode 100644 index 0000000..1248406 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/product/service/impl/ProductMerchantServiceImpl.java @@ -0,0 +1,149 @@ +package com.oying.modules.pc.product.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjUtil; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.oying.exception.EntityExistException; +import com.oying.exception.EntityNotFoundException; +import com.oying.modules.pc.product.converter.ProductImageAssembler; +import com.oying.modules.pc.product.converter.ProductLabelAssembler; +import com.oying.modules.pc.product.domain.Product; +import com.oying.modules.pc.product.domain.ProductImage; +import com.oying.modules.pc.product.domain.ProductLabel; +import com.oying.modules.pc.product.domain.dto.ProductImageCreateRequest; +import com.oying.modules.pc.product.domain.dto.ProductLabelCreateRequest; +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.enums.ProductStatusEnum; +import com.oying.modules.pc.product.service.ProductImageService; +import com.oying.modules.pc.product.service.ProductLabelService; +import com.oying.modules.pc.product.service.ProductMerchantService; +import com.oying.modules.pc.product.service.ProductService; +import com.oying.modules.pc.utils.ImageUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ProductMerchantServiceImpl implements ProductMerchantService { + + private final ProductService productService; + private final ProductImageService productImageService; + private final ProductLabelService productLabelService; + + @Override + @Transactional(rollbackFor = Exception.class) + public void create(ProductMerchantCreateRequest request) { + Product product = new Product(); + BeanUtils.copyProperties(request, product); + request.getImages().stream().findFirst().map(ProductImageCreateRequest::getUploadFileId) + .ifPresent(id -> { + product.setMainImageId(id.toString()); + product.setMainImageUrl(ImageUtils.getPublicObjectUrl(id)); + }); + product.setStatus(ProductStatusEnum.DRAFT.getValue()); + productService.create(product); + + List<ProductImage> productImages = request.getImages().stream().map(i -> { + i.setProductId(product.getProductId()); + return ProductImageAssembler.to(i); + }).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(productImages)) { + productImageService.saveBatch(productImages); + } + + List<ProductLabel> productLabels = request.getLabels().stream().map(i -> { + i.setProductId(product.getProductId()); + return ProductLabelAssembler.to(i); + }).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(productLabels)) { + productLabelService.saveBatch(productLabels); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(ProductMerchantUpdateRequest request) { + Product existingProduct = this.findOrThrow(request.getProductId()); + this.processImagesUpdate(request); + this.processLabelsUpdate(request); + BeanUtils.copyProperties(request, existingProduct); + productService.update(existingProduct); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateImages(ProductMerchantUpdateRequest request) { + this.findOrThrow(request.getProductId()); + this.processImagesUpdate(request); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateLabels(ProductMerchantUpdateRequest request) { + this.findOrThrow(request.getProductId()); + this.processImagesUpdate(request); + } + + @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, ProductStatusEnum.AVAILABLE.getValue()); + productService.update(wrapper); + } + + @Override + public void takeOffShelf(Long productId) { + LambdaUpdateWrapper<Product> wrapper = new LambdaUpdateWrapper<Product>() + .eq(Product::getProductId, productId) + .set(Product::getStatus, ProductStatusEnum.NO_AVAILABLE.getValue()); + productService.update(wrapper); + } + + private Product findOrThrow(Long productId) { + Product existingProduct = productService.getById(productId); + if (ObjUtil.isEmpty(existingProduct)) { + throw new EntityNotFoundException(Product.class, "id", Optional.ofNullable(productId).map(Object::toString).orElse("null")); + } + return existingProduct; + } + + private void processImagesUpdate(ProductMerchantUpdateRequest request) { + if (CollectionUtil.isNotEmpty(request.getDeletedImageIds())) { + productImageService.deleteAll(request.getDeletedImageIds()); + } + if (CollectionUtil.isNotEmpty(request.getUpdatedImages())) { + productImageService.batchUpdate(request.getUpdatedImages()); + } + if (CollectionUtil.isNotEmpty(request.getNewImages())) { + List<ProductImageCreateRequest> newImages = request.getNewImages().stream().peek(i->{i.setProductId(request.getProductId());}).collect(Collectors.toList()); + productImageService.batchCreate(newImages); + } + } + + private void processLabelsUpdate(ProductMerchantUpdateRequest request) { + if (CollectionUtil.isNotEmpty(request.getDeletedLabelIds())) { + productLabelService.deleteAll(request.getDeletedLabelIds()); + } + if (CollectionUtil.isNotEmpty(request.getUpdatedLabels())) { + productLabelService.batchUpdate(request.getUpdatedLabels()); + } + if (CollectionUtil.isNotEmpty(request.getNewLabels())) { + List<ProductLabel> newLabels = request.getNewLabels().stream().peek(i->{i.setProductId(request.getProductId());}).collect(Collectors.toList()); + productLabelService.batchCreate(newLabels); + } + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java index 521debc..da2fed3 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java +++ b/oying-system/src/main/java/com/oying/modules/pc/product/view/ProductCustomerView.java @@ -27,6 +27,12 @@ @ApiModelProperty(value = "店铺ID") private Long storeId; + @ApiModelProperty(value = "条形码") + private String barcode; + + @ApiModelProperty(value = "商品名称") + private String name; + @ApiModelProperty(value = "商品标题") private String title; @@ -42,6 +48,33 @@ @ApiModelProperty(value = "销售价格") private BigDecimal price; + @ApiModelProperty(value = "库存数量") + private Integer stockQuantity; + + @ApiModelProperty(value = "起售数量") + private Integer minPurchaseQuantity; + + @ApiModelProperty(value = "重量(单位:g)") + private Integer weight; + + @ApiModelProperty(value = "宽度(单位:厘米)") + private Integer width; + + @ApiModelProperty(value = "长度(单位:厘米)") + private Integer length; + + @ApiModelProperty(value = "高度(单位:厘米)") + private Integer height; + + @ApiModelProperty(value = "是否支持退货") + private Integer returns; + + @ApiModelProperty(value = "是否支持自提") + private Integer selfPickup; + + @ApiModelProperty(value = "版本号") + private Long version; + @ApiModelProperty(value = "月销售量") private Integer monthlySales = 0; 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 index b558519..5c72d2a 100644 --- 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 @@ -1,5 +1,6 @@ package com.oying.modules.pc.product.view; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; @@ -12,11 +13,73 @@ @Data public class ProductMerchantSimpleView { + @ApiModelProperty(value = "ID") private Long productId; + + @ApiModelProperty(value = "店铺ID") + private Long storeId; + + @ApiModelProperty(value = "条形码") + private String barcode; + + @ApiModelProperty(value = "商品名称") private String name; - private BigDecimal price; - private Integer stockQuantity; - private Integer sold; + + @ApiModelProperty(value = "商品标题") + private String title; + + @ApiModelProperty(value = "一级分类ID") + private Long categoryId; + + @ApiModelProperty(value = "二级分类ID") + private Long secondCategoryId; + + @ApiModelProperty(value = "状态") private Integer status; + @ApiModelProperty(value = "主图片") + private String mainImageId; + + @ApiModelProperty(value = "主图地址") + private String mainImageUrl; + + @ApiModelProperty(value = "商品描述") + private String description; + + @ApiModelProperty(value = "销售价格") + private BigDecimal price; + + @ApiModelProperty(value = "库存数量") + private Integer stockQuantity; + + @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; + + @ApiModelProperty(value = "是否支持退货") + private Integer returns; + + @ApiModelProperty(value = "是否支持自提") + private Integer selfPickup; + + @ApiModelProperty(value = "是否删除") + private Integer deletedFlag; + + @ApiModelProperty(value = "版本号") + private Long version; + } 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 index c7df610..48fba6a 100644 --- 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 @@ -1,5 +1,8 @@ package com.oying.modules.pc.product.view; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + import java.math.BigDecimal; /** @@ -7,15 +10,76 @@ * @author lzp * @date 2025-04-25 */ +@Data public class ProductSimpleView { + @ApiModelProperty(value = "商品ID") private Long productId; - private String productTitle; - private String mainImage; - private BigDecimal price; - private BigDecimal originalPrice; // 原价(用于显示划线价) - //private Double rating; // 评分 - //private Integer monthlySales; // 月销量 + @ApiModelProperty(value = "店铺ID") + private Long storeId; + + @ApiModelProperty(value = "条形码") + private String barcode; + + @ApiModelProperty(value = "商品名称") + private String name; + + @ApiModelProperty(value = "商品标题") + private String title; + + @ApiModelProperty(value = "一级分类ID") + private Long categoryId; + + @ApiModelProperty(value = "二级分类ID") + private Long secondCategoryId; + + @ApiModelProperty(value = "状态") + private Integer status; + + @ApiModelProperty(value = "主图片") + private String mainImageId; + + @ApiModelProperty(value = "主图地址") + private String mainImageUrl; + + @ApiModelProperty(value = "商品描述") + private String description; + + @ApiModelProperty(value = "销售价格") + private BigDecimal price; + + @ApiModelProperty(value = "库存数量") + private Integer stockQuantity; + + @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; + + @ApiModelProperty(value = "是否支持退货") + private Integer returns; + + @ApiModelProperty(value = "是否支持自提") + private Integer selfPickup; + + @ApiModelProperty(value = "是否删除") + private Integer deletedFlag; + + @ApiModelProperty(value = "版本号") + private Long version; } diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java new file mode 100644 index 0000000..4d21d17 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreAssembler.java @@ -0,0 +1,32 @@ +package com.oying.modules.pc.store.converter; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +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.StoreUpdateRequest; +import com.oying.modules.pc.utils.ImageUtils; +import com.oying.utils.SecurityUtils; + +public class StoreAssembler { + + public static Store to(StoreCreateRequest request) { + Store store = new Store(); + BeanUtil.copyProperties(request, store, CopyOptions.create().setIgnoreNullValue(true)); + + store.setMerchantId(SecurityUtils.getCurrentUserId()); + Long logoUploadFileId = request.getLogoUploadFileId(); + store.setLogoImageId(logoUploadFileId); + store.setLogoImageUrl(ImageUtils.getPublicObjectUrl(logoUploadFileId)); + Long coverUploadFileId = request.getCoverUploadFileId(); + store.setCoverImageId(coverUploadFileId); + store.setCoverImageUrl(ImageUtils.getPublicObjectUrl(coverUploadFileId)); + return store; + } + + public static Store to(StoreUpdateRequest request) { + Store store = new Store(); + BeanUtil.copyProperties(request, store, CopyOptions.create().setIgnoreNullValue(true)); + return store; + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreQualificationAssembler.java b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreQualificationAssembler.java new file mode 100644 index 0000000..2ca6bbb --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/store/converter/StoreQualificationAssembler.java @@ -0,0 +1,32 @@ +package com.oying.modules.pc.store.converter; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +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.StoreQualificationUpdateRequest; +import com.oying.modules.pc.utils.ImageUtils; + +public class StoreQualificationAssembler { + + public static StoreQualification to(StoreQualificationCreateRequest request) { + StoreQualification storeQualification = new StoreQualification(); + BeanUtil.copyProperties(request, storeQualification, CopyOptions.create().setIgnoreNullValue(true)); + storeQualification.setQualificationType(request.getType()); + Long imageUploadFileId = request.getImageUploadFileId(); + storeQualification.setQualificationImageId(imageUploadFileId); + storeQualification.setQualificationImageUrl(ImageUtils.getPublicObjectUrl(imageUploadFileId)); + return storeQualification; + } + + public static StoreQualification to(StoreQualificationUpdateRequest request) { + StoreQualification storeQualification = new StoreQualification(); + BeanUtil.copyProperties(request, storeQualification, CopyOptions.create().setIgnoreNullValue(true)); + storeQualification.setQualificationType(request.getType()); + Long imageUploadFileId = request.getImageUploadFileId(); + storeQualification.setQualificationImageId(imageUploadFileId); + storeQualification.setQualificationImageUrl(ImageUtils.getPublicObjectUrl(imageUploadFileId)); + return storeQualification; + } + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreUser.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreUser.java new file mode 100644 index 0000000..591ec0b --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/StoreUser.java @@ -0,0 +1,39 @@ +package com.oying.modules.pc.store.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.oying.base.BaseEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import java.io.Serializable; + +import com.baomidou.mybatisplus.annotation.TableName; + +/** +* @author lzp +* @date 2025-06-05 +**/ +@Getter +@Setter +@TableName("sys_user_store") +public class StoreUser extends BaseEntity implements Serializable { + + @ApiModelProperty(value = "店铺ID") + private Long storeId; + + @ApiModelProperty(value = "用户ID") + private Long userId; + + @ApiModelProperty(value = "角色类型") + private String roleType; + + @ApiModelProperty(value = "权限集(备用)") + private String permissions; + + public void copy(StoreUser source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java index b94cdd0..71a83b9 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java +++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreCustomerDetailDto.java @@ -1,28 +1,80 @@ package com.oying.modules.pc.store.domain.dto; +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; + +import java.time.LocalTime; @Data public class StoreCustomerDetailDto { + @ApiModelProperty(value = "店铺ID") + private Long storeId; + + @ApiModelProperty(value = "商户ID") + private Long merchantId; + + @ApiModelProperty(value = "平台类目") + private Long platformCategoryId; + + @ApiModelProperty(value = "店铺类型:1-自营 2-加盟 3-第三方") + private Integer storeType; + + @ApiModelProperty(value = "店铺名称") private String storeName; + @ApiModelProperty(value = "状态") + private Integer status; + + @ApiModelProperty(value = "店铺logo图片Url") private String logoImageUrl; + @ApiModelProperty(value = "店铺封面图Url") private String coverImageUrl; + @ApiModelProperty(value = "店铺描述") private String description; - private String address; + @ApiModelProperty(value = "联系电话") + private String contactPhone; + + @ApiModelProperty(value = "营业开始时间") + private LocalTime openTime; + + @ApiModelProperty(value = "营业结束时间") + private LocalTime closeTime; private String businessHours; - private String contactPhone; + @ApiModelProperty(value = "详细地址") + private String address; - private Double score; + @ApiModelProperty(value = "经度") + private Double longitude; - private Integer deliveryDuration; + @ApiModelProperty(value = "纬度") + private Double latitude; - private Integer monthlySales; + @ApiModelProperty(value = "营业半径(米)") + private Integer radius; + + @ApiModelProperty(value = "是否支持退货") + private Integer returns; + + @ApiModelProperty(value = "是否支持自提") + private Integer selfPickup; + + @TableField(exist = false) + @ApiModelProperty(value = "评分") + private Double score = 0d; + + @TableField(exist = false) + @ApiModelProperty(value = "配送距离") + private Integer deliveryDuration = 0; + + @TableField(exist = false) + @ApiModelProperty(value = "月销售量") + private Integer monthlySales = 0; } diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java new file mode 100644 index 0000000..9ea552d --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/dto/StoreUpdateRequest.java @@ -0,0 +1,103 @@ +package com.oying.modules.pc.store.domain.dto; + +import com.oying.modules.pc.product.domain.Product; +import com.oying.modules.pc.store.domain.StoreQualification; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.Setter; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; + +/** + * @author lzp + * @date 2025-04-21 + **/ +@Getter +@Setter +public class StoreUpdateRequest implements Serializable { + + @ApiModelProperty(value = "店铺ID") + private Long storeId; + + @ApiModelProperty(value = "商户ID") + private Long merchantId; + + @ApiModelProperty(value = "平台类目") + private Long platformCategoryId; + + @ApiModelProperty(value = "店铺类型") + private Integer storeType; + + @ApiModelProperty(value = "店铺名称") + private String storeName; + + @ApiModelProperty(value = "状态") + private Integer status; + + @ApiModelProperty(value = "店铺logo图片") + private Long logoImageId; + + @ApiModelProperty(value = "店铺logo图片Url") + private String logoImageUrl; + + @ApiModelProperty(value = "店铺封面图") + private Long coverImageId; + + @ApiModelProperty(value = "店铺封面图Url") + private String coverImageUrl; + + @ApiModelProperty(value = "店铺描述") + private String description; + + @ApiModelProperty(value = "配送费用") + private BigDecimal deliveryFee; + + @ApiModelProperty(value = "起送金额") + private BigDecimal deliveryMinimum; + + @ApiModelProperty(value = "联系电话") + private String contactPhone; + + @ApiModelProperty(value = "营业开始时间") + private LocalTime openTime; + + @ApiModelProperty(value = "营业结束时间") + private LocalTime closeTime; + + @ApiModelProperty(value = "详细地址") + private String address; + + @ApiModelProperty(value = "经度") + private Double longitude; + + @ApiModelProperty(value = "纬度") + private Double latitude; + + @ApiModelProperty(value = "营业半径(米)") + private Integer radius; + + @ApiModelProperty(value = "是否支持退货") + private Integer returns; + + @ApiModelProperty(value = "是否支持自提") + private Integer selfPickup; + + @ApiModelProperty(value = "版本号") + private Long version; + + @ApiModelProperty(value = "删除的资质") + private List<Long> deletedQualificationIds = new ArrayList<>(); + + @ApiModelProperty(value = "修改的资质") + private List<StoreQualificationUpdateRequest> updatedQualifications = new ArrayList<>(); + + @ApiModelProperty(value = "新增的资质") + private List<StoreQualification> newQualifications = new ArrayList<>(); + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreCategoryEnum.java b/oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreCategoryEnum.java new file mode 100644 index 0000000..20a2567 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/store/domain/enums/StoreCategoryEnum.java @@ -0,0 +1,28 @@ +package com.oying.modules.pc.store.domain.enums; + +import lombok.Getter; + +@Getter +public enum StoreCategoryEnum { + + NOT(0, "已禁用"), + YES(1, "已启用"); + + private final Integer value; + private final String reasonPhrase; + + StoreCategoryEnum(int value, String reasonPhrase) { + this.value = value; + this.reasonPhrase = reasonPhrase; + } + + public static StoreCategoryEnum get(Integer code) { + for (StoreCategoryEnum value : values()) { + if (value.value.equals(code)) { + return value; + } + } + return null; + } + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreUserMapper.java b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreUserMapper.java new file mode 100644 index 0000000..4eb8732 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/store/mapper/StoreUserMapper.java @@ -0,0 +1,18 @@ +package com.oying.modules.pc.store.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.oying.modules.pc.store.domain.StoreUser; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Mapper; + +/** +* @author lzp +* @date 2025-06-05 +**/ +@Mapper +public interface StoreUserMapper extends BaseMapper<StoreUser> { + + @Insert("INSERT INTO sys_user_store(store_id, user_id, role_type, create_by, permissions, create_time, update_by, update_time) VALUES(#{storeId}, #{userId}, #{roleType}, #{permissions}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime})") + int insert(StoreUser storeUser); + +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java index 04dd21d..3208951 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java +++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreCustomerController.java @@ -1,5 +1,6 @@ package com.oying.modules.pc.store.rest; +import cn.hutool.core.util.ObjUtil; import com.oying.modules.pc.product.domain.Product; import com.oying.modules.pc.product.domain.dto.ProductQueryCriteria; import com.oying.modules.pc.product.domain.enums.ProductStatusEnum; @@ -12,6 +13,7 @@ import com.oying.modules.pc.store.service.StoreQualificationService; import com.oying.modules.pc.store.service.StoreQueryService; import com.oying.modules.pc.store.service.StoreService; +import com.oying.modules.pc.store.view.CustomerStoreView; import com.oying.modules.pc.utils.BusinessHoursUtils; import com.oying.utils.PageResult; import com.oying.utils.R; @@ -57,19 +59,22 @@ @GetMapping(value = "/{storeId}") @ApiOperation("查询店铺") - public ResponseEntity<?> getStoreDetailsById(@PathVariable("storeId") Long storeId) { + public ResponseEntity<?> getStoreById(@PathVariable("storeId") Long storeId) { Store store = storeService.getById(storeId); - //store.setQualifications(this.getQualificationsByStoreId(store.getStoreId())); - StoreCustomerDetailDto storeDto = new StoreCustomerDetailDto(); - BeanUtils.copyProperties(store, storeDto); - storeDto.setBusinessHours(BusinessHoursUtils.formatBusinessHours(store.getOpenTime(), store.getCloseTime())); - return ResponseEntity.ok(R.success(storeDto)); + CustomerStoreView view = new CustomerStoreView(); + BeanUtils.copyProperties(store, view); + view.setBusinessHours(BusinessHoursUtils.formatBusinessHours(store.getOpenTime(), store.getCloseTime())); + return ResponseEntity.ok(R.success(view)); } - private List<StoreQualification> getQualificationsByStoreId(Long storeId) { - StoreQualificationQueryCriteria criteria = new StoreQualificationQueryCriteria(); - criteria.setStoreId(storeId); - return storeQualificationService.queryAll(criteria); + @GetMapping(value = "/{storeId}/details") + @ApiOperation("查询店铺") + public ResponseEntity<?> getStoreDetailsById(@PathVariable("storeId") Long storeId) { + Store store = storeService.getById(storeId); + if (ObjUtil.isNotEmpty(store)) { + store.setQualifications(storeQualificationService.queryByStoreId(storeId)); + } + return ResponseEntity.ok(R.success(store)); } private List<Product> getProductsByStoreId(Long storeId) { diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java index e1eee0a..d1852b3 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java +++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreMerchantController.java @@ -3,8 +3,10 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import com.oying.modules.pc.store.domain.dto.StoreUpdateRequest; +import com.oying.modules.pc.store.service.StoreQualificationService; import com.oying.utils.R; import com.oying.modules.pc.store.domain.Store; import com.oying.modules.pc.store.domain.dto.StoreCreateRequest; @@ -43,6 +45,7 @@ private final StoreService storeService; private final StoreCreateService storeCreateService; + private final StoreQualificationService storeQualificationService; @GetMapping(value = "/list") @ApiOperation("查询所有店铺") @@ -68,13 +71,24 @@ @GetMapping(value = "/{storeId}") @ApiOperation("查询店铺") //@PreAuthorize("@el.check('merchant:store:getById')") - public ResponseEntity<?> getById(@PathVariable Long storeId) { + public ResponseEntity<?> getStoreById(@PathVariable Long storeId) { Store store = storeService.getById(storeId); StoreMerchantView view = new StoreMerchantView(); BeanUtils.copyProperties(store, view); return ResponseEntity.ok(R.success(view)); } + @GetMapping(value = "/{storeId}/details") + @ApiOperation("查询店铺") + //@PreAuthorize("@el.check('merchant:store:getById')") + public ResponseEntity<?> getStoreDetailsById(@PathVariable Long storeId) { + Store store = storeService.getById(storeId); + if (ObjUtil.isNotEmpty(store)) { + store.setQualifications(storeQualificationService.queryByStoreId(storeId)); + } + return ResponseEntity.ok(R.success(store)); + } + @PostMapping @ApiOperation("创建店铺") //@PreAuthorize("@el.check('merchant:store:create')") diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java index fae5612..4a9ee6e 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java +++ b/oying-system/src/main/java/com/oying/modules/pc/store/rest/StoreQualificationCustomerController.java @@ -1,5 +1,7 @@ package com.oying.modules.pc.store.rest; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjUtil; import com.oying.utils.R; @@ -34,14 +36,14 @@ @GetMapping("/list") @ApiOperation("查询店铺资质") //@PreAuthorize("@el.check('customer:storeQualification:list')") - public ResponseEntity<?> getQualifications(@PathVariable Long storeId) { + public ResponseEntity<?> getQualificationsByStoreId(@PathVariable Long storeId) { StoreQualificationQueryCriteria criteria = new StoreQualificationQueryCriteria(); criteria.setStoreId(storeId); List<StoreQualification> qualificationList = storeQualificationService.queryAll(criteria); List<CustomerStoreQualificationView> viewList = Optional.ofNullable(qualificationList).orElse(ListUtil.empty()) .stream().map(i -> { CustomerStoreQualificationView view = new CustomerStoreQualificationView(); - BeanUtils.copyProperties(i, view); + BeanUtil.copyProperties(i, view, CopyOptions.create().setIgnoreNullValue(true)); view.setType(i.getQualificationType()); view.setName(i.getQualificationName()); view.setImageUrl(i.getQualificationImageUrl()); diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java index 08b6ff7..7e23f4e 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java +++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/StoreQualificationService.java @@ -40,6 +40,13 @@ List<StoreQualification> queryBatchIds(List<Long> ids); /** + * 查询 + * @param storeId 条件参数 + * @return List<StoreQualification> + */ + List<StoreQualification> queryByStoreId(Long storeId); + + /** * 创建 * @param resources / */ diff --git a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java index 2307d9a..10b5e26 100644 --- a/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java +++ b/oying-system/src/main/java/com/oying/modules/pc/store/service/impl/StoreQualificationServiceImpl.java @@ -57,6 +57,13 @@ } @Override + public List<StoreQualification> queryByStoreId(Long storeId) { + LambdaQueryWrapper<StoreQualification> wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(StoreQualification::getStoreId, storeId); + return storeQualificationMapper.selectList(wrapper); + } + + @Override @Transactional(rollbackFor = Exception.class) public void create(StoreQualification resources) { storeQualificationMapper.insert(resources); 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 index b68087a..8614da5 100644 --- 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 @@ -1,28 +1,79 @@ package com.oying.modules.pc.store.view; +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.Getter; import lombok.Setter; +import java.time.LocalTime; + @Data public class CustomerStoreView { - private String name; + @ApiModelProperty(value = "店铺ID") + private Long storeId; - private String logoUrl; + @ApiModelProperty(value = "商户ID") + private Long merchantId; + @ApiModelProperty(value = "平台类目") + private Long platformCategoryId; + + @ApiModelProperty(value = "店铺类型:1-自营 2-加盟 3-第三方") + private Integer storeType; + + @ApiModelProperty(value = "店铺名称") + private String storeName; + + @ApiModelProperty(value = "状态") + private Integer status; + + @ApiModelProperty(value = "店铺logo图片Url") + private String logoImageUrl; + + @ApiModelProperty(value = "店铺封面图Url") + private String coverImageUrl; + + @ApiModelProperty(value = "店铺描述") private String description; - private String address; + @ApiModelProperty(value = "联系电话") + private String contactPhone; + + @ApiModelProperty(value = "营业开始时间") + private LocalTime openTime; + + @ApiModelProperty(value = "营业结束时间") + private LocalTime closeTime; private String businessHours; - private String contactPhone; + @ApiModelProperty(value = "详细地址") + private String address; - private Integer score; + @ApiModelProperty(value = "经度") + private Double longitude; - private Integer deliveryDuration; + @ApiModelProperty(value = "纬度") + private Double latitude; - private Integer monthlySales; + @ApiModelProperty(value = "营业半径(米)") + private Integer radius; + + @ApiModelProperty(value = "是否支持退货") + private Integer returns; + + @ApiModelProperty(value = "是否支持自提") + private Integer selfPickup; + + @ApiModelProperty(value = "评分") + private Double score = 0d; + + @ApiModelProperty(value = "配送距离") + private Integer deliveryDuration = 0; + + @ApiModelProperty(value = "月销售量") + private Integer monthlySales = 0; } diff --git a/oying-system/src/main/java/com/oying/modules/pc/utils/BusinessHoursUtils.java b/oying-system/src/main/java/com/oying/modules/pc/utils/BusinessHoursUtils.java new file mode 100644 index 0000000..a5e44bb --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/utils/BusinessHoursUtils.java @@ -0,0 +1,42 @@ +package com.oying.modules.pc.utils; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.time.format.DateTimeFormatter; + +public class BusinessHoursUtils { + + // 时间格式 + private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); + + /** + * 拼接营业时间,如果时间为 null,则返回 "Closed" + * + * @param openTime 开始时间 + * @param closeTime 结束时间 + * @return 格式化的营业时间字符串,如 "8:00-22:00" + */ + public static String formatBusinessHours(LocalTime openTime, LocalTime closeTime) { + if (openTime == null || closeTime == null) { + return "Closed"; + } + return openTime.format(DEFAULT_FORMATTER) + "-" + closeTime.format(DEFAULT_FORMATTER); + } + + // 示例调用 + public static void main(String[] args) { + + // LocalDateTime localDateTime = LocalDateTime.of(2025, Month.MAY, 10, 8, 0, 0); + // LocalDateTime localDateTime2 = LocalDateTime.of(2025, Month.MAY, 10, 22, 0, 0); + + LocalTime openTime = LocalTime.of(8, 0); + LocalTime closeTime = LocalTime.of(22, 0); + + // 正常情况 → "8:00-22:00" + System.out.println(formatBusinessHours(openTime, closeTime)); + + // 如果时间为 null → "Closed" + System.out.println(formatBusinessHours(null, null)); + } +} diff --git a/oying-system/src/main/java/com/oying/modules/pc/utils/ImageUtils.java b/oying-system/src/main/java/com/oying/modules/pc/utils/ImageUtils.java new file mode 100644 index 0000000..5593278 --- /dev/null +++ b/oying-system/src/main/java/com/oying/modules/pc/utils/ImageUtils.java @@ -0,0 +1,31 @@ +package com.oying.modules.pc.utils; + +import com.oying.domain.BucketStorage; +import com.oying.exception.EntityNotFoundException; +import com.oying.service.BucketStorageService; +import com.oying.utils.ObsProperties; +import com.oying.utils.ObsUtils; +import com.oying.utils.SpringBeanHolder; + +import java.util.Optional; + +public class ImageUtils { + + private final static ObsProperties properties = SpringBeanHolder.getBean(ObsProperties.class); + private final static BucketStorageService bucketStorageService = SpringBeanHolder.getBean(BucketStorageService.class); + + public static String getPublicObjectUrl(String path) { + return ObsUtils.getPublicObjectUrl(properties, path); + } + + public static String getPublicObjectUrl(Long storageId) { + return Optional.ofNullable(storageId).map(v -> { + BucketStorage bucketStorage = bucketStorageService.getById(storageId); + String path = Optional.ofNullable(bucketStorage) + .map(BucketStorage::getPath) + .orElseThrow(() -> new EntityNotFoundException(BucketStorage.class, "bucketStorageId", storageId.toString())); + return getPublicObjectUrl(path); + }).orElse(null); + } + +} diff --git a/oying-system/src/main/resources/mapper/pc/product/ProductImageMapper.xml b/oying-system/src/main/resources/mapper/pc/product/ProductImageMapper.xml new file mode 100644 index 0000000..c79fe26 --- /dev/null +++ b/oying-system/src/main/resources/mapper/pc/product/ProductImageMapper.xml @@ -0,0 +1,30 @@ +<?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.ProductImageMapper"> + <resultMap id="BaseResultMap" type="com.oying.modules.pc.product.domain.ProductImage"> + <id column="image_id" property="imageId"/> + <result column="product_id" property="productId"/> + <result column="cloud_storage_id" property="cloudStorageId"/> + <result column="image_type" property="imageType"/> + <result column="image_url" property="imageUrl"/> + <result column="sort_weight" property="sortWeight"/> + <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"> + image_id, product_id, cloud_storage_id, image_type, image_url, sort_weight, create_by, create_time, update_by, update_time + </sql> + + <select id="findAll" resultMap="BaseResultMap"> + select + <include refid="Base_Column_List"/> + from pc_product_image + <where> + </where> + order by image_id desc + </select> + +</mapper> \ No newline at end of file diff --git a/oying-system/src/main/resources/mapper/pc/product/ProductLabelMapper.xml b/oying-system/src/main/resources/mapper/pc/product/ProductLabelMapper.xml new file mode 100644 index 0000000..0403a2f --- /dev/null +++ b/oying-system/src/main/resources/mapper/pc/product/ProductLabelMapper.xml @@ -0,0 +1,28 @@ +<?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.ProductLabelMapper"> + <resultMap id="BaseResultMap" type="com.oying.modules.pc.product.domain.ProductLabel"> + <id column="label_id" property="labelId"/> + <result column="product_id" property="productId"/> + <result column="category_name" property="categoryName"/> + <result column="label_name" property="labelName"/> + <result column="label_value" property="labelValue"/> + <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"> + label_id, product_id, category_name, label_name, label_value, create_by, create_time, update_by, update_time + </sql> + + <select id="findAll" resultMap="BaseResultMap"> + select + <include refid="Base_Column_List"/> + from pc_product_label + <where> + </where> + order by label_id desc + </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 index 76b3c9c..96ddca6 100644 --- a/oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml +++ b/oying-system/src/main/resources/mapper/pc/store/StoreQualificationMapper.xml @@ -8,6 +8,7 @@ <result column="qualification_number" property="qualificationNumber"/> <result column="qualification_name" property="qualificationName"/> <result column="qualification_image_id" property="qualificationImageId"/> + <result column="qualification_image_url" property="qualificationImageUrl"/> <result column="start_date" property="startDate"/> <result column="end_date" property="endDate"/> <result column="status" property="status"/> @@ -18,8 +19,8 @@ </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 + qualification_id, store_id, qualification_type, qualification_number, qualification_name, qualification_image_id, qualification_image_url, + start_date, end_date, status, create_by, create_time, update_by, update_time </sql> <select id="findAll" resultMap="BaseResultMap"> @@ -27,6 +28,9 @@ <include refid="Base_Column_List"/> from pc_store_qualification <where> + <if test="criteria.qualificationId != null"> + and qualification_id = #{criteria.qualificationId} + </if> <if test="criteria.storeId != null"> and store_id = #{criteria.storeId} </if> -- Gitblit v1.9.3