Procházet zdrojové kódy

优惠券相关修改

plf před 3 roky
rodič
revize
7359cbbe6c
21 změnil soubory, kde provedl 1424 přidání a 112 odebrání
  1. 128 0
      src/main/java/com/caimei365/commodity/controller/CouponApi.java
  2. 15 13
      src/main/java/com/caimei365/commodity/controller/ProductPriceApi.java
  3. 93 0
      src/main/java/com/caimei365/commodity/mapper/CouponMapper.java
  4. 54 4
      src/main/java/com/caimei365/commodity/mapper/PageMapper.java
  5. 24 0
      src/main/java/com/caimei365/commodity/model/dto/CollarCouponsDto.java
  6. 22 0
      src/main/java/com/caimei365/commodity/model/dto/RedeemCouponsDto.java
  7. 57 0
      src/main/java/com/caimei365/commodity/model/po/CouponClubPo.java
  8. 49 0
      src/main/java/com/caimei365/commodity/model/po/CouponRedemptionCodePo.java
  9. 45 15
      src/main/java/com/caimei365/commodity/model/search/ProductListVo.java
  10. 32 0
      src/main/java/com/caimei365/commodity/model/vo/ActivityCouponVo.java
  11. 84 0
      src/main/java/com/caimei365/commodity/model/vo/CouponVo.java
  12. 5 0
      src/main/java/com/caimei365/commodity/model/vo/PriceVo.java
  13. 107 34
      src/main/java/com/caimei365/commodity/model/vo/ProductItemVo.java
  14. 85 0
      src/main/java/com/caimei365/commodity/service/CouponService.java
  15. 20 8
      src/main/java/com/caimei365/commodity/service/PageService.java
  16. 9 6
      src/main/java/com/caimei365/commodity/service/PriceService.java
  17. 246 0
      src/main/java/com/caimei365/commodity/service/impl/CouponServiceImpl.java
  18. 81 25
      src/main/java/com/caimei365/commodity/service/impl/PageServiceImpl.java
  19. 9 7
      src/main/java/com/caimei365/commodity/service/impl/PriceServiceImpl.java
  20. 215 0
      src/main/resources/mapper/CouponMapper.xml
  21. 44 0
      src/main/resources/mapper/PageMapper.xml

+ 128 - 0
src/main/java/com/caimei365/commodity/controller/CouponApi.java

@@ -0,0 +1,128 @@
+package com.caimei365.commodity.controller;
+
+import com.caimei365.commodity.model.ResponseJson;
+import com.caimei365.commodity.model.dto.CollarCouponsDto;
+import com.caimei365.commodity.model.dto.RedeemCouponsDto;
+import com.caimei365.commodity.model.vo.CouponVo;
+import com.caimei365.commodity.service.CouponService;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+/**
+ * 优惠券相关
+ *
+ * @author : plf
+ * @date : 2021/8/12
+ */
+@Api(tags = "优惠券相关API")
+@RestController
+@RequestMapping("/commodity/coupon")
+public class CouponApi {
+    private CouponService couponService;
+
+    @Autowired
+    public void setCouponService(CouponService couponService) {
+        this.couponService = couponService;
+    }
+
+    @ApiOperation("已领取优惠券中心")
+    @ApiImplicitParams({
+            @ApiImplicitParam(required = true, name = "userId", value = "机构用户id"),
+            @ApiImplicitParam(required = false, name = "status", value = "使用状态: 1未使用 2已使用 3已失效"),
+            @ApiImplicitParam(required = false, name = "pageNum", value = "页码"),
+            @ApiImplicitParam(required = false, name = "pageSize", value = "每页数量")
+    })
+    @GetMapping("/center")
+    public ResponseJson<PageInfo<CouponVo>> couponCenter(Integer userId, Integer status,
+                                                         @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                         @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
+        if (userId == null) {
+            return ResponseJson.error("参数异常", null);
+        }
+        return couponService.couponCenter(userId, status, pageNum, pageSize);
+    }
+
+    @ApiOperation("活动页")
+    @ApiImplicitParams({
+            @ApiImplicitParam(required = true, name = "couponId", value = "优惠券id"),
+            @ApiImplicitParam(required = true, name = "source", value = "来源 : 1 网站 ; 2 小程序"),
+            @ApiImplicitParam(required = true, name = "userId", value = "机构用户id"),
+            @ApiImplicitParam(required = false, name = "pageNum", value = "页码"),
+            @ApiImplicitParam(required = false, name = "pageSize", value = "每页数量")
+    })
+    @GetMapping("/activity/page")
+    public ResponseJson<Map<String, Object>> activityPage(Integer couponId, Integer userId, Integer source,
+                                                          @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                          @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
+        if (couponId == null || source == null || userId == null) {
+            return ResponseJson.error("参数异常", null);
+        }
+        return couponService.activityPage(couponId, userId, source, pageNum, pageSize);
+    }
+
+    @ApiOperation("领券中心列表")
+    @ApiImplicitParams({
+            @ApiImplicitParam(required = false, name = "userId", value = "机构用户id,0不传"),
+            @ApiImplicitParam(required = false, name = "pageNum", value = "页码"),
+            @ApiImplicitParam(required = false, name = "pageSize", value = "每页数量")
+    })
+    @GetMapping("/collar/list")
+    public ResponseJson<PageInfo<CouponVo>> collarCouponsList(Integer userId, @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                              @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
+        return couponService.collarCouponsList(userId, pageNum, pageSize);
+    }
+
+    @ApiOperation("领取优惠券")
+    @PostMapping("/collar")
+    public ResponseJson<String> collarCoupons(CollarCouponsDto couponsDto) {
+        if (couponsDto.getCouponId() == null || couponsDto.getSource() == null || couponsDto.getUserId() == null) {
+            return ResponseJson.error("参数异常", null);
+        }
+        return couponService.collarCoupons(couponsDto);
+    }
+
+    @ApiOperation("兑换优惠券")
+    @PostMapping("/redeem")
+    public ResponseJson<CouponVo> redeemCoupons(RedeemCouponsDto redeemCouponsDto) {
+        if (redeemCouponsDto.getUserId() == null || redeemCouponsDto.getSource() == null) {
+            return ResponseJson.error("参数异常", null);
+        }
+        if (StringUtils.isBlank(redeemCouponsDto.getRedemptionCode())) {
+            return ResponseJson.error("请输入兑换码", null);
+        }
+        return couponService.redeemCoupons(redeemCouponsDto);
+    }
+
+    @ApiOperation("统计已领取优惠券数量")
+    @ApiImplicitParam(required = true, name = "userId", value = "机构用户id")
+    @GetMapping("/coupons/count")
+    public ResponseJson<Map<String, Integer>> couponsCount(Integer userId) {
+        if (userId == null) {
+            return ResponseJson.error("参数异常", null);
+        }
+        return couponService.couponsCount(userId);
+    }
+
+    @ApiOperation("商品详情相关优惠券")
+    @ApiImplicitParams({
+            @ApiImplicitParam(required = false, name = "userId", value = "机构用户id"),
+            @ApiImplicitParam(required = true, name = "source", value = "来源 : 1 网站 ; 2 小程序"),
+            @ApiImplicitParam(required = true, name = "productId", value = "商品id"),
+            @ApiImplicitParam(required = true, name = "status", value = "状态: 1未领取 2已领取")
+    })
+    @GetMapping("/details/coupons")
+    public ResponseJson<Map<String, Object>> detailsCoupons(Integer userId, Integer productId, Integer source, Integer status) {
+        if (productId == null || source == null || status == null) {
+            return ResponseJson.error("参数异常", null);
+        }
+        return couponService.detailsCoupons(userId, productId, source, status);
+    }
+}

+ 15 - 13
src/main/java/com/caimei365/commodity/controller/ProductPriceApi.java

@@ -22,23 +22,24 @@ import java.util.List;
  * @author : Charles
  * @date : 2021/4/9
  */
