...
|
...
|
@@ -5,7 +5,6 @@ package com.yoho.activity.service.impl; |
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Iterator;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Random;
|
...
|
...
|
@@ -20,9 +19,14 @@ import org.apache.commons.lang3.StringUtils; |
|
|
import org.elasticsearch.common.collect.Lists;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.BeansException;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.context.ApplicationContextAware;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import com.yoho.activity.common.cache.CacheAop;
|
|
|
import com.yoho.activity.common.cache.CacheKeyAndTime;
|
|
|
import com.yoho.activity.common.cache.Cacheable;
|
|
|
import com.yoho.activity.common.helper.SendCouponHelper;
|
|
|
import com.yoho.activity.common.redis.GracefulRedisTemplate;
|
...
|
...
|
@@ -37,7 +41,6 @@ import com.yoho.lottery.dal.LotteryMapper; |
|
|
import com.yoho.lottery.dal.LotteryRecordMapper;
|
|
|
import com.yoho.lottery.dal.PrizeMapper;
|
|
|
import com.yoho.lottery.dal.model.Lottery;
|
|
|
import com.yoho.lottery.dal.model.LotteryPrizeInfo;
|
|
|
import com.yoho.lottery.dal.model.LotteryRecord;
|
|
|
import com.yoho.lottery.dal.model.Prize;
|
|
|
import com.yoho.service.model.order.request.OrderListRequest;
|
...
|
...
|
@@ -46,7 +49,7 @@ import com.yoho.service.model.order.response.Orders; |
|
|
import com.yoho.service.model.order.response.OrdersGoods;
|
|
|
|
|
|
@Service
|
|
|
public class LotteryServiceImpl implements ILotteryService {
|
|
|
public class LotteryServiceImpl implements ILotteryService , ApplicationContextAware {
|
|
|
|
|
|
private static Logger logger = LoggerFactory.getLogger(LotteryServiceImpl.class);
|
|
|
|
...
|
...
|
@@ -81,8 +84,12 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
@Autowired
|
|
|
private GracefulRedisTemplate gracefulRedisTemplate;
|
|
|
|
|
|
private CacheAop cacheAop;
|
|
|
|
|
|
private ILotteryService lotteryService;
|
|
|
|
|
|
@Override
|
|
|
@Cacheable(expireTime = 300)
|
|
|
@Cacheable(expireTime = CacheKeyAndTime.LOTTERY_INTO)
|
|
|
public LotteryRespData getLotteryInfo(Integer lotteryId) {
|
|
|
|
|
|
LotteryRespData data = new LotteryRespData();
|
...
|
...
|
@@ -91,9 +98,6 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
|
|
|
checkLottery(lotteryId, lottery);
|
|
|
|
|
|
// clear properties
|
|
|
clearUnuseProp(lottery, prize);
|
|
|
|
|
|
data.setLottery(lottery);
|
|
|
data.setPrizes(prize);
|
|
|
return data;
|
...
|
...
|
@@ -101,12 +105,12 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
|
|
|
@Override
|
|
|
public LotteryRespData getOrderLotteryState(Integer lotteryId, Integer userId, String orderCode) {
|
|
|
Lottery lottery = lotteryMapper.selectByPrimaryKey(lotteryId);
|
|
|
checkLottery(lotteryId, lottery);
|
|
|
LotteryRespData lotteryInfo = lotteryService.getLotteryInfo(lotteryId);
|
|
|
|
|
|
LotteryRespData data = new LotteryRespData();
|
|
|
List<LotteryRecord> records = lotteryRecordMapper.selectOrderRecords(lotteryId, userId, orderCode,
|
|
|
lotteryId % 10);
|
|
|
List<Integer> recordIds = lotteryRecordMapper.selectOrderRecordIds(null, userId, orderCode,
|
|
|
userId % 10);
|
|
|
LotteryRecord[] records = lotteryService.getLotteryRecordByIds(recordIds, userId % 10);
|
|
|
// 批量查询:内部
|
|
|
if (StringUtils.isBlank(orderCode)) {
|
|
|
Map<String, LotteryRecord> lotteryRecordMap = new HashMap<>();
|
...
|
...
|
@@ -116,24 +120,31 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
data.setLotteryRecordMap(lotteryRecordMap);
|
|
|
} else {
|
|
|
// 检查使用
|
|
|
if (records.isEmpty()) {
|
|
|
if (records.length == 0) {
|
|
|
data.setOrderLotteryCode(STATE_NOT_USE);
|
|
|
data.setOrderLotteryMessage("参加抽奖");
|
|
|
} else {
|
|
|
LotteryRecord rec = records.get(0);
|
|
|
LotteryRecord rec = records[0];
|
|
|
boolean havePrize;
|
|
|
Prize prize = null;
|
|
|
if (rec.getPrizeId() == null || rec.getPrizeId() <= 0) {
|
|
|
havePrize = false;
|
|
|
} else {
|
|
|
prize = prizeMapper.selectByPrimaryKey(rec.getPrizeId());
|
|
|
List<Prize> prizes = lotteryInfo.getPrizes();
|
|
|
for(Prize p : prizes) {
|
|
|
if(p.getId().equals(rec.getPrizeId())) {
|
|
|
prize = p;
|
|
|
}
|
|
|
}
|
|
|
if (prize == null) {
|
|
|
logger.warn("错误的奖品id:活动id{} 奖品id{}", lotteryId, rec.getPrizeId());
|
|
|
}
|
|
|
havePrize = !hasRealPrize(prize);
|
|
|
}
|
|
|
if (havePrize) {
|
|
|
data.setOrderLotteryCode(STATE_USE_HAVA_PRIZE);
|
|
|
data.setOrderLotteryMessage("已中奖");
|
|
|
data.setPrize(prize);
|
|
|
clearPrize(prize);
|
|
|
} else {
|
|
|
data.setOrderLotteryCode(STATE_USE_NO_PRIZE);
|
|
|
data.setOrderLotteryMessage("已抽奖");
|
...
|
...
|
@@ -144,37 +155,40 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public synchronized LotteryRespData lucky(Integer lotteryId, Integer userId, String orderCode) {
|
|
|
public LotteryRespData lucky(Integer lotteryId, Integer userId, String orderCode) {
|
|
|
logger.info("用户{}的订单{}进行抽奖!", userId, orderCode);
|
|
|
// 已抽奖检查
|
|
|
LotteryRespData orderLotteryState = getOrderLotteryState(lotteryId, userId, orderCode);
|
|
|
if (orderLotteryState.getOrderLotteryCode() != STATE_NOT_USE) {
|
|
|
LotteryRespData orderLotteryState = getOrderLotteryState(lotteryId, userId, null);
|
|
|
Map<String, LotteryRecord> recordMap = orderLotteryState.getLotteryRecordMap();
|
|
|
if (recordMap.containsKey(orderCode)) {
|
|
|
logger.info("用户{}的订单{}不符合抽奖条件!", userId, orderCode);
|
|
|
return orderLotteryState;
|
|
|
}
|
|
|
|
|
|
// 本活动中奖次数
|
|
|
int lotteryCount = lotteryRecordMapper.selectUserLotteryPrizeCount(lotteryId, userId, lotteryId % 10);
|
|
|
// int lotteryCount = lotteryRecordMapper.selectUserLotteryPrizeCount(lotteryId, userId, userId % 10);
|
|
|
// 只能中一次
|
|
|
if (lotteryCount > 0) {
|
|
|
if (recordMap.size() > 0) {
|
|
|
logger.info("用户{}的订单{}已经中过奖!", userId, orderCode);
|
|
|
return savePrizeAndGetResp(lotteryId, userId, orderCode, null);
|
|
|
}
|
|
|
|
|
|
// 查询抽奖统计信息
|
|
|
List<LotteryPrizeInfo> lotteryPrizeInfo = lotteryRecordMapper.selectLotteryPrizeInfo(lotteryId, lotteryId % 10);
|
|
|
/*List<LotteryPrizeInfo> lotteryPrizeInfo = lotteryRecordMapper.selectLotteryPrizeInfo(lotteryId, userId % 10);
|
|
|
Map<Integer, Integer> usedMap = new HashMap<>();
|
|
|
for (LotteryPrizeInfo pi : lotteryPrizeInfo) {
|
|
|
usedMap.put(pi.getPrizeId(), pi.getCount());
|
|
|
}
|
|
|
}*/
|
|
|
|
|
|
|
|
|
// 查询奖品总数信息
|
|
|
List<Prize> prizeList = prizeMapper.selectByLotteryId(lotteryId);
|
|
|
LotteryRespData lotteryInfo = lotteryService.getLotteryInfo(lotteryId);
|
|
|
List<Prize> prizeList = lotteryInfo.getPrizes();
|
|
|
Map<Integer, Integer> allMap = new HashMap<>();
|
|
|
for (Prize p : prizeList) {
|
|
|
allMap.put(p.getId(), p.getTotal());
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
// 奖品剩余计算
|
|
|
Map<Integer, Integer> remainMap = new HashMap<>();
|
|
|
for (Integer prizeId : allMap.keySet()) {
|
...
|
...
|
@@ -184,39 +198,70 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
used = 0;
|
|
|
}
|
|
|
remainMap.put(prizeId, all - used);
|
|
|
}
|
|
|
}*/
|
|
|
|
|
|
// 随机抽取一个
|
|
|
Integer prizeId = selectOne(allMap);
|
|
|
logger.info("用户{}的订单{}抽到奖项{}!", userId, orderCode, prizeId);
|
|
|
// 奖品已经抽完
|
|
|
Integer remain = remainMap.get(prizeId);
|
|
|
if (remain <= 0) {
|
|
|
logger.info("用户{}的订单{}抽到奖项{},该奖项剩余量为0!", userId, orderCode, prizeId);
|
|
|
prizeId = null;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 未抽到
|
|
|
if (prizeId == null) {
|
|
|
return savePrizeAndGetResp(lotteryId, userId, orderCode, null);
|
|
|
}
|
|
|
|
|
|
Prize prize = null;
|
|
|
for(Prize p : prizeList) {
|
|
|
if(p.getId().equals(prizeId)) {
|
|
|
prize = p;
|
|
|
}
|
|
|
}
|
|
|
if (prize == null) {
|
|
|
logger.warn("错误的奖品id:活动id{} 奖品id{}", lotteryId, prizeId);
|
|
|
return savePrizeAndGetResp(lotteryId, userId, orderCode, null);
|
|
|
}
|
|
|
|
|
|
int update = 0;
|
|
|
if (prize.getRemain() > 0) {
|
|
|
// 更新剩余奖品
|
|
|
update = prizeMapper.subtractPrize(prizeId);
|
|
|
}
|
|
|
|
|
|
// 奖品已经抽完
|
|
|
if (update == 0) {
|
|
|
logger.info("用户{}的订单{}抽到奖项{},该奖项剩余量为0!", userId, orderCode, prizeId);
|
|
|
try {
|
|
|
cacheAop.clearCache(LotteryServiceImpl.class.getMethod("getLotteryInfo", Integer.class),
|
|
|
new Object[] { lotteryId });
|
|
|
} catch (Exception e) {
|
|
|
logger.warn("清除LotteryServiceImpl.getLotteryInfo lotteryId={}错误", lotteryId);
|
|
|
}
|
|
|
return savePrizeAndGetResp(lotteryId, userId, orderCode, null);
|
|
|
}
|
|
|
|
|
|
LotteryRespData data = savePrizeAndGetResp(lotteryId, userId, orderCode, prizeId);
|
|
|
Prize prize = prizeMapper.selectByPrimaryKey(prizeId);
|
|
|
/*Prize prize = prizeMapper.selectByPrimaryKey(prizeId);
|
|
|
if (!hasRealPrize(prize)) {
|
|
|
logger.info("用户{}的订单{}抽到奖项{},该奖项为nothing!", userId, orderCode, prizeId);
|
|
|
data.setOrderLotteryCode(STATE_USE_NO_PRIZE);
|
|
|
data.setOrderLotteryMessage(MSG_NO_PRIZE);
|
|
|
return data;
|
|
|
}
|
|
|
}*/
|
|
|
|
|
|
data.setPrize(prize);
|
|
|
|
|
|
givePrize(userId, orderCode, prize);
|
|
|
|
|
|
clearPrize(prize);
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
@Cacheable(expireTime = CacheKeyAndTime.LOTTERY_USER_LOTTERY)
|
|
|
public LotteryRecord[] getLotteryRecordByIds(List<Integer> ids, int shardFactor) {
|
|
|
if (ids.isEmpty()) {
|
|
|
return new LotteryRecord[0];
|
|
|
}
|
|
|
List<LotteryRecord> rec = lotteryRecordMapper.selectByIds(ids, shardFactor);
|
|
|
return rec.toArray(new LotteryRecord[rec.size()]);
|
|
|
}
|
|
|
|
|
|
private void givePrize(Integer userId, String orderCode, Prize prize) {
|
|
|
logger.info("用户{}的订单{}抽到奖项{},进行发奖!", userId, orderCode, prize);
|
...
|
...
|
@@ -246,7 +291,7 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
record.setPrizeId(prizeId);
|
|
|
record.setStatus((byte) 0);
|
|
|
record.setModTime((int) (System.currentTimeMillis() / 1000));
|
|
|
lotteryRecordMapper.insert(record, lotteryId % 10);
|
|
|
lotteryRecordMapper.insert(record, userId % 10);
|
|
|
|
|
|
LotteryRespData state = new LotteryRespData();
|
|
|
if (prizeId == null) {
|
...
|
...
|
@@ -365,6 +410,10 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
|
|
|
return goodsVoList;
|
|
|
}
|
|
|
|
|
|
public boolean hasRealPrize(Prize prize) {
|
|
|
return prize != null && !StringUtils.equals("nothing", prize.getPrizeType());
|
|
|
}
|
|
|
|
|
|
private void checkLottery(Integer lotteryId, Lottery lottery) {
|
|
|
if (lottery == null) {
|
...
|
...
|
@@ -373,37 +422,6 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
}
|
|
|
}
|
|
|
|
|
|
private void clearUnuseProp(Lottery lottery, List<Prize> prize) {
|
|
|
|
|
|
if (lottery != null) {
|
|
|
lottery.setUserLimit(null);
|
|
|
lottery.setPersonTotal(null);
|
|
|
lottery.setLimitByFlag(null);
|
|
|
lottery.setProbability(null);
|
|
|
lottery.setPid(null);
|
|
|
}
|
|
|
|
|
|
for (Iterator<Prize> iterator = prize.iterator(); iterator.hasNext();) {
|
|
|
Prize p = iterator.next();
|
|
|
if (!hasRealPrize(p)) {
|
|
|
iterator.remove();
|
|
|
} else {
|
|
|
clearPrize(p);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private boolean hasRealPrize(Prize prize) {
|
|
|
return !StringUtils.equals("nothing", prize.getPrizeType());
|
|
|
}
|
|
|
|
|
|
private void clearPrize(Prize p) {
|
|
|
p.setId(null);
|
|
|
p.setGiftId(null);
|
|
|
p.setPrizeType(null);
|
|
|
p.setTotal(null);
|
|
|
}
|
|
|
|
|
|
private Integer selectOne(Map<Integer, Integer> remainMap) {
|
|
|
int count = 0;
|
|
|
for (Map.Entry<Integer, Integer> entry : remainMap.entrySet()) {
|
...
|
...
|
@@ -425,4 +443,9 @@ public class LotteryServiceImpl implements ILotteryService { |
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
|
|
lotteryService = (ILotteryService) applicationContext.getBean("lotteryServiceImpl");
|
|
|
}
|
|
|
} |
...
|
...
|
|