소스 검색

查看幸运数字和兑奖

chunping 3 년 전
부모
커밋
8115725b07
44개의 변경된 파일1067개의 추가작업 그리고 72개의 파일을 삭제
  1. 34 18
      mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketController.java
  2. 49 0
      mp-common/src/main/java/com/qs/mp/common/enums/CoinLogTypeEnum.java
  3. 39 0
      mp-common/src/main/java/com/qs/mp/common/enums/CouponDiscountTypeEnum.java
  4. 38 0
      mp-common/src/main/java/com/qs/mp/common/enums/CouponDistributeTypeEnum.java
  5. 40 0
      mp-common/src/main/java/com/qs/mp/common/enums/CouponStatusEnum.java
  6. 39 0
      mp-common/src/main/java/com/qs/mp/common/enums/CouponTypeEnum.java
  7. 39 0
      mp-common/src/main/java/com/qs/mp/common/enums/CouponUseAreaEnum.java
  8. 39 0
      mp-common/src/main/java/com/qs/mp/common/enums/PrizeStorageInTypeEnum.java
  9. 38 0
      mp-common/src/main/java/com/qs/mp/common/enums/PrizeStorageStatusEnum.java
  10. 44 0
      mp-common/src/main/java/com/qs/mp/common/enums/TicketPrizeTypeEnum.java
  11. 41 0
      mp-common/src/main/java/com/qs/mp/common/enums/UserCouponStatusEnum.java
  12. 87 19
      mp-common/src/main/java/com/qs/mp/common/utils/DateUtils.java
  13. 1 0
      mp-framework/src/main/java/com/qs/mp/framework/config/SecurityConfig.java
  14. 22 10
      mp-service/src/main/java/com/qs/mp/admin/domain/Coupon.java
  15. 1 1
      mp-service/src/main/java/com/qs/mp/admin/domain/CouponChannel.java
  16. 1 1
      mp-service/src/main/java/com/qs/mp/admin/domain/CouponTicket.java
  17. 11 1
      mp-service/src/main/java/com/qs/mp/admin/domain/TicketAwardsPrize.java
  18. 19 0
      mp-service/src/main/java/com/qs/mp/admin/domain/dto/TicketDrawNumDTO.java
  19. 7 0
      mp-service/src/main/java/com/qs/mp/admin/domain/param/TicketParam.java
  20. 8 0
      mp-service/src/main/java/com/qs/mp/admin/service/ICouponService.java
  21. 65 0
      mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponServiceImpl.java
  22. 1 7
      mp-service/src/main/java/com/qs/mp/user/domain/UserCoin.java
  23. 5 1
      mp-service/src/main/java/com/qs/mp/user/domain/UserCoinLog.java
  24. 7 3
      mp-service/src/main/java/com/qs/mp/user/domain/UserCoupon.java
  25. 53 0
      mp-service/src/main/java/com/qs/mp/user/domain/UserCouponChannel.java
  26. 20 2
      mp-service/src/main/java/com/qs/mp/user/domain/UserPrizeStorage.java
  27. 6 0
      mp-service/src/main/java/com/qs/mp/user/domain/UserTicketOrderItem.java
  28. 13 0
      mp-service/src/main/java/com/qs/mp/user/mapper/UserCouponChannelMapper.java
  29. 7 0
      mp-service/src/main/java/com/qs/mp/user/service/IUserCoinService.java
  30. 16 0
      mp-service/src/main/java/com/qs/mp/user/service/IUserCouponChannelService.java
  31. 17 0
      mp-service/src/main/java/com/qs/mp/user/service/IUserHitPrizeService.java
  32. 10 0
      mp-service/src/main/java/com/qs/mp/user/service/IUserPrizeStorageService.java
  33. 7 0
      mp-service/src/main/java/com/qs/mp/user/service/IUserTicketOrderItemService.java
  34. 0 1
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserCoinLogServiceImpl.java
  35. 36 0
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserCoinServiceImpl.java
  36. 20 0
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserCouponChannelServiceImpl.java
  37. 116 0
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserHitPrizeServiceImpl.java
  38. 29 1
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserPrizeStorageServiceImpl.java
  39. 13 0
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserTicketOrderItemServiceImpl.java
  40. 2 1
      mp-service/src/main/resources/mapper/admin/TicketAwardsPrizeMapper.xml
  41. 2 3
      mp-service/src/main/resources/mapper/user/UserCoinMapper.xml
  42. 19 0
      mp-service/src/main/resources/mapper/user/UserCouponChannelMapper.xml
  43. 4 2
      mp-service/src/main/resources/mapper/user/UserPrizeStorageMapper.xml
  44. 2 1
      mp-service/src/main/resources/mapper/user/UserTicketOrderItemMapper.xml

+ 34 - 18
mp-admin/src/main/java/com/qs/mp/web/controller/api/common/UserTicketController.java → mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketController.java

@@ -8,7 +8,7 @@
  * 版权所有,侵权必究!
  */
 
-package com.qs.mp.web.controller.api.common;
+package com.qs.mp.web.controller.api.user;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -32,6 +32,7 @@ import com.qs.mp.common.enums.UserTicketOrderStatusEnum;
 import com.qs.mp.common.utils.StringUtils;
 import com.qs.mp.user.domain.UserTicketOrder;
 import com.qs.mp.user.domain.UserTicketOrderItem;
+import com.qs.mp.user.service.IUserHitPrizeService;
 import com.qs.mp.user.service.IUserTicketOrderItemService;
 import com.qs.mp.user.service.IUserTicketOrderService;
 import com.qs.mp.utils.SecurityUtils;
