Selaa lähdekoodia

商品列表/详情

Aslee 4 vuotta sitten
vanhempi
commit
19a865e358

+ 39 - 0
src/main/java/com/caimei/controller/ProductApi.java

@@ -2,6 +2,7 @@ package com.caimei.controller;
 
 import com.caimei.model.ResponseJson;
 import com.caimei.model.vo.ClubVo;
+import com.caimei.model.vo.ProductVo;
 import com.caimei.service.ProductService;
 import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.Api;
@@ -11,6 +12,7 @@ import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 /**
@@ -49,4 +51,41 @@ public class ProductApi {
     public ResponseJson<PageInfo<ClubVo>> clubList(Integer organizeId, String name, Integer pageNum, Integer pageSize) {
         return productService.clubList(organizeId, name, pageNum, pageSize);
     }
+
+
+    /**
+     * 立即下单商品列表
+     *
+     * @param organizeId        组织id
+     * @param productName       商品名称
+     * @return
+     */
+    @ApiOperation("立即下单商品列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "organizeId", required = true, value = "组织id"),
+            @ApiImplicitParam(name = "productName", required = false, value = "商品名称"),
+            @ApiImplicitParam(name = "pageNum", required = false, value = "第几页"),
+            @ApiImplicitParam(name = "pageSize", required = false, value = "一页多少条")
+    })
+    @GetMapping("/list")
+    public ResponseJson<PageInfo<ProductVo>> productList(Integer organizeId, String productName,
+                                                         @RequestParam(value = "pageNum", defaultValue = "1")Integer pageNum,
+                                                         @RequestParam(value = "pageSize", defaultValue = "10")Integer pageSize) {
+        return productService.productList(organizeId, productName, pageNum, pageSize);
+    }
+
+    /**
+     * 商品详情
+     *
+     * @param productId        商品Id
+     * @return
+     */
+    @ApiOperation("商品详情")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "productId", required = true, value = "商品Id")
+    })
+    @GetMapping("/details")
+    public ResponseJson<ProductVo> productDetails(Integer productId) {
+        return productService.productDetails(productId);
+    }
 }

+ 65 - 0
src/main/java/com/caimei/mapper/ProductMapper.java

@@ -1,6 +1,9 @@
 package com.caimei.mapper;
 
+import com.caimei.model.po.*;
 import com.caimei.model.vo.ClubVo;
+import com.caimei.model.vo.LadderPriceVo;
+import com.caimei.model.vo.ProductVo;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -22,4 +25,66 @@ public interface ProductMapper {
      * @return
      */
     List<ClubVo> findClubList(@Param("organizeId") Integer organizeId,@Param("name") String name);
+
+    /**
+     * 查询组织商品
+     * @param organizeId
+     * @param productName
+     * @return
+     */
+    List<ProductVo> findProductList(@Param("organizeId") Integer organizeId,@Param("productName") String productName);
+
+    /**
+     * 根据商品Id查询促销活动
+     * @param productId
+     * @return
+     */
+    PromotionsPo findPromotionByProductId(Integer productId);
+
+    /**
+     * 获取阶梯价格
+     * @param productId
+     * @return
+     */
+    List<LadderPriceVo> findLadderPriceByProductId(Integer productId);
+
+    /**
+     * 查询商品
+     * @param productId
+     * @return
+     */
+    ProductVo findProductByProductId(Integer productId);
+
+    /**
+     * 查询商品图片
+     * @param originalProductId 原采美商品Id
+     * @return
+     */
+    List<ProductImagePo> findProductImagesByOriginalId(Integer originalProductId);
+
+    /**
+     * 商品详细信息
+     * @param originalProductId
+     * @return
+     */
+    ProductDetailInfoPo findProductDetailByOriginalId(Integer originalProductId);
+
+    /**
+     * 商品分类名称
+     *
+     * @param bigTypeId
+     * @param smallTypeId
+     * @param tinyTypeId
+     * @return
+     */
+    String findTypeName(@Param("bigTypeId") Integer bigTypeId, @Param("smallTypeId") Integer smallTypeId, @Param("tinyTypeId") Integer tinyTypeId);
+
+    /**
+     *
+     * @param brandId
+     * @return
+     */
+    String findBrandNameByBrandId(Integer brandId);
+
+    List<RelatedParametersPo> findParametersByOriginalId(Integer originalProductId);
 }

+ 75 - 0
src/main/java/com/caimei/model/po/CmBrandPo.java

@@ -0,0 +1,75 @@
+package com.caimei.model.po;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * cm_brand
+ *
+ * @author
+ */
+@Data
+public class CmBrandPo implements Serializable {
+    private Integer id;
+
+    /**
+     * 品牌名字
+     */
+    private String name;
+
+    /**
+     * 添加来源 0:后台添加 ,1:供应商添加
+     */
+    private String source;
+
+    /**
+     * 添加用户ID,后台则为后台用户ID,供应商则为供应商用户ID
+     */
+    private Integer userId;
+
+    /**
+     * 品牌状态 0:待审核,1:审核通过,2:审核失败
+     */
+    private String status;
+
+    /**
+     * 审核备注
+     */
+    private String auditNote;
+
+    /**
+     * 排序
+     */
+    private Integer sort;
+
+    /**
+     * 删除标记 0 否,其余是
+     */
+    private String delFlag;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createDate;
+
+    /**
+     * 最后更新时间
+     */
+    private Date updateDate;
+
+    /**
+     * 品牌logo
+     */
+    private String logo;
+
+    /**
+     * 品牌描述
+     */
+    private String description;
+
+    private static final long serialVersionUID = 1L;
+}

+ 48 - 0
src/main/java/com/caimei/model/po/ProductDetailInfoPo.java

