Pārlūkot izejas kodu

优化达标活动发奖异常;活动查询超时

Eric 2 gadi atpakaļ
vecāks
revīzija
0a5b54419a

+ 1 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/CacheNameEnum.java

@@ -29,6 +29,7 @@ public enum CacheNameEnum implements BaseEnum<String, CacheNameEnum> {
     LOCK_REWARD_STOCK("锁奖品库存变更"),
     LOCK_ACTIVITY_REWARD_STOCK("锁活动奖品变更"),
     LOCK_ACTIVITY_STOCK("锁活动变更"),
+    LOCK_STANDARD_GIFT_CRON("达标活动定时任务锁"),
     ;
     /***
      * 缓存描述

+ 0 - 1
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/AdminApplication.java

@@ -3,7 +3,6 @@ package com.yonge.cooleshow.admin;
 import com.yonge.cooleshow.common.constant.AppConstant;
 import com.yonge.toolset.base.BaseApplication;
 import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 import org.springframework.cloud.openfeign.EnableFeignClients;

+ 15 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/ActivityPlanDao.java

@@ -4,8 +4,7 @@ import java.util.List;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.yonge.cooleshow.biz.dal.entity.ActivityUserReward;
-import com.yonge.cooleshow.biz.dal.vo.MusicActivityVo;
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import org.apache.ibatis.annotations.Param;
 import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
 import com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo;
@@ -69,4 +68,18 @@ public interface ActivityPlanDao extends BaseMapper<ActivityPlan> {
 	 * @return
 	 */
 	ActivityPlanVo selectActivityShare(@Param("type") String type, @Param("userId") Long userId);
+
+	/**
+	 * 活动参与人数统计
+	 * @param activityIds 活动ID
+	 * @return List<StatGroupWrapper>
+	 */
+    List<StatGroupWrapper> selectActivityParticipateStatInfo(@Param("activityIds") List<Long> activityIds);
+
+	/**
+	 * 活动获奖用户统计
+	 * @param activityIds 活动ID
+	 * @return List<StatGroupWrapper>
+	 */
+	List<StatGroupWrapper> selectActivityWinnerStatInfo(@Param("activityIds") List<Long> activityIds);
 }

+ 10 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserFirstTimeDao.java

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.biz.dal.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.biz.dal.dto.search.UserFirstTimeSearch;
 import com.yonge.cooleshow.biz.dal.entity.UserFirstTime;
 import org.apache.ibatis.annotations.Param;
@@ -9,10 +10,19 @@ import java.util.List;
 
 
 public interface UserFirstTimeDao extends BaseMapper<UserFirstTime>{
+
     /**
      * 查询集合
      * @param param
      * @return
      */
     List<UserFirstTime> selectAllList(@Param("param") UserFirstTimeSearch param);
+
+    /**
+     * 达标活动参与用户信息
+     * @param page IPage<UserFirstTime>
+     * @param search UserFirstTimeSearch
+     * @return IPage<UserFirstTime>
+     */
+    List<UserFirstTime> selectActivityParticipateUserPage(@Param("page") IPage<UserFirstTime> page, @Param("record") UserFirstTimeSearch search);
 }

+ 33 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/UserFirstTimeSearch.java

@@ -1,14 +1,13 @@
 package com.yonge.cooleshow.biz.dal.dto.search;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
