Browse Source

1、增加订单支付成功后增加抽奖次数逻辑

rayson 6 months ago
parent
commit
ef2fcc2088
20 changed files with 360 additions and 21 deletions
  1. 27 0
      citu-module-mall/citu-module-promotion-api/src/main/java/com/citu/module/promotion/api/luck/LuckLotteryApi.java
  2. 1 0
      citu-module-mall/citu-module-promotion-api/src/main/java/com/citu/module/promotion/enums/ErrorCodeConstants.java
  3. 27 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/api/luck/LuckLotteryApiImpl.java
  4. 2 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/admin/luck/vo/LuckLotteryDetailRespVO.java
  5. 1 1
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/admin/luck/vo/record/LuckLotteryRecordDetailRespVO.java
  6. 44 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/admin/luck/vo/record/LuckLotteryRecordSimpleRespVO.java
  7. 20 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/AppLuckLotteryController.java
  8. 10 4
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/AppLuckLotteryRecordController.java
  9. 2 2
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/AppLuckPrizeController.java
  10. 20 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/vo/AppLuckLotteryReceiveReqVO.java
  11. 4 1
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/convert/luck/LuckLotteryRecordConvert.java
  12. 41 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/dal/dataobject/luck/LuckUserDO.java
  13. 18 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/dal/mysql/luck/LuckUserMapper.java
  14. 6 0
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryRecordService.java
  15. 26 5
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryRecordServiceImpl.java
  16. 29 1
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryService.java
  17. 70 5
      citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryServiceImpl.java
  18. 1 1
      citu-module-mall/citu-module-promotion-biz/src/main/resources/application.yaml
  19. 2 1
      citu-module-mall/citu-module-trade-biz/src/main/java/com/citu/module/trade/framework/rpc/config/RpcConfiguration.java
  20. 9 0
      citu-module-mall/citu-module-trade-biz/src/main/java/com/citu/module/trade/service/order/handler/TradeLotteryOrderHandler.java

+ 27 - 0
citu-module-mall/citu-module-promotion-api/src/main/java/com/citu/module/promotion/api/luck/LuckLotteryApi.java

@@ -0,0 +1,27 @@
+package com.citu.module.promotion.api.luck;
+
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.module.promotion.enums.ApiConstants;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(name = ApiConstants.NAME)
+@Tag(name = "RPC 服务 - 抽奖活动")
+public interface LuckLotteryApi {
+
+    String PREFIX = ApiConstants.PREFIX + "/luck-lottery";
+
+    @PutMapping(PREFIX + "/update-user-lottery-num-incr")
+    @Operation(summary = "修改用户抽奖次数")
+    @Parameters({
+            @Parameter(name = "skuId", description = "SKU 编号", required = true, example = "2"),
+            @Parameter(name = "userId", description = "用户iD", required = true, example = "3"),
+    })
+    CommonResult<Boolean> updateUserNumIncr(@RequestParam("spuId") Long spuId,
+                                               @RequestParam("userId") Long userId);
+}

+ 1 - 0
citu-module-mall/citu-module-promotion-api/src/main/java/com/citu/module/promotion/enums/ErrorCodeConstants.java