@@ -0,0 +1,48 @@
+package com.caimei.model.po;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * productdetailinfo
+ * @author
+ */
+@Data
+public class ProductDetailInfoPo implements Serializable {
+    private Integer productDetailInfoId;
+
+    /**
+     * 商品Id
+     */
+    private Integer productId;
+
+    private String propValueAlias;
+
+    private String propValueImages;
+
+    /**
+     * 商品详情信息
+     */
+    private String detailInfo;
+
+    private String detailInfoTxt;
+
+    private String seoTitle;
+
+    private String seoKeyword;
+
+    private String seoDes;
+
+    /**
+     * 服务详情
+     */
+    private String serviceInfo;
+
+    /**
+     * 订购方案
+     */
+    private String orderInfo;
+
+    private static final long serialVersionUID = 1L;
+}

+ 46 - 0
src/main/java/com/caimei/model/po/ProductImagePo.java

@@ -0,0 +1,46 @@
+package com.caimei.model.po;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * productimage
+ * @author
+ */
+@Data
+public class ProductImagePo implements Serializable {
+    private Integer productImageId;
+
+    /**
+     * 商品Id
+     */
+    private Integer productId;
+
+    /**
+     * 商品对应供应商Id
+     */
+    private Integer shopId;
+
+    /**
+     * 添加时间
+     */
+    private String addTime;
+
+    /**
+     * 图片
+     */
+    private String image;
+
+    /**
+     * 是否主图:1是,空或0不是
+     */
+    private String mainFlag;
+
+    /**
+     * 排序值
+     */
+    private Integer sortIndex;
+
+    private static final long serialVersionUID = 1L;
+}

+ 63 - 0
src/main/java/com/caimei/model/po/PromotionsPo.java

@@ -0,0 +1,63 @@
+package com.caimei.model.po;
+
+import com.caimei.model.vo.ProductVo;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/8/17
+ */
+@Data
+public class PromotionsPo implements Serializable {
+    private Integer id;
+    /**
+     * 组织Id
+     */
+    private Integer organizeId;
+    /**
+     * 促销名称
+     */
+    private String name;
+    /**
+     * 促销描述
+     */
+    private String description;
+    /**
+     * 分类: 1单品促销,2凑单促销,3店铺促销
+     */
+    private Integer type;
+    /**
+     * 促销方式:1优惠,2满减,3满赠
+     */
+    private Integer mode;
+    /**
+     * 优惠价/满减/满赠的设定价格(如满999赠商品)
+     */
+    private BigDecimal touchPrice;
+    /**
+     * 减免价格
+     */
+    private BigDecimal reducedPrice;
+    /**
+     * 开始时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date beginTime;
+    /**
+     * 结束时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date endTime;
+    /**
+     * 时效:1永久,2区间过期,其它无效
+     */
+    private Integer status;
+}

+ 37 - 0
src/main/java/com/caimei/model/po/RelatedParametersPo.java

@@ -0,0 +1,37 @@
+package com.caimei.model.po;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * cm_product_related_parameters
+ *
+ * @author
+ */
+@Data
+public class RelatedParametersPo implements Serializable {
+    private Integer id;
+
+    /**
+     * 商品ID
+     */
+    private Integer productId;
+
+    /**
+     * 参数名称
+     */
+    private String paramsName;
+
+    /**
+     * 参数内容
+     */
+    private String paramsContent;
+
+    /**
+     * 删除标记 0否 其余是
+     */
+    private String delFlag;
+
+    private static final long serialVersionUID = 1L;
+}

+ 38 - 0
src/main/java/com/caimei/model/vo/LadderPriceVo.java

@@ -0,0 +1,38 @@
+package com.caimei.model.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author Aslee
+ */
+@Data
+public class LadderPriceVo {
+    private Integer id;
+
+    /**
+     * 商品id
+     */
+    private Integer productId;
+
+    /**
+     * 第几阶梯
+     */
+    private Integer ladderNum;
+
+    /**
+     * 购买数量
+     */
+    private Integer buyNum;
+
+    /**
+     * 购买价格
+     */
+    private BigDecimal buyPrice;
+
+    /**
+     * 阶梯价格数量区间显示
+     */
+    private String buyNumRangeShow;
+}

+ 164 - 0
src/main/java/com/caimei/model/vo/ProductVo.java

@@ -0,0 +1,164 @@
+package com.caimei.model.vo;
+
+import com.caimei.model.po.ProductDetailInfoPo;
+import com.caimei.model.po.ProductImagePo;
+import com.caimei.model.po.PromotionsPo;
+import com.caimei.model.po.RelatedParametersPo;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Aslee
+ * @date : 2021/3/23
+ */
+@Data
+public class ProductVo {
+
+    /**
+     * 商品Id
+     */
+    private Integer productId;
+
+    /**
+     * 原采美商品Id
+     */
+    private Integer originalProductId;
+
+    /**
+     * 商品名称
+     */
+    private String productName;
+
+    /**
+     * 商品图片
+     */
+    private String mainImage;
+
+    /**
+     * 机构价
+     */
+    private BigDecimal price;
+
+    /**
+     * 规格
+     */
+    private String unit;
+
+    /**
+     * 起订量
+     */
+    private Integer minBuyNumber;
+
+    /**
+     * 启用阶梯价格标识 0否 1是
+     */
+    private Integer ladderPriceFlag;
+
+    /**
+     * 是否含税   0不含税,1含税,2未知
+     */
+    private Integer includedTax;
+
+    /**
+     * 发票类型(基于是否含税基础)   1增值税票,2普通票, 3不能开票
+     */
+    private Integer invoiceType;
+
+    /**
+     * 开票税点(基于不含税基础) :增值税默认13%,普通票6%取值范围[0-100]
+     */
+    private BigDecimal clubTaxPoint;
+
+    /**
+     * 展示价格
+     */
+    private BigDecimal retailPrice;
+
+    /**
+     * 商品状态:0已下架,1已上架
+     */
+    private Integer status;
+
+    /**
+     * 商品标签用英文逗号隔开,中文逗号或其它一律不作切割
+     */
+    private String tags;
+
+
+
+
+
+    /**
+     * 阶梯价格集合
+     */
+    private List<LadderPriceVo> ladderPriceList;
+
+    /**
+     * 商品是否处于活动状态:1是,空或0不是[活动商品和actFlag含义不同]
+     */
+    private Integer actStatus;
+
+    /**
+     * 促销活动
+     */
+    private PromotionsPo promotion;
+
+    /**
+     * 标签数组
+     */
+    private String[] tagsList;
+
+    /**
+     * 商品图片
+     */
+    private List<ProductImagePo> imageList;
+
+    /**
+     * 商品详情
+     */
+    private ProductDetailInfoPo productDetail;
+
+    /**
+     * 机构用户价格等级(范围1-5)【V6.2.0版本已废弃-根据价格范围显示等级】
+     */
+    private String priceGrade;
+
+    /**
+     * 一级分类id
+     */
+    private Integer bigTypeId;
+
+    /**
+     * 二级分类id
+     */
+    private Integer smallTypeId;
+
+    /**
+     * 三级分类Id
+     */
+    private Integer tinyTypeId;
+
+    /**
+     * 所在分类名称
+     */
+    private String typeName;
+
+    /**
+     * 品牌Id
+     */
+    private Integer brandId;
+
+    /**
+     * 品牌名称
+     */
+    private String brandName;
+
+    /**
+     * 相关参数
+     */
+    private List<RelatedParametersPo> parametersList;
+}

