|
|
/**
|
|
|
*
|
|
|
*/
|
|
|
package com.yoho.activity.other.timer;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Map.Entry;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import com.yoho.activity.common.enums.UserTypeEnum;
|
|
|
import com.yoho.activity.common.utils.DateUtils;
|
|
|
import com.yoho.activity.common.utils.MapUtil;
|
|
|
import com.yoho.activity.common.utils.MapUtil.FunctionExPlus;
|
|
|
import com.yoho.activity.common.utils.PropertiesUtil;
|
|
|
import com.yoho.queue.dal.IDrawlineActivityDAO;
|
|
|
import com.yoho.queue.dal.IDrawlinePrizeSettingDAO;
|
|
|
import com.yoho.queue.dal.IDrawlineUserQueueDAO;
|
|
|
import com.yoho.queue.dal.IDrawlineVirtualUserDAO;
|
|
|
import com.yoho.queue.dal.model.DrawlineActivity;
|
|
|
import com.yoho.queue.dal.model.DrawlinePrizeSetting;
|
|
|
import com.yoho.queue.dal.model.DrawlineUserQueue;
|
|
|
import com.yoho.queue.dal.model.DrawlineVirtualUser;
|
|
|
|
|
|
/**
|
|
|
* 描述:自动插入马甲
|
|
|
* 一分钟执行一次
|
|
|
* 规则
|
|
|
* 第一次判断,该活动只要有一个真实用户参加,就直接插入100个马甲;如果该活动还没有任何用户参加,则不增加马甲
|
|
|
* 从第二分钟开始,每次插入的马甲数,是前一分钟内,新增的真实用户数的5倍
|
|
|
*
|
|
|
* @author ping.huang 2016年3月5日
|
|
|
*/
|
|
|
@Component
|
|
|
public class AddVirtualUser {
|
|
|
|
|
|
static Logger log = LoggerFactory.getLogger(AddVirtualUser.class);
|
|
|
|
|
|
@Resource
|
|
|
IDrawlineVirtualUserDAO drawlineVirtualUserDAO;
|
|
|
@Resource
|
|
|
IDrawlineActivityDAO drawlineActivityDAO;
|
|
|
@Resource
|
|
|
IDrawlineUserQueueDAO drawlineUserQueueDAO;
|
|
|
@Resource
|
|
|
IDrawlinePrizeSettingDAO drawlinePrizeSettingDAO;
|
|
|
|
|
|
//各个活动下,待进入排队的马甲
|
|
|
Map<Integer, List<DrawlineVirtualUser>> waitAddUserMap = new HashMap<Integer, List<DrawlineVirtualUser>>();
|
|
|
|
|
|
//所有的活动
|
|
|
List<DrawlineActivity> activityList = null;
|
|
|
|
|
|
//所有的活动ID
|
|
|
List<Integer> activityIdList = new ArrayList<Integer>();
|
|
|
|
|
|
//是否第一次
|
|
|
Map<Integer, Boolean> first = new HashMap<Integer, Boolean>();
|
|
|
|
|
|
/**
|
|
|
* 初始化一些参数
|
|
|
*/
|
|
|
public void init() {
|
|
|
|
|
|
waitAddUserMap = new HashMap<Integer, List<DrawlineVirtualUser>>();
|
|
|
activityList = new ArrayList<DrawlineActivity>();
|
|
|
activityIdList = new ArrayList<Integer>();
|
|
|
//first = new HashMap<Integer, Boolean>();
|
|
|
|
|
|
//初始化所有活动
|
|
|
activityList = drawlineActivityDAO.selectAllActivity(DateUtils.getCurrentTimeSecond());
|
|
|
|
|
|
if (activityList == null || activityList.size() == 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
for (DrawlineActivity activity : activityList) {
|
|
|
activityIdList.add(activity.getId());
|
|
|
}
|
|
|
//查询这些活动下,已经进入排队的马甲
|
|
|
List<DrawlineUserQueue> queueList = drawlineUserQueueDAO.selectByTypeAndActivityIds(StringUtils.join(activityIdList, ","), UserTypeEnum.VIRTUAL_USER.getValue());
|
|
|
|
|
|
//初始化所有的马甲用户
|
|
|
List<DrawlineVirtualUser> userList = drawlineVirtualUserDAO.selectWaitQueueVirtualUser();
|
|
|
|
|
|
if (userList != null) {
|
|
|
//打乱马甲顺序
|
|
|
Collections.shuffle(userList);
|
|
|
}
|
|
|
|
|
|
List<DrawlineVirtualUser> waitList = null;
|
|
|
for (DrawlineActivity activity : activityList) {
|
|
|
for (DrawlineVirtualUser user : userList) {
|
|
|
//如果该马甲已经在该活动下排队过,则排除
|
|
|
if (userIsExists(activity.getId().intValue(), user.getUid().intValue(), queueList)) {
|
|
|
continue;
|
|
|
}
|
|
|
//没有排队过,则进入等待排队的队列
|
|
|
waitList = waitAddUserMap.get(activity.getId());
|
|
|
if (waitList == null) {
|
|
|
waitList = new ArrayList<DrawlineVirtualUser>();
|
|
|
}
|
|
|
waitList.add(user);
|
|
|
waitAddUserMap.put(activity.getId(), waitList);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void run() {
|
|
|
log.info("start add virtuals");
|
|
|
boolean execute = PropertiesUtil.getExecuteTask();
|
|
|
if (!execute) {
|
|
|
log.info("properties is false exit task");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//初始化数据
|
|
|
init();
|
|
|
|
|
|
//没有活动,直接退出
|
|
|
if (activityList == null || activityList.size() == 0) {
|
|
|
log.info("activityList is empty over");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//添加白名单
|
|
|
addWhiteUser();
|
|
|
|
|
|
//马甲全部排队完了,直接退出
|
|
|
if (!checkVirtual()) {
|
|
|
log.info("wait virtual is empty over");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//查询所有的活动,前一分钟内实际增加的真实用户数
|
|
|
int currTime = DateUtils.getCurrentTimeSecond();
|
|
|
List<Map<String, Object>> realUserCountList = drawlineUserQueueDAO.selectRealUserCountByActivityIds(StringUtils.join(activityIdList, ","), currTime - 60, currTime);
|
|
|
if (realUserCountList == null) {
|
|
|
realUserCountList = new ArrayList<Map<String,Object>>();
|
|
|
}
|
|
|
//list转map
|
|
|
Map<Integer, Integer> realUserCountMap = null;
|
|
|
if (realUserCountList != null) {
|
|
|
realUserCountMap = MapUtil.transformListMap(realUserCountList, new FunctionExPlus<Map<String, Object>, Integer, Integer>() {
|
|
|
|
|
|
@Override
|
|
|
public Integer applyKey(Map<String, Object> input) {
|
|
|
return Integer.parseInt(input.get("activity_id").toString());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public Integer applyValue(Map<String, Object> input) {
|
|
|
return Integer.parseInt(input.get("nums").toString());
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
if (realUserCountMap == null) {
|
|
|
realUserCountMap = new HashMap<Integer, Integer>();
|
|
|
}
|
|
|
|
|
|
//活动下,等待排队的马甲
|
|
|
List<DrawlineVirtualUser> waitList = null;
|
|
|
//需要加入的马甲数量
|
|
|
int num = 0, n = 0;
|
|
|
DrawlineUserQueue queueUser = null;
|
|
|
int currentTime = (int) (System.currentTimeMillis() / 1000);
|
|
|
for (DrawlineActivity activity : activityList) {
|
|
|
n = 0;
|
|
|
// if (realUserCountMap.get(activity.getId()) == null || realUserCountMap.get(activity.getId()) == 0) {
|
|
|
// //该活动还没有一个用户参加,则不增加马甲
|
|
|
// continue;
|
|
|
// }
|
|
|
waitList = waitAddUserMap.get(activity.getId());
|
|
|
if (waitList == null || waitList.size() == 0) {
|
|
|
log.info("wait queue user is empty with activityId is {}, activityName is {}", activity.getId(), activity.getActivityName());
|
|
|
continue;
|
|
|
}
|
|
|
if (first.get(activity.getId()) == null) {
|
|
|
num = 100;
|
|
|
first.put(activity.getId(), true);
|
|
|
} else {
|
|
|
num = 5 * (realUserCountMap.get(activity.getId()) == null ? 0 : realUserCountMap.get(activity.getId()).intValue());
|
|
|
}
|
|
|
|
|
|
//进入排队
|
|
|
for (int i = 0; i < waitList.size(); i++) {
|
|
|
n++;
|
|
|
if (n > num) {
|
|
|
break;
|
|
|
}
|
|
|
queueUser = new DrawlineUserQueue();
|
|
|
queueUser.setActivityId(activity.getId());
|
|
|
queueUser.setUid(waitList.get(i).getUid());
|
|
|
queueUser.setUserType((byte) UserTypeEnum.VIRTUAL_USER.getValue());
|
|
|
queueUser.setStatus((byte) 1);
|
|
|
queueUser.setCreateTime(currentTime);
|
|
|
queueUser.setUpdateTime(currentTime);
|
|
|
//插入排队表,因为排队字段sort必须要连续,为了避免锁表到导致真实用户插入问题,这里需要在循环里面插入数据库
|
|
|
drawlineUserQueueDAO.insertAutoSort(queueUser);
|
|
|
//插入成功后,需要从等待排队的马甲中删除
|
|
|
waitList.remove(waitList.get(i));
|
|
|
i--;
|
|
|
}
|
|
|
}
|
|
|
log.info("end add virtuals");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 添加白名单
|
|
|
*/
|
|
|
private void addWhiteUser() {
|
|
|
// 查询所有的奖品设置
|
|
|
List<DrawlinePrizeSetting> prizeList = drawlinePrizeSettingDAO.selectByActivityIds(StringUtils.join(activityIdList, ","));
|
|
|
if (prizeList == null || prizeList.size() == 0) {
|
|
|
log.info("addWhiteUser prize is empty");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// list 转 map
|
|
|
Map<Integer, String> whileMap = null;
|
|
|
if (prizeList != null) {
|
|
|
whileMap = MapUtil.transformListMap(prizeList, new FunctionExPlus<DrawlinePrizeSetting, Integer, String>() {
|
|
|
|
|
|
@Override
|
|
|
public Integer applyKey(DrawlinePrizeSetting input) {
|
|
|
return input.getActivityId();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public String applyValue(DrawlinePrizeSetting input) {
|
|
|
return input.getWhiteList();
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// 查询所有排队的真实用户
|
|
|
List<DrawlineUserQueue> queueList = drawlineUserQueueDAO.selectByTypeAndActivityIds(StringUtils.join(activityIdList, ","), UserTypeEnum.REAL_USER.getValue());
|
|
|
|
|
|
String[] whileArr = null;
|
|
|
String whiteStr = "";
|
|
|
DrawlineUserQueue queueUser = null;
|
|
|
int currentTime = (int) (System.currentTimeMillis() / 1000);
|
|
|
for (DrawlineActivity activity : activityList) {
|
|
|
whiteStr = whileMap.get(activity.getId());
|
|
|
if (StringUtils.isEmpty(whiteStr)) {
|
|
|
continue;
|
|
|
}
|
|
|
whileArr = whiteStr.split(",");
|
|
|
for (String white : whileArr) {
|
|
|
if (whiteIsExists(queueList, activity.getId().intValue(), Integer.parseInt(white))) {
|
|
|
log.debug("white user={} is queue in activityId={} exit", white, activity.getId());
|
|
|
continue;
|
|
|
}
|
|
|
//该白名单没有排队过,则进入排队
|
|
|
queueUser = new DrawlineUserQueue();
|
|
|
queueUser.setActivityId(activity.getId());
|
|
|
queueUser.setUid(Integer.parseInt(white));
|
|
|
queueUser.setUserType((byte) UserTypeEnum.REAL_USER.getValue());
|
|
|
queueUser.setStatus((byte) 1);
|
|
|
queueUser.setCreateTime(currentTime);
|
|
|
queueUser.setUpdateTime(currentTime);
|
|
|
//插入排队表
|
|
|
drawlineUserQueueDAO.insertAutoSort(queueUser);
|
|
|
//一次只插入一条白名单
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 判断该白名单是否已经排队过
|
|
|
* @param queueList
|
|
|
* @param activityId
|
|
|
* @param whiteUid
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean whiteIsExists(List<DrawlineUserQueue> queueList, int activityId, int whiteUid) {
|
|
|
if (queueList == null || queueList.size() == 0) {
|
|
|
return false;
|
|
|
}
|
|
|
for (DrawlineUserQueue queue : queueList) {
|
|
|
if (queue.getActivityId() == null || queue.getUid() == null) {
|
|
|
continue;
|
|
|
}
|
|
|
if (queue.getActivityId().intValue() == activityId && queue.getUid().intValue() == whiteUid) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 检查是否还有剩余的马甲
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean checkVirtual() {
|
|
|
if (waitAddUserMap == null || waitAddUserMap.size() == 0) {
|
|
|
return false;
|
|
|
}
|
|
|
List<DrawlineVirtualUser> l = null;
|
|
|
for (Entry<Integer, List<DrawlineVirtualUser>> entry : waitAddUserMap.entrySet()) {
|
|
|
l = entry.getValue();
|
|
|
if (l != null && l.size() > 0) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 查询该活动下,这个马甲有没有排队过
|
|
|
* @param activityId
|
|
|
* @param uid
|
|
|
* @param queueList
|
|
|
* @return
|
|
|
*/
|
|
|
private boolean userIsExists(int activityId, int uid, List<DrawlineUserQueue> queueList) {
|
|
|
if (queueList == null || queueList.size() == 0) {
|
|
|
return false;
|
|
|
}
|
|
|
for (DrawlineUserQueue user : queueList) {
|
|
|
if (user.getActivityId() != null && user.getActivityId().intValue() == activityId && user.getUid() != null && user.getUid().intValue() == uid) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
} |
...
|
...
|
|