补充前次提交的遗漏内容,前次提交SHA:a6f4dd
30 files added
13 files modified
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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)); |
| | | } |
| | | } |
New file |
| | |
| | | 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)); |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | |
| | | |
| | | private Long secondCategoryId; |
| | | |
| | | private Integer active; |
| | | |
| | | @ApiModelProperty(value = "页码", example = "1") |
| | | private Integer page = 1; |
| | | |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | |
| | | 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()); |
| | |
| | | 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(); |
New file |
| | |
| | | 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); |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
New file |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | |
| | | @ApiModelProperty(value = "店铺ID") |
| | | private Long storeId; |
| | | |
| | | @ApiModelProperty(value = "条形码") |
| | | private String barcode; |
| | | |
| | | @ApiModelProperty(value = "商品名称") |
| | | private String name; |
| | | |
| | | @ApiModelProperty(value = "商品标题") |
| | | private String title; |
| | | |
| | |
| | | @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; |
| | | |
| | |
| | | package com.oying.modules.pc.product.view; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | |
| | | @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; |
| | | |
| | | } |
| | |
| | | package com.oying.modules.pc.product.view; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | |
| | | * @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; |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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)); |
| | | } |
| | | } |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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<>(); |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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); |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | |
| | | @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) { |
| | |
| | | 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; |
| | |
| | | |
| | | private final StoreService storeService; |
| | | private final StoreCreateService storeCreateService; |
| | | private final StoreQualificationService storeQualificationService; |
| | | |
| | | @GetMapping(value = "/list") |
| | | @ApiOperation("查询所有店铺") |
| | |
| | | @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')") |
| | |
| | | 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; |
| | |
| | | @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()); |
| | |
| | | List<StoreQualification> queryBatchIds(List<Long> ids); |
| | | |
| | | /** |
| | | * 查询 |
| | | * @param storeId 条件参数 |
| | | * @return List<StoreQualification> |
| | | */ |
| | | List<StoreQualification> queryByStoreId(Long storeId); |
| | | |
| | | /** |
| | | * 创建 |
| | | * @param resources / |
| | | */ |
| | |
| | | } |
| | | |
| | | @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); |
| | |
| | | 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; |
| | | |
| | | } |
New file |
| | |
| | | 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)); |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | <?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> |
| | |
| | | <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"/> |
| | |
| | | </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"> |
| | |
| | | <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> |