+ 30 - 0
src/main/java/com/caimei/service/ProductService.java

@@ -2,6 +2,7 @@ package com.caimei.service;
 
 import com.caimei.model.ResponseJson;
 import com.caimei.model.vo.ClubVo;
+import com.caimei.model.vo.ProductVo;
 import com.github.pagehelper.PageInfo;
 
 /**
@@ -21,4 +22,33 @@ public interface ProductService {
      * @return
      */
     ResponseJson<PageInfo<ClubVo>> clubList(Integer organizeId, String name, Integer pageNum, Integer pageSize);
+
+    /**
+     * 商品列表
+     * @param organizeId
+     * @param productName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PageInfo<ProductVo>> productList(Integer organizeId, String productName, Integer pageNum, Integer pageSize);
+
+    /**
+     * 设置商品价格
+     * @param product
+     */
+    void setProductPrice(ProductVo product);
+
+    /**
+     * 获取阶梯价
+     * @param product
+     */
+    void getLadderPrice(ProductVo product);
+
+    /**
+     * 商品详情
+     * @param productId
+     * @return
+     */
+    ResponseJson<ProductVo> productDetails(Integer productId);
 }

+ 155 - 0
src/main/java/com/caimei/service/impl/ProductServiceImpl.java

@@ -2,13 +2,22 @@ package com.caimei.service.impl;
 
 import com.caimei.mapper.ProductMapper;
 import com.caimei.model.ResponseJson;
+import com.caimei.model.po.*;
 import com.caimei.model.vo.ClubVo;
+import com.caimei.model.vo.LadderPriceVo;
+import com.caimei.model.vo.ProductVo;
 import com.caimei.service.ProductService;