-@Api(tags="商品价格API")
+@Api(tags = "商品价格API")
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/commodity/price")
 public class ProductPriceApi {
 
     private final PriceService priceService;
+
     /**
      * 获取商品详情价格
      *
-     * @param userId      用户Id
-     * @param productId   商品Id
+     * @param userId    用户Id
+     * @param productId 商品Id
      */
     @ApiOperation("获取商品详情价格(旧:/product/detail/price)(注意:supplierId更改为shopId)")
     @ApiImplicitParams({
-        @ApiImplicitParam(required = true, name = "userId", value = "用户Id"),
-        @ApiImplicitParam(required = true, name = "productId", value = "商品Id")
+            @ApiImplicitParam(required = true, name = "userId", value = "用户Id"),
+            @ApiImplicitParam(required = true, name = "productId", value = "商品Id")
     })
     @GetMapping("detail")
     public ResponseJson<PriceVo> getDetailPrice(Integer userId, Integer productId) {
@@ -51,26 +52,27 @@ public class ProductPriceApi {
     /**
      * 获取商品列表价格
      *
-     * @param userId       用户Id
-     * @param productIds   商品Id
+     * @param userId     用户Id
+     * @param productIds 商品Id
      */
     @ApiOperation("获取商品列表价格(旧:/product/listPrice)(注意:supplierId更改为shopId)")
     @ApiImplicitParams({
-        @ApiImplicitParam(required = true, name = "userId", value = "用户Id"),
-        @ApiImplicitParam(required = true, name = "productIds", value = "商品Ids,逗号拼接")
+            @ApiImplicitParam(required = true, name = "userId", value = "用户Id"),
+            @ApiImplicitParam(required = true, name = "productIds", value = "商品Ids,逗号拼接"),
+            @ApiImplicitParam(required = true, name = "source", value = "来源 : 1 网站 ; 2 小程序")
     })
     @GetMapping("/list")
-    public ResponseJson<List<PriceVo>> getProductPrice(Integer userId, String productIds) {
-        if (null == userId || StringUtils.isEmpty(productIds)) {
+    public ResponseJson<List<PriceVo>> getProductPrice(Integer userId, String productIds, Integer source) {
+        if (null == userId || StringUtils.isEmpty(productIds) || source == null) {
             return ResponseJson.error("参数错误", null);
         }
-        return priceService.getListPrice(userId, productIds);
+        return priceService.getListPrice(userId, productIds, source);
     }
 
     /**
      * 获取阶梯价格
      *
-     * @param productId   商品Id
+     * @param productId 商品Id
      */
     @ApiOperation("获取阶梯价格(旧:/product/ladderPrice)(注意:supplierId更改为shopId)")
     @ApiImplicitParam(required = true, name = "productId", value = "商品Id")

+ 93 - 0
src/main/java/com/caimei365/commodity/mapper/CouponMapper.java

@@ -0,0 +1,93 @@
+package com.caimei365.commodity.mapper;
+
+import com.caimei365.commodity.model.po.CouponClubPo;
+import com.caimei365.commodity.model.po.CouponRedemptionCodePo;
+import com.caimei365.commodity.model.vo.ActivityCouponVo;
+import com.caimei365.commodity.model.vo.CouponVo;
+import com.caimei365.commodity.model.vo.ProductItemVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/12
+ */
+@Mapper
+public interface CouponMapper {
+    /**
+     * 查询用户优惠券
+     *
+     * @param userId 机构用户id
+     * @param status 使用状态: 1未使用 2已使用 3已失效
+     * @return
+     */
+    List<CouponVo> findCouponClub(@Param("userId") Integer userId, @Param("status") Integer status);
+
+    /**
+     * 查询活动券详情
+     *
+     * @param couponId 优惠券id
+     * @return
+     */
+    ActivityCouponVo findCouponById(Integer couponId);
+
+    /**
+     * 查询优惠券对应商品
+     *
+     * @param couponId 优惠券id
+     * @param source   来源 : 1 网站 ; 2 小程序
+     * @return
+     */
+    List<ProductItemVo> findCouponProduct(@Param("couponId") Integer couponId, @Param("source") Integer source);
+
+    /**
+     * 查询可以领取的券
+     *
+     * @param userId
+     * @return
+     */
+    List<CouponVo> findCouponList(Integer userId);
+
+    /**
+     * 查询优惠券信息
+     *
+     * @param couponId
+     * @return
+     */
+    CouponVo getCoupons(Integer couponId);
+
+    /**
+     * 查询兑换码是否有效
+     *
+     * @param redemptionCode 兑换码
+     * @return
+     */
+    CouponRedemptionCodePo findCouponRedemptionCode(String redemptionCode);
+
+    /**
+     * 查询用户是否已经领取优惠券
+     *
+     * @param userId   机构用户id
+     * @param couponId 优惠券id
+     * @return
+     */
+    Integer findCouponClubByUserId(@Param("userId") Integer userId, @Param("couponId") Integer couponId);
+
+    /**
+     * 保存领取优惠券记录
+     *
+     * @param couponClub
+     */
+    void insertCouponClub(CouponClubPo couponClub);
+
+    /**
+     * 更新兑换状态
+     *
+     * @param id 兑换码id
+     */
+    void updateRedemptionCode(Integer id);
+}

+ 54 - 4
src/main/java/com/caimei365/commodity/mapper/PageMapper.java

@@ -1,6 +1,5 @@
 package com.caimei365.commodity.mapper;
 
-import com.caimei365.commodity.model.vo.ProductRepairVo;
 import com.caimei365.commodity.model.search.ProductListVo;
 import com.caimei365.commodity.model.vo.*;
 import org.apache.ibatis.annotations.Mapper;
@@ -18,89 +17,122 @@ import java.util.List;
 public interface PageMapper {
     /**
      * 查询页面信息
+     *
      * @param pageId 页面Id
      */
     Integer getPageTypeSort(Integer pageId);
+
     /**
      * 查询分页详情热搜词
+     *
      * @param pageId
      */
     List<HotSearchVo> getHotSearchByPageId(Integer pageId, Integer source);
+
     /**
      * 首页楼层
+     *
      * @param source
      */
     List<PageFloorVo> getHomePageFloor(Integer source);
+
     /**
      * 查询页面信息商品楼层
+     *
      * @param pageId
      */
     List<PageFloorVo> getFloorByPageId(Integer pageId, Integer source);
+
     /**
      * 查询楼层内容
+     *
      * @param id 页面id
      */
     FloorContentVo getFloorContentById(Integer id);
+
     /**
      * 查询楼层相关图片
-     * @param id 页面id
+     *
+     * @param id     页面id
      * @param source
      */
     List<FloorImageVo> getFloorImageById(Integer id, Integer source);
+
     /**
      * 查询楼层内容
+     *
      * @param id 楼层id
      */
     FloorContentVo getFloorContentByCentreId(Integer id);
+
     /**
      * 查询楼层相关图片
-     * @param id 楼层id
+     *
+     * @param id     楼层id
      * @param source
      */
     List<FloorImageVo> getFloorImageByCentreId(Integer id, Integer source);
+
     /**
      * 获取商品及价格
+     *
      * @param productId
      */
     ProductItemVo getProductItemById(Integer productId);
+
     /**
      * 优质供应商楼层
      */
     ShopFloorVo getSupplierFloorImage();
+
     /**
      * 查询优质供应商数据
+     *
      * @param source
      */
     List<ShopImageVo> getSupplierImage(Integer source);
+
     /**
      * 商品详情页
      */
     ProductDetailVo getProductDetails(Integer productId);
+
     /**
      * 再次购买
+     *
      * @param userId 用户Id
      */
     List<ProductItemVo> getBuyAgainProducts(Integer userId);
+
     /**
      * 项目仪器详情页
+     *
      * @param equipmentId
      */
     EquipmentVo getEquipmentById(Integer equipmentId);
+
     /**
      * 根据仪器id和类型id获取仪器参数
      */
     List<EquipmentParameterVo> getEquipmentParametersByType(Integer equipmentId, Integer typeId);
+
     /**
      * 二级专题楼层下的数据
      */
     List<ImageLinkVo> getImageLinkByFloorId(Integer floorId);
+
     /**
      * 详情-相关推荐
      */
     List<ProductListVo> getProductRecommendsById(Integer productId);
+
     List<ProductListVo> getAutoProductRecommends(Integer productId);
-    /** 页面数据 */
+
+    /**
+     * 页面数据
+     */
     CmPageVo findCmPageById(Integer pageId);
+
     /**
      * 获取搜索热门关键字
      */
@@ -110,6 +142,7 @@ public interface PageMapper {
      * 获取头部菜单
      */
     List<TopMenuVo> getTopMenus(Integer source);
+
     /**
      * 获取底部链接分类
      */
@@ -134,4 +167,21 @@ public interface PageMapper {
      * 维修详情
      */
     ProductRepairVo getMaintenanceById(Integer id);
+
+    /**
+     * 查询所有有效的优惠券
+     *
+     * @param userId
+     * @return
+     */
+    List<CouponVo> findAllCoupon(Integer userId);
+
+    /**
+     * 查询所有优惠券指定商品id
+     *
+     * @param couponId 优惠券id
+     * @param source   来源: 1小程序 2pc商城
+     * @return
+     */
+    List<Integer> findAllProductId(@Param("couponId") Integer couponId, @Param("source") Integer source);
 }

+ 24 - 0
src/main/java/com/caimei365/commodity/model/dto/CollarCouponsDto.java

@@ -0,0 +1,24 @@
+package com.caimei365.commodity.model.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/12
+ */
+@Data
+public class CollarCouponsDto implements Serializable {
+    @ApiModelProperty("优惠券id")
+    private Integer couponId;
+
+    @ApiModelProperty("机构用户id")
+    private Integer userId;
+
+    @ApiModelProperty("来源 : 1 网站 ; 2 小程序")
+    private Integer source;
+}

+ 22 - 0
src/main/java/com/caimei365/commodity/model/dto/RedeemCouponsDto.java

@@ -0,0 +1,22 @@
+package com.caimei365.commodity.model.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/16
+ */
+@Data
+public class RedeemCouponsDto {
+    @ApiModelProperty("机构用户id")
+    private Integer userId;
+
+    @ApiModelProperty("兑换码")
+    private String redemptionCode;
+
+    @ApiModelProperty("来源 : 1 网站 ; 2 小程序")
+    private Integer source;
+}

+ 57 - 0
src/main/java/com/caimei365/commodity/model/po/CouponClubPo.java

@@ -0,0 +1,57 @@
+package com.caimei365.commodity.model.po;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/16
+ */
+@Data
+public class CouponClubPo {
+    private Integer id;
+
+    /**
+     * 机构用户Id
+     */
+    private Integer userId;
+
+    /**
+     * 优惠券id
+     */
+    private Integer couponId;
+
+    /**
+     * 订单id
+     */
+    private Integer orderId;
+
+    /**
+     * 领取渠道:1网站 2小程序 3订单退回
+     */
+    private Integer source;
+
+    /**
+     * 使用状态 1未使用 2已使用
+     */
+    private String status;
+
+    /**
+     * 领取时间
+     */
+    private Date createDate;
+
+    /**
+     * 使用时间
+     */
+    private Date useDate;
+
+    /**
+     * 删除标记 0否 其余是
+     */
+    private String delFlag;
+
+}

+ 49 - 0
src/main/java/com/caimei365/commodity/model/po/CouponRedemptionCodePo.java

@@ -0,0 +1,49 @@
+package com.caimei365.commodity.model.po;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/12
+ */
+@Data
+public class CouponRedemptionCodePo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    /**
+     * 优惠券id
+     */
+    private Integer couponId;
+
+    /**
+     * 机构用户id
+     */
+    private Integer userId;
+
+    /**
+     * 兑换码(16位)
+     */
+    private String redemptionCode;
+
+    /**
+     * 兑换状态:1未兑换 2已兑换
+     */
+    private Integer status;
+
+    /**
+     * 兑换时间
+     */
+    private Date redemptionTime;
+
+    /**
+     * 添加时间
+     */
+    private Date addTime;
+}

+ 45 - 15
src/main/java/com/caimei365/commodity/model/search/ProductListVo.java

@@ -12,35 +12,65 @@ import java.io.Serializable;
  */
 @Data
 public class ProductListVo implements Serializable {
-    /** 阿里云索引Id */
+    /**
+     * 阿里云索引Id
+     */
     private Integer mainId;
-    /** 商品productID */
+    /**
+     * 商品productID
+     */
     private Integer productId;
-    /** 名称name */
+    /**
+     * 名称name
+     */
     private String name;
-    /** 主图mainImage */
+    /**
+     * 主图mainImage
+     */
     private String image;
-    /** 品牌 */
+    /**
+     * 品牌
+     */
     private String brandName;
-    /** 包装规格 */
+    /**
+     * 包装规格
+     */
     private String unit;
-    /** 商品货号 */
+    /**
+     * 商品货号
+     */
     private String code;
-    /** 机构价 */
+    /**
+     * 机构价
+     */
     private Double price;
-    /** 是否公开机构价 0公开价格 1不公开价格 */
+    /**
+     * 是否公开机构价 0公开价格 1不公开价格
+     */
     private Integer priceFlag;
-    /** 计算后价格等级 */
+    /**
+     * 计算后价格等级
+     */
     private Integer priceGrade;
-    /** 所属供应商Id,关联供应商表 */
+    /**
+     * 所属供应商Id,关联供应商表
+     */
     private Integer shopId;
-    /** 搜索关键词searchKey */
+    /**
+     * 搜索关键词searchKey
+     */
     private String keyword;
-    /** 美博会商品活动状态 */
+    /**
+     * 美博会商品活动状态
+     */
     private Integer beautyActFlag;
-    /** 商品可见度: 3:所有人可见,2:普通机构可见,1:会员机构可见 */
+    /**
+     * 商品可见度: 3:所有人可见,2:普通机构可见,1:会员机构可见
+     */
     private Integer visibility;
-    /** 活动状态:1有效,0失效 */
+    /**
+     * 活动状态:1有效,0失效
+     */
     private Integer actStatus;
 
     private static final long serialVersionUID = 1L;

+ 32 - 0
src/main/java/com/caimei365/commodity/model/vo/ActivityCouponVo.java

@@ -0,0 +1,32 @@
+package com.caimei365.commodity.model.vo;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/12
+ */
+@Data
+public class ActivityCouponVo {
+    /**
+     * 优惠券id
+     */
+    private Integer couponId;
+
+    /**
+     * 活动主题
+     */
+    private String name;
+
+    /**
+     * 网站活动页banner
+     */
+    private String pcBanner;
+
+    /**
+     * 小程序活动页banner
+     */
+    private String appletsBanner;
+}

+ 84 - 0
src/main/java/com/caimei365/commodity/model/vo/CouponVo.java

@@ -0,0 +1,84 @@
+package com.caimei365.commodity.model.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/12
+ */
+@Data
+public class CouponVo implements Serializable {
+    /**
+     * 优惠券id
+     */
+    private Integer couponId;
+
+    /**
+     * 优惠券金额(面值)
+     */
+    private BigDecimal couponAmount;
+
+    /**
+     * 优惠满减条件金额
+     */
+    private BigDecimal touchPrice;
+
+    /**
+     * 使用开始时间(有效期)
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date startDate;
+
+    /**
+     * 使用结束时间(有效期)
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date endDate;
+
+    /**
+     * 劵类型 0活动券 1品类券 2用户专享券 3店铺券 4新用户券
+     */
+    private Integer couponType;
+
+    /**
+     * 机构用户id(用户专享券有效)
+     */
+    private Integer userId;
+
+    /**
+     * 供应商id(店铺券有效)
+     */
+    private Integer shopId;
+
+    /**
+     * 优惠商品:1全商城商品 2指定商品(活动券有效)
+     */
+    private Integer productType;
+
+    /**
+     * 优惠品类:1产品 2仪器(品类券有效)
+     */
+    private Integer categoryType;
+
+    /**
+     * 供应商名称
+     */
+    private String shopName;
+
+    /**
+     * 使用状态: 1未使用 2已使用 3已失效
+     */
+    private Integer useStatus;
+
+    /**
+     * 领取状态: 0未领取 1已领取 (前端使用)
+     */
+    private Integer couponBtnType = 0;
+}

+ 5 - 0
src/main/java/com/caimei365/commodity/model/vo/PriceVo.java

@@ -97,5 +97,10 @@ public class PriceVo implements Serializable {
      */
     private String invoiceType;
 
+    /**
+     * 优惠券标识是否显示
+     */
+    private Boolean couponsLogo = false;
+
 }
 

+ 107 - 34
src/main/java/com/caimei365/commodity/model/vo/ProductItemVo.java

@@ -15,35 +15,65 @@ import java.util.List;
 @Data
 public class ProductItemVo implements Serializable {
     private static final long serialVersionUID = 1L;
-    /** itemId */
+    /**
+     * itemId
+     */
     private Integer id;
-    /** 商品productID */
+    /**
+     * 商品productID
+     */
     private Integer productId;
-    /** 名称name */
+    /**
+     * 名称name
+     */
     private String name;
-    /** 主图mainImage */
+    /**
+     * 主图mainImage
+     */
     private String image;
-    /** 品牌 */
+    /**
+     * 品牌
+     */
     private String brandName;
-    /** 包装规格 */
+    /**
+     * 包装规格
+     */
     private String unit;
-    /** 商品货号 */
+    /**
+     * 商品货号
+     */
     private String code;
-    /** 机构价 */
+    /**
+     * 机构价
+     */
     private Double price;
-    /** 是否公开机构价 0公开价格 1不公开价格 */
+    /**
+     * 是否公开机构价 0公开价格 1不公开价格
+     */
     private Integer priceFlag;
-    /** 计算后价格等级 */
+    /**
+     * 计算后价格等级
+     */
     private Integer priceGrade;
-    /** 商品可见度:(3:所有人可见,2:普通机构可见,1:会员机构可见) */
+    /**
+     * 商品可见度:(3:所有人可见,2:普通机构可见,1:会员机构可见)
+     */
     private String visibility;
-    /** 所属供应商Id,关联供应商表 */
+    /**
+     * 所属供应商Id,关联供应商表
+     */
     private Integer shopId;
-    /** 搜索关键词searchKey */
+    /**
+     * 搜索关键词searchKey
+     */
     private String keyword;
-    /** 美博会商品活动状态 */
+    /**
+     * 美博会商品活动状态
+     */
     private Integer beautyActFlag;
-    /** 商品原价 */
+    /**
+     * 商品原价
+     */
     private Double originalPrice;
     /**
      * 成本价选中标志:1固定成本 2比例成
@@ -53,51 +83,89 @@ public class ProductItemVo implements Serializable {
      * 固定成本价
      */
     private Double costPrice;
-    /** 购买数量 */
+    /**
+     * 购买数量
+     */
     private Integer number;
-    /** 是否是赠品 2是,其他否 */
+    /**
+     * 是否是赠品 2是,其他否
+     */
     private Integer productType;
-    /** 增量 */
+    /**
+     * 增量
+     */
     private Integer step;
-    /** 起订量 */
+    /**
+     * 起订量
+     */
     private Integer minBuyNumber;
     /**
      * 最大购买量
      */
     private Integer maxBuyNumber;
-    /** 商品上架状态:0逻辑删除 1待审核 2已上架 3已下架 8审核未通过 9已冻结 */
+    /**
+     * 商品上架状态:0逻辑删除 1待审核 2已上架 3已下架 8审核未通过 9已冻结
+     */
     private Integer validFlag;
-    /** 活动状态:1有效,0失效 */
+    /**
+     * 活动状态:1有效,0失效
+     */
     private Integer actStatus;
-    /** 启用阶梯价格标识:1是,0否 */
+    /**
+     * 启用阶梯价格标识:1是,0否
+     */
     private Integer ladderPriceFlag;
-    /** 库存 */
+    /**
+     * 库存
+     */
     private Integer stock;
-    /** 购物车失效状态:0有效,1后台删除的,2冻结的,3下架,4售罄 >7库存不足,5价格仅会员可见,6未公开价格 */
+    /**
+     * 购物车失效状态:0有效,1后台删除的,2冻结的,3下架,4售罄 >7库存不足,5价格仅会员可见,6未公开价格
+     */
     private Integer status;
-    /** 阶梯价 */
+    /**
+     * 阶梯价
+     */
     List<LadderPriceVo> ladderPrices;
-    /** 促销活动 */
+    /**
+     * 促销活动
+     */
     private PromotionsVo promotions;
-    /** 商品的类别:1正常商品(默认),2二手商品 */
+    /**
+     * 商品的类别:1正常商品(默认),2二手商品
+     */
     private String productCategory;
-    /** 商品货号 */
+    /**
+     * 商品货号
+     */
     private String productCode;
-    /** 商品是否默认选中 */
+    /**
+     * 商品是否默认选中
+     */
     private Boolean productsChecked = false;
     /**
      * 成本大于复购价 或 当前机构价小于复购价
      */
     private Boolean repurchasePriceState = false;
-    /** 是否含税 0不含税,1含税,2未知 */
+    /**
+     * 是否含税 0不含税,1含税,2未知
+     */
     private String includedTax;
-    /** 发票类型(基于是否含税基础) 1增值税票,2普通票, 3不能开票 */
+    /**
+     * 发票类型(基于是否含税基础) 1增值税票,2普通票, 3不能开票
+     */
     private String invoiceType;
-    /** 机构税率 */
+    /**
+     * 机构税率
+     */
     private BigDecimal taxRate;
-    /** 用户身份: 2-会员机构, 4-普通机构 */
+    /**
+     * 用户身份: 2-会员机构, 4-普通机构
+     */
     private Integer userIdentity;
-    /** 是否启用详聊,1不开启,2开启(开启详聊不展示交易价)*/
+    /**
+     * 是否启用详聊,1不开启,2开启(开启详聊不展示交易价)
+     */
     private Integer detailTalkFlag;
     /**
      * 内部商品名称
@@ -151,4 +219,9 @@ public class ProductItemVo implements Serializable {
      * 判断是否勾选(前端使用)
      */
     private Boolean isChecked = false;
+
+    /**
+     * 优惠券标识是否显示
+     */
+    private Boolean couponsLogo = false;
 }

+ 85 - 0
src/main/java/com/caimei365/commodity/service/CouponService.java

@@ -0,0 +1,85 @@
+package com.caimei365.commodity.service;
+
+import com.caimei365.commodity.model.ResponseJson;
+import com.caimei365.commodity.model.dto.CollarCouponsDto;
+import com.caimei365.commodity.model.dto.RedeemCouponsDto;
+import com.caimei365.commodity.model.vo.CouponVo;
+import com.github.pagehelper.PageInfo;
+
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/12
+ */
+public interface CouponService {
+    /**
+     * 已领取优惠券中心
+     *
+     * @param userId   机构用户id
+     * @param status   使用状态: 1未使用 2已使用 3已失效
+     * @param pageNum  页码
+     * @param pageSize 每页数量
+     * @return
+     */
+    ResponseJson<PageInfo<CouponVo>> couponCenter(Integer userId, Integer status, int pageNum, int pageSize);
+
+    /**
+     * 活动券部分商品活动数据
+     *
+     * @param couponId 活动券id
+     * @param userId   机构用户id
+     * @param source   来源: 1小程序 2pc商城
+     * @param pageNum  页码
+     * @param pageSize 每页数量
+     * @return
+     */
+    ResponseJson<Map<String, Object>> activityPage(Integer couponId, Integer userId, Integer source, int pageNum, int pageSize);
+
+    /**
+     * 领券中心
+     *
+     * @param userId   机构用户id
+     * @param pageNum  页码
+     * @param pageSize 每页数量
+     * @return
+     */
+    ResponseJson<PageInfo<CouponVo>> collarCouponsList(Integer userId, int pageNum, int pageSize);
+
+    /**
+     * 领取优惠券
+     *
+     * @param couponsDto
+     * @return
+     */
+    ResponseJson<String> collarCoupons(CollarCouponsDto couponsDto);
+
+    /**
+     * 兑换优惠券
+     *
+     * @param redeemCouponsDto
+     * @return
+     */
+    ResponseJson<CouponVo> redeemCoupons(RedeemCouponsDto redeemCouponsDto);
+
+    /**
+     * 统计已领取优惠券数量
+     *
+     * @param userId 机构用户id
+     * @return
+     */
+    ResponseJson<Map<String, Integer>> couponsCount(Integer userId);
+
+    /**
+     * 商品详情相关优惠券
+     *
+     * @param userId    机构用户id
+     * @param productId 商品id
+     * @param source    来源 : 1 网站 ; 2 小程序
+     * @param status    状态: 1未领取 2已领取
+     * @return
+     */
+    ResponseJson<Map<String, Object>> detailsCoupons(Integer userId, Integer productId, Integer source, Integer status);
+}

+ 20 - 8
src/main/java/com/caimei365/commodity/service/PageService.java

@@ -2,7 +2,6 @@ package com.caimei365.commodity.service;
 
 import com.caimei365.commodity.model.ResponseJson;
 import com.caimei365.commodity.model.po.ProductParameterPo;
-import com.caimei365.commodity.model.vo.ProductRepairVo;
 import com.caimei365.commodity.model.search.ProductListVo;
 import com.caimei365.commodity.model.vo.*;
 
@@ -43,6 +42,7 @@ public interface PageService {
 
     /**
      * 首页基础数据(小程序)
+     *
      * @param source 来源 : 1 网站 ; 2 小程序
      */
     ResponseJson<Map<String, Object>> getHomeInit(Integer source);
@@ -60,8 +60,8 @@ public interface PageService {
      * 楼层详情
      *
      * @param floorId 楼层id
-     * @param userId 用户id
-     * @param source 来源 : 1 网站 ; 2 小程序
+     * @param userId  用户id
+     * @param source  来源 : 1 网站 ; 2 小程序
      */
     ResponseJson<Map<String, Object>> getPageFloorData(Integer floorId, Integer userId, Integer source);
 
@@ -69,8 +69,8 @@ public interface PageService {
      * 分页详情楼层详情
      *
      * @param centreId 分页详情楼层id
-     * @param userId 用户id
-     * @param source 来源 : 1 网站 ; 2 小程序
+     * @param userId   用户id
+     * @param source   来源 : 1 网站 ; 2 小程序
      */
     ResponseJson<Map<String, Object>> getPageCentreData(Integer centreId, Integer userId, Integer source);
 
@@ -85,12 +85,13 @@ public interface PageService {
     /**
      * 再次购买商品列表
      *
-     * @param userId    用户Id
+     * @param userId 用户Id
      */
     ResponseJson<PaginationVo<ProductItemVo>> getBuyAgainProducts(Integer userId, int pageNum, int pageSize);
 
     /**
      * 项目仪器详情页
+     *
      * @param equipmentId 项目仪器Id
      */
     ResponseJson<EquipmentVo> getEquipmentDetails(Integer equipmentId);
@@ -112,15 +113,26 @@ public interface PageService {
     /**
      * 商品详情页-相关推荐
      *
-     * @param productId 商品Id
+     * @param productId     商品Id
      * @param recommendType 相关推荐类型: 0自动选择, 1手动推荐
-     * @param userId    用户Id
+     * @param userId        用户Id
      */
     ResponseJson<List<ProductListVo>> getProductDetailRecommends(Integer productId, Integer recommendType, Integer userId);
 
     /**
      * 商品维修(链接分享数据)
+     *
      * @param code 维修code
      */
     ResponseJson<ProductRepairVo> getProductRepair(String code);
+
+    /**
+     * 优惠券标识是否显示
+     *
+     * @param userId    机构用户id
+     * @param productId 商品id
+     * @param source    来源 : 1 网站 ; 2 小程序
+     * @return
+     */
+    Boolean setCouponsLogo(Integer userId, Integer productId, Integer source);
 }

+ 9 - 6
src/main/java/com/caimei365/commodity/service/PriceService.java

@@ -16,23 +16,26 @@ public interface PriceService {
     /**
      * 获取商品详情价格
      *
-     * @param userId      用户Id
-     * @param productId   商品Id
+     * @param userId    用户Id
+     * @param productId 商品Id
      * @return PriceVo
      */
     ResponseJson<PriceVo> getDetailPrice(Integer userId, Integer productId);
+
     /**
      * 获取商品列表价格
      *
-     * @param userId       用户Id
-     * @param productIds   商品Id
+     * @param userId     用户Id
+     * @param productIds 商品Id
+     * @param source     来源 : 1 网站 ; 2 小程序
      * @return List<PriceVo>
      */
-    ResponseJson<List<PriceVo>> getListPrice(Integer userId, String productIds);
+    ResponseJson<List<PriceVo>> getListPrice(Integer userId, String productIds, Integer source);
+
     /**
      * 获取阶梯价格
      *
-     * @param productId   商品Id
+     * @param productId 商品Id
      * @return LadderPriceVo
      */
     ResponseJson<List<LadderPriceVo>> getLadderPrice(Integer productId);

+ 246 - 0
src/main/java/com/caimei365/commodity/service/impl/CouponServiceImpl.java

@@ -0,0 +1,246 @@
+package com.caimei365.commodity.service.impl;
+
+import com.caimei365.commodity.components.PriceUtilService;
+import com.caimei365.commodity.mapper.CouponMapper;
+import com.caimei365.commodity.mapper.PageMapper;
+import com.caimei365.commodity.mapper.ShopMapper;
+import com.caimei365.commodity.model.ResponseJson;
+import com.caimei365.commodity.model.dto.CollarCouponsDto;
+import com.caimei365.commodity.model.dto.RedeemCouponsDto;
+import com.caimei365.commodity.model.po.CouponClubPo;
+import com.caimei365.commodity.model.po.CouponRedemptionCodePo;
+import com.caimei365.commodity.model.vo.ActivityCouponVo;
+import com.caimei365.commodity.model.vo.CouponVo;
+import com.caimei365.commodity.model.vo.ProductItemVo;
+import com.caimei365.commodity.model.vo.ShopVo;
+import com.caimei365.commodity.service.CouponService;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * Description
+ *
+ * @author : plf
+ * @date : 2021/8/12
+ */
+@Service
+public class CouponServiceImpl implements CouponService {
+    @Resource
+    private CouponMapper couponMapper;
+    @Resource
+    private ShopMapper shopMapper;
+    @Resource
+    private PageMapper pageMapper;
+    @Resource
+    private PriceUtilService priceUtilService;
+
+    /**
+     * 已领取优惠券中心
+     *
+     * @param userId   机构用户id
+     * @param status   使用状态: 1未使用 2已使用 3已失效
+     * @param pageNum  页码
+     * @param pageSize 每页数量
+     */
+    @Override
+    public ResponseJson<PageInfo<CouponVo>> couponCenter(Integer userId, Integer status, int pageNum, int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CouponVo> couponList = couponMapper.findCouponClub(userId, status);
+        couponList.forEach(coupon -> {
+            setShopName(coupon);
+            coupon.setUseStatus(status);
+        });
+        PageInfo<CouponVo> pageInfo = new PageInfo<>(couponList);
+        return ResponseJson.success(pageInfo);
+    }
+
+    /**
+     * set店铺名称
+     *
+     * @param coupon 优惠券
+     */
+    private void setShopName(CouponVo coupon) {
+        if (coupon.getCouponType() == 3 && coupon.getShopId() != null) {
+            //店铺券
+            ShopVo shop = shopMapper.getProductShopById(coupon.getShopId());
+            if (shop != null && StringUtils.isNotBlank(shop.getName())) {
+                String shopName = shop.getName();
+                if (shopName.length() > 10) {
+                    shopName = shopName.substring(0, 10) + "...";
+                }
+                coupon.setShopName(shopName);
+            }
+        }
+    }
+
+    /**
+     * 活动券部分商品活动数据
+     *
+     * @param couponId 活动券id
+     * @param userId   机构用户id
+     * @param source   来源 : 1 网站 ; 2 小程序
+     * @param pageNum  页码
+     * @param pageSize 每页数量
+     */
+    @Override
+    public ResponseJson<Map<String, Object>> activityPage(Integer couponId, Integer userId, Integer source, int pageNum, int pageSize) {
+        Map<String, Object> map = new HashMap<>(2);
+        ActivityCouponVo coupon = couponMapper.findCouponById(couponId);
+        if (coupon == null) {
+            return ResponseJson.error("活动已失效", null);
+        }
+        PageHelper.startPage(pageNum, pageSize);
+        List<ProductItemVo> productList = couponMapper.findCouponProduct(couponId, source);
+        productList.forEach(p -> {
+            p.setCouponsLogo(true);
+            priceUtilService.setProductDetails(userId, p);
+        });
+        PageInfo<ProductItemVo> pageInfo = new PageInfo<>(productList);
+        map.put("coupon", coupon);
+        map.put("pageInfo", pageInfo);
+        return ResponseJson.success(map);
+    }
+
+    @Override
+    public ResponseJson<PageInfo<CouponVo>> collarCouponsList(Integer userId, int pageNum, int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CouponVo> couponList = couponMapper.findCouponList(userId);
+        couponList.forEach(this::setShopName);
+        PageInfo<CouponVo> pageInfo = new PageInfo<>(couponList);
+        return ResponseJson.success(pageInfo);
+    }
+
+    @Override
+    public ResponseJson<String> collarCoupons(CollarCouponsDto couponsDto) {
+        Integer id = couponMapper.findCouponClubByUserId(couponsDto.getUserId(), couponsDto.getCouponId());
+        if (id != null && id > 0) {
+            return ResponseJson.error("已经领取过了", null);
+        }
+        CouponClubPo couponClub = new CouponClubPo();
+        BeanUtils.copyProperties(couponsDto, couponClub);
+        couponClub.setStatus("1");
+        couponClub.setCreateDate(new Date());
+        couponClub.setDelFlag("0");
+        couponMapper.insertCouponClub(couponClub);
+        return ResponseJson.success("领取成功");
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public ResponseJson<CouponVo> redeemCoupons(RedeemCouponsDto redeemCouponsDto) {
+        CouponRedemptionCodePo redemptionCode = couponMapper.findCouponRedemptionCode(redeemCouponsDto.getRedemptionCode());
+        if (redemptionCode == null) {
+            return ResponseJson.error("请输入正确的兑换码", null);
+        }
+        if (redemptionCode.getStatus() == 2) {
+            return ResponseJson.error("兑换码已使用,请更换兑换码进行兑换", null);
+        }
+        CouponVo coupon = couponMapper.getCoupons(redemptionCode.getCouponId());
+        Date date = new Date();
+        if (coupon == null || date.compareTo(coupon.getStartDate()) < 0 || date.compareTo(coupon.getEndDate()) > 0) {
+            return ResponseJson.error("兑换的优惠券已失效", null);
+        }
+        CouponClubPo couponClub = new CouponClubPo();
+        couponClub.setCouponId(redemptionCode.getCouponId());
+        couponClub.setUserId(redeemCouponsDto.getUserId());
+        couponClub.setSource(redeemCouponsDto.getSource());
+        couponClub.setStatus("1");
+        couponClub.setCreateDate(new Date());
+        couponClub.setDelFlag("0");
+        couponMapper.insertCouponClub(couponClub);
+        couponMapper.updateRedemptionCode(redemptionCode.getId());
+        return ResponseJson.success(coupon);
+    }
+
+    @Override
+    public ResponseJson<Map<String, Integer>> couponsCount(Integer userId) {
+        Map<String, Integer> map = new HashMap<>(3);
+        List<CouponVo> unusedList = couponMapper.findCouponClub(userId, 1);
+        List<CouponVo> usedList = couponMapper.findCouponClub(userId, 2);
+        List<CouponVo> expiredList = couponMapper.findCouponClub(userId, 3);
+        int unusedNum = unusedList == null ? 0 : unusedList.size();
+        int usedNum = usedList == null ? 0 : usedList.size();
+        int expiredNum = expiredList == null ? 0 : expiredList.size();
+        map.put("unusedNum", unusedNum);
+        map.put("usedNum", usedNum);
+        map.put("expiredNum", expiredNum);
+        return ResponseJson.success(map);
+    }
+
+    @Override
+    public ResponseJson<Map<String, Object>> detailsCoupons(Integer userId, Integer productId, Integer source, Integer status) {
+        Map<String, Object> map = new HashMap<>(3);
+        ProductItemVo product = pageMapper.getProductItemById(productId);
+        if (product == null) {
+            return ResponseJson.error("商品数据异常", null);
+        }
+        //未领取
+        List<CouponVo> notCouponList = couponMapper.findCouponList(userId);
+        filterCoupon(source, product, notCouponList);
+        map.put("notCouponNum", notCouponList == null ? 0 : notCouponList.size());
+        //已领取
+        List<CouponVo> couponList = couponMapper.findCouponClub(userId, 1);
+        filterCoupon(source, product, couponList);
+        map.put("couponNum", couponList == null ? 0 : couponList.size());
+        if (status == 1) {
+            //未领取
+            map.put("couponList", notCouponList);
+        } else {
+            //已领取
+            map.put("couponList", couponList);
+        }
+        List<CouponVo> list = new ArrayList<>();
+        if (notCouponList != null) {
+            list.addAll(notCouponList);
+        }
+        if (couponList != null) {
+            list.addAll(couponList);
+        }
+        list.sort(new Comparator<CouponVo>() {
+            @Override
+            public int compare(CouponVo o1, CouponVo o2) {
+                return o2.getCouponAmount().compareTo(o1.getCouponAmount());
+            }
+        });
+        map.put("list", list);
+        return ResponseJson.success(map);
+    }
+
+    /**
+     * 过滤与商品无关的优惠券
+     *
+     * @param source
+     * @param product
+     * @param couponList
+     */
+    private void filterCoupon(Integer source, ProductItemVo product, List<CouponVo> couponList) {
+        if (couponList != null && couponList.size() > 0) {
+            Iterator<CouponVo> iterator = couponList.iterator();
+            while (iterator.hasNext()) {
+                CouponVo coupon = iterator.next();
+                if (coupon.getCouponType() == 0 && coupon.getProductType() == 2) {
+                    //活动券
+                    List<Integer> productIds = pageMapper.findAllProductId(coupon.getCouponId(), source);
+                    if (!productIds.contains(product.getProductId())) {
+                        iterator.remove();
+                        continue;
+                    }
+                }
+                if (coupon.getCouponType() == 1 && !coupon.getCategoryType().equals(product.getCommodityType())) {
+                    iterator.remove();
+                    continue;
+                }
+                if (coupon.getCouponType() == 3 && !coupon.getShopId().equals(product.getShopId())) {
+                    iterator.remove();
+                }
+            }
+        }
+    }
+}

+ 81 - 25
src/main/java/com/caimei365/commodity/service/impl/PageServiceImpl.java

@@ -1,5 +1,6 @@
 package com.caimei365.commodity.service.impl;
 
+import com.caimei365.commodity.components.PriceUtilService;
 import com.caimei365.commodity.mapper.PageMapper;
 import com.caimei365.commodity.mapper.PriceMapper;
 import com.caimei365.commodity.mapper.ProductTypeMapper;
@@ -8,13 +9,11 @@ import com.caimei365.commodity.model.ResponseJson;
 import com.caimei365.commodity.model.po.ProductDetailInfoPo;
 import com.caimei365.commodity.model.po.ProductImagePo;
 import com.caimei365.commodity.model.po.ProductParameterPo;
-import com.caimei365.commodity.model.vo.ProductRepairVo;
 import com.caimei365.commodity.model.search.ProductListVo;
 import com.caimei365.commodity.model.vo.*;
 import com.caimei365.commodity.service.PageService;
 import com.caimei365.commodity.utils.AppletsLinkUtil;
 import com.caimei365.commodity.utils.ImageUtils;
-import com.caimei365.commodity.components.PriceUtilService;
 import com.caimei365.commodity.utils.MathUtil;
 import com.github.pagehelper.PageHelper;
 import lombok.extern.slf4j.Slf4j;
@@ -49,6 +48,7 @@ public class PageServiceImpl implements PageService {
     private PriceUtilService priceUtilService;
     @Resource
     private ProductTypeMapper productTypeMapper;
+
     /**
      * 获取分类列表
      *
@@ -58,21 +58,21 @@ public class PageServiceImpl implements PageService {
     @Override
     @Cacheable(value = "getCommodityClassify", key = "#typeSort +'-'+ #source", unless = "#result == null")
     public ResponseJson<List<BigTypeVo>> getClassify(Integer typeSort, String source) {
-        List<BigTypeVo> bigTypeList = productTypeMapper.getBigTypeList(typeSort,source);
+        List<BigTypeVo> bigTypeList = productTypeMapper.getBigTypeList(typeSort, source);
         bigTypeList.forEach(bigType -> {
             String caiMeiImage = ImageUtils.getImageURL("caiMeiImage", null, 0, domain);
-            bigType.setWwwIcon(StringUtils.isEmpty(bigType.getWwwIcon())?caiMeiImage:bigType.getWwwIcon());
-            bigType.setCrmIcon(StringUtils.isEmpty(bigType.getCrmIcon())?caiMeiImage:bigType.getCrmIcon());
+            bigType.setWwwIcon(StringUtils.isEmpty(bigType.getWwwIcon()) ? caiMeiImage : bigType.getWwwIcon());
+            bigType.setCrmIcon(StringUtils.isEmpty(bigType.getCrmIcon()) ? caiMeiImage : bigType.getCrmIcon());
             List<SmallTypeVo> smallTypeList = productTypeMapper.getSmallTypeList(bigType.getBigTypeId(), source);
             if (!CollectionUtils.isEmpty(smallTypeList)) {
                 smallTypeList.forEach(smallType -> {
-                    smallType.setWwwIcon(StringUtils.isEmpty(smallType.getWwwIcon())?caiMeiImage:smallType.getWwwIcon());
-                    smallType.setCrmIcon(StringUtils.isEmpty(smallType.getCrmIcon())?caiMeiImage:smallType.getCrmIcon());
+                    smallType.setWwwIcon(StringUtils.isEmpty(smallType.getWwwIcon()) ? caiMeiImage : smallType.getWwwIcon());
+                    smallType.setCrmIcon(StringUtils.isEmpty(smallType.getCrmIcon()) ? caiMeiImage : smallType.getCrmIcon());
                     List<TinyTypeVo> tinyTypeList = productTypeMapper.getTinyTypeList(smallType.getSmallTypeId(), source);
                     if (!CollectionUtils.isEmpty(tinyTypeList)) {
                         tinyTypeList.forEach(tinyType -> {
-                            tinyType.setWwwIcon(StringUtils.isEmpty(tinyType.getWwwIcon())?caiMeiImage:tinyType.getWwwIcon());
-                            tinyType.setCrmIcon(StringUtils.isEmpty(tinyType.getCrmIcon())?caiMeiImage:tinyType.getCrmIcon());
+                            tinyType.setWwwIcon(StringUtils.isEmpty(tinyType.getWwwIcon()) ? caiMeiImage : tinyType.getWwwIcon());
+                            tinyType.setCrmIcon(StringUtils.isEmpty(tinyType.getCrmIcon()) ? caiMeiImage : tinyType.getCrmIcon());
                         });
                         smallType.setTinyTypeList(tinyTypeList);
                     }
@@ -103,7 +103,7 @@ public class PageServiceImpl implements PageService {
             setFloorLinkType(floorContent);
             floor.setFloorContent(floorContent);
             List<FloorImageVo> floorImageList = pageMapper.getFloorImageByCentreId(floor.getId(), source);
-            setFloorImageProduct(userId, floorImageList);
+            setFloorImageProduct(userId, floorImageList, source);
             floor.setFloorImageList(floorImageList);
         }
         map.put("typeSort", typeSort);
@@ -136,7 +136,7 @@ public class PageServiceImpl implements PageService {
                 floorIterator.remove();
                 continue;
             }
-            setFloorImageProduct(userId, floorImageList);
+            setFloorImageProduct(userId, floorImageList, source);
             floor.setFloorImageList(floorImageList);
         }
         map.put("homePageFloor", homePageFloor);
@@ -162,6 +162,7 @@ public class PageServiceImpl implements PageService {
 
     /**
      * 首页基础数据(小程序)
+     *
      * @param source 来源 : 1 网站 ; 2 小程序
      */
     @Override
@@ -225,7 +226,7 @@ public class PageServiceImpl implements PageService {
         if (StringUtils.isNotBlank(page.getHeadLink())) {
             Integer linkType = AppletsLinkUtil.getLinkType(page.getHeadLink());
             page.setLinkType(linkType);
-            page.setLinkParam(AppletsLinkUtil.getLinkParam(linkType,page.getHeadLink()));
+            page.setLinkParam(AppletsLinkUtil.getLinkParam(linkType, page.getHeadLink()));
         }
         List<PageFloorVo> floorList = pageMapper.getFloorByPageId(pageId, source);
         for (PageFloorVo floor : floorList) {
@@ -233,7 +234,7 @@ public class PageServiceImpl implements PageService {
             setFloorLinkType(floorContent);
             floor.setFloorContent(floorContent);
             List<FloorImageVo> floorImageList = pageMapper.getFloorImageByCentreId(floor.getId(), source);
-            setFloorImageProduct(userId, floorImageList);
+            setFloorImageProduct(userId, floorImageList, source);
             floor.setFloorImageList(floorImageList);
         }
         Map<String, Object> map = new HashMap<>(2);
@@ -257,7 +258,7 @@ public class PageServiceImpl implements PageService {
         FloorContentVo floorContent = pageMapper.getFloorContentById(floorId);
         setFloorLinkType(floorContent);
         List<FloorImageVo> floorImageList = pageMapper.getFloorImageById(floorId, source);
-        setFloorImageProduct(userId, floorImageList);
+        setFloorImageProduct(userId, floorImageList, source);
         Map<String, Object> map = new HashMap<>(2);
         map.put("floorContent", floorContent);
         map.put("floorImageList", floorImageList);
@@ -279,7 +280,7 @@ public class PageServiceImpl implements PageService {
         FloorContentVo floorContent = pageMapper.getFloorContentByCentreId(centreId);
         setFloorLinkType(floorContent);
         List<FloorImageVo> floorImageList = pageMapper.getFloorImageByCentreId(centreId, source);
-        setFloorImageProduct(userId, floorImageList);
+        setFloorImageProduct(userId, floorImageList, source);
         Map<String, Object> map = new HashMap<>(2);
         map.put("floorContent", floorContent);
         map.put("floorImageList", floorImageList);
@@ -300,7 +301,7 @@ public class PageServiceImpl implements PageService {
             product = new ProductDetailVo();
             product.setValidFlag(0);
         }
-        boolean validFlag = 2 != product.getProductCategory() && 2 == product.getValidFlag() && (product.getStock()== null || product.getStock() == 0);
+        boolean validFlag = 2 != product.getProductCategory() && 2 == product.getValidFlag() && (product.getStock() == null || product.getStock() == 0);
         if (validFlag) {
             //已上架但库存为0的正常商品,设置为已售罄商品
             product.setValidFlag(4);
@@ -422,12 +423,12 @@ public class PageServiceImpl implements PageService {
         PageHelper.startPage(pageNum, pageSize);
         List<ProductItemVo> productList = pageMapper.getBuyAgainProducts(userId);
         productList.forEach(product -> {
-            double price = product.getPrice()!=null?product.getPrice():0d;
-            double costPrice = product.getCostPrice()!=null?product.getCostPrice():0d;
-            double discountPrice = product.getDiscountPrice()!=null?product.getDiscountPrice():0d;
+            double price = product.getPrice() != null ? product.getPrice() : 0d;
+            double costPrice = product.getCostPrice() != null ? product.getCostPrice() : 0d;
+            double discountPrice = product.getDiscountPrice() != null ? product.getDiscountPrice() : 0d;
             Integer costFlag = product.getCostCheckFlag();
             // 成本大于等于复购价 或 复购价大于机构价
-            boolean state = (costFlag == 1 && MathUtil.compare(costPrice, discountPrice) >=0) || MathUtil.compare(discountPrice, price) >0;
+            boolean state = (costFlag == 1 && MathUtil.compare(costPrice, discountPrice) >= 0) || MathUtil.compare(discountPrice, price) > 0;
             product.setRepurchasePriceState(state);
             // 设置商品主图及价格
             priceUtilService.setProductDetails(userId, product);
@@ -547,7 +548,9 @@ public class PageServiceImpl implements PageService {
         Integer identity = 0;
         if (null != userId && userId > 0) {
             identity = priceMapper.getIdentityByUserId(userId);
-            if (null == identity){identity = 0;}
+            if (null == identity) {
+                identity = 0;
+            }
         }
         List<ProductListVo> list = null;
         //相关推荐类型 0自动选择(默认); 1手动推荐
@@ -556,13 +559,13 @@ public class PageServiceImpl implements PageService {
         } else {
             list = pageMapper.getProductRecommendsById(productId);
         }
-        if (null != list && list.size()>0) {
+        if (null != list && list.size() > 0) {
             // identity: 0个人,1协销,2会员机构,3供应商,4普通机构
             // visibility:3:所有人可见,2:普通机构可见,1:会员机构可见
             // boolean passFlag = identity ==1 || identity == 2 || product.getVisibility()==3 || (identity == 4 && product.getVisibility()==2);
             try {
                 Integer finalIdentity = identity;
-                list.removeIf(product -> (null == product || null == product.getVisibility() || !(finalIdentity == 1 || finalIdentity == 2 || product.getVisibility()==3 || (finalIdentity == 4 && product.getVisibility()==2))));
+                list.removeIf(product -> (null == product || null == product.getVisibility() || !(finalIdentity == 1 || finalIdentity == 2 || product.getVisibility() == 3 || (finalIdentity == 4 && product.getVisibility() == 2))));
                 list.forEach(product -> {
                     // 设置 图片路径
                     product.setImage(ImageUtils.getImageURL("product", product.getImage(), 0, domain));
@@ -591,7 +594,7 @@ public class PageServiceImpl implements PageService {
             // 维修详情
             repair = pageMapper.getMaintenanceById(maintenanceId);
         }
-        if (null == repair){
+        if (null == repair) {
             return ResponseJson.error("无效的链接!", null);
         }
         List<String> imageList = new ArrayList<>();
@@ -640,6 +643,7 @@ public class PageServiceImpl implements PageService {
 
     /**
      * 设置跳转参数
+     *
      * @param floorContent FloorContentVo
      */
     private void setFloorLinkType(FloorContentVo floorContent) {
@@ -665,7 +669,7 @@ public class PageServiceImpl implements PageService {
     /**
      * 设置楼层相关图片的商品信息
      */
-    private void setFloorImageProduct(Integer userId, List<FloorImageVo> floorImageList) {
+    private void setFloorImageProduct(Integer userId, List<FloorImageVo> floorImageList, Integer source) {
         Iterator<FloorImageVo> iterator = floorImageList.iterator();
         while (iterator.hasNext()) {
             FloorImageVo image = iterator.next();
@@ -699,6 +703,9 @@ public class PageServiceImpl implements PageService {
                             iterator.remove();
                         }
                     }
+                    //优惠券标识
+                    Boolean couponsLogo = setCouponsLogo(userId, image.getProductId(), source);
+                    product.setCouponsLogo(couponsLogo);
                 } else {
                     iterator.remove();
                 }
@@ -707,4 +714,53 @@ public class PageServiceImpl implements PageService {
             }
         }
     }
+
+    /**
+     * 优惠券标识是否显示
+     *
+     * @param userId    机构用户id
+     * @param productId 商品id
+     * @param source    来源 : 1 网站 ; 2 小程序
+     * @return
+     */
+    @Override
+    public Boolean setCouponsLogo(Integer userId, Integer productId, Integer source) {
+        boolean couponsLogo = false;
+        ProductItemVo product = pageMapper.getProductItemById(productId);
+        List<CouponVo> couponList = pageMapper.findAllCoupon(userId);
+        if (couponList != null && couponList.size() > 0) {
+            for (CouponVo coupon : couponList) {
+                if (coupon.getCouponType() == 4 || coupon.getCouponType() == 2) {
+                    //用户券与用户专享券
+                    couponsLogo = true;
+                    break;
+                }
+                if (coupon.getCouponType() == 0) {
+                    if (coupon.getProductType() == 1) {
+                        //活动券-全商城商品
+                        couponsLogo = true;
+                        break;
+                    } else {
+                        //活动券-指定商品
+                        List<Integer> productIds = pageMapper.findAllProductId(coupon.getCouponId(), source);
+                        if (productIds.contains(productId)) {
+                            couponsLogo = true;
+                            break;
+                        }
+                    }
+                }
+                if (coupon.getCouponType() == 3 && product.getShopId().equals(coupon.getShopId())) {
+                    //店铺券
+                    couponsLogo = true;
+                    break;
+                }
+                if (coupon.getCouponType() == 1 && product.getCommodityType().equals(coupon.getCategoryType())) {
+                    //品类券
+                    couponsLogo = true;
+                    break;
+                }
+            }
+        }
+        return couponsLogo;
+    }
 }

+ 9 - 7
src/main/java/com/caimei365/commodity/service/impl/PriceServiceImpl.java

@@ -5,7 +5,10 @@ import com.caimei365.commodity.components.PriceUtilService;
 import com.caimei365.commodity.mapper.PriceMapper;
 import com.caimei365.commodity.mapper.PromotionsMapper;
 import com.caimei365.commodity.model.ResponseJson;
-import com.caimei365.commodity.model.vo.*;
+import com.caimei365.commodity.model.vo.LadderPriceVo;
+import com.caimei365.commodity.model.vo.PriceVo;
+import com.caimei365.commodity.model.vo.TaxVo;
+import com.caimei365.commodity.service.PageService;
 import com.caimei365.commodity.service.PriceService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -29,6 +32,8 @@ public class PriceServiceImpl implements PriceService {
     private PromotionsMapper promotionsMapper;
     @Resource
     private PriceUtilService priceUtilService;
+    @Resource
+    private PageService pageService;
 
     /**
      * 获取商品详情价格
@@ -55,7 +60,7 @@ public class PriceServiceImpl implements PriceService {
      * @return List<PriceVo>
      */
     @Override
-    public ResponseJson<List<PriceVo>> getListPrice(Integer userId, String productIds) {
+    public ResponseJson<List<PriceVo>> getListPrice(Integer userId, String productIds, Integer source) {
         List<Integer> productIdList = Lists.newArrayList();
         if (productIds.contains(",")) {
             String[] productArr = productIds.split(",");
@@ -73,6 +78,8 @@ public class PriceServiceImpl implements PriceService {
         for (PriceVo price : priceList) {
             // 根据用户id设置详细价格
             priceUtilService.setPriceByUserId(price, userId);
+            Boolean couponsLogo = pageService.setCouponsLogo(userId, price.getProductId(), source);
+            price.setCouponsLogo(couponsLogo);
         }
         log.info(">>>读取商品列表价格,商品IDs:" + productIds + ",用户ID:" + userId);
         return ResponseJson.success(priceList);
@@ -93,9 +100,4 @@ public class PriceServiceImpl implements PriceService {
         }
         return ResponseJson.success(ladderPrices);
     }
-
-
-
-
-
 }

+ 215 - 0
src/main/resources/mapper/CouponMapper.xml

@@ -0,0 +1,215 @@
+<?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.caimei365.commodity.mapper.CouponMapper">
+    <select id="findCouponClub" resultType="com.caimei365.commodity.model.vo.CouponVo">
+        SELECT
+          cc.`id` AS "couponId",
+          cc.`couponAmount`,
+          cc.`touchPrice`,
+          cc.`startDate`,
+          cc.`endDate`,
+          cc.`couponType`,
+          cc.`userId`,
+          cc.`shopId`,
+          cc.`productType`,
+          cc.`categoryType`
+        FROM
+          cm_coupon_club a
+          LEFT JOIN cm_coupon cc ON a.couponId = cc.id
+        WHERE
+          cc.delFlag = 0
+          AND a.delFlag = 0
+          AND a.userId = #{userId}
+          <if test="status == 1">
+              AND a.status = 1
+              AND NOW() BETWEEN cc.startDate
+              AND cc.endDate
+          </if>
+          <if test="status == 2">
+            AND a.status = 2
+            AND NOW() BETWEEN cc.startDate
+            AND cc.endDate
+          </if>
+          <if test="status == 3">
+              AND NOW() NOT BETWEEN cc.startDate
+              AND cc.endDate
+          </if>
+          AND cc.status != 2
+        ORDER BY
+          a.createDate DESC
+    </select>
+
+    <select id="findCouponById" resultType="com.caimei365.commodity.model.vo.ActivityCouponVo">
+        SELECT
+          id AS "couponId",
+          NAME,
+          pcBanner,
+          appletsBanner
+        FROM
+          cm_coupon
+        WHERE
+          productType = 2
+          AND delFlag = 0
+          AND couponType = 0
+          AND NOW() BETWEEN startDate
+          AND endDate
+          AND status != 2
+          AND id = #{couponId}
+    </select>
+
+    <select id="findCouponProduct" resultType="com.caimei365.commodity.model.vo.ProductItemVo">
+        SELECT
+          p.productID AS productId,
+          p.actStatus,
+          p.name,
+          p.aliasName,
+          p.mainImage AS image,
+          p.unit,
+          p.productCode AS CODE,
+          p.price1TextFlag AS priceFlag,
+          p.price1 AS price,
+          p.costPrice,
+          p.costCheckFlag,
+          p.shopID AS shopId,
+          p.searchKey AS keyword,
+          p.price8Text AS beautyActFlag,
+          p.minBuyNumber AS minBuyNumber,
+          p.maxBuyNumber AS maxBuyNumber,
+          p.ladderPriceFlag,
+          p.normalPrice,
+          p.step,
+          p.shopID AS shopId,
+          p.taxPoint AS taxRate,
+          p.includedTax,
+          p.invoiceType,
+          p.productCategory AS productCategory,
+          p.validFlag,
+          p.featuredFlag,
+          p.commodityType,
+          p.bigTypeID AS bigTypeId,
+          p.smallTypeID AS smallTypeId,
+          p.tinyTypeID AS tinyTypeId
+        FROM
+          cm_coupon_product a
+          LEFT JOIN product p ON a.productId = p.productID
+        WHERE
+          a.delFlag = 0
+          AND a.couponId = #{couponId}
+          <if test="source == 1">
+              AND a.pcStatus = 1
+          </if>
+          <if test="source == 2">
+              AND a.appletsStatus = 1
+          </if>
+        ORDER BY
+            -a.sort DESC
+    </select>
+
+    <select id="findCouponList" resultType="com.caimei365.commodity.model.vo.CouponVo">
+        SELECT
+          `id` AS "couponId",
+          `couponAmount`,
+          `touchPrice`,
+          `startDate`,
+          `endDate`,
+          `couponType`,
+          `userId`,
+          `shopId`,
+          `productType`,
+          `categoryType`
+        FROM
+          cm_coupon
+        WHERE
+          delFlag = 0
+          AND NOW() BETWEEN startDate
+          AND endDate
+          AND status != 2
+          AND couponsMode = 0
+          <if test="userId == null or userId == 0">
+              AND couponType != 2
+          </if>
+          <if test="userId > 0">
+              AND id NOT IN(SELECT couponId FROM cm_coupon_club WHERE userId = #{userId})
+              AND (couponType IN (0,1,3)
+              OR couponType = 2 AND userId = #{userId}
+              OR (SELECT registerTime FROM USER WHERE userID = #{userId}) <![CDATA[ >= ]]> startDate)
+          </if>
+        ORDER BY
+          createDate DESC
+    </select>
+
+    <select id="getCoupons" resultType="com.caimei365.commodity.model.vo.CouponVo">
+        SELECT
+          `id` AS "couponId",
+          `couponAmount`,
+          `touchPrice`,
+          `startDate`,
+          `endDate`,
+          `couponType`,
+          `userId`,
+          `shopId`,
+          `productType`,
+          `categoryType`
+        FROM
+          cm_coupon
+        WHERE
+          delFlag = 0
+          AND status != 2
+          AND id = #{couponId}
+    </select>
+
+    <select id="findCouponRedemptionCode" resultType="com.caimei365.commodity.model.po.CouponRedemptionCodePo">
+        SELECT
+          `id`,
+          `couponId`,
+          `userId`,
+          `redemptionCode`,
+          `status`,
+          `redemptionTime`,
+          `addTime`
+        FROM
+          `cm_coupon_redemption_code`
+        WHERE
+          redemptionCode = #{redemptionCode}
+    </select>
+
+    <select id="findCouponClubByUserId" resultType="integer">
+        SELECT
+          `id`
+        FROM
+          `cm_coupon_club`
+        WHERE
+          userId = #{userId}
+          AND couponId = #{couponId}
+    </select>
+
+    <insert id="insertCouponClub">
+        INSERT INTO `cm_coupon_club` (
+          `userId`,
+          `couponId`,
+          `orderId`,
+          `source`,
+          `status`,
+          `createDate`,
+          `useDate`,
+          `delFlag`
+        )
+        VALUES
+          (
+            #{userId},
+            #{couponId},
+            #{orderId},
+            #{source},
+            #{status},
+            #{createDate},
+            #{useDate},
+            #{delFlag}
+          )
+    </insert>
+
+    <update id="updateRedemptionCode">
+        UPDATE cm_coupon_redemption_code SET status = 2, redemptionTime = NOW() WHERE id = #{id}
+    </update>
+</mapper>

+ 44 - 0
src/main/resources/mapper/PageMapper.xml

@@ -341,4 +341,48 @@
         limit 1
     </select>
 
+    <select id="findAllCoupon" resultType="com.caimei365.commodity.model.vo.CouponVo">
+        SELECT
+            `id` AS "couponId",
+            `couponAmount`,
+            `touchPrice`,
+            `startDate`,
+            `endDate`,
+            `couponType`,
+            `userId`,
+            `shopId`,
+            `productType`,
+            `categoryType`
+        FROM
+           cm_coupon
+        WHERE
+           delFlag = 0
+            AND NOW() BETWEEN startDate
+            AND endDate
+            AND status != 2
+            AND couponsMode = 0
+        <if test="userId > 0">
+            AND (couponType IN (0,1,3)
+            OR couponType = 2 AND userId = #{userId}
+            OR (SELECT registerTime FROM USER WHERE userID = #{userId}) <![CDATA[ >= ]]> startDate)
+        </if>
+        ORDER BY
+          createDate DESC
+    </select>
+
+    <select id="findAllProductId" resultType="integer">
+        SELECT
+          productId
+        FROM
+          cm_coupon_product
+        WHERE
+          couponId = #{couponId}
+          <if test="source == 1">
+              AND pcStatus = 2
+          </if>
+          <if test="source == 2">
+              AND appletsStatus = 1
+          </if>
+    </select>
+
 </mapper>