@@ -68,6 +69,9 @@ public class UserTicketController extends BaseApiController {
   @Autowired
   private IUserTicketOrderItemService userTicketOrderItemService;
 
+  @Autowired
+  private IUserHitPrizeService userHitPrizeService;
+
   @Autowired
   private MapperFacade mapperFacade;
 
@@ -128,9 +132,8 @@ public class UserTicketController extends BaseApiController {
 
     // 已付款的盲票,需要校验当前用户是否有权限查看
     if (ticket.getStatus() == TicketStatusEnum.ACTIVATED) {
-      List<UserTicketOrderItem> itemList = userTicketOrderItemService.list(new QueryWrapper<UserTicketOrderItem>().eq("t1.ticket_id", param.getTicketId())
-          .eq("t1.userId", userId).eq("t2.status", UserTicketOrderStatusEnum.FINISHED));
-      if (CollectionUtils.isEmpty(itemList)) {
+      UserTicketOrderItem orderItem = userTicketOrderItemService.queryFinishedOrderItem(userId, param.getTicketId());
+      if (null == orderItem) {
         return AjaxResult.error(ErrorCodeEnum.ERROR_CODE_1018);
       }
     }
@@ -158,6 +161,7 @@ public class UserTicketController extends BaseApiController {
   @PostMapping("/ticket/queryHitPrizeList")
   @ApiOperation(value = "查看兑奖奖品" , notes = "根据盲票ID,查看兑奖奖品")
   public AjaxResult queryHitPrizeList(@RequestBody TicketParam param) {
+    Long userId = SecurityUtils.getLoginUser().getUserId();
     if (StringUtils.isBlank(param.getTicketId())) {
       return AjaxResult.error("参数异常,盲票ID缺失");
     }
@@ -173,23 +177,35 @@ public class UserTicketController extends BaseApiController {
       return AjaxResult.error(ErrorCodeEnum.ERROR_CODE_1019);
     }
 
-//    UserTicketOrder ticketOrder =
+    List<TicketAwardsPrize> ticketAwardsPrizes = userHitPrizeService.listPrize(ticket, userId);
+    return AjaxResult.success(ticketAwardsPrizes);
+  }
 
-    TicketBox ticketBox = ticketBoxService.getById(ticket.getBoxId());
+  /**
+   * 兑奖
+   */
+  @PostMapping("/ticket/cashPrize")
+  @ApiOperation(value = "兑奖" , notes = "选择奖品兑奖")
+  public AjaxResult cashPrize(@RequestBody TicketParam param) {
+    Long userId = SecurityUtils.getLoginUser().getUserId();
+    if (StringUtils.isBlank(param.getTicketId()) || StringUtils.isBlank(param.getAwardsId())
+    || StringUtils.isBlank(param.getPrizeId())) {
+      return AjaxResult.error("参数缺失");
+    }
 
-    TicketVO ticketVO = new TicketVO();
-    ticketVO.setPrizeList(ticketAwardsPrizeService.listPrizeVO(new QueryWrapper<TicketAwardsPrize>()
-        .eq("t1.box_id", ticketBox.getBoxId()).orderByAsc("t1.sort").orderByDesc("t2.value")));
-    ticketVO.setTicketId(ticket.getTicketId());
-    ticketVO.setBoxId(ticket.getBoxId());
-    ticketVO.setTitle(ticketBox.getTitle());
-    ticketVO.setSerialNo(ticket.getSerialNo());
-    ticketVO.setFacePrice(ticket.getFacePrice());
-    ticketVO.setSalePrice(ticketBox.getSalePrice());
-    ticketVO.setPlainLuckyNum(ticket.getPlainLuckyNum());
-    ticketVO.setStatus(ticket.getStatus().getValue());
+    Ticket ticket = ticketService.getById(param.getTicketId());
+    if (null == ticket) {
+      return AjaxResult.error("参数异常,盲票不存在");
+    }
+    if (ticket.getStatus() == TicketStatusEnum.CASHED) {
+      return AjaxResult.error(ErrorCodeEnum.ERROR_CODE_1017);
+    }
+    if (ticket.getStatus() != TicketStatusEnum.ACTIVATED) {
+      return AjaxResult.error(ErrorCodeEnum.ERROR_CODE_1019);
+    }
 
-    return AjaxResult.success(ticketVO);
+    userHitPrizeService.cashPrize(ticket, userId, param.getAwardsId(), param.getPrizeId());
+    return AjaxResult.success();
   }
 
 }

+ 49 - 0
mp-common/src/main/java/com/qs/mp/common/enums/CoinLogTypeEnum.java

@@ -0,0 +1,49 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ * @auther zhongcp
+ * @create 2022 2022/3/7 2:30 下午
+ * @describe
+ */
+public enum CoinLogTypeEnum implements IEnum<Integer> {
+
+  PRIZE(1, "盲票奖品"),
+  CASHED(2, "商品兑换");
+
+
+  private final int value;
+  private final String desc;
+  public static final int INCOME = 1;   //收支类型 1收入
+  public static final int EXPENSES = 0;  //0支出
+
+  CoinLogTypeEnum(int value, String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  public static CoinLogTypeEnum getCoinLogTypeEnum(int value) {
+    for (CoinLogTypeEnum coinLogTypeEnum : CoinLogTypeEnum.values()) {
+      if (coinLogTypeEnum.getValue() == value) {
+        return coinLogTypeEnum;
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public Integer getValue() {
+    return value;
+  }
+
+
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value", value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 39 - 0
mp-common/src/main/java/com/qs/mp/common/enums/CouponDiscountTypeEnum.java

@@ -0,0 +1,39 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ * @auther zhongcp
+ * @create 2022 2022/3/7 2:30 下午
+ * @describe
+ */
+public enum CouponDiscountTypeEnum implements IEnum<Integer> {
+
+  MONEY_OFF(1, "代金券"),
+  DISCOUNT(2, "折扣券"),
+  EXCHANGE(3, "兑换券");
+
+
+  private final int value;
+  private final String desc;
+
+  CouponDiscountTypeEnum(int value, String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public Integer getValue() {
+    return value;
+  }
+
+
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value", value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 38 - 0
mp-common/src/main/java/com/qs/mp/common/enums/CouponDistributeTypeEnum.java

@@ -0,0 +1,38 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ * @auther zhongcp
+ * @create 2022 2022/3/7 2:30 下午
+ * @describe
+ */
+public enum CouponDistributeTypeEnum implements IEnum<Integer> {
+
+  SYSTEM(1, "系统发放"),
+  USER_DRAW(2, "用户主动领取");
+
+
+  private final int value;
+  private final String desc;
+
+  CouponDistributeTypeEnum(int value, String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public Integer getValue() {
+    return value;
+  }
+
+
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value", value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 40 - 0
mp-common/src/main/java/com/qs/mp/common/enums/CouponStatusEnum.java

@@ -0,0 +1,40 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ *
+ * 卡券上下架状态
+ *
+ */
+public enum CouponStatusEnum implements IEnum<String> {
+
+  PUT_ON("on", "上架"),
+  PUT_OFF("off", "下架");
+
+  private final String value;
+  private final String desc;
+
+  CouponStatusEnum(final String value, final String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public String getValue() {
+    return value;
+  }
+
+  /**
+   * 重写toString,单个转化成json
+   * @return
+   */
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value",value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 39 - 0
mp-common/src/main/java/com/qs/mp/common/enums/CouponTypeEnum.java

@@ -0,0 +1,39 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ * @auther zhongcp
+ * @create 2022 2022/3/7 2:30 下午
+ * @describe
+ */
+public enum CouponTypeEnum implements IEnum<Integer> {
+
+  TICKET_ORDER(1, "用户盲票购买优惠券"),
+  SITE_CONSUME(2, "用户门店消费优惠券"),
+  CHANNEL(3, "经销商盲票采购优惠券");
+
+
+  private final int value;
+  private final String desc;
+
+  CouponTypeEnum(int value, String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public Integer getValue() {
+    return value;
+  }
+
+
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value", value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 39 - 0
mp-common/src/main/java/com/qs/mp/common/enums/CouponUseAreaEnum.java

@@ -0,0 +1,39 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ * @auther zhongcp
+ * @create 2022 2022/3/7 2:30 下午
+ * @describe
+ */
+public enum CouponUseAreaEnum implements IEnum<Integer> {
+
+  COMMON(0, "通用"),
+  PRE_SCOPE(1, "指定范围"), // 生成优惠券的时候设定使用范围
+  POST_SCOPE(2, "指定范围"); // 发放的时候动态设定使用范围
+
+
+  private final int value;
+  private final String desc;
+
+  CouponUseAreaEnum(int value, String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public Integer getValue() {
+    return value;
+  }
+
+
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value", value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 39 - 0
mp-common/src/main/java/com/qs/mp/common/enums/PrizeStorageInTypeEnum.java

@@ -0,0 +1,39 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ * 奖品入库类型
+ * @auther zhongcp
+ * @create 2022 2022/3/7 2:30 下午
+ * @describe
+ */
+public enum PrizeStorageInTypeEnum implements IEnum<Integer> {
+
+  TICKET_CASHED(1, "奖品兑奖"),
+  COIN_EXCHANGE(2, "盲豆兑换");
+
+
+  private final int value;
+  private final String desc;
+
+  PrizeStorageInTypeEnum(int value, String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public Integer getValue() {
+    return value;
+  }
+
+
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value", value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 38 - 0
mp-common/src/main/java/com/qs/mp/common/enums/PrizeStorageStatusEnum.java

@@ -0,0 +1,38 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ * @auther zhongcp
+ * @create 2022 2022/3/7 2:30 下午
+ * @describe
+ */
+public enum PrizeStorageStatusEnum implements IEnum<Integer> {
+
+  NOT_DISTRIBUTED(1, "待提货"),
+  HAS_DISTRIBUTED(2, "已提货");
+
+
+  private final int value;
+  private final String desc;
+
+  PrizeStorageStatusEnum(int value, String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public Integer getValue() {
+    return value;
+  }
+
+
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value", value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 44 - 0
mp-common/src/main/java/com/qs/mp/common/enums/TicketPrizeTypeEnum.java

@@ -0,0 +1,44 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONType;
+import com.baomidou.mybatisplus.annotation.IEnum;
+import com.qs.mp.common.json.EnumValueDeserializer;
+
+/**
+ *
+ * 盲票奖品类型
+ *
+ */
+@JSONType(deserializer = EnumValueDeserializer.class)
+public enum TicketPrizeTypeEnum implements IEnum<String> {
+
+  GOODS("goods", "商品"),
+  COUPON("coupon", "优惠券"),
+  COIN("coin", "盲币");
+
+  private final String value;
+  private final String desc;
+
+  TicketPrizeTypeEnum(final String value, final String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public String getValue() {
+    return value;
+  }
+
+  /**
+   * 重写toString,单个转化成json
+   * @return
+   */
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value",value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 41 - 0
mp-common/src/main/java/com/qs/mp/common/enums/UserCouponStatusEnum.java

@@ -0,0 +1,41 @@
+package com.qs.mp.common.enums;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ *
+ * 用户卡券使用状态
+ *
+ */
+public enum UserCouponStatusEnum implements IEnum<Integer> {
+
+  UNUSED(1, "未使用"),
+  USED(2, "已使用"),
+  OVERDUE(3, "已过期"),;
+
+  private final Integer value;
+  private final String desc;
+
+  UserCouponStatusEnum(final Integer value, final String desc) {
+    this.value = value;
+    this.desc = desc;
+  }
+
+  @Override
+  public Integer getValue() {
+    return value;
+  }
+
+  /**
+   * 重写toString,单个转化成json
+   * @return
+   */
+  @Override
+  public String toString() {
+    JSONObject object = new JSONObject();
+    object.put("value",value);
+    object.put("desc", desc);
+    return object.toString();
+  }
+}

+ 87 - 19
mp-common/src/main/java/com/qs/mp/common/utils/DateUtils.java

@@ -6,10 +6,15 @@ import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
 import org.apache.commons.lang3.time.DateFormatUtils;
+import org.joda.time.DateTime;
+import org.joda.time.Days;
+import org.joda.time.Months;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
 
 /**
  * 时间工具类
- * 
+ *
  * @author ygp
  */
 public class DateUtils extends org.apache.commons.lang3.time.DateUtils
@@ -18,20 +23,26 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
 
     public static String YYYY_MM = "yyyy-MM";
 
+    public static String YYYYMM = "yyyyMM";
+
     public static String YYYY_MM_DD = "yyyy-MM-dd";
 
     public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
 
+    public static String YYYYMMDD = "yyyyMMdd";
+
+    public static String YYYYDOTMMDOTDD = "yyyy.MM.dd";
+
     public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
-    
+
     private static String[] parsePatterns = {
-            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", 
+            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
             "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
             "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
 
     /**
      * 获取当前Date型日期
-     * 
+     *
      * @return Date() 当前日期
      */
     public static Date getNowDate()
@@ -39,9 +50,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
         return new Date();
     }
 
+    public static Date getToday() {
+        String s = parseDateToStr(YYYY_MM_DD, new Date());
+        return dateTime(YYYY_MM_DD, s);
+    }
+
     /**
      * 获取当前日期, 默认格式为yyyy-MM-dd
-     * 
+     *
      * @return String
      */
     public static String getDate()
@@ -86,6 +102,45 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
         }
     }
 
+    public static final Date parseDateToDay(Date date) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        String s = sdf.format(date);
+        try {
+            return sdf.parse(s);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 计算两个日期之间相差多少天,一个月按30天算
+     * @param begin
+     * @param end
+     * @return
+     */
+    public static final int diff(Date begin, Date end) {
+        DateTimeFormatter formatter = DateTimeFormat.forPattern(YYYY_MM_DD);
+        DateTime startDay = formatter.parseDateTime(parseDateToStr(YYYY_MM_DD, begin));
+        DateTime endDay = formatter.parseDateTime(parseDateToStr(YYYY_MM_DD, end));
+        int days = Days.daysBetween(startDay, endDay).getDays();
+        return days;
+    }
+
+    /**
+     * 计算两个日期之间相差多少个月
+     * @param begin
+     * @param end
+     * @return
+     */
+    public static final int diffMonth(Date begin, Date end) {
+
+        DateTimeFormatter formatter = DateTimeFormat.forPattern(YYYY_MM_DD);
+        DateTime startDay = formatter.parseDateTime(parseDateToStr(YYYY_MM_DD, begin));
+        DateTime endDay = formatter.parseDateTime(parseDateToStr(YYYY_MM_DD, end));
+        int months = Months.monthsBetween(startDay, endDay).getMonths();
+        return months;
+    }
+
     /**
      * 日期路径 即年/月/日 如2018/08/08
      */
@@ -104,6 +159,20 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
         return DateFormatUtils.format(now, "yyyyMMdd");
     }
 
+    public static final Date parseStrToDate(String str, String pattern){
+        if (str == null)
+        {
+            return null;
+        }
+        try
+        {
+            return parseDate(str, pattern);
+        }
+        catch (ParseException e)
+        {
+            return null;
+        }
+    }
     /**
      * 日期型字符串转化为日期 格式
      */
@@ -122,7 +191,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
             return null;
         }
     }
-    
+
     /**
      * 获取服务器启动时间
      */
@@ -153,18 +222,17 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
         // long sec = diff % nd % nh % nm / ns;
         return day + "天" + hour + "小时" + min + "分钟";
     }
-    
-    /**
-     * 获取当天零点零分时间
-     * @return
-     */
-    public static Date getNowZero() {
-	    Calendar calendar = Calendar.getInstance();
-        calendar.setTime(new Date());
-        calendar.set(Calendar.HOUR_OF_DAY, 0);
-        calendar.set(Calendar.MINUTE, 0);
-        calendar.set(Calendar.SECOND, 0);
-        Date zero = calendar.getTime();
-        return zero;
+
+    public static Date getNowAddMonth(Date now, int months) {
+    	SimpleDateFormat sj = new SimpleDateFormat("yyyyMMdd");
+        try {
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(now);
+            calendar.add(Calendar.MONTH, months);
+            return calendar.getTime();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
     }
 }

+ 1 - 0
mp-framework/src/main/java/com/qs/mp/framework/config/SecurityConfig.java

@@ -124,6 +124,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/*/api-docs").anonymous()
                 .antMatchers("/druid/**").anonymous()
                 .antMatchers("/service/notify/**").anonymous()
+                .antMatchers("/api/v1/mp/user/mall/**").anonymous()
 
                 // 除上面外的所有请求全部需要鉴权认证
                 .anyRequest().authenticated()

+ 22 - 10
mp-service/src/main/java/com/qs/mp/admin/domain/Coupon.java

@@ -1,9 +1,16 @@
 package com.qs.mp.admin.domain;
 
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.qs.mp.common.enums.CouponDiscountTypeEnum;
+import com.qs.mp.common.enums.CouponDistributeTypeEnum;
+import com.qs.mp.common.enums.CouponStatusEnum;
+import com.qs.mp.common.enums.CouponTypeEnum;
+import com.qs.mp.common.enums.CouponUseAreaEnum;
 import java.io.Serializable;
 import java.util.Date;
 import lombok.Data;
@@ -22,8 +29,8 @@ public class Coupon implements Serializable {
   /**
    * 主键
    */
-  @TableId(value = "coupon_id", type = IdType.AUTO)
-  private Long couponId;
+  @TableId(value = "coupon_id", type = IdType.INPUT)
+  private String couponId;
 
   /**
    * 标题
@@ -35,7 +42,8 @@ public class Coupon implements Serializable {
    * 类型;1用户盲票购买优惠券、2用户门店消费优惠券、3经销商盲票采购优惠券
    */
   @TableField("type")
-  private Integer type;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private CouponTypeEnum type;
 
   /**
    * 图片
@@ -53,7 +61,8 @@ public class Coupon implements Serializable {
    * 优惠类型;1代金券、2折扣券、3兑换券
    */
   @TableField("discount_type")
-  private Integer discountType;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private CouponDiscountTypeEnum discountType;
 
   /**
    * 优惠金额(比例)
@@ -68,22 +77,25 @@ public class Coupon implements Serializable {
   private Integer minOrderAmt;
 
   /**
-   * 状态;0下架 1正常
+   * 状态;off下架 on正常
    */
   @TableField("status")
-  private Integer status;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private CouponStatusEnum status;
 
   /**
-   * 使用范围;0通用 1指定范围
+   * 使用范围;0通用 1生成券时指定范围 2发放时动态指定范围
    */
   @TableField("use_area")
-  private Integer useArea;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private CouponUseAreaEnum useArea;
 
   /**
-   * 发放方式;0系统发放 1用户主动领取
+   * 发放方式;1系统发放 2用户主动领取
    */
   @TableField("distribute_type")
-  private Integer distributeType;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private CouponDistributeTypeEnum distributeType;
 
   /**
    * 叠加使用;0不允许 1允许

+ 1 - 1
mp-service/src/main/java/com/qs/mp/admin/domain/CouponChannel.java

@@ -29,7 +29,7 @@ public class CouponChannel implements Serializable {
    * 优惠券ID
    */
   @TableField("coupon_id")
-  private Long couponId;
+  private String couponId;
 
   /**
    * 渠道ID

+ 1 - 1
mp-service/src/main/java/com/qs/mp/admin/domain/CouponTicket.java

@@ -29,7 +29,7 @@ public class CouponTicket implements Serializable {
    * 优惠券ID
    */
   @TableField("coupon_id")
-  private Long couponId;
+  private String couponId;
 
   /**
    * 盲票组ID

+ 11 - 1
mp-service/src/main/java/com/qs/mp/admin/domain/TicketAwardsPrize.java

@@ -1,9 +1,12 @@
 package com.qs.mp.admin.domain;
 
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.qs.mp.common.enums.TicketPrizeTypeEnum;
 import java.io.Serializable;
 import java.util.Date;
 import lombok.Data;
@@ -59,7 +62,8 @@ public class TicketAwardsPrize implements Serializable {
    * 奖品类型 1 实物商品 2优惠券 3平台代币
    */
   @TableField("prize_type")
-  private String prizeType;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private TicketPrizeTypeEnum prizeType;
 
   /**
    * 奖品数
@@ -73,6 +77,12 @@ public class TicketAwardsPrize implements Serializable {
   @TableField("cashed_qty")
   private Integer cashedQty;
 
+  /**
+   * 剩余奖品数
+   */
+  @TableField("remain_qty")
+  private Integer remainQty;
+
   /**
    * 奖品价值
    */

+ 19 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/dto/TicketDrawNumDTO.java

@@ -0,0 +1,19 @@
+package com.qs.mp.admin.domain.dto;
+
+import lombok.Data;
+
+/**
+ * 盲票抽奖号码
+ * @author zhongcp
+ * @Date 2022/3/8
+ */
+@Data
+public class TicketDrawNumDTO {
+  // 奖项ID
+  private String id;
+  // 奖项名
+  private String name;
+  // 号码
+  private int num;
+
+}

+ 7 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/param/TicketParam.java

@@ -13,4 +13,11 @@ public class TicketParam {
 	@ApiModelProperty(value = "盲票ID",required=false)
 	private String ticketId;
 
+	@ApiModelProperty(value = "奖项ID",required=false)
+	private String awardsId;
+
+	@ApiModelProperty(value = "奖品ID",required=false)
+	private String prizeId;
+
+
 }

+ 8 - 0
mp-service/src/main/java/com/qs/mp/admin/service/ICouponService.java

@@ -2,6 +2,7 @@ package com.qs.mp.admin.service;
 
 import com.qs.mp.admin.domain.Coupon;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.qs.mp.admin.domain.Ticket;
 
 /**
  * <p>
@@ -13,4 +14,11 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface ICouponService extends IService<Coupon> {
 
+  /**
+   * 发放
+   * @param ticket
+   * @param userId
+   * @param couponId
+   */
+  void distribute(Ticket ticket, Long userId, String couponId);
 }

+ 65 - 0
mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponServiceImpl.java

@@ -1,10 +1,28 @@
 package com.qs.mp.admin.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.qs.mp.admin.domain.Coupon;
+import com.qs.mp.admin.domain.Ticket;
 import com.qs.mp.admin.mapper.CouponMapper;
 import com.qs.mp.admin.service.ICouponService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qs.mp.common.enums.CouponUseAreaEnum;
+import com.qs.mp.common.enums.UserCouponStatusEnum;
+import com.qs.mp.common.exception.ServiceException;
+import com.qs.mp.common.utils.DateUtils;
+import com.qs.mp.common.utils.LogUtil;
+import com.qs.mp.system.service.id.BizIdGenerator;
+import com.qs.mp.user.domain.UserCoupon;
+import com.qs.mp.user.domain.UserCouponChannel;
+import com.qs.mp.user.domain.UserTicketOrderItem;
+import com.qs.mp.user.service.IUserCouponChannelService;
+import com.qs.mp.user.service.IUserCouponService;
+import com.qs.mp.user.service.IUserTicketOrderItemService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * <p>
@@ -17,4 +35,51 @@ import org.springframework.stereotype.Service;
 @Service
 public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements ICouponService {
 
+  protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+  @Autowired
+  private IUserCouponService userCouponService;
+
+  @Autowired
+  private IUserCouponChannelService userCouponChannelService;
+
+  @Autowired
+  private BizIdGenerator bizIdGenerator;
+
+  @Autowired
+  private IUserTicketOrderItemService userTicketOrderItemService;
+
+  @Override
+  @Transactional
+  public void distribute(Ticket ticket, Long userId, String couponId) {
+    Coupon coupon = getById(couponId);
+    UserCoupon userCoupon = new UserCoupon();
+    userCoupon.setId(bizIdGenerator.newId());
+    userCoupon.setUserId(userId);
+    userCoupon.setVerifyCode(bizIdGenerator.newId());
+    userCoupon.setCouponId(coupon.getCouponId());
+    if (coupon.getDueDays() > 0) {
+      userCoupon.setValidStart(DateUtils.getToday());
+      userCoupon.setValidEnd(DateUtils.addDays(userCoupon.getValidStart(), coupon.getDueDays()));
+    } else {
+      userCoupon.setValidStart(coupon.getValidStart());
+      userCoupon.setValidEnd(coupon.getValidEnd());
+    }
+    userCoupon.setStatus(UserCouponStatusEnum.UNUSED);
+    userCouponService.save(userCoupon);
+
+    // 确定限定范围
+    if (coupon.getUseArea() == CouponUseAreaEnum.POST_SCOPE) {
+      UserTicketOrderItem orderItem = userTicketOrderItemService.queryFinishedOrderItem(userId, ticket.getTicketId());
+      if (null == orderItem || null == orderItem.getChannelId()) {
+        LogUtil.error(logger, "优惠券的限定使用范围类型为发放时生成,但找不到关联的渠道ID。orderItem:{0}", new Object[]{
+            JSONObject.toJSONString(orderItem)});
+        throw new ServiceException("优惠券发放失败");
+      }
+      UserCouponChannel userCouponChannel = new UserCouponChannel();
+      userCouponChannel.setUserCouponId(userCoupon.getId());
+      userCouponChannel.setChannelId(orderItem.getChannelId());
+      userCouponChannelService.save(userCouponChannel);
+    }
+  }
 }

+ 1 - 7
mp-service/src/main/java/com/qs/mp/user/domain/UserCoin.java

@@ -19,16 +19,10 @@ public class UserCoin implements Serializable {
 
   private static final long serialVersionUID = 1L;
 
-  /**
-   * 主键
-   */
-  @TableId(value = "id", type = IdType.AUTO)
-  private Long id;
-
   /**
    * 用户ID
    */
-  @TableField("user_id")
+  @TableId(value = "user_id", type = IdType.INPUT)
   private Long userId;
 
   /**

+ 5 - 1
mp-service/src/main/java/com/qs/mp/user/domain/UserCoinLog.java

@@ -1,9 +1,12 @@
 package com.qs.mp.user.domain;
 
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.qs.mp.common.enums.CoinLogTypeEnum;
 import java.io.Serializable;
 import java.util.Date;
 import lombok.Data;
@@ -35,7 +38,8 @@ public class UserCoinLog implements Serializable {
    * 交易类型
    */
   @TableField("type")
-  private Integer type;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private CoinLogTypeEnum type;
 
   /**
    * 交易后余额

+ 7 - 3
mp-service/src/main/java/com/qs/mp/user/domain/UserCoupon.java

@@ -1,9 +1,12 @@
 package com.qs.mp.user.domain;
 
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.qs.mp.common.enums.UserCouponStatusEnum;
 import java.io.Serializable;
 import java.util.Date;
 import lombok.Data;
@@ -23,7 +26,7 @@ public class UserCoupon implements Serializable {
    * 主键
    */
   @TableId(value = "id", type = IdType.INPUT)
-  private Long id;
+  private String id;
 
   /**
    * 用户ID
@@ -41,7 +44,7 @@ public class UserCoupon implements Serializable {
    * 优惠券ID
    */
   @TableField("coupon_id")
-  private Long couponId;
+  private String couponId;
 
   /**
    * 生效日
@@ -71,7 +74,8 @@ public class UserCoupon implements Serializable {
    * 状态;1未使用 2已使用 3已过期
    */
   @TableField("status")
-  private Integer status;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private UserCouponStatusEnum status;
 
   /**
    * 创建时间

+ 53 - 0
mp-service/src/main/java/com/qs/mp/user/domain/UserCouponChannel.java

@@ -0,0 +1,53 @@
+package com.qs.mp.user.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * @describe 经销商门店优惠券使用范围限制实体类
+ * @auther quanshu
+ * @create 2022-03-09 09:23:17
+ */
+@TableName("mp_user_coupon_channel")
+@Data
+public class UserCouponChannel implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * 主键
+   */
+  @TableId(value = "id", type = IdType.AUTO)
+  private Long id;
+
+  /**
+   * 用户优惠券ID
+   */
+  @TableField("user_coupon_id")
+  private String userCouponId;
+
+  /**
+   * 渠道ID
+   */
+  @TableField("channel_id")
+  private Long channelId;
+
+  /**
+   * 创建时间
+   */
+  @TableField("created_time")
+  private Date createdTime;
+
+  /**
+   * 更新时间
+   */
+  @TableField("updated_time")
+  private Date updatedTime;
+
+
+}

+ 20 - 2
mp-service/src/main/java/com/qs/mp/user/domain/UserPrizeStorage.java

@@ -1,9 +1,13 @@
 package com.qs.mp.user.domain;
 
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
+import com.qs.mp.common.enums.PrizeStorageStatusEnum;
 import java.io.Serializable;
 import java.util.Date;
 import lombok.Data;
@@ -65,13 +69,27 @@ public class UserPrizeStorage implements Serializable {
    * 商品数
    */
   @TableField("goods_num")
-  private String goodsNum;
+  private Integer goodsNum;
+
+  /**
+   * 入库类型;1盲票兑奖、2盲豆兑换
+   */
+  @TableField("in_type")
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private PrizeStorageInTypeEnum inType;
+
+  /**
+   * 关联业务ID
+   */
+  @TableField("ref_id")
+  private String refId;
 
   /**
    * 状态;1待提货、2已提货
    */
   @TableField("status")
-  private Integer status;
+  @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
+  private PrizeStorageStatusEnum status;
 
   /**
    * 创建时间

+ 6 - 0
mp-service/src/main/java/com/qs/mp/user/domain/UserTicketOrderItem.java

@@ -49,6 +49,12 @@ public class UserTicketOrderItem implements Serializable {
   @TableField("ticket_id")
   private String ticketId;
 
+  /**
+   * 线下购买渠道ID
+   */
+  @TableField("channel_id")
+  private Long channelId;
+
   /**
    * 创建时间
    */

+ 13 - 0
mp-service/src/main/java/com/qs/mp/user/mapper/UserCouponChannelMapper.java

@@ -0,0 +1,13 @@
+package com.qs.mp.user.mapper;
+
+import com.qs.mp.user.domain.UserCouponChannel;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @auther quanshu
+ * @create 2022-03-09 09:23:17
+ * @describe 经销商门店优惠券使用范围限制mapper类
+ */
+public interface UserCouponChannelMapper extends BaseMapper<UserCouponChannel> {
+
+}

+ 7 - 0
mp-service/src/main/java/com/qs/mp/user/service/IUserCoinService.java

@@ -13,4 +13,11 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IUserCoinService extends IService<UserCoin> {
 
+  /**
+   * 发放代币
+   * @param userId
+   * @param logCoin
+   * @param bizId
+   */
+  void produce(Long userId, Integer logCoin, String bizId);
 }

+ 16 - 0
mp-service/src/main/java/com/qs/mp/user/service/IUserCouponChannelService.java

@@ -0,0 +1,16 @@
+package com.qs.mp.user.service;
+
+import com.qs.mp.user.domain.UserCouponChannel;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 经销商门店优惠券使用范围限制 服务类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-03-09
+ */
+public interface IUserCouponChannelService extends IService<UserCouponChannel> {
+
+}

+ 17 - 0
mp-service/src/main/java/com/qs/mp/user/service/IUserHitPrizeService.java

@@ -1,7 +1,11 @@
 package com.qs.mp.user.service;
 
+import com.qs.mp.admin.domain.Ticket;
+import com.qs.mp.admin.domain.TicketAwardsPrize;
+import com.qs.mp.admin.domain.vo.TicketAwardsPrizeVO;
 import com.qs.mp.user.domain.UserHitPrize;
 import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
 
 /**
  * <p>
@@ -13,4 +17,17 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IUserHitPrizeService extends IService<UserHitPrize> {
 
+  /**
+   * 查看盲票中奖奖品列表
+   * @param ticket
+   * @return
+   */
+  List<TicketAwardsPrize> listPrize(Ticket ticket, Long userId);
+
+  /**
+   * 兑奖
+   * @param ticket
+   * @return
+   */
+  void cashPrize(Ticket ticket, Long userId, String awardsId, String prizeId);
 }

+ 10 - 0
mp-service/src/main/java/com/qs/mp/user/service/IUserPrizeStorageService.java

@@ -1,5 +1,7 @@
 package com.qs.mp.user.service;
 
+import com.qs.mp.admin.domain.TicketAwardsPrize;
+import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
 import com.qs.mp.user.domain.UserPrizeStorage;
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -13,4 +15,12 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IUserPrizeStorageService extends IService<UserPrizeStorage> {
 
+  /**
+   * 商品入用户的奖品库
+   * @param userId
+   * @param ticketAwardsPrize
+   * @param inTypeEnum
+   * @param refId
+   */
+  void takeInStorage(Long userId, TicketAwardsPrize ticketAwardsPrize, PrizeStorageInTypeEnum inTypeEnum, String refId);
 }

+ 7 - 0
mp-service/src/main/java/com/qs/mp/user/service/IUserTicketOrderItemService.java

@@ -13,4 +13,11 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IUserTicketOrderItemService extends IService<UserTicketOrderItem> {
 
+  /**
+   * 查询购票订单明细
+   * @param userId
+   * @param ticketId
+   * @return
+   */
+  UserTicketOrderItem queryFinishedOrderItem(Long userId, String ticketId);
 }

+ 0 - 1
mp-service/src/main/java/com/qs/mp/user/service/impl/UserCoinLogServiceImpl.java

@@ -16,5 +16,4 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class UserCoinLogServiceImpl extends ServiceImpl<UserCoinLogMapper, UserCoinLog> implements IUserCoinLogService {
-
 }

+ 36 - 0
mp-service/src/main/java/com/qs/mp/user/service/impl/UserCoinServiceImpl.java

@@ -1,10 +1,17 @@
 package com.qs.mp.user.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.qs.mp.common.enums.CoinLogTypeEnum;
 import com.qs.mp.user.domain.UserCoin;
+import com.qs.mp.user.domain.UserCoinLog;
 import com.qs.mp.user.mapper.UserCoinMapper;
+import com.qs.mp.user.service.IUserCoinLogService;
 import com.qs.mp.user.service.IUserCoinService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import java.util.Date;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * <p>
@@ -17,4 +24,33 @@ import org.springframework.stereotype.Service;
 @Service
 public class UserCoinServiceImpl extends ServiceImpl<UserCoinMapper, UserCoin> implements IUserCoinService {
 
+  @Autowired
+  private IUserCoinLogService userCoinLogService;
+
+  @Override
+  @Transactional
+  public void produce(Long userId, Integer logCoin, String bizId) {
+    UserCoin userCoin = getById(userId);
+    if (null == userCoin) {
+      userCoin = new UserCoin();
+      userCoin.setUserId(userId);
+      userCoin.setCoin(logCoin);
+      save(userCoin);
+    } else {
+      update(new LambdaUpdateWrapper<UserCoin>().set(UserCoin::getCoin, userCoin.getCoin() + logCoin)
+          .eq(UserCoin::getUserId, userId).eq(UserCoin::getCoin, userCoin.getCoin()));
+    }
+
+    UserCoinLog userCoinLog = new UserCoinLog();
+    userCoinLog.setUserId(userId);
+    userCoinLog.setType(CoinLogTypeEnum.PRIZE);
+    userCoinLog.setMoney(userCoin.getCoin() + logCoin);
+    userCoinLog.setLogMoney(logCoin);
+    userCoinLog.setIncomeExpense(CoinLogTypeEnum.INCOME);
+    userCoinLog.setLogText("盲票奖品");
+    userCoinLog.setBizTime(new Date());
+    userCoinLog.setRefType(1);
+    userCoinLog.setRefId(bizId);
+    userCoinLogService.save(userCoinLog);
+  }
 }

+ 20 - 0
mp-service/src/main/java/com/qs/mp/user/service/impl/UserCouponChannelServiceImpl.java

@@ -0,0 +1,20 @@
+package com.qs.mp.user.service.impl;
+
+import com.qs.mp.user.domain.UserCouponChannel;
+import com.qs.mp.user.mapper.UserCouponChannelMapper;
+import com.qs.mp.user.service.IUserCouponChannelService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 经销商门店优惠券使用范围限制 服务实现类
+ * </p>
+ *
+ * @author quanshu
+ * @since 2022-03-09
+ */
+@Service
+public class UserCouponChannelServiceImpl extends ServiceImpl<UserCouponChannelMapper, UserCouponChannel> implements IUserCouponChannelService {
+
+}

+ 116 - 0
mp-service/src/main/java/com/qs/mp/user/service/impl/UserHitPrizeServiceImpl.java

@@ -1,10 +1,47 @@
 package com.qs.mp.user.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.qs.mp.admin.domain.Coupon;
+import com.qs.mp.admin.domain.Ticket;
+import com.qs.mp.admin.domain.TicketAwardsPrize;
+import com.qs.mp.admin.domain.dto.TicketDrawNumDTO;
+import com.qs.mp.admin.service.ICouponService;
+import com.qs.mp.admin.service.ITicketAwardsPrizeService;
+import com.qs.mp.admin.service.ITicketService;
+import com.qs.mp.common.enums.CouponUseAreaEnum;
+import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
+import com.qs.mp.common.enums.PrizeStorageStatusEnum;
+import com.qs.mp.common.enums.TicketPrizeTypeEnum;
+import com.qs.mp.common.enums.UserCouponStatusEnum;
+import com.qs.mp.common.exception.ServiceException;
+import com.qs.mp.common.utils.DateUtils;
+import com.qs.mp.common.utils.LogUtil;
+import com.qs.mp.system.service.id.BizIdGenerator;
+import com.qs.mp.user.domain.UserCoupon;
+import com.qs.mp.user.domain.UserCouponChannel;
 import com.qs.mp.user.domain.UserHitPrize;
+import com.qs.mp.user.domain.UserPrizeStorage;
+import com.qs.mp.user.domain.UserTicketOrderItem;
 import com.qs.mp.user.mapper.UserHitPrizeMapper;
+import com.qs.mp.user.service.IUserCoinService;
+import com.qs.mp.user.service.IUserCouponChannelService;
+import com.qs.mp.user.service.IUserCouponService;
 import com.qs.mp.user.service.IUserHitPrizeService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qs.mp.user.service.IUserPrizeStorageService;
+import com.qs.mp.user.service.IUserTicketOrderItemService;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import org.codehaus.janino.IClass.IField;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
 /**
  * <p>
@@ -17,4 +54,83 @@ import org.springframework.stereotype.Service;
 @Service
 public class UserHitPrizeServiceImpl extends ServiceImpl<UserHitPrizeMapper, UserHitPrize> implements IUserHitPrizeService {
 
+  protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+  @Autowired
+  private IUserTicketOrderItemService userTicketOrderItemService;
+
+  @Autowired
+  private ITicketAwardsPrizeService ticketAwardsPrizeService;
+
+  @Autowired
+  private IUserPrizeStorageService userPrizeStorageService;
+
+  @Autowired
+  private IUserCoinService userCoinService;
+
+  @Autowired
+  private ICouponService couponService;
+
+  @Override
+  public List<TicketAwardsPrize> listPrize(Ticket ticket, Long userId) {
+    UserHitPrize userHitPrize = getOne(new LambdaQueryWrapper<UserHitPrize>().eq(UserHitPrize::getTicketId, ticket.getTicketId()));
+    UserTicketOrderItem orderItem = userTicketOrderItemService.queryFinishedOrderItem(userId, ticket.getTicketId());
+    if (null == orderItem) {
+      LogUtil.error(logger, "查询盲票的奖品信息,盲票订单不存在。ticketId:{0}, userId:{1}",
+          new Object[]{ticket.getTicketId(), userId});
+      throw new ServiceException("盲票订单不存在");
+    }
+
+    if (null == userHitPrize) {
+      List<TicketDrawNumDTO> drawNumDTOList = JSONObject.parseArray(ticket.getDrawNum(), TicketDrawNumDTO.class);
+      for (TicketDrawNumDTO ticketDrawNumDTO : drawNumDTOList) {
+        if (ticketDrawNumDTO.getNum() == ticket.getPlainLuckyNum()) {
+          userHitPrize = new UserHitPrize();
+          userHitPrize.setUserId(userId);
+          userHitPrize.setOrderId(orderItem.getOrderId());
+          userHitPrize.setOrderItemId(orderItem.getItemId());
+          userHitPrize.setTicketId(ticket.getTicketId());
+          userHitPrize.setAwardsId(ticketDrawNumDTO.getId());
+          // 奖品ID等用户选择后填入
+//          userHitPrize.setPrizeId();
+          save(userHitPrize);
+        }
+      }
+    }
+    List<TicketAwardsPrize> awardsPrizes = ticketAwardsPrizeService.list(new LambdaQueryWrapper<TicketAwardsPrize>()
+        .eq(TicketAwardsPrize::getAwardsId, userHitPrize.getAwardsId()).orderByDesc(TicketAwardsPrize::getRemainQty));
+    return awardsPrizes;
+  }
+
+  @Override
+  @Transactional
+  public void cashPrize(Ticket ticket, Long userId, String awardsId, String prizeId) {
+    // 更新奖品已兑奖数量
+    TicketAwardsPrize ticketAwardsPrize = ticketAwardsPrizeService.getById(prizeId);
+    if (ticketAwardsPrize.getRemainQty() <= 0) {
+      throw new ServiceException("奖品已兑完,请重新选择");
+    }
+    // 乐观锁
+    ticketAwardsPrizeService.update(new LambdaUpdateWrapper<TicketAwardsPrize>().set(TicketAwardsPrize::getCashedQty, ticketAwardsPrize.getCashedQty() + 1)
+        .set(TicketAwardsPrize::getRemainQty, ticketAwardsPrize.getRemainQty() - 1)
+        .eq(TicketAwardsPrize::getPrizeId, prizeId).eq(TicketAwardsPrize::getCashedQty, ticketAwardsPrize.getCashedQty()));
+
+    // 保存奖品到中奖记录中
+    UserHitPrize userHitPrize = getOne(new LambdaQueryWrapper<UserHitPrize>().eq(UserHitPrize::getTicketId, ticket.getTicketId()));
+    userHitPrize.setPrizeId(prizeId);
+    updateById(userHitPrize);
+
+    // 放入仓库
+    if (ticketAwardsPrize.getPrizeType() == TicketPrizeTypeEnum.COIN) {
+      userCoinService.produce(userId, ticketAwardsPrize.getValue(), String.valueOf(userHitPrize.getId()));
+    } else if (ticketAwardsPrize.getPrizeType() == TicketPrizeTypeEnum.COUPON) {
+      couponService.distribute(ticket, userId, ticketAwardsPrize.getRefId());
+    } else {
+      userPrizeStorageService.takeInStorage(userId, ticketAwardsPrize, PrizeStorageInTypeEnum.TICKET_CASHED, String.valueOf(userHitPrize.getId()));
+    }
+  }
+
+
+
+
 }

+ 29 - 1
mp-service/src/main/java/com/qs/mp/user/service/impl/UserPrizeStorageServiceImpl.java

@@ -1,5 +1,10 @@
 package com.qs.mp.user.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.qs.mp.admin.domain.TicketAwardsPrize;
+import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
+import com.qs.mp.common.enums.PrizeStorageStatusEnum;
 import com.qs.mp.user.domain.UserPrizeStorage;
 import com.qs.mp.user.mapper.UserPrizeStorageMapper;
 import com.qs.mp.user.service.IUserPrizeStorageService;
@@ -16,5 +21,28 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class UserPrizeStorageServiceImpl extends ServiceImpl<UserPrizeStorageMapper, UserPrizeStorage> implements IUserPrizeStorageService {
-
+  @Override
+  public void takeInStorage(Long userId, TicketAwardsPrize ticketAwardsPrize, PrizeStorageInTypeEnum inTypeEnum, String refId) {
+    UserPrizeStorage userPrizeStorage = getOne(new LambdaQueryWrapper<UserPrizeStorage>()
+        .eq(UserPrizeStorage::getGoodsId, ticketAwardsPrize.getRefId()).eq(UserPrizeStorage::getUserId,
+            userId)
+        .eq(UserPrizeStorage::getStatus, PrizeStorageStatusEnum.NOT_DISTRIBUTED));
+    if (null == userPrizeStorage) {
+      userPrizeStorage = new UserPrizeStorage();
+      userPrizeStorage.setUserId(userId);
+      userPrizeStorage.setGoodsId(ticketAwardsPrize.getRefId());
+      userPrizeStorage.setSkuId(null);
+      userPrizeStorage.setProperties(null);
+      userPrizeStorage.setTitle(ticketAwardsPrize.getTitle());
+      userPrizeStorage.setPicUrl(ticketAwardsPrize.getPicUrl());
+      userPrizeStorage.setGoodsNum(1);
+      userPrizeStorage.setInType(inTypeEnum);
+      userPrizeStorage.setRefId(refId);
+      userPrizeStorage.setStatus(PrizeStorageStatusEnum.NOT_DISTRIBUTED);
+      save(userPrizeStorage);
+    } else {
+      update(new LambdaUpdateWrapper<UserPrizeStorage>().set(UserPrizeStorage::getGoodsNum, userPrizeStorage.getGoodsNum() + 1)
+          .eq(UserPrizeStorage::getStorageId, userPrizeStorage.getStorageId()).eq(UserPrizeStorage::getGoodsNum, userPrizeStorage.getGoodsNum()));
+    }
+  }
 }

+ 13 - 0
mp-service/src/main/java/com/qs/mp/user/service/impl/UserTicketOrderItemServiceImpl.java

@@ -1,10 +1,14 @@
 package com.qs.mp.user.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qs.mp.common.enums.UserTicketOrderStatusEnum;
 import com.qs.mp.user.domain.UserTicketOrderItem;
 import com.qs.mp.user.mapper.UserTicketOrderItemMapper;
 import com.qs.mp.user.service.IUserTicketOrderItemService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import java.util.List;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
 /**
  * <p>
@@ -17,4 +21,13 @@ import org.springframework.stereotype.Service;
 @Service
 public class UserTicketOrderItemServiceImpl extends ServiceImpl<UserTicketOrderItemMapper, UserTicketOrderItem> implements IUserTicketOrderItemService {
 
+  @Override
+  public UserTicketOrderItem queryFinishedOrderItem(Long userId, String ticketId) {
+    List<UserTicketOrderItem> itemList = getBaseMapper().listTicketOrderItemVO(new QueryWrapper<UserTicketOrderItem>().eq("t1.ticket_id", ticketId)
+        .eq("t1.userId", userId).eq("t2.status", UserTicketOrderStatusEnum.FINISHED));
+    if (CollectionUtils.isEmpty(itemList)) {
+      return null;
+    }
+    return itemList.get(0);
+  }
 }

+ 2 - 1
mp-service/src/main/resources/mapper/admin/TicketAwardsPrizeMapper.xml

@@ -13,6 +13,7 @@
         <result column="prize_type" property="prizeType" />
         <result column="quantity" property="quantity" />
         <result column="cashed_qty" property="cashedQty" />
+        <result column="remain_qty" property="remainQty" />
         <result column="value" property="value" />
         <result column="created_time" property="createdTime" />
         <result column="updated_time" property="updatedTime" />
@@ -20,7 +21,7 @@
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        prize_id, box_id, awards_id, ref_id, title, pic_url, prize_type, quantity, cashed_qty, value, created_time, updated_time
+        prize_id, box_id, awards_id, ref_id, title, pic_url, prize_type, quantity, cashed_qty, remain_qty, value, created_time, updated_time
     </sql>
 
     <select id="listPrizeVO" resultType="com.qs.mp.admin.domain.vo.TicketAwardsPrizeVO">

+ 2 - 3
mp-service/src/main/resources/mapper/user/UserCoinMapper.xml

@@ -4,7 +4,6 @@
 
     <!-- 通用查询映射结果 -->
     <resultMap id="BaseResultMap" type="com.qs.mp.user.domain.UserCoin">
-        <id column="id" property="id" />
         <result column="user_id" property="userId" />
         <result column="coin" property="coin" />
         <result column="created_time" property="createdTime" />
@@ -13,7 +12,7 @@
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id, user_id, coin, created_time, updated_time
+        user_id, coin, created_time, updated_time
     </sql>
 
-</mapper>
+</mapper>

+ 19 - 0
mp-service/src/main/resources/mapper/user/UserCouponChannelMapper.xml

@@ -0,0 +1,19 @@
+<?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.qs.mp.user.mapper.UserCouponChannelMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qs.mp.user.domain.UserCouponChannel">
+        <id column="id" property="id" />
+        <result column="user_coupon_id" property="userCouponId" />
+        <result column="channel_id" property="channelId" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_time" property="updatedTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, user_coupon_id, channel_id, created_time, updated_time
+    </sql>
+
+</mapper>

+ 4 - 2
mp-service/src/main/resources/mapper/user/UserPrizeStorageMapper.xml

@@ -12,6 +12,8 @@
         <result column="title" property="title" />
         <result column="pic_url" property="picUrl" />
         <result column="goods_num" property="goodsNum" />
+        <result column="in_type" property="inType" />
+        <result column="ref_id" property="refId" />
         <result column="status" property="status" />
         <result column="created_time" property="createdTime" />
         <result column="updated_time" property="updatedTime" />
@@ -19,7 +21,7 @@
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        storage_id, user_id, goods_id, sku_id, properties, title, pic_url, goods_num, status, created_time, updated_time
+        storage_id, user_id, goods_id, sku_id, properties, title, pic_url, goods_num, in_type, ref_id, status, created_time, updated_time
     </sql>
 
-</mapper>
+</mapper>

+ 2 - 1
mp-service/src/main/resources/mapper/user/UserTicketOrderItemMapper.xml

@@ -9,13 +9,14 @@
         <result column="user_id" property="userId" />
         <result column="box_id" property="boxId" />
         <result column="ticket_id" property="ticketId" />
+        <result column="channel_id" property="channelId" />
         <result column="created_time" property="createdTime" />
         <result column="updated_time" property="updatedTime" />
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        item_id, order_id, user_id, box_id, ticket_id, created_time, updated_time
+        item_id, order_id, user_id, box_id, ticket_id, channel_id, created_time, updated_time
     </sql>
 
     <select id="listTicketOrderItemVO" resultMap="BaseResultMap">