+import com.caimei.util.MathUtil;
+import com.caimei.util.ProductUtils;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -21,6 +30,8 @@ import java.util.List;
 public class ProductServiceImpl implements ProductService {
     @Resource
     private ProductMapper productMapper;
+    @Value("${caimei.oldapi}")
+    private String domain;
 
     @Override
     public ResponseJson<PageInfo<ClubVo>> clubList(Integer organizeId, String name, Integer pageNum, Integer pageSize) {
@@ -32,4 +43,148 @@ public class ProductServiceImpl implements ProductService {
 
         return ResponseJson.success(pageInfo);
     }
+
+    @Override
+    public ResponseJson<PageInfo<ProductVo>> productList(Integer organizeId, String productName, Integer pageNum, Integer pageSize) {
+        if (null == organizeId) {
+            return ResponseJson.error("参数异常", null);
+        }
+        PageHelper.startPage(pageNum,pageSize);
+        List<ProductVo> productList = productMapper.findProductList(organizeId, productName);
+        for (ProductVo product : productList) {
+            setProductPrice(product);
+        }
+        PageInfo<ProductVo> pageInfo = new PageInfo<>(productList);
+        return ResponseJson.success(pageInfo);
+    }
+
+
+
+
+    @Override
+    public ResponseJson<ProductVo> productDetails(Integer productId) {
+        ProductVo product = productMapper.findProductByProductId(productId);
+        if (product == null) {
+            //商品不存在
+            return ResponseJson.error("商品不存在",null);
+        }
+        String[] split = null;
+        //商品标签
+        if (product.getTags() != null) {
+            String tags = product.getTags();
+            tags = tags.replace(" ", ",").replace("、", ",").replace(",", ",");
+            if (tags.contains(",")) {
+                split = tags.split(",");
+                List<String> list = new ArrayList();
+                for (String s : split) {
+                    if (s != null && !s.equals("")) {
+                        list.add(s);
+                    }
+                }
+                split = list.toArray(new String[list.size()]);
+            }
+        }
+        product.setTagsList(split);
+        product.setMainImage(ProductUtils.getImageURL("product", product.getMainImage(), 0, domain));
+        //商品图片
+        List<ProductImagePo> imageList = productMapper.findProductImagesByOriginalId(product.getOriginalProductId());
+        for (ProductImagePo image : imageList) {
+            String imageURL = ProductUtils.getImageURL("product", image.getImage(), 0, domain);
+            image.setImage(imageURL);
+        }
+        product.setImageList(imageList);
+        //商品详情
+        ProductDetailInfoPo productDetail = productMapper.findProductDetailByOriginalId(product.getOriginalProductId());
+        product.setProductDetail(productDetail);
+        //价格等级
+        String priceGrade = ProductUtils.getPriceGrade(product.getPrice().doubleValue());
+        product.setPriceGrade(priceGrade);
+        //商品分类
+        String typeName = productMapper.findTypeName(product.getBigTypeId(),product.getSmallTypeId(), product.getTinyTypeId());
+        product.setTypeName(typeName);
+        //品牌名称
+        String brandName = productMapper.findBrandNameByBrandId(product.getBrandId());
+        if (StringUtils.isNotBlank(brandName)) {
+            product.setBrandName(brandName);
+        }
+        //相关参数
+        List<RelatedParametersPo> parametersList = productMapper.findParametersByOriginalId(product.getOriginalProductId());
+        product.setParametersList(parametersList);
+        if (0 != product.getStatus()) {
+            setProductPrice(product);
+        }
+        return ResponseJson.success(product);
+    }
+
+
+
+    @Override
+    public void setProductPrice(ProductVo product){
+        // 设置图片
+        product.setMainImage(ProductUtils.getImageURL("product", product.getMainImage(), 0, domain));
+        // 设置商品展示价格
+        PromotionsPo activity = productMapper.findPromotionByProductId(product.getProductId());
+        if (null != activity) {
+            product.setActStatus(1);
+            product.setPromotion(activity);
+            product.setLadderPriceFlag(0);
+            // 活动价
+            if (activity.getType() == 1 && null != activity.getTouchPrice()) {
+                product.setRetailPrice(activity.getTouchPrice());
+            }else {
+                product.setRetailPrice(product.getPrice());
+            }
+        } else if (1 == product.getLadderPriceFlag()) {
+            // 启用阶梯价格
+            getLadderPrice(product);
+        } else {
+            product.setActStatus(0);
+            product.setLadderPriceFlag(0);
+            product.setRetailPrice(product.getPrice());
+        }
+        //添加税费
+        boolean addTaxFlag = (0 == product.getIncludedTax() && (1 == product.getInvoiceType() || 2 == product.getInvoiceType()));
+        if (addTaxFlag) {
+            BigDecimal addedValueTax = MathUtil.div(MathUtil.mul(product.getRetailPrice(), product.getClubTaxPoint()), BigDecimal.valueOf(100));
+            BigDecimal price = MathUtil.add(product.getRetailPrice(), addedValueTax);
+            product.setRetailPrice(price);
+            if (activity != null && activity.getType() == 1 && activity.getMode() == 1) {
+                activity.setTouchPrice(price);
+            }
+        }
+    }
+
+    @Override
+    public void getLadderPrice(ProductVo product) {
+        product.setActStatus(0);
+        // 启用阶梯价格
+        List<LadderPriceVo> ladderPriceList = productMapper.findLadderPriceByProductId(product.getProductId());
+        if (ladderPriceList.size() > 0) {
+            for (int i = 0; i < ladderPriceList.size(); i++) {
+                if (null != ladderPriceList.get(i)) {
+                    String buyNumRangeShow;
+                    if ((i + 1) < ladderPriceList.size() && null != ladderPriceList.get(i + 1)) {
+                        buyNumRangeShow = ladderPriceList.get(i).getBuyNum() + "~" + (ladderPriceList.get(i + 1).getBuyNum() - 1L);
+                    } else {
+                        buyNumRangeShow = "≥" + ladderPriceList.get(i).getBuyNum();
+                    }
+                    ladderPriceList.get(i).setBuyNumRangeShow(buyNumRangeShow);
+                }
+            }
+            product.setRetailPrice(ladderPriceList.get(0).getBuyPrice());
+            product.setMinBuyNumber(ladderPriceList.get(0).getBuyNum());
+            product.setLadderPriceList(ladderPriceList);
+            //阶梯价列表添加税费
+            boolean addTaxFlag = (0 == product.getIncludedTax() && (1 == product.getInvoiceType() || 2 == product.getInvoiceType()));
+            if (addTaxFlag) {
+                ladderPriceList.stream().forEach(item->{
+                    item.setBuyPrice(MathUtil.add(item.getBuyPrice(), MathUtil.div(MathUtil.mul(item.getBuyPrice(), product.getClubTaxPoint()), 100)));
+                });
+            }
+        } else {
+            // 阶梯价格异常,关闭阶梯价格
+            product.setLadderPriceFlag(0);
+            product.setRetailPrice(product.getPrice());
+        }
+    }
 }

+ 366 - 0
src/main/java/com/caimei/util/MathUtil.java

@@ -0,0 +1,366 @@
+package com.caimei.util;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/3/19
+ */
+
+public class MathUtil {
+
+
+
+	public static int default_scale = 4;
+
+	private static final int MAX_GENERATE_COUNT = 99999;
+	private static int generateCount = 0;
+
+
+	/**
+	 * 两个实数相除,默认四舍五入到4位
+	 *
+	 * @param v1
+	 * @param v2
+	 * @return
+	 */
+	public static BigDecimal div(Object v1, Object v2) {
+		return div(v1, v2, default_scale);
+	}
+
+	/**
+	 * 两个实数相除,默认四舍五入到scale位
+	 *
+	 * @param v1
+	 * @param v2
+	 * @param scale
+	 * @return
+	 */
+	public static BigDecimal div(Object v1, Object v2, int scale) {
+		if (scale < 0) {
+			throw new IllegalArgumentException("四舍五入的位数不能为负数");
+		}
+		BigDecimal b1 = convert(v1);
+		BigDecimal b2 = convert(v2);
+		if (equal0(b2)) {
+			throw new IllegalArgumentException("除数不能为0");
+		}
+		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
+	}
+
+	public static String formatDouble(double s) {
+		DecimalFormat fmt = new DecimalFormat("0.00");
+		return fmt.format(s);
+	}
+
+	public static String[] intersect(String[] arr1, String[] arr2){
+		List<String> l = new LinkedList<String>();
+		Set<String> common = new HashSet<String>();
+		for(String str:arr1){
+			if(!l.contains(str)){
+				l.add(str);
+			}
+		}
+		for(String str:arr2){
+			if(l.contains(str)){
+				common.add(str);
+			}
+		}
+		String[] result={};
+		return common.toArray(result);
+	}
+
+
+	public static synchronized String getUniqueString() {
+		if (generateCount > 99999) {generateCount = 0;}
+		String uniqueNumber = Long.toString(System.currentTimeMillis())
+				+ Integer.toString(generateCount);
+		generateCount++;
+		return uniqueNumber;
+	}
+
+	/**
+	 *
+	 * 构造函数
+	 */
+	private MathUtil() {
+
+	}
+
+	/**
+	 * 类型转换函数
+	 *
+	 * @param o
+	 * @return
+	 */
+	public static BigDecimal convert(Object o) {
+		if (o == null) {
+			return BigDecimal.ZERO;
+		} else if (o instanceof BigDecimal) {
+			return (BigDecimal) o;
+		}
+		String str = o.toString();
+		if (StringUtils.isNotBlank(str)) {
+			return new BigDecimal(str);
+		} else {
+			return BigDecimal.ZERO;
+		}
+	}
+
+	/**
+	 * 两个实数相加
+	 *
+	 * @param v1
+	 * @param v2
+	 * @return
+	 */
+	public static BigDecimal add(Object v1, Object v2) {
+		BigDecimal b1 = convert(v1);
+		BigDecimal b2 = convert(v2);
+		return b1.add(b2);
+
+	}
+
+	/**
+	 * 两个实数相减
+	 *
+	 * @param v1
+	 * @param v2
+	 * @return
+	 */
+	public static BigDecimal sub(Object v1, Object v2) {
+		BigDecimal b1 = convert(v1);
+		BigDecimal b2 = convert(v2);
+		return b1.subtract(b2);
+
+	}
+
+	/**
+	 * 两个实数相乘
+	 *
+	 * @param v1
+	 * @param v2
+	 * @return
+	 */
+	public static BigDecimal mul(Object v1, Object v2) {
+		BigDecimal b1 = convert(v1);
+		BigDecimal b2 = convert(v2);
+		return b1.multiply(b2);
+
+	}
+
+	/**
+	 * 相个实数相乘并四舍五入到Sacle位
+	 *
+	 * @param v1
+	 * @param v2
+	 * @param scale
+	 * @return
+	 */
+	public static BigDecimal mul(Object v1, Object v2, int scale) {
+		if (scale < 0) {
+			throw new IllegalArgumentException("四舍五入的位数不能为负数");
+		}
+		BigDecimal b1 = convert(v1);
+		BigDecimal b2 = convert(v2);
+		return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP);
+
+	}
+
+	/**
+	 * 两个实数比较
+	 *
+	 * @param v1
+	 * @param v2
+	 * @return
+	 */
+	public static int compare(Object v1, Object v2) {
+		BigDecimal b1 = convert(v1);
+		BigDecimal b2 = convert(v2);
+		return b1.compareTo(b2);
+	}
+
+	public static boolean equal0(Object v1) {
+		BigDecimal b1 = convert(v1);
+		return b1.compareTo(BigDecimal.ZERO) == 0;
+	}
+
+	public static boolean notEqual0(Object v1) {
+		BigDecimal b1 = convert(v1);
+		return b1.compareTo(BigDecimal.ZERO) != 0;
+	}
+
+	/**
+	 * 两个整数比较
+	 *
+	 * @param v1
+	 * @param v2
+	 * @return
+	 */
+	public static int compareInt(Integer v1, Integer v2) {
+
+		if (v1 == null) {
+			v1 = new Integer(0);
+		}
+		if (v2 == null) {
+			v2 = new Integer(0);
+		}
+		return v1.compareTo(v2);
+	}
+
+	/**
+	 * 判断两个整数是否相等
+	 *
+	 * @param v1
+	 * @param v2
+	 * @return
+	 */
+	public static boolean equal(Integer v1, Integer v2) {
+
+		int result = compareInt(v1, v2);
+		return result == 0;
+	}
+
+	/**
+	 * 判断两个整数不等
+	 *
+	 * @param v1
+	 * @param v2
+	 * @return
+	 */
+	public static boolean notEqual(Integer v1, Integer v2) {
+		int result = compareInt(v1, v2);
+		return result != 0;
+	}
+
+	/**
+	 * 实数的四舍五入函数
+	 *
+	 * @param v
+	 * @param scale
+	 * @return
+	 */
+	public static BigDecimal round(Object v, int scale) {
+		if (scale < 0) {
+			throw new IllegalArgumentException("四舍五入的位数不能为负数");
+		}
+		BigDecimal b = convert(v);
+		return b.setScale(scale, BigDecimal.ROUND_HALF_UP);
+	}
+
+	/**
+	 * 将字符串转换成整型
+	 *
+	 * @param value
+	 * @param defaultNum
+	 * @return
+	 */
+	public static int parsetInt(String value, int defaultNum) {
+		if (value != null && !value.equals("")) {
+			int num = defaultNum;
+			try {
+				num = Integer.parseInt(value);
+			} catch (Exception ignored) {
+			}
+			return num;
+		} else {
+			return defaultNum;
+		}
+	}
+
+	/**
+	 * 将string转换为double
+	 *
+	 * @param value
+	 * @param defaultNum
+	 * @return
+	 */
+	public static double parseDouble(String value, double defaultNum) {
+		if (StringUtils.isBlank(value)) {
+			return defaultNum;
+		}
+
+		value = value.replaceAll(",", "");
+		value = value.replaceAll(" ", "");
+		value = value.replaceAll("¥", "");
+
+		double num = defaultNum;
+		try {
+			num = Double.parseDouble(value);
+		} catch (Exception ignored) {
+		}
+		return num;
+	}
+
+	/**
+	 * 将string 转换为double
+	 *
+	 * @param value
+	 * @return
+	 */
+	public static double parseDouble(String value) {
+		return parseDouble(value, 0);
+	}
+
+	public static int isNullInteger(Integer v) {
+		if (v == null) {
+			return 0;
+		} else {
+			return v.intValue();
+		}
+	}
+
+	//
+	private static double EARTH_RADIUS = 6378.137;
+
+	private static double rad(double d) {
+
+		return d * Math.PI / 180.0;
+
+	}
+
+	public static double getDistance(double lat1, double lng1, double lat2,
+
+	double lng2) {
+
+		double radLat1 = rad(lat1);
+
+		double radLat2 = rad(lat2);
+
+		double a = radLat1 - radLat2;
+
+		double b = rad(lng1) - rad(lng2);
+
+		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+
+		+ Math.cos(radLat1) * Math.cos(radLat2)
+
+		* Math.pow(Math.sin(b / 2), 2)));
+
+		s = s * EARTH_RADIUS;
+
+		s = Math.round(s * 10000) / 10000;
+
+		return s;
+
+	}
+
+	public static void main(String[] args){
+		double lat1=118.105736;
+		double lng1=24.491558;
+		double lat2=118.110749;
+		double lng2=24.492824;
+		double t=getDistance(lat1,lng1,lat2,lng2);
+		System.out.println(t);
+	}
+
+}

