소스 검색

Merge branch 'mp-server-test' into 'master'

Mp server test

See merge request quanshu/mp-server!788
zhong chunping 2 년 전
부모
커밋
e32debba3b

+ 45 - 5
mp-admin/src/main/java/com/qs/mp/web/controller/api/user/MarketingController.java

@@ -1,24 +1,29 @@
 package com.qs.mp.web.controller.api.user;
 
+import cn.hutool.core.date.LocalDateTimeUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.qs.mp.admin.domain.Marketing;
 import com.qs.mp.admin.domain.MarketingAwards;
 import com.qs.mp.admin.domain.MarketingAwardsPrize;
+import com.qs.mp.admin.domain.MarketingMsg;
 import com.qs.mp.admin.domain.vo.MarketingAwardsVO;
 import com.qs.mp.admin.service.IMarketingAwardsPrizeService;
 import com.qs.mp.admin.service.IMarketingAwardsService;
+import com.qs.mp.admin.service.IMarketingMsgService;
 import com.qs.mp.admin.service.IMarketingService;
 import com.qs.mp.common.core.domain.AjaxResult;
 import com.qs.mp.common.core.page.TableDataInfo;
 import com.qs.mp.common.core.redis.DistributedLocker;
+import com.qs.mp.common.core.redis.RedisCache;
 import com.qs.mp.common.enums.MarketingCodeTypeEnum;
 import com.qs.mp.common.enums.MarketingStatusEnum;
 import com.qs.mp.common.enums.UserTypeEnum;
 import com.qs.mp.common.exception.ServiceException;
 import com.qs.mp.common.utils.DateUtils;
 import com.qs.mp.common.utils.StringUtils;
+import com.qs.mp.framework.redis.RedisKey;
 import com.qs.mp.framework.redis.RedisLockKey;
 import com.qs.mp.framework.security.handle.HostHolder;
 import com.qs.mp.framework.service.IWxSubscribeMessage;
@@ -39,6 +44,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
+import java.time.LocalDateTime;
 import org.aspectj.weaver.loadtime.Aj;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -90,6 +96,12 @@ public class MarketingController extends BaseApiController {
     @Autowired
     private IWxSubscribeMessage wxSubscribeMessage;
 
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private IMarketingMsgService marketingMsgService;
+
     @PostMapping("/generateCode/{marketingId}")
     @ApiOperation("立即获取抽奖码")
     public AjaxResult generateCode(@PathVariable("marketingId") Long marketingId) {
@@ -228,9 +240,14 @@ public class MarketingController extends BaseApiController {
         }finally {
             distributedLocker.unlock(lockKey);
         }
-        // 异步给被助力人发送成功消息
-        wxSubscribeMessage.sendMarketingHelp(helpedUserId, marketing);
 
+        // 保存助力成功消息记录
+        MarketingMsg marketingMsg = new MarketingMsg();
+        marketingMsg.setMarketingId(marketing.getId());
+        marketingMsg.setContext(marketing.getTitle());
+        marketingMsg.setUserId(helpedUserId);
+        marketingMsg.setType(3);
+        marketingMsgService.save(marketingMsg);
 
         return AjaxResult.success("助力成功");
     }
@@ -246,7 +263,6 @@ public class MarketingController extends BaseApiController {
         return AjaxResult.success("邀请码生成成功",MarketingUtils.generateInviteCode(userId));
     }
 
-
     @PostMapping("/list")
     @ApiOperation("获取营销活动列表")
     @ApiResponses(
@@ -273,6 +289,10 @@ public class MarketingController extends BaseApiController {
             queryWrapper.gt(Marketing::getEndTime, now);
             queryWrapper.orderByAsc(Marketing::getEndTime, Marketing::getStartTime);
         }else if(userMarketingQueryParam.getTriggerStatus() == 1) {
+            // 过滤30天之前的
+            LocalDateTime localDateTime = LocalDateTimeUtil.now().minusDays(30);
+            queryWrapper.ge(Marketing::getEndTime, localDateTime);
+
             // 开奖的排序
             queryWrapper.orderByDesc(Marketing::getEndTime);
         }
@@ -288,12 +308,22 @@ public class MarketingController extends BaseApiController {
                             .eq(MarketingHitPrize::getMarketingId, marketing.getId())
                             .eq(MarketingHitPrize::getUserId, finalUserId));
                     userMarketingListVO.setIsHit(count);
+                } else {
+                    String fakeNumKey = RedisKey.build(RedisKey.MARKETING_FAKE_NUM, marketing.getId());
+                    Integer fakeNum = redisCache.getCacheObject(fakeNumKey);
+                    if (fakeNum == null) {
+                        int realNum = marketingUserCodeService.countRealUserNumByMarketingId(marketing.getId());
+                        fakeNum = realNum * 2;
+                        redisCache.setCacheObject(fakeNumKey, fakeNum, 30, TimeUnit.HOURS);
+                    }
+                    userMarketingListVO.setFakeNum(fakeNum);
                 }
                 return userMarketingListVO;
             }).collect(Collectors.toList());
         }