-import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * @Author: liweifan
@@ -33,6 +32,11 @@ public class UserFirstTimeSearch extends QueryInfo{
 	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
 	private Date endTime;
 
+	// 活动ID
+	private Long activityId;
+	// 活动参与用户ID
+	private List<Long> userIds;
+
 	public Long getUserId() {
 		return userId;
 	}
@@ -72,4 +76,31 @@ public class UserFirstTimeSearch extends QueryInfo{
 	public void setEndTime(Date endTime) {
 		this.endTime = endTime;
 	}
+
+	public Long getActivityId() {
+		return activityId;
+	}
+
+	public void setActivityId(Long activityId) {
+		this.activityId = activityId;
+	}
+
+	public List<Long> getUserIds() {
+		return userIds;
+	}
+
+	public void setUserIds(List<Long> userIds) {
+		this.userIds = userIds;
+	}
+
+
+	public UserFirstTimeSearch activityId(Long activityId) {
+		this.activityId = activityId;
+		return this;
+	}
+
+	public UserFirstTimeSearch userIds(List<Long> userIds) {
+		this.userIds = userIds;
+		return this;
+	}
 }

+ 63 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/EQueryOp.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+/**
+ * Created by Eric.Shang on 30/5/17.
+ */
+public enum EQueryOp {
+    FUNCTION_1(1),
+    FUNCTION_2(2),
+    FUNCTION_3(3),
+    FUNCTION_4(4),
+    FUNCTION_5(5),
+    FUNCTION_6(6),
+    FUNCTION_7(7),
+    FUNCTION_8(8),
+    FUNCTION_9(9),
+    FUNCTION_10(10),
+    FUNCTION_11(11),
+    FUNCTION_12(12),
+    FUNCTION_13(13),
+    FUNCTION_14(14),
+    FUNCTION_15(15),
+    FUNCTION_16(16),
+    FUNCTION_17(17),
+    FUNCTION_18(18),
+    FUNCTION_19(19),
+    FUNCTION_20(20),
+    FUNCTION_21(21),
+    UNKNOWN(-1);
+
+    private final int value;
+
+    public int getValue() {
+        return value;
+    }
+
+    EQueryOp(int value) {
+        this.value = value;
+    }
+
+    /**
+     * 校验枚举合法性
+     * @param value 枚举值
+     * @return boolean
+     */
+    public boolean valid(int value) {
+        return (this.getValue() == value);
+    }
+
+    /**
+     * 枚举对象
+     * @param value 枚举值
+     * @return EQueryOp
+     */
+    public static EQueryOp getOp(int value) {
+        EQueryOp[] values = EQueryOp.values();
+        for (EQueryOp item : values) {
+            if (item.getValue() == value) {
+                return item;
+            }
+        }
+        return UNKNOWN;
+    }
+}

+ 119 - 33
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityPlanServiceImpl.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.ActivityPlanDao;
@@ -23,6 +24,8 @@ import com.yonge.cooleshow.biz.dal.entity.ActivityPlanReward;
 import com.yonge.cooleshow.biz.dal.entity.ActivityRegistration;
 import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.EQueryOp;
+import com.yonge.cooleshow.biz.dal.enums.MK;
 import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
 import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationService;
@@ -39,14 +42,24 @@ import com.yonge.cooleshow.biz.dal.vo.MusicActivityVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.activity.ActivityTeacherWrapper;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
-import com.yonge.cooleshow.common.enums.*;
+import com.yonge.cooleshow.common.enums.ActivityResourceEnum;
+import com.yonge.cooleshow.common.enums.ActivityShareEnum;
+import com.yonge.cooleshow.common.enums.ActivityTypeEnum;
+import com.yonge.cooleshow.common.enums.CacheNameEnum;
+import com.yonge.cooleshow.common.enums.EStatus;
+import com.yonge.cooleshow.common.enums.RegistrationMethodEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.base.util.ThreadPool;
 import com.yonge.toolset.payment.util.DistributedLock;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -169,9 +182,50 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
 
         List<ActivityPlanVo> wrappers = baseMapper.selectPage(page, query);
 
+        if (CollectionUtils.isEmpty(wrappers)) {
+            return page.setRecords(wrappers);
+        }
+
+        List<Long> activityIds = wrappers.stream()
+                .map(ActivityPlan::getId).distinct().collect(Collectors.toList());
+
+        // 参与人数
+        Map<Long, Integer> participantNumMap = Maps.newConcurrentMap();
+        // 获奖人数
+        Map<Long, Integer> winnerNumMap = Maps.newConcurrentMap();
+        Lists.partition(activityIds, 30).parallelStream().forEach(item ->
+
+            Lists.newArrayList(EQueryOp.values()).parallelStream().forEach(dataType -> {
+
+                switch (dataType) {
+                    case FUNCTION_1:
+                        // 参与人数
+                        Map<Long, Integer> participantMap = getBaseMapper().selectActivityParticipateStatInfo(activityIds).stream()
+                                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));
+
+                        participantNumMap.putAll(participantMap);
+                        break;
+                    case FUNCTION_2:
+                        // 获奖人数
+                        Map<Long, Integer> winnerMap = getBaseMapper().selectActivityWinnerStatInfo(activityIds).stream()
+                                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));
+
+                        winnerNumMap.putAll(winnerMap);
+                        break;
+                    default:
+                        break;
+                }
+
+            })
+        );
+
         // 分享活动-参与人数获奖人数相等
         for (ActivityPlanVo item : wrappers) {
 
+            // 参与人数、获奖人数
+            item.registrationNum(participantNumMap.getOrDefault(item.getId(), 0))
+                    .rewardNum(winnerNumMap.getOrDefault(item.getId(), 0));
+
             // 重置分享活动获奖与参与人数
             if (ActivityTypeEnum.SHARE == item.getActivityType()) {
                 item.setRegistrationNum(item.getRewardNum());
@@ -576,43 +630,75 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void activityState() {
-        List<ActivityPlan> list = baseMapper.activityState();
-        for (ActivityPlan plan : list) {
-            DistributedLock.of(redissonClient)
-                    .runIfLockToFunction(CacheNameEnum.LOCK_ACTIVITY_STOCK.getRedisKey(plan.getId())
-                            , (id) -> {
-                                ActivityPlan activityPlan = getById(id);
-                                if (activityPlan.getActivityState() == 0) {
-                                    activityPlan.setActivityState(1);
-                                    baseMapper.updateById(activityPlan);
-
-                                    //开始活动
-                                    Consumer<Long> afterFunction = startActivity.get(activityPlan.getActivityType());
-                                    if (!Objects.isNull(afterFunction)) {
-                                        afterFunction.accept(activityPlan.getId());
-                                    }
-                                } else {
-                                    activityPlan.setActivityState(0);
-                                    activityPlan.setRewardFlag(1);
-                                    baseMapper.updateById(activityPlan);
-
-                                    //完成活动
-                                    Consumer<Long> afterFunction = successActivity.get(activityPlan.getActivityType());
-                                    if (!Objects.isNull(afterFunction)) {
-                                        afterFunction.accept(activityPlan.getId());
+
+        // 方法调整为异常执行,预防HTTP接口调用返回超时响应
+        ThreadPool.getExecutor().submit(() -> {
+
+            List<ActivityPlan> list = baseMapper.activityState();
+            for (ActivityPlan plan : list) {
+                DistributedLock.of(redissonClient)
+                        .runIfLockToFunction(CacheNameEnum.LOCK_ACTIVITY_STOCK.getRedisKey(plan.getId())
+                                , (id) -> {
+                                    ActivityPlan activityPlan = getById(id);
+                                    if (activityPlan.getActivityState() == 0) {
+                                        activityPlan.setActivityState(1);
+                                        baseMapper.updateById(activityPlan);
+
+                                        //开始活动
+                                        Consumer<Long> afterFunction = startActivity.get(activityPlan.getActivityType());
+                                        if (!Objects.isNull(afterFunction)) {
+                                            afterFunction.accept(activityPlan.getId());
+                                        }
+                                    } else {
+                                        activityPlan.setActivityState(0);
+                                        activityPlan.setRewardFlag(1);
+                                        baseMapper.updateById(activityPlan);
+
+                                        //完成活动
+                                        Consumer<Long> afterFunction = successActivity.get(activityPlan.getActivityType());
+                                        if (!Objects.isNull(afterFunction)) {
+                                            afterFunction.accept(activityPlan.getId());
+                                        }
                                     }
-                                }
-                                return true;
-                            }, plan.getId(), 10l);
-        }
+                                    return true;
+                                }, plan.getId(), 10l);
+            }
+
+        });
+
     }
 
-    @Override
     @Transactional(rollbackFor = Exception.class)
+    @Override
     public void activityIng() {
-        for (ActivityTypeEnum activityTypeEnum : activityIng.keySet()) {
-            activityIng.get(activityTypeEnum).accept(null);
-        }
+
+        // 当前处理任务调整为异步执行
+        ThreadPool.getExecutor().submit(() -> {
+
+            RLock lock = redissonClient.getLock(CacheNameEnum.LOCK_STANDARD_GIFT_CRON.getCode());
+            try {
+                if (lock.isLocked()) {
+                    log.warn("activityIng {}, lockName={}", DateTime.now().toString(MK.TIME_PATTERN), lock.getName());
+                    return;
+                }
+
+                // 增加达标活动计算同步标识,前一个请求未执行完时忽略后续执行请求
+                lock.lock();
+
+                for (ActivityTypeEnum activityTypeEnum : activityIng.keySet()) {
+                    activityIng.get(activityTypeEnum).accept(null);
+                }
+
+            } catch (Exception e) {
+                log.error("activityIng time={}", DateTime.now().toString(MK.TIME_PATTERN), e);
+            } finally {
+                // 释放锁
+                if (lock.isLocked() && lock.isHeldByCurrentThread()) {
+                    lock.unlock(); // 删除同步标识
+                }
+            }
+        });
+
     }
 
     @Override

+ 58 - 7
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityPlanStandardServiceImpl.java

@@ -1,8 +1,12 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.yonge.cooleshow.biz.dal.dao.ActivityPlanStandardDao;
+import com.yonge.cooleshow.biz.dal.dao.UserFirstTimeDao;
 import com.yonge.cooleshow.biz.dal.dto.ActivityPlanDto;
 import com.yonge.cooleshow.biz.dal.dto.ActivityPlanRewardDto;
 import com.yonge.cooleshow.biz.dal.dto.search.UserFirstTimeSearch;
@@ -25,6 +29,7 @@ import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.ConditionMethodEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.payment.util.DistributedLock;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.joda.time.DateTime;
 import org.redisson.api.RedissonClient;
@@ -38,7 +43,6 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.stream.Collectors;
 
 
@@ -60,6 +64,8 @@ public class ActivityPlanStandardServiceImpl extends ServiceImpl<ActivityPlanSta
     private ActivityRegistrationService activityRegistrationService;
     @Autowired
     private RedissonClient redissonClient;
+    @Autowired
+    private UserFirstTimeDao userFirstTimeMapper;
 
     @Override
     public boolean createOrUpdate(ActivityPlanDto activityPlan) {
@@ -82,10 +88,12 @@ public class ActivityPlanStandardServiceImpl extends ServiceImpl<ActivityPlanSta
 
     @Override
     public void activityIng(Object param) {
+
         //查询当前进行的活动
         List<ActivityPlan> activityIds = activityPlanService.list(Wrappers.<ActivityPlan>lambdaQuery()
                 .eq(ActivityPlan::getActivityType, ActivityTypeEnum.STANDARD_GIFT)
                 .eq(ActivityPlan::getActivityState, 1)
+                //.ge(ActivityPlan::getActivityEnd, DateTime.now().toDate())
                 .select(ActivityPlan::getId));
 
         for (ActivityPlan activityPlan : activityIds) {
@@ -96,6 +104,7 @@ public class ActivityPlanStandardServiceImpl extends ServiceImpl<ActivityPlanSta
     }
 
     private Boolean dealActivityIng(Long activityId) {
+
         ActivityPlanVo detail = activityPlanService.detail(activityId);
         if (null == detail) {
             return true;
@@ -110,20 +119,64 @@ public class ActivityPlanStandardServiceImpl extends ServiceImpl<ActivityPlanSta
         search.setStartTime(detail.getActivityStart());
         search.setEndTime(detail.getActivityEnd());
         search.setUserType(detail.getActivityClient().getCode());
-
-        String timeType = planStandard.getCondition();
-        search.setTimeType(timeType);
+        search.setTimeType(planStandard.getCondition());
 
         // 达标活动匹配条件数
         int conditionNum = planStandard.getCondition().split(",").length;
 
+        // 分页查询达标活动匹配用户信息;在根据用户ID查询对应激活时间记录信息
+        IPage<UserFirstTime> page = new Page<>(1, 10);
+        userFirstTimeMapper.selectActivityParticipateUserPage(page, search.activityId(activityId));
+
+        // 当前匹配条件用户数
+        int limit = 30; // 分页行数
+        long maxPage = (page.getTotal() - 1) / limit + 1;
+
+        // 分页查询匹配用户信息
+        UserFirstTimeSearch query;
+        List<Long> userIds;
+        for (long pageNum = 1; pageNum <= maxPage; pageNum++) {
+
+            // 匹配用户ID
+            userIds = userFirstTimeMapper.selectActivityParticipateUserPage(new Page<>(pageNum, limit),
+                            search.activityId(activityId)).stream()
+                    .map(UserFirstTime::getUserId).distinct().collect(Collectors.toList());
+
+            if (CollectionUtils.isEmpty(userIds)) {
+                continue;
+            }
+
+            // 匹配用户查询条件
+            query = JSON.parseObject(JSON.toJSONString(search.userIds(userIds)), UserFirstTimeSearch.class);
+            //log.info("dealActivityIng query={}", JSON.toJSONString(query));
+
+            // 用户达标活动获奖发送记录
+            activityUserSendRewardRecordInfo(activityId, detail, planStandard, query, conditionNum);
+        }
+
+        return true;
+    }
+
+    /**
+     * 活动用户发奖记录信息
+     * @param activityId 活动ID
+     * @param detail ActivityPlanVo
+     * @param planStandard ActivityPlanStandard
+     * @param search UserFirstTimeSearch
+     * @param conditionNum 达标活动匹配条件
+     */
+    private void activityUserSendRewardRecordInfo(Long activityId,
+                                                     ActivityPlanVo detail,
+                                                     ActivityPlanStandard planStandard,
+                                                     UserFirstTimeSearch search,
+                                                     int conditionNum) {
         // 用户激活时间
         Map<Long, List<Long>> userActiveTimeMap = userFirstTimeService.selectAllList(search).stream()
                 .collect(Collectors.groupingBy(UserFirstTime::getUserId,
                         Collectors.mapping(x -> new DateTime(x.getTime()).getMillis(), Collectors.toList())));
 
         if (MapUtils.isEmpty(userActiveTimeMap)) {
-            return true;
+            return;
         }
 
         List<ActivityPlanRewardDto> activityPlanRewardDtos = activityPlanRewardService.queryActivityPlanReward(activityId);
@@ -153,8 +206,6 @@ public class ActivityPlanStandardServiceImpl extends ServiceImpl<ActivityPlanSta
             }
 
         }
-
-        return true;
     }
 
     private void sendUserReward(Long userId, Long activityId, Date winningTime, List<ActivityPlanRewardDto> activityPlanRewardDtos) {

+ 4 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserFirstTimeServiceImpl.java

@@ -2,15 +2,15 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.biz.dal.dao.UserFirstTimeDao;
 import com.yonge.cooleshow.biz.dal.dto.search.UserFirstTimeSearch;
+import com.yonge.cooleshow.biz.dal.entity.UserFirstTime;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.UserFirstTimeService;
 import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
-import org.springframework.stereotype.Service;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import com.yonge.cooleshow.biz.dal.entity.UserFirstTime;
-import com.yonge.cooleshow.biz.dal.dao.UserFirstTimeDao;
-import com.yonge.cooleshow.biz.dal.service.UserFirstTimeService;
+import org.springframework.stereotype.Service;
 
 import java.util.Date;
 import java.util.List;

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/ActivityPlanVo.java

@@ -83,4 +83,15 @@ public class ActivityPlanVo extends ActivityPlan{
 	public void setUpdateByName(String updateByName) {
 		this.updateByName = updateByName;
 	}
+
+
+	public ActivityPlanVo registrationNum(Integer registrationNum) {
+		this.registrationNum = registrationNum;
+		return this;
+	}
+
+	public ActivityPlanVo rewardNum(Integer rewardNum) {
+		this.rewardNum = rewardNum;
+		return this;
+	}
 }

+ 29 - 4
cooleshow-user/user-biz/src/main/resources/config/mybatis/ActivityPlanMapper.xml

@@ -62,10 +62,10 @@
     
     <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo">
 		SELECT         
-        	<include refid="baseColumns" />,
-		        u.username_ as updateByName,
-		        (select count(1) from activity_registration r where t.id_ = r.activity_id_) as registrationNum,
-                (select count(distinct r.user_id_) from activity_user_reward r where t.id_ = r.activity_id_) as rewardNum
+        	<include refid="baseColumns" />
+		    ,   u.username_ as updateByName
+		    /*,   (select count(1) from activity_registration r where t.id_ = r.activity_id_) as registrationNum*/
+		    /*,   (select count(distinct r.user_id_) from activity_user_reward r where t.id_ = r.activity_id_) as rewardNum*/
 		FROM activity_plan t
         LEFT JOIN  sys_user u on t.update_by_ = u.id_
         <where>
@@ -133,4 +133,29 @@
             </if>
         </where>
     </select>
+
+    <!--活动参与人数、获奖人数统计-->
+    <select id="selectActivityParticipateStatInfo"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper">
+        SELECT t1.activity_id_ AS id, COUNT(DISTINCT t1.id_) AS total FROM activity_registration t1
+        <where>
+            <if test="activityIds != null">
+                AND t1.activity_id_ IN (<foreach collection="activityIds" separator="," item="item">#{item}</foreach>)
+            </if>
+        </where>
+        GROUP BY t1.activity_id_
+    </select>
+
+    <select id="selectActivityWinnerStatInfo"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper">
+        SELECT t1.activity_id_ AS id, COUNT(DISTINCT t1.user_id_) AS total FROM activity_user_reward t1
+        <where>
+            <if test="activityIds != null">
+                AND t1.activity_id_ IN (<foreach collection="activityIds" separator="," item="item">#{item}</foreach>)
+            </if>
+        </where>
+        GROUP BY t1.activity_id_
+    </select>
+    <!--活动参与人数、获奖人数统计-->
+
 </mapper>

+ 30 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserFirstTimeMapper.xml

@@ -28,10 +28,13 @@
             <if test="param.userId != null">
                 and t.user_id_ = #{param.userId}
             </if>
+            <if test="param.userIds != null">
+                AND t.user_id_ IN (<foreach collection="param.userIds" separator="," item="item">#{item}</foreach>)
+            </if>
             <if test="param.userType != null and param.userType != ''">
                 and find_in_set(t.user_type_ , #{param.userType})
             </if>
-            <if test="param.timeType != null and param.userType != ''">
+            <if test="param.timeType != null and param.timeType != ''">
                 and find_in_set(t.time_type_ , #{param.timeType})
             </if>
             <if test="param.startTime != null">
@@ -43,4 +46,30 @@
         </where>
         order by t.time_
     </select>
+
+    <!--达标活动参与用户-->
+    <select id="selectActivityParticipateUserPage"
+            resultType="com.yonge.cooleshow.biz.dal.entity.UserFirstTime">
+        SELECT t1.user_id_ AS userId FROM user_first_time t1
+        <where>
+            <if test="record.userType != null and record.userType != ''">
+                and find_in_set(t1.user_type_ , #{record.userType})
+            </if>
+            <if test="record.timeType != null and record.timeType != ''">
+                and find_in_set(t1.time_type_ , #{record.timeType})
+            </if>
+            <if test="record.startTime != null">
+                and t1.time_ &gt;= #{record.startTime}
+            </if>
+            <if test="record.endTime != null">
+                and t1.time_ &lt;= #{record.endTime}
+            </if>
+            <if test="record.activityId != null">
+                AND t1.user_id_ NOT IN (SELECT t2.user_id_ FROM activity_user_reward t2 WHERE t2.activity_id_ = #{record.activityId})
+            </if>
+        </where>
+        GROUP BY t1.user_id_ ORDER BY t1.user_id_ ASC
+    </select>
+    <!--达标活动参与用户-->
+
 </mapper>