Browse Source

附加产品提交

lishiqiang 2 weeks ago
parent
commit
bbe8a643a9
15 changed files with 487 additions and 211 deletions
  1. 1 6
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/productSpu/groupVO/ProductGroupSaveReqVO.java
  2. 23 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/productSpu/spuVO/ProductSpecSaveReqVO.java
  3. 7 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/productSpu/spuVO/ProductSpuRespVO.java
  4. 3 1
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/productSpu/spuVO/ProductSpuSaveReqVO.java
  5. 95 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/spuship/SpuShipController.java
  6. 27 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/spuship/vo/SpuShipPageReqVO.java
  7. 30 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/spuship/vo/SpuShipRespVO.java
  8. 21 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/spuship/vo/SpuShipSaveReqVO.java
  9. 38 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/dal/dataobject/spuship/SpuShipDO.java
  10. 25 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/dal/mysql/spuship/SpuShipMapper.java
  11. 23 71
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/productGroup/ProductGroupServiceImpl.java
  12. 33 132
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/productSpu/ProductSpuServiceImpl.java
  13. 55 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/spuship/SpuShipService.java
  14. 74 0
      ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/spuship/SpuShipServiceImpl.java
  15. 32 1
      ship-module-product/ship-module-product-biz/src/main/resources/mapper/productSpu/ProductSpuMapper.xml

+ 1 - 6
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/productSpu/groupVO/ProductGroupSaveReqVO.java