@@ -145,6 +145,7 @@ public interface ErrorCodeConstants {
     ErrorCode LUCK_LOTTERY_NAME_USED = new ErrorCode(1_013_050_04, "幸运抽奖活动名称({})已经被使用");
     ErrorCode LUCK_LOTTERY_PRODUCT_USED = new ErrorCode(1_013_050_05, "该商品已被其他活动选择,请修改选中商品或修改对应的抽奖活动");
     ErrorCode LUCK_LOTTERY_PRODUCT_NOT_SELECTED = new ErrorCode(1_013_050_06, "请选择下单指定商品");
+    ErrorCode LUCK_LOTTERY_USER_NUM_EXCEED = new ErrorCode(1_013_050_07, "抽奖次数不足");
 
     // ========== 幸运抽奖-奖品 1-013-051-00 ==========
     ErrorCode LUCK_PRIZE_NOT_EXISTS = new ErrorCode(1_013_051_01, "幸运抽奖奖品不存在");

+ 27 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/api/luck/LuckLotteryApiImpl.java

@@ -0,0 +1,27 @@
+package com.citu.module.promotion.api.luck;
+
+import com.citu.framework.common.pojo.CommonResult;
+import com.citu.module.promotion.service.luck.LuckLotteryService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 幸运抽奖活动 Api 接口实现类
+ *
+ * @author HUIHUI
+ */
+@RestController // 提供 RESTful API 接口,给 Feign 调用
+@Validated
+public class LuckLotteryApiImpl implements LuckLotteryApi{
+
+    @Resource
+    private LuckLotteryService luckLotteryService;
+
+    @Override
+    public CommonResult<Boolean> updateUserNumIncr(Long spuId, Long userId) {
+        luckLotteryService.updateUserNumIncr(spuId, userId);
+        return CommonResult.success(true);
+    }
+}

+ 2 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/admin/luck/vo/LuckLotteryDetailRespVO.java

@@ -16,4 +16,6 @@ public class LuckLotteryDetailRespVO extends LuckLotteryRespVO {
     @Schema(description = "商品信息", example = "9192")
     private List<ProductSpuRespDTO> spuList;
 
+
+
 }

+ 1 - 1
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/admin/luck/vo/record/LuckLotteryRecordDetailRespVO.java

@@ -14,7 +14,7 @@ import lombok.Data;
 public class LuckLotteryRecordDetailRespVO {
 
     @Schema(description = "记录")
-    private LuckLotteryRecordRespVO record;
+    private LuckLotteryRecordSimpleRespVO record;
 
     @Schema(description = "活动")
     private LuckLotteryDetailRespVO lottery;

+ 44 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/admin/luck/vo/record/LuckLotteryRecordSimpleRespVO.java

@@ -0,0 +1,44 @@
+package com.citu.module.promotion.controller.admin.luck.vo.record;
+
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 幸运抽奖-抽奖简易记录 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class LuckLotteryRecordSimpleRespVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "6084")
+    @ExcelProperty("id")
+    private Long id;
+
+    @Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "9325")
+    @ExcelProperty("用户id")
+    private Long userId;
+
+    @Schema(description = "活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "14605")
+    @ExcelProperty("活动id")
+    private Long lotteryId;
+
+    @Schema(description = "奖品id", requiredMode = Schema.RequiredMode.REQUIRED, example = "369")
+    @ExcelProperty("奖品id")
+    private Long prizeId;
+
+    @Schema(description = "奖品类型(1未中奖 2积分 3余额 4红包 5优惠券 6站内商品 7等级经验 8用户等级 9svip天数 99自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("奖品类型(1未中奖 2积分 3余额 4红包 5优惠券 6站内商品 7等级经验 8用户等级 9svip天数 99自定义)")
+    private String type;
+
+    @Schema(description = "奖品扩展", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+    @ExcelProperty("奖品扩展")
+    private Object extend;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 20 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/AppLuckLotteryController.java

@@ -3,7 +3,9 @@ package com.citu.module.promotion.controller.app.luck;
 
 import com.citu.framework.common.pojo.CommonResult;
 import com.citu.framework.common.util.object.BeanUtils;
+import com.citu.framework.security.core.annotations.PreAuthenticated;
 import com.citu.module.promotion.controller.admin.luck.vo.LuckLotteryRespVO;
+import com.citu.module.promotion.controller.admin.luck.vo.prize.LuckPrizeDetailRespVO;
 import com.citu.module.promotion.dal.dataobject.luck.LuckLotteryDO;
 import com.citu.module.promotion.service.luck.LuckLotteryService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -19,6 +21,7 @@ import java.time.LocalDateTime;
 import java.util.List;
 
 import static com.citu.framework.common.pojo.CommonResult.success;
+import static com.citu.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 
 @Tag(name = "用户 APP - 幸运抽奖-活动")
 @RestController
@@ -47,4 +50,21 @@ public class AppLuckLotteryController {
         return success(BeanUtils.toBean(luckLotteryService.getLuckLottery(id), LuckLotteryRespVO.class));
     }
 
+    @GetMapping("/get/by-spu-id")
+    @Operation(summary = "根据商品id获取抽奖活动")
+    public CommonResult<LuckLotteryRespVO> getLuckLotteryBySpuId(@RequestParam("spuId") Long spuId) {
+        LuckLotteryDO luckLottery = luckLotteryService.getLuckLotteryBySpuId(String.valueOf(spuId));
+        if (null == luckLottery) {
+            return success(null);
+        }
+        luckLotteryService.checkTimeExpired(luckLottery);
+        return success(BeanUtils.toBean(luckLottery, LuckLotteryRespVO.class));
+    }
+
+    @GetMapping("/get/user-num")
+    @PreAuthenticated
+    @Operation(summary = "获取用户抽奖次数")
+    public CommonResult<Integer> getUserNum(@RequestParam("lotteryId") Long lotteryId) {
+        return success(luckLotteryService.getUserNum(lotteryId,getLoginUserId()));
+    }
 }

+ 10 - 4
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/AppLuckLotteryRecordController.java

@@ -8,15 +8,13 @@ import com.citu.framework.security.core.annotations.PreAuthenticated;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordDetailRespVO;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordPageReqVO;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordRespVO;
+import com.citu.module.promotion.controller.app.luck.vo.AppLuckLotteryReceiveReqVO;
 import com.citu.module.promotion.dal.dataobject.luck.LuckLotteryRecordDO;
 import com.citu.module.promotion.service.luck.LuckLotteryRecordService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
@@ -56,4 +54,12 @@ public class AppLuckLotteryRecordController {
             (@RequestParam("lotteryId") Long lotteryId) {
         return success(luckLotteryRecordService.getLuckLotteryRecordList(lotteryId, getLoginUserId()));
     }
+
+    @PostMapping("/receive")
+    @PreAuthenticated
+    @Operation(summary = "领取奖品")
+    public CommonResult<Boolean> receive(@Valid @RequestBody AppLuckLotteryReceiveReqVO reqVO) {
+        luckLotteryRecordService.receive(reqVO, getLoginUserId());
+        return success(true);
+    }
 }

+ 2 - 2
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/AppLuckPrizeController.java

@@ -39,9 +39,9 @@ public class AppLuckPrizeController {
     getLuckPrizeExtendAreaMap(@RequestParam("spuId") Long spuId,
                               @RequestParam(value = "type", required = false) String type,
                               @RequestParam(value = "parentAreaId", required = false) Long parentAreaId) {
-        LuckLotteryDO luckLottery = luckLotteryService.getLuckLotteryListBySpuId(String.valueOf(spuId));
+        LuckLotteryDO luckLottery = luckLotteryService.getLuckLotteryBySpuId(String.valueOf(spuId));
         if (null == luckLottery) {
-            return null;
+            return success(null);
         }
         return success(luckPrizeService.getLuckPrizeExtendAreaMap(luckLottery.getId(), type, parentAreaId));
     }

+ 20 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/controller/app/luck/vo/AppLuckLotteryReceiveReqVO.java

@@ -0,0 +1,20 @@
+package com.citu.module.promotion.controller.app.luck.vo;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Schema(description = "用户端 - 幸运抽奖-抽奖领用 Request VO")
+@Data
+public class AppLuckLotteryReceiveReqVO {
+
+    @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "6084")
+    @NotNull(message = "id不能为空")
+    private Long id;
+
+    @Schema(description = "收获地址、备注等")
+    private String receiveInfo;
+
+}

+ 4 - 1
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/convert/luck/LuckLotteryRecordConvert.java

@@ -5,6 +5,7 @@ import com.citu.module.promotion.controller.admin.luck.vo.LuckLotteryDetailRespV
 import com.citu.module.promotion.controller.admin.luck.vo.prize.LuckPrizeDetailRespVO;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordDetailRespVO;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordRespVO;
+import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordSimpleRespVO;
 import com.citu.module.promotion.dal.dataobject.luck.LuckLotteryRecordDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
@@ -23,9 +24,11 @@ public interface LuckLotteryRecordConvert {
 
     LuckLotteryRecordRespVO convert(LuckLotteryRecordDO bean);
 
+    LuckLotteryRecordSimpleRespVO convert2(LuckLotteryRecordDO bean);
+
     List<LuckLotteryRecordRespVO> convertList(List<LuckLotteryRecordDO> list);
 
-    LuckLotteryRecordDetailRespVO convertDetail(LuckLotteryRecordRespVO record,
+    LuckLotteryRecordDetailRespVO convertDetail(LuckLotteryRecordSimpleRespVO record,
                                                 LuckLotteryDetailRespVO lottery,
                                                 LuckPrizeDetailRespVO prize,
                                                 UserInfoRespDTO user);

+ 41 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/dal/dataobject/luck/LuckUserDO.java

@@ -0,0 +1,41 @@
+package com.citu.module.promotion.dal.dataobject.luck;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.citu.framework.mybatis.core.dataobject.BaseDO;
+import lombok.*;
+
+/**
+ * 幸运抽奖-用户 DO
+ *
+ * @author Rayson
+ */
+@TableName(value = "promotion_luck_user", autoResultMap = true)
+@KeySequence("promotion_luck_user_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class LuckUserDO extends BaseDO {
+
+    /**
+     * id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 抽奖活动id
+     */
+    private Long lotteryId;
+    /**
+     * 用户id
+     */
+    private Long userId;
+    /**
+     * 抽奖数量
+     */
+    private Integer num;
+}

+ 18 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/dal/mysql/luck/LuckUserMapper.java

@@ -0,0 +1,18 @@
+package com.citu.module.promotion.dal.mysql.luck;
+
+import com.citu.framework.mybatis.core.mapper.BaseMapperX;
+import com.citu.module.promotion.dal.dataobject.luck.LuckUserDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 幸运抽奖-用户 Mapper
+ *
+ * @author Rayson
+ */
+@Mapper
+public interface LuckUserMapper extends BaseMapperX<LuckUserDO> {
+
+    default LuckUserDO getByUserId(Long lotteryId,Long userId) {
+        return selectOne(LuckUserDO::getLotteryId, lotteryId, LuckUserDO::getUserId, userId);
+    }
+}

+ 6 - 0
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryRecordService.java

@@ -6,6 +6,7 @@ import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryReco
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordPageReqVO;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordRespVO;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordSaveReqVO;
+import com.citu.module.promotion.controller.app.luck.vo.AppLuckLotteryReceiveReqVO;
 import com.citu.module.promotion.dal.dataobject.luck.LuckLotteryRecordDO;
 
 import javax.validation.Valid;
@@ -79,4 +80,9 @@ public interface LuckLotteryRecordService {
     PageResult<LuckLotteryRecordDetailRespVO> page(LuckLotteryRecordPageReqVO pageReqVO);
 
 
+    /**
+     * 领用
+     * @param reqVO 领用信息
+     */
+    void receive(AppLuckLotteryReceiveReqVO reqVO, Long userId);
 }

+ 26 - 5
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryRecordServiceImpl.java

@@ -1,6 +1,7 @@
 package com.citu.module.promotion.service.luck;
 
 import cn.hutool.core.collection.CollUtil;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
 import com.baomidou.lock.annotation.Lock4j;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
@@ -10,11 +11,13 @@ import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryReco
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordPageReqVO;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordRespVO;
 import com.citu.module.promotion.controller.admin.luck.vo.record.LuckLotteryRecordSaveReqVO;
+import com.citu.module.promotion.controller.app.luck.vo.AppLuckLotteryReceiveReqVO;
 import com.citu.module.promotion.convert.luck.LuckLotteryRecordConvert;
 import com.citu.module.promotion.dal.dataobject.luck.LuckLotteryDO;
 import com.citu.module.promotion.dal.dataobject.luck.LuckLotteryRecordDO;
 import com.citu.module.promotion.dal.dataobject.luck.LuckPrizeDO;
 import com.citu.module.promotion.dal.mysql.luck.LuckLotteryRecordMapper;
+import com.citu.module.promotion.dal.mysql.luck.LuckUserMapper;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
@@ -76,10 +79,12 @@ public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
         luckLotteryRecordMapper.deleteById(id);
     }
 
-    private void validateLuckLotteryRecordExists(Long id) {
-        if (luckLotteryRecordMapper.selectById(id) == null) {
+    private LuckLotteryRecordDO validateLuckLotteryRecordExists(Long id) {
+        LuckLotteryRecordDO luckLotteryRecord = getLuckLotteryRecord(id);
+        if (null == luckLotteryRecord) {
             throw exception(LUCK_LOTTERY_RECORD_NOT_EXISTS);
         }
+        return luckLotteryRecord;
     }
 
     @Override
@@ -93,6 +98,7 @@ public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
     }
 
     @Override
+    @DSTransactional
     @Lock4j(keys = {"#lotteryId", "#userId"}, acquireTimeout = 6000)
     public LuckLotteryRecordRespVO raffle(Long lotteryId, Long userId) {
         // 获取活动
@@ -135,11 +141,14 @@ public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
                 .isDeliver(false)
                 .build();
         luckLotteryRecordMapper.insert(luckLotteryRecord);
+
+        // 扣除额度
+        luckLotteryService.updateUserNumDecr(lotteryId, userId);
+
         return LuckLotteryRecordConvert.INSTANCE.convert(luckLotteryRecord);
     }
 
 
-
     @Override
     public List<LuckLotteryRecordDetailRespVO> getLuckLotteryRecordList(Long lotteryId, Long userId) {
         // 查询记录
@@ -154,7 +163,7 @@ public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
         for (LuckLotteryRecordDO record : luckLotteryRecordList) {
 
             list.add(LuckLotteryRecordConvert.INSTANCE.convertDetail(
-                    LuckLotteryRecordConvert.INSTANCE.convert(record),
+                    LuckLotteryRecordConvert.INSTANCE.convert2(record),
                     luckLotteryService.detail(record.getLotteryId()),
                     luckPrizeService.detail(record.getPrizeId()),
                     user)
@@ -181,7 +190,7 @@ public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
         for (LuckLotteryRecordDO record : pageResult.getList()) {
             // 查询数据拼接对象
             LuckLotteryRecordDetailRespVO resp = LuckLotteryRecordConvert.INSTANCE.convertDetail(
-                    LuckLotteryRecordConvert.INSTANCE.convert(record),
+                    LuckLotteryRecordConvert.INSTANCE.convert2(record),
                     luckLotteryService.detail(record.getLotteryId()),
                     luckPrizeService.detail(record.getPrizeId()),
                     user.stream().filter(userInfo ->
@@ -195,4 +204,16 @@ public class LuckLotteryRecordServiceImpl implements LuckLotteryRecordService {
 
         return result;
     }
+
+    @Override
+    public void receive(AppLuckLotteryReceiveReqVO reqVO, Long userId) {
+        LuckLotteryRecordDO luckLotteryRecord = validateLuckLotteryRecordExists(reqVO.getId());
+        if (luckLotteryRecord.getUserId().equals(userId)) {
+            // 是自己领取的
+            luckLotteryRecord.setIsReceive(true);
+            luckLotteryRecord.setReceiveInfo(reqVO.getReceiveInfo());
+            luckLotteryRecordMapper.updateById(luckLotteryRecord);
+        }
+
+    }
 }

+ 29 - 1
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryService.java

@@ -96,5 +96,33 @@ public interface LuckLotteryService {
      * 根据spuId获得抽奖活动
      * @param spuId 商品id
      */
-    LuckLotteryDO getLuckLotteryListBySpuId(String spuId);
+    LuckLotteryDO getLuckLotteryBySpuId(String spuId);
+
+    /**
+     * 根据spuId增加用户抽奖次数
+     * @param spuId 商品id
+     * @param userId 用户id
+     **/
+    void updateUserNumIncr(Long spuId,Long userId);
+
+
+    /**
+     * 根据抽奖活动id减少用户抽奖次数
+     * @param lotteryId 活动id
+     * @param userId 用户id
+     **/
+    void updateUserNumDecr(Long lotteryId,Long userId);
+
+    /**
+     * 校验抽奖活动时间是否过期
+     * @param luckLottery 抽奖活动
+     **/
+    void checkTimeExpired(LuckLotteryDO luckLottery);
+
+    /**
+     * 获取用户抽奖次数
+     * @param lotteryId 活动id
+     * @param userId 用户id
+     **/
+    Integer getUserNum(Long lotteryId,Long userId);
 }

+ 70 - 5
citu-module-mall/citu-module-promotion-biz/src/main/java/com/citu/module/promotion/service/luck/LuckLotteryServiceImpl.java

@@ -2,6 +2,8 @@ package com.citu.module.promotion.service.luck;
 
 
 import cn.hutool.core.collection.CollUtil;
+import com.baomidou.lock.annotation.Lock4j;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.citu.framework.common.pojo.PageResult;
 import com.citu.framework.common.util.object.BeanUtils;
 import com.citu.module.product.api.spu.ProductSpuApi;
@@ -11,7 +13,9 @@ import com.citu.module.promotion.controller.admin.luck.vo.LuckLotteryPageReqVO;
 import com.citu.module.promotion.controller.admin.luck.vo.LuckLotterySaveReqVO;
 import com.citu.module.promotion.convert.luck.LuckLotteryConvert;
 import com.citu.module.promotion.dal.dataobject.luck.LuckLotteryDO;
+import com.citu.module.promotion.dal.dataobject.luck.LuckUserDO;
 import com.citu.module.promotion.dal.mysql.luck.LuckLotteryMapper;
+import com.citu.module.promotion.dal.mysql.luck.LuckUserMapper;
 import com.citu.module.promotion.enums.luck.LuckLotteryFactorEnum;
 import com.citu.module.promotion.enums.luck.LuckStatusEnum;
 import org.springframework.stereotype.Service;
@@ -41,6 +45,9 @@ public class LuckLotteryServiceImpl implements LuckLotteryService {
     @Resource
     private ProductSpuApi productSpuApi;
 
+    @Resource
+    private LuckUserMapper luckUserMapper;
+
     @Override
     public Long createLuckLottery(LuckLotterySaveReqVO createReqVO) {
         // 插入
@@ -56,7 +63,7 @@ public class LuckLotteryServiceImpl implements LuckLotteryService {
                 throw exception(LUCK_LOTTERY_PRODUCT_NOT_SELECTED);
             }
             for (String spuId : createReqVO.getFactorInfo()) {
-                LuckLotteryDO luckLottery = luckLotteryMapper.getLuckLotteryListBySpuId(spuId,null);
+                LuckLotteryDO luckLottery = luckLotteryMapper.getLuckLotteryListBySpuId(spuId, null);
                 if (null != luckLottery) {
                     // 已经存在
                     throw exception(LUCK_LOTTERY_PRODUCT_USED);
@@ -74,7 +81,7 @@ public class LuckLotteryServiceImpl implements LuckLotteryService {
     public void updateLuckLottery(LuckLotterySaveReqVO updateReqVO) {
         // 校验存在
         LuckLotteryDO luckLottery = validateLuckLotteryExists(updateReqVO.getId());
-        LuckLotteryDO exist =  luckLotteryMapper.selectByName(updateReqVO.getName());
+        LuckLotteryDO exist = luckLotteryMapper.selectByName(updateReqVO.getName());
         if (null != exist &&
                 !Objects.equals(luckLottery.getId(), exist.getId())) {
             throw exception(LUCK_LOTTERY_NAME_USED, updateReqVO.getName());
@@ -88,7 +95,7 @@ public class LuckLotteryServiceImpl implements LuckLotteryService {
                 throw exception(LUCK_LOTTERY_PRODUCT_NOT_SELECTED);
             }
             for (String spuId : updateReqVO.getFactorInfo()) {
-                LuckLotteryDO spuExist = luckLotteryMapper.getLuckLotteryListBySpuId(spuId,null);
+                LuckLotteryDO spuExist = luckLotteryMapper.getLuckLotteryListBySpuId(spuId, null);
                 if (null != spuExist && !Objects.equals(luckLottery.getId(), spuExist.getId())) {
                     // 已经存在
                     throw exception(LUCK_LOTTERY_PRODUCT_USED);
@@ -125,6 +132,12 @@ public class LuckLotteryServiceImpl implements LuckLotteryService {
     @Override
     public LuckLotteryDO valid(Long id) {
         LuckLotteryDO luckLottery = validateLuckLotteryExists(id);
+        checkTimeExpired(luckLottery);
+        return luckLottery;
+    }
+
+    @Override
+    public void checkTimeExpired(LuckLotteryDO luckLottery) {
         LocalDateTime now = LocalDateTime.now();
         // 判断活动有没有开始,没有开始抛出异常
         if (luckLottery.getStartTime().isAfter(now)) {
@@ -134,7 +147,6 @@ public class LuckLotteryServiceImpl implements LuckLotteryService {
         if (luckLottery.getEndTime().isBefore(now)) {
             throw exception(LUCK_LOTTERY_END);
         }
-        return luckLottery;
     }
 
     @Override
@@ -183,7 +195,60 @@ public class LuckLotteryServiceImpl implements LuckLotteryService {
     }
 
     @Override
-    public LuckLotteryDO getLuckLotteryListBySpuId(String spuId) {
+    public LuckLotteryDO getLuckLotteryBySpuId(String spuId) {
         return luckLotteryMapper.getLuckLotteryListBySpuId(spuId, LuckStatusEnum.ENABLE.getStatus());
     }
+
+    @Override
+    @Lock4j(keys = {"#spuId", "#userId"}, acquireTimeout = 6000)
+    public void updateUserNumIncr(Long spuId, Long userId) {
+        // 根据spuId获取抽奖活动
+        LuckLotteryDO luckLottery = getLuckLotteryBySpuId(String.valueOf(spuId));
+        if (null == luckLottery) {
+            // 没有对应的活动
+            return;
+        }
+        // 校验活动
+        checkTimeExpired(luckLottery);
+        LuckUserDO luckUser = luckUserMapper.getByUserId(luckLottery.getId(), userId);
+        if (null == luckUser) {
+            // 不存在
+            luckUser = new LuckUserDO();
+            luckUser.setLotteryId(luckLottery.getId());
+            luckUser.setUserId(userId);
+            luckUser.setNum(1);
+            luckUserMapper.insert(luckUser);
+        } else {
+            // 存在
+            luckUser.setNum(luckUser.getNum() + 1);
+            luckUserMapper.updateById(luckUser);
+        }
+    }
+
+    @Override
+    @Lock4j(keys = {"#lotteryId", "#userId"}, acquireTimeout = 6000)
+    public void updateUserNumDecr(Long lotteryId, Long userId) {
+        LuckLotteryDO luckLottery = valid(lotteryId);
+        Integer num = getUserNum(luckLottery.getId(), userId);
+        if (num <= 0) {
+            // 没有抽奖的额度
+            throw exception(LUCK_LOTTERY_USER_NUM_EXCEED);
+        }
+        luckUserMapper.update(new LambdaUpdateWrapper<LuckUserDO>()
+                .eq(LuckUserDO::getLotteryId, luckLottery.getId())
+                .eq(LuckUserDO::getUserId, userId)
+                .eq(LuckUserDO::getNum, num)
+                .setSql("num = num - 1")
+        );
+    }
+
+    @Override
+    public Integer getUserNum(Long lotteryId, Long userId) {
+        LuckUserDO luckUser =
+                luckUserMapper.selectOne(LuckUserDO::getLotteryId, lotteryId, LuckUserDO::getUserId, userId);
+        if (null == luckUser) {
+            return 0;
+        }
+        return luckUser.getNum();
+    }
 }

+ 1 - 1
citu-module-mall/citu-module-promotion-biz/src/main/resources/application.yaml

@@ -50,7 +50,7 @@ mybatis-plus:
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
   global-config:
     db-config:
-      id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。
+      id-type: ASSIGN_ID # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。
       #      id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库
       #      id-type: INPUT # 用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库
       #      id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解

+ 2 - 1
citu-module-mall/citu-module-trade-biz/src/main/java/com/citu/module/trade/framework/rpc/config/RpcConfiguration.java

@@ -18,6 +18,7 @@ import com.citu.module.promotion.api.bargain.BargainRecordApi;
 import com.citu.module.promotion.api.combination.CombinationRecordApi;
 import com.citu.module.promotion.api.coupon.CouponApi;
 import com.citu.module.promotion.api.discount.DiscountActivityApi;
+import com.citu.module.promotion.api.luck.LuckLotteryApi;
 import com.citu.module.promotion.api.point.PointActivityApi;
 import com.citu.module.promotion.api.reward.RewardActivityApi;
 import com.citu.module.promotion.api.seckill.SeckillActivityApi;
@@ -33,7 +34,7 @@ import org.springframework.context.annotation.Configuration;
         BargainActivityApi.class, BargainRecordApi.class, CombinationRecordApi.class,
         CouponApi.class, DiscountActivityApi.class, RewardActivityApi.class, SeckillActivityApi.class, PointActivityApi.class,
         MemberUserApi.class, MemberPointApi.class, MemberLevelApi.class, MemberAddressApi.class, MemberConfigApi.class,
-        ProductSpuApi.class, ProductSkuApi.class, ProductCommentApi.class, ProductCategoryApi.class,
+        ProductSpuApi.class, ProductSkuApi.class, ProductCommentApi.class, ProductCategoryApi.class, LuckLotteryApi.class,
         PayOrderApi.class, PayRefundApi.class, PayTransferApi.class, PayWalletApi.class,
         AdminUserApi.class, NotifyMessageSendApi.class, SocialClientApi.class, SocialUserApi.class
 })

+ 9 - 0
citu-module-mall/citu-module-trade-biz/src/main/java/com/citu/module/trade/service/order/handler/TradeLotteryOrderHandler.java

@@ -1,9 +1,11 @@
 package com.citu.module.trade.service.order.handler;
 
+import com.citu.module.promotion.api.luck.LuckLotteryApi;
 import com.citu.module.trade.dal.dataobject.order.TradeOrderDO;
 import com.citu.module.trade.dal.dataobject.order.TradeOrderItemDO;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
 import java.util.List;
 
 /**
@@ -14,8 +16,15 @@ import java.util.List;
 @Component
 public class TradeLotteryOrderHandler implements TradeOrderHandler {
 
+    @Resource
+    private LuckLotteryApi luckLotteryApi;
+
     @Override
     public void afterPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems) {
         // 订单支付后
+        orderItems.forEach(orderItem -> {
+            luckLotteryApi.updateUserNumIncr(orderItem.getSpuId(), orderItem.getUserId()).getCheckedData();
+        });
+
     }
 }