+ 128 - 0
src/main/java/com/caimei/util/ProductUtils.java

@@ -0,0 +1,128 @@
+package com.caimei.util;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2020/3/25
+ */
+public class ProductUtils {
+	public static String getImageURL(String dirName, String src, String domain) {
+		return getImageURL(dirName, src, 0,domain);
+	}
+	/***
+	 * 获取图片地址
+	 *
+	 * @param src
+	 *            保存在数据库中的图片文件名
+	 * @param type
+	 *            图片的前缀 (如 type = 200 那么则获取的图片是 200_XXX的图片)
+	 * @param dirName
+	 *            图片保存的文件夹名 如 (league)
+	 * @param domain
+	 * 			   加上域名拼成完整路径
+	 * @return
+	 */
+	public static String getImageURL(String dirName, String src, int type, String domain) {
+
+
+		//正式环境 域名 http --- https处理
+		if (domain != null && !"".equals(domain) && domain.startsWith("http:") && domain.toLowerCase().lastIndexOf("test")== -1 && domain.toLowerCase().lastIndexOf("localhost")== -1) {
+			domain = domain.replace("http:", "https:");
+		}
+
+		//正式环境 图片地址 http --- https处理
+		if(src != null && src.startsWith("https:")){
+			//非正式环境 使用http
+			if (domain !=null && !"".equals(domain) && domain.toLowerCase().lastIndexOf("test")>-1 || domain.toLowerCase().lastIndexOf("localhost")>-1){
+				src = src.replace("https:","http:");
+			}
+			return src;
+		}
+
+		//正式环境 图片地址  http --- https处理
+		if(src != null && src.startsWith("http:")){
+			//非正式环境 使用http
+			if (domain !=null && !"".equals(domain) && domain.toLowerCase().lastIndexOf("test")==-1 && domain.toLowerCase().lastIndexOf("localhost")==-1){
+				src = src.replace("http:","https:");
+			}
+			return src;
+		}
+		type = 0 ;
+		dirName = dirName.trim();
+		if (dirName == null) {dirName = "";}
+		if(src == null || src.equalsIgnoreCase("null")) {src = "";}
+		if (src.indexOf(",") > 0) {
+			String tmp = src;
+			src = tmp.substring(0, tmp.indexOf(","));
+		}
+		String image = "/img/default/none.jpg";
+		if (dirName.equals("user")) {
+			image = "/img/default/HeaderImg.png";
+		} else if (dirName.equals("club")) {
+			image = "/img/default/default_club.jpg";
+		} else if (dirName.equals("shopLogo")) {
+			image = "/img/default/suppliver.jpg";
+		}else if (dirName.equals("caiMeiImage")) {
+			image = "/img/default/caiMeiImage.jpg";
+		}else {
+			image = "/img/default/none.jpg";
+		}
+		if (src != null && !src.equals("")) {
+			if (type != 0 || dirName.equals("product")) {
+				src = src.replace("\\", "/");
+				String srcActual = src;
+				String subDirName = "";
+				int index = src.lastIndexOf("/");
+
+				if (index != -1) {
+					subDirName = src.substring(0, index + 1);
+					srcActual = src.substring(index + 1);
+				}
+				boolean b = src.startsWith("/uploadFile");
+				if(b){
+					image = src;
+				}else{
+					image = "/uploadFile/" + dirName + "/" + subDirName
+							+ (type == 0 ? "" : type + "_") + srcActual;
+				}
+			} else {
+				boolean b = src.startsWith("/uploadFile");
+				if(b){
+					image = src;
+				}else{
+					image = "/uploadFile/" + dirName + "/" + src;
+				}
+			}
+		}else {
+			if(StringUtils.isEmpty(image)) {
+				image = "/img/default/none.jpg";
+			}
+		}
+		return domain + image;
+	}
+
+	public static String getProductImageURL(String image, int type, String domain) {
+		if (image == null) {
+			return getImageURL("product", "", type, domain);
+		}
+		return getImageURL("product", image, type, domain);
+	}
+
+	public static String getPriceGrade(Double price){
+        if (price <= 2.5 * 10000L) {
+        	return "1";
+        } else if (price <= 10 * 10000) {
+            return "2";
+        } else if (price <= 25 * 10000) {
+            return "3";
+        } else if (price <= 50 * 10000) {
+            return "4";
+        } else {
+            return "5";
+        }
+	}
+
+}