-
-        return getDataTable(userMarketingListVOList);
+        TableDataInfo dataTable = getDataTable(list);
+        dataTable.setRows(userMarketingListVOList);
+        return dataTable;
     }
 
     @PostMapping("/detail/{id}")
@@ -317,6 +347,16 @@ public class MarketingController extends BaseApiController {
         UserMarketingDetailVO userMarketingDetailVO = new UserMarketingDetailVO();
         BeanUtils.copyProperties(marketing, userMarketingDetailVO);
 
+        String fakeNumKey = RedisKey.build(RedisKey.MARKETING_FAKE_NUM, id);
+        Integer fakeNum = redisCache.getCacheObject(fakeNumKey);
+        if (fakeNum == null) {
+            int realNum = marketingUserCodeService.countRealUserNumByMarketingId(id);
+            fakeNum = realNum * 2;
+            redisCache.setCacheObject(fakeNumKey, fakeNum, 30, TimeUnit.HOURS);
+        }
+
+        userMarketingDetailVO.setFakeNum(fakeNum);
+
         List<MarketingAwards> awardsList = marketingAwardsService.list(new LambdaQueryWrapper<MarketingAwards>().eq(MarketingAwards::getMarketingId, id));
         if (CollectionUtils.isNotEmpty(awardsList)) {
             List<MarketingAwardsVO> list = awardsList.stream().map(marketingAwards -> {

+ 87 - 10
mp-quartz/src/main/java/com/qs/mp/quartz/task/MarketingTask.java

@@ -105,11 +105,64 @@ public class MarketingTask {
 
 
     /**
-     * 发送活动开始通知
+     * 活动通知消息生成
+     * @param type 消息类型,1活动开奖通知,2活动开始通知
      */
-    public void sendMessage() {
+    public void sendMessage(Integer type) {
         MarketingTask proxy = (MarketingTask) AopContext.currentProxy();
-        proxy.saveMarketingMsg();
+        if (type == 1) {
+            proxy.saveMarketingLotteryMsg();
+        } else if (type == 2) {
+            proxy.saveMarketingMsg();
+        }
+    }
+
+    /**
+     * 生成开奖发送消息
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public void saveMarketingLotteryMsg() {
+        // 获取已开奖,且未发送开奖通知的活动
+        List<Marketing> marketingList = marketingService.list(new LambdaQueryWrapper<Marketing>()
+            .eq(Marketing::getTriggerStatus, 1)
+            .eq(Marketing::getIsOn, MarketingStatusEnum.ON.getValue())
+            .eq(Marketing::getIsSendLottery, 0));
+        if (CollectionUtils.isEmpty(marketingList)) {
+            return;
+        }
+
+        for (Marketing marketing : marketingList) {
+            // 保存开奖消息
+            // 获取所有的参与用户的用户id去重
+            List<MarketingUserCode> sendMsgUserList = marketingUserCodeService.list(new LambdaQueryWrapper<MarketingUserCode>()
+                .select(MarketingUserCode::getUserId)
+                .eq(MarketingUserCode::getMarketingId, marketing.getId())
+                .eq(MarketingUserCode::getUserType, UserTypeEnum.ORDINARY.getValue())
+                .groupBy(MarketingUserCode::getUserId));
+            if (CollectionUtils.isEmpty(sendMsgUserList)) {
+                marketingService.update(new LambdaUpdateWrapper<Marketing>()
+                    .set(Marketing::getIsSendLottery, 1)
+                    .eq(Marketing::getId, marketing.getId()));
+                continue;
+            }
+            List<MarketingMsg> marketingMsgList = new ArrayList<>();
+            for (MarketingUserCode marketingUserCode : sendMsgUserList) {
+                // 封装开奖订阅消息
+                MarketingMsg marketingMsg = new MarketingMsg();
+                marketingMsg.setType(1);
+                marketingMsg.setMarketingId(marketing.getId());
+                marketingMsg.setContext(marketing.getTitle());
+                marketingMsg.setUserId(marketingUserCode.getUserId());
+                marketingMsgList.add(marketingMsg);
+            }
+            boolean rtn = marketingMsgService.saveBatch(marketingMsgList);
+            Assert.isTrue(rtn, "保存活动开奖消息失败。marketingId:" + marketing.getId());
+
+            rtn = marketingService.update(new LambdaUpdateWrapper<Marketing>()
+                .set(Marketing::getIsSendLottery, 1)
+                .eq(Marketing::getId, marketing.getId()));
+            Assert.isTrue(rtn, "更新活动开奖信息发送状态失败。marketingId:" + marketing.getId());
+        }
 
     }
 
@@ -209,9 +262,21 @@ public class MarketingTask {
         }
 
         try {
-            List<MarketingMsg> marketingMsgList = marketingMsgService.list(new LambdaQueryWrapper<MarketingMsg>()
-                .eq(MarketingMsg::getType, type)
-                .last("limit " + limit));
+            List<MarketingMsg> marketingMsgList = new ArrayList<>();
+            if (type == 3) {
+                // 获取活动通知信息
+                marketingMsgList = marketingMsgService.list(new LambdaQueryWrapper<MarketingMsg>()
+                    .select(MarketingMsg::getMarketingId, MarketingMsg::getUserId, MarketingMsg::getContext)
+                    .eq(MarketingMsg::getType, 3)
+                    .groupBy(MarketingMsg::getMarketingId, MarketingMsg::getUserId, MarketingMsg::getContext)
+                    .last("limit " + limit));
+
+            } else {
+                marketingMsgList = marketingMsgService.list(new LambdaQueryWrapper<MarketingMsg>()
+                    .eq(MarketingMsg::getType, type)
+                    .last("limit " + limit));
+            }
+
 
             if (CollectionUtils.isEmpty(marketingMsgList)) {
                 return;
@@ -221,17 +286,29 @@ public class MarketingTask {
                 Marketing marketing = new Marketing();
                 marketing.setId(marketingMsg.getMarketingId());
                 marketing.setTitle(marketingMsg.getContext());
-                if (marketingMsg.getType() == 1) {
+                if (type == 1) {
                     // 发送活动开奖通知
                     wxSubscribeMessage.sendMarketingLottery(marketingMsg.getUserId(), marketing);
-                } else {
+                } else if (type == 2){
                     // 发送活动开始通知
                     wxSubscribeMessage.sendMarketingStart(marketingMsg.getUserId(), marketing);
+                } else if (type == 3) {
+                    // 发送助力成功通知
+                    wxSubscribeMessage.sendMarketingHelp(marketingMsg.getUserId(), marketing);
                 }
             }
 
-            // 删除已发送的消息
-            marketingMsgService.removeByIds(marketingMsgList.stream().map(MarketingMsg::getId).collect(Collectors.toList()));
+            if (type == 3) {
+                List<Long> userIdList = marketingMsgList.stream().map(MarketingMsg::getUserId)
+                    .collect(Collectors.toList());
+                marketingMsgService.remove(new LambdaUpdateWrapper<MarketingMsg>()
+                    .eq(MarketingMsg::getType, 3)
+                    .in(MarketingMsg::getUserId, userIdList));
+            } else {
+                // 删除已发送的消息
+                marketingMsgService.removeByIds(marketingMsgList.stream().map(MarketingMsg::getId).collect(Collectors.toList()));
+            }
+
         } catch (Exception e) {
             LogUtil.error(logger, e, "发送活动订阅通知异常");
         } finally {

+ 4 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/Marketing.java

@@ -105,6 +105,10 @@ public class Marketing implements Serializable {
     @TableField("is_send")
     private Integer isSend;
 
+    @ApiModelProperty("是否发送开奖通知:0未发送,1已发送")
+    @TableField("is_send_lottery")
+    private Integer isSendLottery;
+
     /**
      * 创建时间
      */

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

@@ -43,7 +43,7 @@ public class MarketingMsg implements Serializable {
     private Long userId;
 
     /**
-     * 信息类型1开奖,2活动开始
+     * 信息类型1开奖,2活动开始,3助力通知
      */
     @TableField("type")
     private Integer type;
@@ -64,7 +64,6 @@ public class MarketingMsg implements Serializable {
      * 逻辑删除标识
      */
     @TableField("is_deleted")
-    @TableLogic
     private Integer isDeleted;
 
 

+ 18 - 8
mp-service/src/main/java/com/qs/mp/admin/service/impl/MarketingServiceImpl.java

@@ -20,6 +20,7 @@ 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.common.utils.bean.BeanUtils;
+import com.qs.mp.framework.redis.RedisKey;
 import com.qs.mp.framework.service.IWxSubscribeMessage;
 import com.qs.mp.system.domain.SysUser;
 import com.qs.mp.system.service.ISysUserService;
@@ -128,6 +129,7 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
         marketing.setRealNum(0);
         marketing.setIsOn(MarketingStatusEnum.OFF.getValue());
         marketing.setIsSend(0);
+        marketing.setIsSendLottery(0);
         marketing.setTriggerStatus(0);
         marketing.setCreatedTime(null);
         Assert.isTrue(this.save(marketing), "复制营销活动失败");
@@ -185,14 +187,17 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
         // 保存助力信息
         marketingUserCodeService.save(marketingUserCode);
 
-        Marketing marketing = this.getById(marketingId);
 
         // 设置更新虚拟参与人数
         int randomNum = (int) 1 + (int) (Math.random() * 3);
-        // 更新活动参与人数
-        this.update(new LambdaUpdateWrapper<Marketing>().set(Marketing::getFakeNum, marketing.getFakeNum() + randomNum)
-            .eq(Marketing::getId, marketing.getId()));
-
+        String fakeNumKey = RedisKey.build(RedisKey.MARKETING_FAKE_NUM, marketingId);
+        Integer fakeNum = redisCache.getCacheObject(fakeNumKey);
+        if (fakeNum == null) {
+            fakeNum = marketingUserCodeService.countRealUserNumByMarketingId(marketingId);
+            redisCache.setCacheObject(fakeNumKey, fakeNum * 2 + randomNum, 30, TimeUnit.HOURS);
+        } else {
+            redisCache.setCacheObject(fakeNumKey, fakeNum + randomNum, 30, TimeUnit.HOURS);
+        }
     }
 
 
@@ -492,9 +497,14 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
 
         // 设置更新虚拟参与人数
         int randomNum = (int) 1 + (int) (Math.random() * 3);
-        // 更新活动参与人数
-        this.update(new LambdaUpdateWrapper<Marketing>().set(Marketing::getFakeNum, marketing.getFakeNum() + randomNum)
-            .eq(Marketing::getId, marketing.getId()));
+        String fakeNumKey = RedisKey.build(RedisKey.MARKETING_FAKE_NUM, marketing.getId());
+        Integer fakeNum = redisCache.getCacheObject(fakeNumKey);
+        if (fakeNum == null) {
+            fakeNum = marketingUserCodeService.countRealUserNumByMarketingId(marketing.getId());
+            redisCache.setCacheObject(fakeNumKey, fakeNum * 2 + randomNum, 30, TimeUnit.HOURS);
+        } else {
+            redisCache.setCacheObject(fakeNumKey, fakeNum + randomNum, 30, TimeUnit.HOURS);
+        }
 
     }
 

+ 1 - 0
mp-service/src/main/java/com/qs/mp/framework/redis/RedisKey.java

@@ -9,6 +9,7 @@ import com.qs.mp.common.utils.MessageHelper;
  *
  */
 public enum RedisKey {
+    MARKETING_FAKE_NUM("marketing_fake_num_{0}", "营销活动虚拟参与人数"),
     OPEN_LINK_KEY("open_link_key_{0}_{1}","微信scheme码缓存key"),
     WX_APP_TOKEN_KEY("app_token_key_{0}", "小程序app token"),
     CHANNEL_ORDER_KEY("channel_order_{0}", "经销商下的盲票采购单"),

+ 0 - 1
mp-service/src/main/java/com/qs/mp/framework/service/impl/WxSubscribeMessageImpl.java

@@ -51,7 +51,6 @@ public class WxSubscribeMessageImpl implements IWxSubscribeMessage {
   }
 
   @Override
-  @Async("threadPoolTaskExecutor")
   public void sendMarketingHelp(Long userId, Marketing marketing) {
     String openId = getOpenIdByUserId(userId);
     WxSubscribeMessage wxSubscribeMessage = new WxSubscribeMessage(userAppId, openId, state);