@@ -19,7 +19,7 @@ public class ProductGroupSaveReqVO {
     private Long productId;
 
     @Schema(description = "基础产品ID;平台产品时为关联ID", example = "8989")
-    @NotNull(message = "基础产品ID不能为空")
+//    @NotNull(message = "基础产品ID不能为空")
     private Long productBaseId;
 
     @Schema(description = "基础产品类型;0自建子票 1平台产品", example = "1")
@@ -37,23 +37,18 @@ public class ProductGroupSaveReqVO {
     private Long firstResourceId;
 
     @Schema(description = "规格ID", example = "7216")
-    @NotNull(message = "规格ID不能为空")
     private Long specificationId;
 
     @Schema(description = "成本价格", example = "14190")
-    @NotNull(message = "成本价格不能为空")
     private BigDecimal costPrice;
 
     @Schema(description = "销售价格", example = "27592")
-    @NotNull(message = "销售价格不能为空")
     private BigDecimal salePrice;
 
     @Schema(description = "规格类型:common通用 full全价 half半价 free免票", example = "1")
-    @NotEmpty(message = "规格类型不能为空")
     private String specType;
 
     @Schema(description = "是否必选;0否 1是")
-    @NotNull(message = "是否必选不能为空")
     private Integer needChoose;
 
     @Schema(description = "非必选项目最大选择数量")

+ 23 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/productSpu/spuVO/ProductSpecSaveReqVO.java

@@ -0,0 +1,23 @@
+package com.yc.ship.module.product.controller.admin.productSpu.spuVO;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Schema(description = "管理后台 - 产品组合新增/修改 Request VO")
+@Data
+public class ProductSpecSaveReqVO {
+
+    @Schema(description = "规格类型:common通用 full全价 half半价 free免票", example = "1")
+    private String specType;
+
+
+    @Schema(description = "成本价格", example = "14190")
+    private BigDecimal costPrice;
+
+    @Schema(description = "销售价格", example = "27592")
+    private BigDecimal salePrice;
+
+
+}

+ 7 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/productSpu/spuVO/ProductSpuRespVO.java

@@ -19,6 +19,7 @@ import com.yc.ship.module.product.controller.admin.productTakeRule.vo.ProductTak
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
+import javax.validation.Valid;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
@@ -44,6 +45,12 @@ public class ProductSpuRespVO {
     @Schema(description = "产品id", example = "1")
     private Long id;
 
+    @Schema(description = "游船列表")
+    private String shipIds;
+
+    @Schema(description = "产品规格信息")
+    private List<ProductSpecSaveReqVO> productSpecList;
+
     @Schema(description = "产品编码")
     private String productCode;
 

+ 3 - 1
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/productSpu/spuVO/ProductSpuSaveReqVO.java

@@ -37,7 +37,6 @@ public class ProductSpuSaveReqVO {
     private String productCode;
 
     @Schema(description = "产品类型", example = "2")
-    @NotNull(message = "产品类型不能为空")
     private Integer productType;
 
     @Schema(description = "产品分类", example = "21748")
@@ -104,6 +103,9 @@ public class ProductSpuSaveReqVO {
     private Integer hasBreakfast;
 
     @Schema(description = "产品规格信息")
+    private List<@Valid ProductSpecSaveReqVO> productSpecList;
+
+    @Schema(description = "基础产品产品规格信息")
     private List<@Valid ProductGroupSaveReqVO> productGroupList;
 
     @Schema(description = "平台产品信息")

+ 95 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/spuship/SpuShipController.java

@@ -0,0 +1,95 @@
+package com.yc.ship.module.product.controller.admin.spuship;
+
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Operation;
+
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+
+import com.yc.ship.framework.common.pojo.PageParam;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.pojo.CommonResult;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+import static com.yc.ship.framework.common.pojo.CommonResult.success;
+
+import com.yc.ship.framework.excel.core.util.ExcelUtils;
+
+import com.yc.ship.framework.apilog.core.annotation.ApiAccessLog;
+import static com.yc.ship.framework.apilog.core.enums.OperateTypeEnum.*;
+
+import com.yc.ship.module.product.controller.admin.spuship.vo.*;
+import com.yc.ship.module.product.dal.dataobject.spuship.SpuShipDO;
+import com.yc.ship.module.product.service.spuship.SpuShipService;
+
+@Tag(name = "管理后台 - 产品游船")
+@RestController
+@RequestMapping("/product/spu-ship")
+@Validated
+public class SpuShipController {
+
+    @Resource
+    private SpuShipService spuShipService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建产品游船")
+    @PreAuthorize("@ss.hasPermission('product:spu-ship:create')")
+    public CommonResult<Long> createSpuShip(@Valid @RequestBody SpuShipSaveReqVO createReqVO) {
+        return success(spuShipService.createSpuShip(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新产品游船")
+    @PreAuthorize("@ss.hasPermission('product:spu-ship:update')")
+    public CommonResult<Boolean> updateSpuShip(@Valid @RequestBody SpuShipSaveReqVO updateReqVO) {
+        spuShipService.updateSpuShip(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除产品游船")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('product:spu-ship:delete')")
+    public CommonResult<Boolean> deleteSpuShip(@RequestParam("id") Long id) {
+        spuShipService.deleteSpuShip(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得产品游船")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('product:spu-ship:query')")
+    public CommonResult<SpuShipRespVO> getSpuShip(@RequestParam("id") Long id) {
+        SpuShipDO spuShip = spuShipService.getSpuShip(id);
+        return success(BeanUtils.toBean(spuShip, SpuShipRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得产品游船分页")
+    @PreAuthorize("@ss.hasPermission('product:spu-ship:query')")
+    public CommonResult<PageResult<SpuShipRespVO>> getSpuShipPage(@Valid SpuShipPageReqVO pageReqVO) {
+        PageResult<SpuShipDO> pageResult = spuShipService.getSpuShipPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, SpuShipRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出产品游船 Excel")
+    @PreAuthorize("@ss.hasPermission('product:spu-ship:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportSpuShipExcel(@Valid SpuShipPageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<SpuShipDO> list = spuShipService.getSpuShipPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "产品游船.xls", "数据", SpuShipRespVO.class,
+                        BeanUtils.toBean(list, SpuShipRespVO.class));
+    }
+
+}

+ 27 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/spuship/vo/SpuShipPageReqVO.java

@@ -0,0 +1,27 @@
+package com.yc.ship.module.product.controller.admin.spuship.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import com.yc.ship.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static com.yc.ship.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 产品游船分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class SpuShipPageReqVO extends PageParam {
+
+    @Schema(description = "游船ID", example = "4820")
+    private String shipId;
+
+    private Long productId;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 30 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/spuship/vo/SpuShipRespVO.java

@@ -0,0 +1,30 @@
+package com.yc.ship.module.product.controller.admin.spuship.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 产品游船 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class SpuShipRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "26054")
+    @ExcelProperty("主键")
+    private Long id;
+
+    @Schema(description = "游船ID", example = "4820")
+    @ExcelProperty("游船ID")
+    private String shipId;
+
+    @Schema(description = "产品ID", example = "4820")
+    private Long productId;
+
+    @Schema(description = "创建时间")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 21 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/controller/admin/spuship/vo/SpuShipSaveReqVO.java

@@ -0,0 +1,21 @@
+package com.yc.ship.module.product.controller.admin.spuship.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import javax.validation.constraints.*;
+
+@Schema(description = "管理后台 - 产品游船新增/修改 Request VO")
+@Data
+public class SpuShipSaveReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "26054")
+    private Long id;
+
+    @Schema(description = "游船ID", example = "4820")
+    private String shipId;
+
+    @Schema(description = "产品ID", example = "4820")
+    private Long productId;
+
+}

+ 38 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/dal/dataobject/spuship/SpuShipDO.java

@@ -0,0 +1,38 @@
+package com.yc.ship.module.product.dal.dataobject.spuship;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import java.time.LocalDateTime;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.*;
+import com.yc.ship.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 产品游船 DO
+ *
+ * @author lsq
+ */
+@TableName("product_spu_ship")
+@KeySequence("product_spu_ship_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SpuShipDO extends BaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 游船ID
+     */
+    private String shipId;
+
+    private Long productId;
+
+}

+ 25 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/dal/mysql/spuship/SpuShipMapper.java

@@ -0,0 +1,25 @@
+package com.yc.ship.module.product.dal.mysql.spuship;
+
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.mybatis.core.mapper.BaseMapperX;
+import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
+import com.yc.ship.module.product.controller.admin.spuship.vo.SpuShipPageReqVO;
+import com.yc.ship.module.product.dal.dataobject.spuship.SpuShipDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 产品游船 Mapper
+ *
+ * @author lsq
+ */
+@Mapper
+public interface SpuShipMapper extends BaseMapperX<SpuShipDO> {
+
+    default PageResult<SpuShipDO> selectPage(SpuShipPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<SpuShipDO>()
+                .eqIfPresent(SpuShipDO::getShipId, reqVO.getShipId())
+                .betweenIfPresent(SpuShipDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(SpuShipDO::getId));
+    }
+
+}

+ 23 - 71
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/productGroup/ProductGroupServiceImpl.java

@@ -1,9 +1,11 @@
 package com.yc.ship.module.product.service.productGroup;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.yc.ship.framework.common.pojo.PageResult;
 import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
 import com.yc.ship.module.product.controller.admin.productSpu.groupVO.ProductGroupPageReqVO;
 import com.yc.ship.module.product.controller.admin.productSpu.groupVO.ProductGroupSaveReqVO;
 import com.yc.ship.module.product.controller.admin.productSpu.skuVO.ProductSkuSaveReqVO;
@@ -85,79 +87,29 @@ public class ProductGroupServiceImpl implements ProductGroupService {
     @Override
     @Transactional
     public void saveSkuAndGroupList(List<ProductGroupSaveReqVO> specGroupList, List<ProductSkuSaveReqVO> productSkuList, Long productId) {
-        // 对比group数据
-        List<ProductGroupDO> groupDOList = productGroupMapper.selectList(new LambdaQueryWrapper<ProductGroupDO>()
+        List<ProductGroupDO> groupDOs = BeanUtils.toBean(specGroupList, ProductGroupDO.class);
+        groupDOs.forEach(group -> {
+            group.setId(IdWorker.getId(group));
+            group.setProductId(productId);
+            group.setDeleted(false);
+        });
+        productGroupMapper.update(new LambdaUpdateWrapper<ProductGroupDO>()
                 .eq(ProductGroupDO::getProductId, productId)
-                .eq(ProductGroupDO::getDeleted, false)
-                .eq(ProductGroupDO::getProductBaseType, 0)
+                .set(ProductGroupDO::getDeleted, 1)
         );
-        // 是否修改group数据
-        boolean groupDataChanged = groupDOList.size() != specGroupList.size();
-        if (!groupDataChanged) {
-            Set<Integer> hashCode1 = groupDOList.stream().map(ProductGroupDO::hashCode).collect(Collectors.toSet());
-            Set<Integer> hashCode2 = specGroupList.stream().map(ProductGroupSaveReqVO::hashCode).collect(Collectors.toSet());
-            groupDataChanged = !hashCode1.equals(hashCode2);
-        }
-        if (!groupDataChanged && groupDOList.isEmpty()) {
-            // 旅行社组合产品 只有分销产品的情况 判断规格价格是否相同
-            List<ProductSkuDO> skuDBList = productSkuMapper.selectList(ProductSkuDO::getProductId, productId, ProductSkuDO::getDeleted, false);
-            Set<Integer> hashCode1 = skuDBList.stream().map(ProductSkuDO::hashCode).collect(Collectors.toSet());
-            Set<Integer> hashCode2 = productSkuList.stream().map(ProductSkuSaveReqVO::hashCode).collect(Collectors.toSet());
-            groupDataChanged = !hashCode1.equals(hashCode2);
-        }
-        if (groupDataChanged) {
-            // 删除旧的 保存新的 sku
-            List<ProductSkuDO> skuDBList = productSkuMapper.selectList(ProductSkuDO::getProductId, productId, ProductSkuDO::getDeleted, false);
-            List<Long> idList = skuDBList.stream().map(ProductSkuDO::getId).collect(Collectors.toList());
-            if (!idList.isEmpty()) {
-                productSkuMapper.deleteBatchIds(idList);
-            }
-            //保存新的sku
-            List<ProductSkuDO> newSkuList = BeanUtils.toBean(productSkuList, ProductSkuDO.class);
-            newSkuList.forEach(sku -> {
-                sku.setId(IdWorker.getId(sku));
-                sku.setProductId(productId);
-                sku.setDeleted(false);
-            });
-            productSkuMapper.insertBatch(newSkuList);
-            //修改分销商绑定的sku信息
-            for (ProductSkuDO oldSku : skuDBList) {
-                for (ProductSkuDO newSku : newSkuList) {
-                    if (newSku.getSpecType().equals(oldSku.getSpecType())) {
-                        productGroupMapper.updateDistributorProductId(oldSku.getId(), newSku.getId(), newSku.getSalePrice());
-                        productGroupMapper.updateDistributorPrice(oldSku.getId(), newSku.getId(), newSku.getSalePrice());
-                    }
-                }
-            }
-            if (!newSkuList.isEmpty()) {
-                BigDecimal minSalePrice = newSkuList.stream()
-                        .min(Comparator.comparing(ProductSkuDO::getSalePrice)).get().getSalePrice();
-                productGroupMapper.updateDistributorProduct(productId, minSalePrice);
-            }
-
-            // 删除旧的 保存新的 自建 group
-
-            idList = groupDOList.stream().map(ProductGroupDO::getId).collect(Collectors.toList());
-            if (!idList.isEmpty()) {
-                productGroupMapper.deleteBatchIds(idList);
-            }
-            newSkuList.forEach(sku -> {
-                // 只有一个规格&规格类型相同&必选项目 保存skuId
-                List<ProductGroupSaveReqVO> collect = specGroupList.stream()
-                        .filter(group -> group.getIsMatched() && sku.getSpecType().equals(group.getSpecType()) && group.getNeedChoose() == 1)
-                        .collect(Collectors.toList());
-                if (!collect.isEmpty()) {
-                    collect.forEach(group -> group.setSkuId(sku.getId()));
-                }
-            });
-            List<ProductGroupDO> groupDOs = BeanUtils.toBean(specGroupList, ProductGroupDO.class);
-            groupDOs.forEach(group -> {
-                group.setId(IdWorker.getId(group));
-                group.setProductId(productId);
-                group.setDeleted(false);
-            });
-            productGroupMapper.insertBatch(groupDOs);
-        }
+        productGroupMapper.insertBatch(groupDOs);
+
+        List<ProductSkuDO> newSkuList = BeanUtils.toBean(productSkuList, ProductSkuDO.class);
+        newSkuList.forEach(sku -> {
+            sku.setId(IdWorker.getId(sku));
+            sku.setProductId(productId);
+            sku.setDeleted(false);
+        });
+        productSkuMapper.update(new LambdaUpdateWrapper<ProductSkuDO>()
+                .set(ProductSkuDO::getDeleted, 1)
+                .eq(ProductSkuDO::getProductId, productId)
+        );
+        productSkuMapper.insertBatch(newSkuList);
     }
 
 }

+ 33 - 132
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/productSpu/ProductSpuServiceImpl.java

@@ -13,6 +13,7 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.yc.ship.framework.common.pojo.CommonResult;
 import com.yc.ship.framework.common.pojo.PageResult;
 import com.yc.ship.framework.common.util.object.BeanUtils;
+import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
 import com.yc.ship.framework.mybatis.core.query.MPJLambdaWrapperX;
 import com.yc.ship.framework.mybatis.core.util.MyBatisUtils;
 import com.yc.ship.framework.security.core.LoginUser;
@@ -44,6 +45,7 @@ import com.yc.ship.module.product.dal.dataobject.productSaleRule.ProductSaleRule
 import com.yc.ship.module.product.dal.dataobject.productSku.ProductSkuDO;
 import com.yc.ship.module.product.dal.dataobject.productSpu.ProductSpuDO;
 import com.yc.ship.module.product.dal.dataobject.productTakeRule.ProductTakeRuleDO;
+import com.yc.ship.module.product.dal.dataobject.spuship.SpuShipDO;
 import com.yc.ship.module.product.dal.mysql.productBase.ProductBaseMapper;
 import com.yc.ship.module.product.dal.mysql.productBasicRule.ProductBasicRuleMapper;
 import com.yc.ship.module.product.dal.mysql.productCheckRule.ProductCheckRuleMapper;
@@ -56,11 +58,13 @@ import com.yc.ship.module.product.dal.mysql.productSaleRule.ProductSaleRuleMappe
 import com.yc.ship.module.product.dal.mysql.productSku.ProductSkuMapper;
 import com.yc.ship.module.product.dal.mysql.productSpu.ProductSpuMapper;
 import com.yc.ship.module.product.dal.mysql.productTakeRule.ProductTakeRuleMapper;
+import com.yc.ship.module.product.dal.mysql.spuship.SpuShipMapper;
 import com.yc.ship.module.product.enums.SpecTypeEnum;
 import com.yc.ship.module.product.service.productGroup.ProductGroupService;
 import com.yc.ship.module.resource.controller.admin.category.vo.CategoryListReqVO;
 import com.yc.ship.module.resource.controller.admin.category.vo.CategoryRespVO;
 import com.yc.ship.module.resource.controller.admin.resource.vo.ReducedResourceRespVO;
+import com.yc.ship.module.resource.dal.dataobject.category.CategoryDO;
 import com.yc.ship.module.resource.dal.dataobject.resource.ResourceDO;
 import com.yc.ship.module.resource.dal.mysql.resource.ResourceMapper;
 import com.yc.ship.module.resource.enums.UseStatusEnum;
@@ -104,6 +108,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
     private final ProductBasicRuleMapper productBasicMapper;
     private final ProductSaleRuleMapper productSaleMapper;
     private final ProductTakeRuleMapper productTakeMapper;
+    private final SpuShipMapper spuShipMapper;
     private final ProductCheckRuleMapper productCheckMapper;
     private final ProductRefundRuleMapper productRefundMapper;
     private final ProductNoticeRuleMapper productNoticeMapper;
@@ -132,6 +137,14 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         productSpu.setId(IdWorker.getId(productSpu));
         productSpuMapper.insert(productSpu);
 
+        String[] ships = createReqVO.getShipIds().split(",");
+        for (String ship : ships) {
+            SpuShipDO spuShip = new SpuShipDO();
+            spuShip.setId(IdWorker.getId(spuShip));
+            spuShip.setShipId(ship);
+            spuShip.setProductId(productSpu.getId());
+            spuShipMapper.insert(spuShip);
+        }
         if (ObjectUtil.isNotEmpty(createReqVO.getProductSaleChannels())) {
             // 保存销售渠道
             String[] channels = createReqVO.getProductSaleChannels().split(",");
@@ -189,7 +202,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
             });
         }
         // 保存sku 与 group 信息
-        saveSkuAndGroupList(createReqVO.getProductGroupList(), createReqVO.getProductSkuList(), platProductPriceList,productSpu.getId());
+        saveSkuAndGroupList(createReqVO.getProductGroupList(), createReqVO.getProductSkuList(),productSpu.getId());
         // 返回
         return productSpu.getId();
     }
@@ -202,109 +215,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
      */
     void saveSkuAndGroupList(List<ProductGroupSaveReqVO> specGroupList,
                              List<ProductSkuSaveReqVO> productSkuList,
-                             List<PlatProductPriceRespVO> platProductPriceList,
                              Long productId) {
-        if (productSkuList.isEmpty()) {
-            Set<String> specTypeSet = specGroupList.stream().map(ProductGroupSaveReqVO::getSpecType).collect(Collectors.toSet());
-            specTypeSet.addAll(platProductPriceList.stream().map(PlatProductPriceRespVO::getSpecType).collect(Collectors.toSet()));
-            for (String specType : specTypeSet) {
-                ProductSkuSaveReqVO sku = new ProductSkuSaveReqVO();
-                sku.setProductId(productId);
-                sku.setSpecType(specType);
-                sku.setCostPrice(BigDecimal.ZERO);
-                sku.setSalePrice(BigDecimal.ZERO);
-                sku.setSalePriceIsEmpty(true);
-                productSkuList.add(sku);
-            }
-        } else {
-            productSkuList.forEach(sku -> sku.setCostPrice(BigDecimal.ZERO));
-        }
-
-        // region 保存满足 必选项目&只有一个规格 的基础产品规格成本价
-        // 筛选必选项目规格
-        List<ProductGroupSaveReqVO> mustList = specGroupList.stream().filter(group -> group.getNeedChoose() == 1).collect(Collectors.toList());
-        List<ProductGroupSaveReqVO> nomustList = specGroupList.stream().filter(group -> group.getNeedChoose() == 0).collect(Collectors.toList());
-        // 过滤多个规格的基础产品
-        List<Long> multiSizeProductBaseIds = new ArrayList<>();
-        Map<Long, List<ProductGroupSaveReqVO>> productBaseMap = mustList.stream().collect(Collectors.groupingBy(ProductGroupSaveReqVO::getProductBaseId));
-        productBaseMap.forEach((productBaseId, list) -> {
-            Set<Long> collect = list.stream().map(ProductGroupSaveReqVO::getSpecificationId).collect(Collectors.toSet());
-            if (collect.size() > 1) {
-                multiSizeProductBaseIds.add(productBaseId);
-            }
-        });
-        if (!multiSizeProductBaseIds.isEmpty()) {
-            // 多规格基础产品标记 IsMatched = true
-            mustList.forEach(group -> group.setIsMatched(multiSizeProductBaseIds.contains(group.getProductBaseId())));
-        }
-        // 根据规格类型分组
-        Map<String, List<ProductGroupSaveReqVO>> groupMap = mustList.stream().collect(Collectors.groupingBy(ProductGroupSaveReqVO::getSpecType));
-        // 累加同规格的成本价
-        groupMap.forEach((specType, list) -> {
-            ProductSkuSaveReqVO skuDO = new ProductSkuSaveReqVO();
-            skuDO.setProductId(productId);
-            skuDO.setSpecType(specType);
-            skuDO.setCostPrice(BigDecimal.ZERO);
-            skuDO.setSalePrice(BigDecimal.ZERO);
-            list.forEach(spec -> {
-                // 多规格基础产品不累加成本价
-                if (!spec.getIsMatched()) {
-                    skuDO.setCostPrice(skuDO.getCostPrice().add(spec.getCostPrice()));
-                    skuDO.setSalePrice(skuDO.getSalePrice().add(spec.getSalePrice()));
-                }
-                spec.setIsMatched(!spec.getIsMatched());
-                nomustList.add(spec);
-            });
-            productSkuList.stream().filter(sku -> ObjectUtil.equal(sku.getSpecType(), specType))
-                    .findFirst().ifPresent(sku -> {
-                        sku.setCostPrice(skuDO.getCostPrice());
-                        if (sku.getSalePriceIsEmpty()) {
-                            sku.setSalePrice(skuDO.getSalePrice());
-                        }
-                    });
-        });
-        // endregion
-
-        if (!platProductPriceList.isEmpty()) {
-            // 根据规格类型分组
-            Map<String, List<PlatProductPriceRespVO>> platMap = platProductPriceList.stream().collect(Collectors.groupingBy(PlatProductPriceRespVO::getSpecType));
-            platMap.forEach((specType, list) -> {
-                ProductSkuSaveReqVO skuDO = new ProductSkuSaveReqVO();
-                skuDO.setProductId(productId);
-                skuDO.setSpecType(specType);
-                skuDO.setCostPrice(BigDecimal.ZERO);
-                skuDO.setSalePrice(BigDecimal.ZERO);
-                list.forEach(spec -> {
-                    skuDO.setCostPrice(skuDO.getCostPrice().add(spec.getCostPrice()));
-                    skuDO.setSalePrice(skuDO.getSalePrice().add(spec.getSalePrice()));
-                });
-                productSkuList.stream().filter(sku -> ObjectUtil.equal(sku.getSpecType(), specType))
-                        .findFirst().ifPresent(sku -> {
-                            sku.setCostPrice(skuDO.getCostPrice());
-                            if (sku.getSalePriceIsEmpty()) {
-                                sku.setSalePrice(sku.getSalePrice().add(skuDO.getSalePrice()));
-                            }
-                        });
-            });
-        }
-        // 累加 通用规格 成本价
-        List<ProductSkuSaveReqVO> commonTempList = productSkuList.stream()
-                .filter(sku -> ObjectUtil.equal(sku.getSpecType(), SpecTypeEnum.COMMON.getType()))
-                .collect(Collectors.toList());
-        if (!commonTempList.isEmpty()) {
-            ProductSkuSaveReqVO skuDO = commonTempList.get(0);
-            if (productSkuList.size() > 1) {
-                productSkuList.remove(skuDO);
-                productSkuList.forEach(sku -> {
-                    sku.setCostPrice(sku.getCostPrice().add(skuDO.getCostPrice()));
-                    if (sku.getSalePriceIsEmpty()) {
-                        sku.setSalePrice(sku.getSalePrice().add(skuDO.getSalePrice()));
-                    }
-                });
-            }
-        }
         // 产品sku规格信息的新增与修改
-        productGroupService.saveSkuAndGroupList(nomustList, productSkuList, productId);
+        productGroupService.saveSkuAndGroupList(specGroupList, productSkuList, productId);
     }
 
     @Override
@@ -338,6 +251,15 @@ public class ProductSpuServiceImpl implements ProductSpuService {
             }
         }
 
+        spuShipMapper.delete(SpuShipDO::getProductId, updateObj.getId());
+        String[] ships = updateReqVO.getShipIds().split(",");
+        for (String ship : ships) {
+            SpuShipDO spuShip = new SpuShipDO();
+            spuShip.setId(IdWorker.getId(spuShip));
+            spuShip.setShipId(ship);
+            spuShip.setProductId(updateReqVO.getId());
+            spuShipMapper.insert(spuShip);
+        }
         ProductBasicRuleDO basicRuleDO = BeanUtils.toBean(updateReqVO.getProductBasicRule(), ProductBasicRuleDO.class);
         productBasicMapper.updateById(basicRuleDO);
 
@@ -359,37 +281,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         ProductOtherRuleDO otherRuleDO = BeanUtils.toBean(updateReqVO.getProductOtherRule(), ProductOtherRuleDO.class);
         productOtherMapper.updateById(otherRuleDO);
 
-        Long tenantId = TenantContextHolder.getTenantId();
-        List<PlatProductPriceRespVO> platProductPriceList = new ArrayList<>();
-        if (updateReqVO.getPlatProductList() != null && !updateReqVO.getPlatProductList().isEmpty()) {
-            // 分销产品信息的新增与修改
-            List<ProductGroupDO> groupDBList = productGroupMapper.selectList(new LambdaQueryWrapper<ProductGroupDO>()
-                    .eq(ProductGroupDO::getProductId, updateObj.getId())
-                    .eq(ProductGroupDO::getProductBaseType, 1)
-                    .eq(ProductGroupDO::getDeleted, 0));
-            List<Long> idList = groupDBList.stream().map(ProductGroupDO::getId).collect(Collectors.toList());
-            if (!idList.isEmpty()) {
-                productGroupMapper.deleteBatchIds(idList);
-            }
-            for(PlatProductSaveReqVO item : updateReqVO.getPlatProductList()) {
-                if (item.getPlatProductPriceList() != null && !item.getPlatProductPriceList().isEmpty()) {
-                    platProductPriceList.addAll(item.getPlatProductPriceList());
-                }
-                Map<String, Object> idMap = productGroupMapper.selectDistributorProductId(tenantId, item.getPlatProductId());
-                if (idMap.isEmpty()) {
-                    throw exception(NO_PLAT_PRODUCT_AVAILABLE);
-                }
-                item.setProductId(updateObj.getId());
-                item.setProductBaseId(MapUtil.getLong(idMap, "id"));
-                item.setId(IdWorker.getId());
-            }
-            List<ProductGroupDO> list = BeanUtils.toBean(updateReqVO.getPlatProductList(), ProductGroupDO.class);
-            productGroupMapper.insertBatch(list);
-        } else {
-            productGroupMapper.deletePlatProduct(updateObj.getId());
-        }
         // 保存sku信息
-        saveSkuAndGroupList(updateReqVO.getProductGroupList(), updateReqVO.getProductSkuList(), platProductPriceList, updateReqVO.getId());
+        saveSkuAndGroupList(updateReqVO.getProductGroupList(), updateReqVO.getProductSkuList(), updateReqVO.getId());
     }
 
     @Override
@@ -449,6 +342,14 @@ public class ProductSpuServiceImpl implements ProductSpuService {
             ProductBasicRuleDO basicRuleDO = productBasicMapper.selectById(id);
             spuRespVO.setProductBasicRule(BeanUtils.toBean(basicRuleDO, ProductBasicRuleRespVO.class));
 
+            List<SpuShipDO> spuShipDOS = spuShipMapper.selectList(
+                    new LambdaQueryWrapperX<SpuShipDO>()
+                    .eqIfPresent(SpuShipDO::getProductId, id)
+                    .eq(SpuShipDO::getDeleted, false)
+            );
+            String shipIds = spuShipDOS.stream().map(SpuShipDO::getShipId).collect(Collectors.joining(","));
+            spuRespVO.setShipIds(shipIds);
+
             ProductSaleRuleDO saleRuleDO = productSaleMapper.selectById(id);
             spuRespVO.setProductSaleRule(BeanUtils.toBean(saleRuleDO, ProductSaleRuleRespVO.class));
 

+ 55 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/spuship/SpuShipService.java

@@ -0,0 +1,55 @@
+package com.yc.ship.module.product.service.spuship;
+
+import java.util.*;
+import javax.validation.*;
+import com.yc.ship.module.product.controller.admin.spuship.vo.*;
+import com.yc.ship.module.product.dal.dataobject.spuship.SpuShipDO;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.pojo.PageParam;
+
+/**
+ * 产品游船 Service 接口
+ *
+ * @author lsq
+ */
+public interface SpuShipService {
+
+    /**
+     * 创建产品游船
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createSpuShip(@Valid SpuShipSaveReqVO createReqVO);
+
+    /**
+     * 更新产品游船
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateSpuShip(@Valid SpuShipSaveReqVO updateReqVO);
+
+    /**
+     * 删除产品游船
+     *
+     * @param id 编号
+     */
+    void deleteSpuShip(Long id);
+
+    /**
+     * 获得产品游船
+     *
+     * @param id 编号
+     * @return 产品游船
+     */
+    SpuShipDO getSpuShip(Long id);
+
+    /**
+     * 获得产品游船分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 产品游船分页
+     */
+    PageResult<SpuShipDO> getSpuShipPage(SpuShipPageReqVO pageReqVO);
+
+}

+ 74 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/spuship/SpuShipServiceImpl.java

@@ -0,0 +1,74 @@
+package com.yc.ship.module.product.service.spuship;
+
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import com.yc.ship.module.product.controller.admin.spuship.vo.*;
+import com.yc.ship.module.product.dal.dataobject.spuship.SpuShipDO;
+import com.yc.ship.framework.common.pojo.PageResult;
+import com.yc.ship.framework.common.pojo.PageParam;
+import com.yc.ship.framework.common.util.object.BeanUtils;
+
+import com.yc.ship.module.product.dal.mysql.spuship.SpuShipMapper;
+
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.yc.ship.module.product.enums.ErrorCodeConstants.*;
+
+/**
+ * 产品游船 Service 实现类
+ *
+ * @author lsq
+ */
+@Service
+@Validated
+public class SpuShipServiceImpl implements SpuShipService {
+
+    @Resource
+    private SpuShipMapper spuShipMapper;
+
+    @Override
+    public Long createSpuShip(SpuShipSaveReqVO createReqVO) {
+        // 插入
+        SpuShipDO spuShip = BeanUtils.toBean(createReqVO, SpuShipDO.class);
+        spuShipMapper.insert(spuShip);
+        // 返回
+        return spuShip.getId();
+    }
+
+    @Override
+    public void updateSpuShip(SpuShipSaveReqVO updateReqVO) {
+        // 校验存在
+        validateSpuShipExists(updateReqVO.getId());
+        // 更新
+        SpuShipDO updateObj = BeanUtils.toBean(updateReqVO, SpuShipDO.class);
+        spuShipMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteSpuShip(Long id) {
+        // 校验存在
+        validateSpuShipExists(id);
+        // 删除
+        spuShipMapper.deleteById(id);
+    }
+
+    private void validateSpuShipExists(Long id) {
+        if (spuShipMapper.selectById(id) == null) {
+            throw exception(500,"不存在");
+        }
+    }
+
+    @Override
+    public SpuShipDO getSpuShip(Long id) {
+        return spuShipMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<SpuShipDO> getSpuShipPage(SpuShipPageReqVO pageReqVO) {
+        return spuShipMapper.selectPage(pageReqVO);
+    }
+
+}

+ 32 - 1
ship-module-product/ship-module-product-biz/src/main/resources/mapper/productSpu/ProductSpuMapper.xml

@@ -49,7 +49,7 @@
             <result property="stock" column="stock"/>
         </association>
         <collection property="productGroupList" column="id" select="selectSpuGroupList" javaType="ArrayList"
-                    ofType="com.yc.ship.module.ota.controller.admin.distributorproduct.vo.product.ProductGroupRespVO"/>
+                    ofType="com.yc.ship.module.product.controller.admin.productSpu.groupVO.ProductGroupRespVO"/>
     </resultMap>
 
     <select id="selectPage2" resultMap="ProductSpuRespMap">
@@ -199,6 +199,37 @@
         ORDER BY p.create_time desc
     </select>
 
+    <select id="selectSpuGroupList" resultType="com.yc.ship.module.product.controller.admin.productSpu.groupVO.ProductGroupRespVO">
+        SELECT
+        pg.id,
+        pg.product_id productId,
+        pg.product_base_id productBaseId,
+        pg.product_base_type productBaseType,
+        pg.sku_id skuId,
+        pg.project_id projectId,
+        pg.specification_id specificationId,
+        pg.first_resource_id firstResourceId,
+        pg.cost_price costPrice,
+        pg.sale_price salePrice,
+        pg.spec_type specType,
+        pg.need_choose needChoose,
+        p.product_name productName,
+        pb.`name` productBaseName,
+        pb.can_repeat_buy canRepeatBuy,
+        pp.`name` projectName,
+        pp.`name` specificationName
+        FROM
+        product_group pg
+        INNER JOIN product_spu p ON p.id = pg.product_id
+        INNER JOIN product_base pb ON pb.id = pg.product_base_id
+        INNER JOIN product_project pp ON pp.id = pg.project_id
+        WHERE
+        pg.deleted = 0
+        and pg.product_base_type = 0
+        AND pg.product_id = #{id}
+        ORDER BY pg.id,pg.update_time
+    </select>
+
     <select id="getProductSpuListByStatus" resultType="com.yc.ship.module.product.dal.dataobject.productSpu.ProductSpuDO">
         SELECT
             t1.*