+ 96 - 1
src/main/resources/backup.sql

@@ -17,4 +17,99 @@ CREATE TABLE `cm_organize_buyer`(
   `delFlag` CHAR(1) COMMENT '0 有效 其它无效',
   PRIMARY KEY (`id`)
 ) CHARSET=utf8mb4
-COMMENT='组织采购人员表';
+COMMENT='组织采购人员表';
+-- 组织商品表
+CREATE TABLE `cm_organize_product` (
+    `id` INT NOT NULL AUTO_INCREMENT,
+    `organizeId` INT NULL COMMENT '组织Id',
+    `productId` INT NULL COMMENT '商品Id',
+    `ladderPriceFlag` INT NULL DEFAULT 0 COMMENT '启用阶梯价格标识 0否 1是',
+    `price` DECIMAL(11,2) NULL COMMENT '机构价',
+    `includedTax` INT NULL COMMENT '是否含税   0不含税,1含税,2未知',
+    `invoiceType` INT NULL COMMENT '发票类型(基于是否含税基础)   1增值税专用发票,2增值税普通发票, 3不能开票',
+    `clubTaxPoint` DECIMAL(11,2) NULL DEFAULT 0 COMMENT '机构税率 :增值税默认13%,普通票6%取值范围[0-100]',
+    `shopTaxPoint` DECIMAL(11,2) NULL DEFAULT 0 COMMENT '供应商税率:增值专用发票默认13%,增值税普通发票6%取值范围[0-100]',
+    `minBuyNumber` INT NULL COMMENT '最小起订量',
+    `costType` INT NULL COMMENT '成本价类型:1固定成本 2比例成本',
+    `costPrice` DECIMAL(11,2) NULL DEFAULT 0 COMMENT '成本价',
+    `costProportional` DECIMAL(11,2) NULL DEFAULT 0 COMMENT '比例成本百分比',
+    `postageType` INT NULL DEFAULT 0 COMMENT '是否包邮 0包邮 1到付 2默认(遵循运费规则)',
+    `status` INT NULL DEFAULT 1 COMMENT '商品状态:0已下架,1已上架',
+    `addTime` DATETIME NULL COMMENT '添加时间',
+    `delFlag` INT NULL DEFAULT 0 COMMENT '删除标识:0未删除,1已删除',
+PRIMARY KEY (`id`))
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = utf8
+COLLATE = utf8_bin
+COMMENT = '采美组织商品表';
+
+-- 组织商品阶梯价格表
+CREATE TABLE `caimei`.`organize_product_ladder_price` (
+      `id` INT NOT NULL AUTO_INCREMENT,
+      `productId` INT NULL COMMENT '组织商品Id',
+      `ladderNum` INT NULL COMMENT '第几阶梯',
+      `buyNum` INT NULL COMMENT '购买数量',
+      `buyPrice` DECIMAL(11,2) NULL COMMENT '购买价格',
+PRIMARY KEY (`id`))
+ENGINE = InnoDB
+DEFAULT CHARACTER SET = utf8
+COLLATE = utf8_bin
+COMMENT = '组织商品阶梯价格表';
+
+
+-- 新建 cm_organize_promotions 组织促销活动表
+drop table `cm_organize_promotions` ;
+create table `cm_organize_promotions` (
+                                          `id` int(11) not null auto_increment,
+                                          `organizeId` INT NULL COMMENT '组织Id',
+                                          `name` varchar(8) default null comment '促销名称',
+                                          `description` varchar(50) default null comment '促销描述',
+                                          `type` CHAR(1) default null comment '分类: 1单品促销,2凑单促销,3店铺促销',
+                                          `mode` CHAR(1) default null comment '促销方式:1优惠,2满减,3满赠',
+                                          `touchPrice` decimal(10,2) default null comment '优惠价/满减/满赠的设定价格(如满999赠商品)',
+                                          `reducedPrice` decimal(10,2) default null comment '减免价格',
+                                          `beginTime` datetime default null comment '开始时间',
+                                          `endTime` datetime default null comment '结束时间',
+                                          `status` CHAR(1) default null comment '时效:1永久,2区间过期,其它无效',
+                                          `delFlag` CHAR(1) default null COMMENT '0已关闭,1已删除',
+                                          `addTime` datetime default null comment '添加时间',
+                                          `updateTime` datetime default null comment '修改时间',
+                                          primary key (`id`)
+) engine=innodb default charset=utf8mb4 comment='组织促销活动表';
+-- 新建 cm_organize_promotions_product 组织促销活动_组织商品_关系表
+create table `cm_organize_promotions_product` (
+                                                  `id` int(11) not null auto_increment,
+                                                  `promotionsId` int(11) not null comment '促销活动id',
+                                                  `supplierId` int(11) default null comment '店铺id(店铺促销时供应商ID)',
+                                                  `productId` int(11) default null comment '组织商品id',
+                                                  `addTime` datetime default null comment '添加时间',
+                                                  `updateTime` datetime default null comment '修改时间',
+                                                  primary key (`id`)
+) engine=innodb auto_increment=208 default charset=utf8mb4 comment='促销活动_商品_关系表';
+-- 新建 cm_organize_promotions_product 组织促销活动_组织赠品表
+create table `cm_organize_promotions_gift` (
+                                               `id` int(11) not null auto_increment,
+                                               `productId` int(11) not null comment '组织赠品商品id',
+                                               `number` int(11) not null default 1 comment '赠品数量',
+                                               `promotionsId` int(11) not null comment '促销活动id',
+                                               `addTime` datetime default null comment '添加时间',
+                                               `updateTime` datetime default null comment '修改时间',
+                                               primary key (`id`)
+) engine=innodb auto_increment=208 default charset=utf8mb4 comment='促销活动_赠品表';
+-- 新建 cm_organize_promotions_order 组织促销活动_订单_关系表
+create table `cm_organize_promotions_order` (
+                                                `id` int(11) not null auto_increment,
+                                                `orderId` int(11) not null comment '主订单id',
+                                                `promotionsId` int(11) not null comment '促销活动id',
+                                                `name` varchar(8) not null comment '促销名称',
+                                                `description` varchar(50) default null comment '促销描述',
+                                                `type` CHAR(1) default null comment '分类: 1单品促销,2凑单促销,3店铺促销',
+                                                `mode` CHAR(1) default null comment '促销方式:1优惠,2满减,3满赠',
+                                                `touchPrice` decimal(10,2) default null comment '优惠价/满减/满赠的设定价格(如满999赠商品)',
+                                                `reducedPrice` decimal(10,2) default null comment '减免价格',
+                                                `status` CHAR(1) default null comment '时效:1永久,2区间过期,其它无效',
+                                                `beginTime` datetime default null comment '活动开始时间',
+                                                `endTime` datetime default null comment '活动结束时间',
+                                                primary key (`id`)
+) engine=innodb default charset=utf8mb4 comment='订单组织促销记录表';
+

