Authored by chaogeng

Merge branch 'test' of http://git.dev.yoho.cn/yoho30/yohobuy-activity into test

/**
*
*/
package com.yoho.activity.other.restapi;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yoho.activity.other.timer.AddVirtualUser;
import com.yoho.activity.queue.ApiResponse;
/**
* 描述:
*
* @author ping.huang 2016年3月10日
*/
@Controller
public class ExecuteAddVirtualRest {
@Resource
AddVirtualUser addVirtualUser;
static Logger logger = LoggerFactory.getLogger(ExecuteAddVirtualRest.class);
@RequestMapping(params = "method=app.drawline.executeAddVirtualUser")
@ResponseBody
public ApiResponse executeAddVirtualUser() {
logger.info("Enter executeAddVirtualUser:");
addVirtualUser.run();
return new ApiResponse.ApiResponseBuilder().build();
}
}
... ...
/**
*
*/
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;
}
}
... ...
... ... @@ -30,12 +30,14 @@ public class SendUserAwardTimer {
public void sendAwardToLuckyUser() {
boolean execute = PropertiesUtil.getExecuteTask();
log.info(" SendUserAwardTimer.sendAwardToLuckyUser, execute is {}", execute);
if (!execute) {
log.info("properties is false exit task");
return;
}
// 对中奖表中的所有记录做发放
log.info(" start luckyUserService.sendAwardToLuckyUser");
luckyUserService.sendAwardToLuckyUser(null);
}
... ...
... ... @@ -24,7 +24,7 @@ public class TimeTaskRest {
public ApiResponse luckyDraw() {
logger.info("Enter luckyDraw.");
JSONArray jsonArray = timeTaskService.luckyDraw();
JSONArray jsonArray = timeTaskService.luckyDraw(true);
ApiResponse apiResponse = new ApiResponse();
apiResponse.setData(jsonArray);
... ...
... ... @@ -4,7 +4,7 @@ import com.alibaba.fastjson.JSONArray;
public interface ITimeTaskService {
JSONArray luckyDraw();
JSONArray luckyDraw(boolean handler);
void shutdownLuckyDraw();
... ...
... ... @@ -70,6 +70,10 @@ public class DrawlineList2MapServiceImpl implements IDrawlineList2MapService {
if (null == userBaseRspBO) {
continue;
}
String nickname = userBaseRspBO.getNickname();
if (nickname.matches("\\d{11}")) {
userBaseRspBO.setNickname(nickname.substring(0, 3) + "****" + nickname.substring(7));
}
userBaseRspBOMap.put(userBaseRspBO.getUid(), userBaseRspBO);
}
... ... @@ -140,5 +144,9 @@ public class DrawlineList2MapServiceImpl implements IDrawlineList2MapService {
logger.debug("Outer getDrawlineUserQueueMap. activityId is {}, uidList is {}, drawlineUserQueueMap is {}", activityId, uidList, drawlineUserQueueMap);
return drawlineUserQueueMap;
}
public static void main(String[] args) {
System.out.println("11111234567".matches("\\d{11}"));
}
}
... ...
... ... @@ -168,7 +168,7 @@ public class LuckyUserServiceImpl implements ILuckyUserService {
@Override
public void sendAwardToLuckyUser(ActivityReqBO activityReqBO) {
logger.info("Enter LuckyUserServiceImpl.sendAwardToLuckyUser");
logger.info("Enter LuckyUserServiceImpl.sendAwardToLuckyUser activityReqBO is {}", activityReqBO);
List<DrawlineLuckyUser> luckyUserList = new ArrayList<DrawlineLuckyUser>();
if(activityReqBO == null){
// 取出所有活动的中奖记录列表
... ... @@ -178,10 +178,12 @@ public class LuckyUserServiceImpl implements ILuckyUserService {
// 取出指定活动的中奖记录列表
// 查询中奖用户总数
int total = luckyUserDAO.selectCountByActivityId(activityId);
logger.info("LuckyUserServiceImpl.sendAwardToLuckyUser, total is {}", total);
// 查询drawline_lucky_user表里获取中奖用户列表
luckyUserList = luckyUserDAO.selectByActivityId(activityId, 0, total);
}
logger.debug("LuckyUserServiceImpl.sendAwardToLuckyUser, luckyUserList.size is {}", luckyUserList.size());
if(CollectionUtils.isEmpty(luckyUserList)){
return;
}
... ... @@ -195,6 +197,7 @@ public class LuckyUserServiceImpl implements ILuckyUserService {
});
// 对每个activityidmap批量发送限购码
logger.debug("start processActivityMap()");
processActivityMap(transformListMap);
}
... ... @@ -232,6 +235,7 @@ public class LuckyUserServiceImpl implements ILuckyUserService {
}
// 10个中奖记录一个批次调promotion接口发放限购码奖励
int activityLuckyUserCount = activityLuckyUserList.size();
logger.info("LuckyUserServiceImpl.sendAwardPerActivity, activityLuckyUserCount is {}", activityLuckyUserCount);
int page = 0 == activityLuckyUserCount % BATCH_SEND_AWARD_NUM ? activityLuckyUserCount / BATCH_SEND_AWARD_NUM : activityLuckyUserCount / BATCH_SEND_AWARD_NUM + 1;
List<DrawlineLuckyUser> perActivityLuckyUserList = new ArrayList<DrawlineLuckyUser>();
for (int i = 0; i < page; i++) {
... ... @@ -256,6 +260,7 @@ public class LuckyUserServiceImpl implements ILuckyUserService {
logger.info("end invoke promotion.batchAddLimitCodeReceiveRecord");
// 处理中奖用户发放结果,发放成功的修改表状态
logger.info("start updateLuckyUserStatus, activityId is {}", activityId);
updateLuckyUserStatus(limitCodeUserBoArray, activityId);
}
}
... ... @@ -273,7 +278,9 @@ public class LuckyUserServiceImpl implements ILuckyUserService {
for (LimitCodeUserBo limitCodeUserBo : limitCodeUserBoArray) {
uids.add(limitCodeUserBo.getUid());
}
logger.info("start luckyUserDAO.updatePrizeStatusByActIdAndUids, activityId is {}, uids is {}", activityId, uids);
luckyUserDAO.updatePrizeStatusByActIdAndUids(activityId, uids);
logger.debug("end luckyUserDAO.updatePrizeStatusByActIdAndUids, activityId is {}, uids is {}", activityId, uids);
}
}
... ...
... ... @@ -77,8 +77,8 @@ public class TimeTaskServiceImpl implements ITimeTaskService {
}
}
public JSONArray luckyDraw() {
logger.info("Enter luckyDraw.");
public JSONArray luckyDraw(boolean handler) {
logger.info("Enter luckyDraw. param handler is {}", handler);
// (1)查询未成功抽奖的活动
List<DrawlineActivity> drawlineActivityList = drawlineActivityDAO.selectByNotLuckydraw();
... ... @@ -102,10 +102,12 @@ public class TimeTaskServiceImpl implements ITimeTaskService {
if (currentTime > endTime) {
jsonArray.add(luckyDraw(id, endTime));
} else {
if (TIMETASK_LUCKYDRAW_LIST.contains(id)) {
continue;
if (!handler) {
if (TIMETASK_LUCKYDRAW_LIST.contains(id)) {
continue;
}
TIMETASK_LUCKYDRAW_LIST.add(id);
}
TIMETASK_LUCKYDRAW_LIST.add(id);
long delay = endTime - currentTime - 300000;
delay = 0 > delay ? 0 : delay;
... ...
... ... @@ -34,7 +34,7 @@ public class LuckyDrawService {
return;
}
timeTaskService.luckyDraw();
timeTaskService.luckyDraw(false);
logger.info("Outer LuckyDrawService thread run.");
}
... ...
... ... @@ -9,6 +9,7 @@
<property name="drawline.luckydraw.interval" defaultValue="1440" description="执行定时抽奖任务间隔" />
<property name="drawline.luckyUserNotice.interval" defaultValue="120" description="执行抽奖结果通知任务间隔" />
<property name="is_debug_enable" defaultValue="false" description="开通接口访问校验" />
</group>
<script>
<generate template="META-INF/autoconf/databases.yml" destfile="WEB-INF/classes/databases.yml" />
... ...