+ 5 - 0
src/main/resources/config/beta/application-beta.yml

@@ -53,3 +53,8 @@ logging:
 swagger:
   enabled: false
 
+# 新旧www服务域名
+caimei:
+  oldapi: https://www-b.caimei365.com
+  newapi: https://spi-b.caimei365.com
+  imageDomain: https://img-b.caimei365.com

+ 6 - 0
src/main/resources/config/dev/application-dev.yml

@@ -58,3 +58,9 @@ swagger:
 wx:
   AppId: wxca7172d7a20bdf7a
   AppSecret: d7f853a64b73d01ef93f3829852a790e
+
+# 新旧www服务域名
+caimei:
+  oldapi: http://localhost:8100
+  newapi: http://localhost:8008
+  imageDomain: https://img-b.caimei365.com

+ 5 - 0
src/main/resources/config/prod/application-prod.yml

@@ -53,4 +53,9 @@ logging:
 swagger:
   enabled: false
 
+# 新旧www服务域名
+caimei:
+  oldapi: https://www.caimei365.com
+  newapi: https://spi.caimei365.com
+  imageDomain: https://img.caimei365.com
 

+ 111 - 2
src/main/resources/mapper/ProductMapper.xml

@@ -18,10 +18,119 @@
           AND u.validFlag = 1
           <if test="name != null and name != ''">
               AND (
-                u.name LIKE CONCAT("%",#{name}, "%")
-                OR u.userName LIKE CONCAT("%",#{name}, "%")
+                u.name LIKE CONCAT('%',#{name}, '%')
+                OR u.userName LIKE CONCAT('%',#{name}, '%')
               )
           </if>
     </select>
+    <select id="findProductList" resultType="com.caimei.model.vo.ProductVo">
+        select
+            cop.id as productId,
+            p.name as productName,
+            p.mainImage,
+            p.unit,
+            cop.price,
+            cop.minBuyNumber,
+            cop.ladderPriceFlag,
+            cop.includedTax,
+            cop.invoiceType,
+            cop.clubTaxPoint
+        from cm_organize_product cop
+            left join product p on cop.productId = p.productID
+        where cop.organizeId = #{organizeId} and cop.delFlag = 0
+            <if test="productName != null and productName != ''">
+                and p.name like concat('%',#{productName},'%')
+            </if>
+    </select>
+
+    <select id="findPromotionByProductId" resultType="com.caimei.model.po.PromotionsPo">
+        select op.id,
+               op.name,
+               op.description,
+               op.type,
+               op.mode,
+               op.touchPrice,
+               op.reducedPrice,
+               op.beginTime,
+               op.endTime,
+               op.status,
+               opp.productId,
+               opp.supplierId
+        from cm_organize_promotions op
+        left join cm_organize_promotions_product opp on op.id = opp.promotionsId
+        where opp.productId = #{productId}
+          and (op.status = 1 or (op.status = 2 and (NOW() between op.beginTime and op.endTime)))
+          and op.delFlag not in (1,2)
+        order by op.type desc
+        limit 1
+    </select>
+    <select id="findLadderPriceByProductId" resultType="com.caimei.model.vo.LadderPriceVo">
+        SELECT
+        id, productId, ladderNum, buyNum, buyPrice
+        FROM
+        product_ladder_price
+        WHERE
+        productId = #{productId}
+        ORDER BY
+        ladderNum ASC
+    </select>
+    <select id="findProductByProductId" resultType="com.caimei.model.vo.ProductVo">
+        select
+            cop.id as productId,
+            cop.productId as originalProductId,
+            cop.price,
+            cop.minBuyNumber,
+            cop.ladderPriceFlag,
+            cop.includedTax,
+            cop.invoiceType,
+            cop.clubTaxPoint,
+            cop.status,
+            p.name as productName,
+            p.mainImage,
+            p.unit,
+            p.tags,
+            p.bigTypeID as bigTypeId,
+            p.smallTypeID as smallTypeId,
+            p.tinyTypeID as tinyTypeId,
+            p.brandID as brandId
+        from cm_organize_product cop
+                 left join product p on cop.productId = p.productID
+        where cop.delFlag = 0 and cop.id = #{productId}
+    </select>
+    <select id="findProductImagesByOriginalId" resultType="com.caimei.model.po.ProductImagePo">
+        select
+            productImageID as productImageId, productID as productId, shopID as shopId, addTime, image, mainFlag, sortIndex
+        from productimage
+        where productID = #{productId}
+        ORDER BY mainFlag DESC
+    </select>
+    <select id="findProductDetailByOriginalId" resultType="com.caimei.model.po.ProductDetailInfoPo">
+        select
+            productDetailInfoID as productDetailInfoId, productID as productId, propValueAlias, propValueImages, detailInfo, detailInfoTxt,
+            seoTitle, seoKeyword, seoDes, serviceInfo, orderInfo
+        from productdetailinfo
+        where productID = #{productId,jdbcType=BIGINT}
+    </select>
+    <select id="findTypeName" resultType="java.lang.String">
+        SELECT
+            CONCAT_WS('-', b.name,s.name, t.name)
+        FROM
+            bigtype b
+                LEFT JOIN smalltype s ON s.smallTypeID = #{smallTypeId}
+                LEFT JOIN tinytype t ON t.tinyTypeID = #{tinyTypeId}
+        WHERE
+            b.bigTypeID = #{bigTypeId};
+    </select>
+    <select id="findBrandNameByBrandId" resultType="java.lang.String">
+        SELECT name
+         FROM cm_brand WHERE id = #{brandId} and delFlag = '0' and status = '1'
+    </select>
+    <select id="findParametersByOriginalId" resultType="com.caimei.model.po.RelatedParametersPo">
+        SELECT id, paramsName, paramsContent
+        FROM cm_product_related_parameters
+        WHERE productId = #{productId}
+          AND delFlag = '0';
+
+    </select>
 
 </mapper>