bravo-super
This commit is contained in:
@@ -10,6 +10,7 @@ import com.accompany.business.service.mq.RocketMQService;
|
||||
import com.accompany.common.constant.Constant;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import com.accompany.common.status.BusiStatus;
|
||||
import com.accompany.common.utils.RandomUtil;
|
||||
import com.accompany.core.exception.ServiceException;
|
||||
import com.accompany.core.model.Room;
|
||||
import com.accompany.core.service.SysConfService;
|
||||
@@ -20,6 +21,7 @@ import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -53,14 +55,20 @@ public class BravoGiftSendService {
|
||||
private JedisService jedisService;
|
||||
|
||||
private final BigDecimal divisor = new BigDecimal("125");
|
||||
private final BigDecimal oneThousand = new BigDecimal("1000");
|
||||
private final BigDecimal fiveHundred = new BigDecimal("500");
|
||||
|
||||
public void draw(long senderUid, Integer partitionId, Room room, List<Long> receiverList,
|
||||
Gift gift, int everyGiftNum, Date sendGiftTime) {
|
||||
|
||||
BigDecimal everyoneGoldNum = BigDecimal.valueOf(everyGiftNum).multiply(BigDecimal.valueOf(gift.getGoldPrice()));
|
||||
BigDecimal everyGiftNumB = BigDecimal.valueOf(everyGiftNum);
|
||||
BigDecimal everyoneGoldNum = everyGiftNumB.multiply(BigDecimal.valueOf(gift.getGoldPrice()));
|
||||
int multiple = everyoneGoldNum.divide(divisor, 0, RoundingMode.DOWN).intValue();
|
||||
int multipleGiftNum = multiple * everyGiftNum;
|
||||
|
||||
BigDecimal userNum = BigDecimal.valueOf(receiverList.size());
|
||||
long totalTimes = everyGiftNumB.multiply(userNum).longValue();
|
||||
long totalInput = userNum.multiply(everyGiftNumB).longValue();
|
||||
|
||||
BravoGiftConfig config = getConfig();
|
||||
BravoGiftConfig partitionConfig = config.getRatioByPartitionId(partitionId);
|
||||
SuperLuckyGiftIncomeAllot incomeAllot = incomeAllotService.calculate(partitionConfig, gift, everyGiftNum, receiverList);
|
||||
@@ -70,19 +78,57 @@ public class BravoGiftSendService {
|
||||
log.info("[brave] uid {}, partitionId {}, addStockGoldNum {}, afterStock {}",
|
||||
senderUid, partitionId, incomeAllot.getRemainValue(), afterStock);
|
||||
|
||||
Map<Long, BravoRecord> recordMap = draw(config, senderUid, partitionId, gift, everyGiftNum, everyoneGoldNum, divisor, multipleGiftNum, receiverList, room, sendGiftTime);
|
||||
int userTicketNum = userMetaService.updateUserMetaBefore(senderUid, totalTimes, totalInput);
|
||||
|
||||
Map<Long, BravoRecord> recordMap = draw(config, senderUid, partitionId, gift, everyGiftNum, everyoneGoldNum,
|
||||
divisor, multiple, multipleGiftNum, userTicketNum, receiverList, room, sendGiftTime);
|
||||
log.info("[brave] uid {}, totalWinGoldNum {}", senderUid, JSON.toJSONString(recordMap));
|
||||
|
||||
sendMq(recordMap);
|
||||
}
|
||||
|
||||
public Map<Long, BravoRecord> draw(BravoGiftConfig config, Long senderUid, int partitionId,
|
||||
Gift gift, int everyGiftNum, BigDecimal totalInput, BigDecimal divisor, int multipleGiftNum,
|
||||
List<Long> receiverList, Room room, Date sendGiftTime) {
|
||||
Gift gift, int everyGiftNum, BigDecimal everyInput, BigDecimal divisor, int multiple, int multipleGiftNum,
|
||||
int userTicketNum, List<Long> receiverList, Room room, Date sendGiftTime) {
|
||||
|
||||
if (multipleGiftNum > 1 && userTicketNum > 1){
|
||||
int needTicketNum = multipleGiftNum == 2? 1 : multipleGiftNum == 4 ? 2 : 8;
|
||||
int superNum = Math.min(userTicketNum / needTicketNum, receiverList.size());
|
||||
if (superNum < 1){
|
||||
return drawMultiple(config, senderUid, partitionId, gift, everyGiftNum, everyInput, divisor, multipleGiftNum, receiverList, room, sendGiftTime);
|
||||
}
|
||||
int superTicketNum = needTicketNum * superNum;
|
||||
int subSuperNum = userMetaService.subSuperNum(senderUid, needTicketNum, superNum, superTicketNum);
|
||||
if (subSuperNum < 1){
|
||||
return drawMultiple(config, senderUid, partitionId, gift, everyGiftNum, everyInput, divisor, multipleGiftNum, receiverList, room, sendGiftTime);
|
||||
}
|
||||
superNum = subSuperNum;
|
||||
List<Long> superGrilList = receiverList.subList(0, superNum);
|
||||
receiverList.removeAll(superGrilList);
|
||||
if (CollectionUtils.isEmpty(receiverList)){
|
||||
return drawSuper(config, senderUid, partitionId, gift, everyGiftNum, everyInput, multiple, superGrilList, room, sendGiftTime);
|
||||
}
|
||||
|
||||
Map<Long, BravoRecord> recordMap = new HashMap<>();
|
||||
recordMap.putAll(drawSuper(config, senderUid, partitionId, gift, everyGiftNum, everyInput, multiple, superGrilList, room, sendGiftTime));
|
||||
recordMap.putAll(drawMultiple(config, senderUid, partitionId, gift, everyGiftNum, everyInput, divisor, multipleGiftNum, receiverList, room, sendGiftTime));
|
||||
return recordMap;
|
||||
}
|
||||
return drawMultiple(config, senderUid, partitionId, gift, everyGiftNum, everyInput, divisor, multipleGiftNum, receiverList, room, sendGiftTime);
|
||||
}
|
||||
|
||||
private Map<Long, BravoRecord> drawSuper(BravoGiftConfig config, Long senderUid, int partitionId, Gift gift, int giftNum,
|
||||
BigDecimal everyInput, int multiple, List<Long> superGrilList, Room room, Date sendGiftTime) {
|
||||
return superGrilList.parallelStream()
|
||||
.collect(Collectors.toMap(receiverUid-> receiverUid,
|
||||
receiverUid-> drawSuper(config, senderUid, partitionId, gift, giftNum, receiverUid, everyInput, divisor, multiple, room, sendGiftTime)));
|
||||
}
|
||||
|
||||
private Map<Long, BravoRecord> drawMultiple(BravoGiftConfig config, Long senderUid, int partitionId, Gift gift, int everyGiftNum, BigDecimal everyInput, BigDecimal divisor, int multipleGiftNum, List<Long> receiverList, Room room, Date sendGiftTime){
|
||||
return receiverList.parallelStream()
|
||||
.collect(Collectors.toMap(receiverUid-> receiverUid,
|
||||
receiverUid-> drawMultiple(config, senderUid, partitionId, gift, everyGiftNum,
|
||||
receiverUid, totalInput, divisor, multipleGiftNum, room, sendGiftTime)));
|
||||
receiverUid, everyInput, divisor, multipleGiftNum, room, sendGiftTime)));
|
||||
}
|
||||
|
||||
private void sendMq(Map<Long, BravoRecord> recordMap) {
|
||||
@@ -119,12 +165,52 @@ public class BravoGiftSendService {
|
||||
rocketMQService.sendBatchBravoMessage(messageList);
|
||||
}
|
||||
|
||||
public BravoRecord drawSuper(BravoGiftConfig config, long senderUid, int partitionId, Gift gift, int giftNum, long receiverUid, BigDecimal everyInput,
|
||||
BigDecimal divisor, int multiple, Room room, Date sendGiftTime) {
|
||||
BravoResult drawResult = new BravoResult();
|
||||
drawResult.setInput(everyInput);
|
||||
drawResult.setOutput(BigDecimal.ZERO);
|
||||
int random = RandomUtil.randomByRange(0, 10);
|
||||
if (random < 3){
|
||||
BigDecimal superMultiple = multiple >= 8? oneThousand: fiveHundred;
|
||||
BigDecimal output = everyInput.multiply(superMultiple);
|
||||
drawResult.setOutput(output);
|
||||
log.info("[bravo] super yes, uid {} receiver {} random {} multiple {} superMultiple {} output {} ",
|
||||
senderUid, receiverUid, random, multiple, superMultiple, output);
|
||||
}
|
||||
return updateMeta(config, senderUid, partitionId, gift, giftNum, receiverUid, everyInput, divisor, room, sendGiftTime, drawResult);
|
||||
}
|
||||
|
||||
public BravoRecord drawMultiple(BravoGiftConfig config, long senderUid, int partitionId,
|
||||
Gift gift, int giftNum, long receiverUid, BigDecimal totalInput, BigDecimal divisor, int multipleGiftNum, Room room, Date sendGiftTime) {
|
||||
List<BravoResult> drawResultList = poolService.drawMultipleFromPool(config, senderUid, partitionId, multipleGiftNum);
|
||||
return updateMeta(config, senderUid, partitionId, gift, giftNum, receiverUid, totalInput, divisor, room, sendGiftTime, drawResultList);
|
||||
}
|
||||
|
||||
private BravoRecord updateMeta(BravoGiftConfig config, long senderUid, int partitionId,
|
||||
Gift gift, int giftNum, long receiverUid, BigDecimal totalInput, BigDecimal divisor, Room room, Date sendGiftTime,
|
||||
BravoResult drawResult){
|
||||
BigDecimal afterMultiple = drawResult.getOutput();
|
||||
// 平台库存
|
||||
if (afterMultiple.compareTo(BigDecimal.ZERO) > 0L){
|
||||
BigDecimal preWinGoldNum = afterMultiple.multiply(divisor);
|
||||
if (!judgeStock(partitionId, preWinGoldNum, senderUid, receiverUid)){
|
||||
afterMultiple = BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
drawResult.setAfterOutput(afterMultiple);
|
||||
|
||||
BigDecimal winGoldNum = afterMultiple.multiply(divisor);
|
||||
userMetaService.updateUserMetaAfter(senderUid, totalInput, winGoldNum);
|
||||
|
||||
if (winGoldNum.compareTo(BigDecimal.ZERO) > 0){
|
||||
settlementService.syncSendReward(config, senderUid, room, gift, winGoldNum, afterMultiple);
|
||||
}
|
||||
|
||||
return recordService.buildRecord(senderUid, partitionId, gift, giftNum, null != room? room.getUid(): null,
|
||||
receiverUid,false, afterMultiple, winGoldNum, sendGiftTime);
|
||||
}
|
||||
|
||||
private BravoRecord updateMeta(BravoGiftConfig config, long senderUid, int partitionId,
|
||||
Gift gift, int giftNum, long receiverUid, BigDecimal totalInput, BigDecimal divisor, Room room, Date sendGiftTime,
|
||||
List<BravoResult> drawResultList){
|
||||
@@ -142,7 +228,7 @@ public class BravoGiftSendService {
|
||||
|
||||
BigDecimal multiple = drawResultList.stream().map(BravoResult::getAfterOutput).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal winGoldNum = multiple.multiply(divisor);
|
||||
userMetaService.updateUserMeta(senderUid, totalInput, winGoldNum);
|
||||
userMetaService.updateUserMetaAfter(senderUid, totalInput, winGoldNum);
|
||||
|
||||
if (winGoldNum.compareTo(BigDecimal.ZERO) > 0){
|
||||
settlementService.syncSendReward(config, senderUid, room, gift, winGoldNum, multiple);
|
||||
|
@@ -36,6 +36,24 @@ public class BravoRecordService extends ServiceImpl<BravoRecordMapper, BravoReco
|
||||
@Resource(name = "bizExecutor")
|
||||
private ThreadPoolExecutor bizExecutor;
|
||||
|
||||
public BravoRecord buildRecord(long senderUid, int partitionId, Gift gift, int giftNum, Long roomUid, long receiverUid,
|
||||
boolean isSupplement, BigDecimal afterMultiple, BigDecimal winGoldNum, Date sendGiftTime) {
|
||||
BravoRecord record = new BravoRecord();
|
||||
record.setUid(senderUid);
|
||||
record.setPartitionId(partitionId);
|
||||
record.setReceiverUid(receiverUid);
|
||||
record.setRoomUid(roomUid);
|
||||
record.setGiftId(gift.getGiftId());
|
||||
record.setGiftNum(giftNum);
|
||||
record.setGiftGoldPrice(gift.getGoldPrice());
|
||||
record.setResultGroupByPool(null);
|
||||
record.setIsSupplement(isSupplement);
|
||||
record.setAfterMultiple(afterMultiple);
|
||||
record.setWinGoldNum(winGoldNum);
|
||||
record.setCreateTime(sendGiftTime);
|
||||
return record;
|
||||
}
|
||||
|
||||
public BravoRecord buildRecord(long senderUid, int partitionId, Gift gift, int giftNum, Long roomUid, long receiverUid, List<BravoResult> resultList,
|
||||
boolean isSupplement, BigDecimal afterMultiple, BigDecimal winGoldNum, Date sendGiftTime) {
|
||||
BravoRecord record = new BravoRecord();
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package com.accompany.business.service.lucky;
|
||||
|
||||
import com.accompany.business.dto.lucky.BravoResult;
|
||||
import com.accompany.business.dto.lucky.Lucky24Result;
|
||||
import com.accompany.common.redis.RedisKey;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RList;
|
||||
@@ -23,8 +22,10 @@ public class BravoUserMetaService {
|
||||
private static final String TIMES_KEY = "times";
|
||||
public static final String INPUT_KEY = "input";
|
||||
public static final String OUTPUT_KEY = "output";
|
||||
public static final String TICKET_NUM_KEY = "ticket_num";
|
||||
|
||||
private static final int HISTORY_QUEUE_SIZE = 2000;
|
||||
private static final long TICKET_PRICE = 2000000L;
|
||||
|
||||
@Autowired
|
||||
private RedissonClient redissonClient;
|
||||
@@ -60,18 +61,37 @@ public class BravoUserMetaService {
|
||||
return productionRatio;
|
||||
}
|
||||
|
||||
public void updateUserMeta(long senderUid, BigDecimal input, BigDecimal output) {
|
||||
public int updateUserMetaBefore(long senderUid, long num, long input) {
|
||||
RMap<String, Number> userMetaMap = getUserMeta(senderUid);
|
||||
long times = userMetaMap.addAndGet(TIMES_KEY, num).longValue();
|
||||
long totalInputAfter = userMetaMap.addAndGet(INPUT_KEY, input).longValue();
|
||||
long totalInputBefore = totalInputAfter - input;
|
||||
|
||||
long addTicketNum = 0L;
|
||||
int remainTicketNum = 0;
|
||||
long ticketNumAfter = totalInputAfter / TICKET_PRICE;
|
||||
long tickerNumBefore = totalInputBefore / TICKET_PRICE;
|
||||
if (ticketNumAfter > tickerNumBefore) {
|
||||
addTicketNum = ticketNumAfter - tickerNumBefore;
|
||||
remainTicketNum = userMetaMap.addAndGet(TICKET_NUM_KEY, addTicketNum).intValue();
|
||||
}
|
||||
|
||||
log.info("[bravo] updateUserMetaBefore uid {} times {} totalInput {} addTicketNum {} remainTicketNum {}",
|
||||
senderUid, times, totalInputAfter, addTicketNum, remainTicketNum);
|
||||
|
||||
return remainTicketNum;
|
||||
}
|
||||
|
||||
public void updateUserMetaAfter(long senderUid, BigDecimal input, BigDecimal output) {
|
||||
RList<BravoResult> historyQueue = getUserHistoryQueue(senderUid);
|
||||
historyQueue.add(0, new BravoResult(null, input, output, null, null));
|
||||
historyQueue.expireAsync(Duration.of(14, ChronoUnit.DAYS));
|
||||
|
||||
RMap<String, Number> userMetaMap = getUserMeta(senderUid);
|
||||
long times = userMetaMap.addAndGet(TIMES_KEY, 1L).longValue();
|
||||
long totalInput = userMetaMap.addAndGet(INPUT_KEY, input).longValue();
|
||||
long totalOutput = userMetaMap.addAndGet(OUTPUT_KEY, output).longValue();
|
||||
|
||||
log.info("[bravo] updateUserMeta uid {} times {} totalInput {} totalOutput {}",
|
||||
senderUid, times, totalInput, totalOutput);
|
||||
log.info("[bravo] updateUserMetaAfter uid {} totalOutput {}",
|
||||
senderUid, totalOutput);
|
||||
}
|
||||
|
||||
public RMap<String, Number> getUserMeta(Long uid) {
|
||||
@@ -82,4 +102,24 @@ public class BravoUserMetaService {
|
||||
return redissonClient.getList(RedisKey.bravo_user_history.getKey(uid.toString()));
|
||||
}
|
||||
|
||||
public int subSuperNum(long uid, int needTicketNum, int superNum, int superTicketNum) {
|
||||
RMap<String, Number> userMetaMap = getUserMeta(uid);
|
||||
int afterNum = userMetaMap.addAndGet(TICKET_NUM_KEY, -superTicketNum).intValue();
|
||||
if (afterNum >= 0){
|
||||
return superNum;
|
||||
}
|
||||
for (int i = superNum - 1; i > 0; i--) {
|
||||
afterNum += needTicketNum;
|
||||
if (afterNum >= 0){
|
||||
int returnNum = superNum - i;
|
||||
int returnTicketNum = returnNum * needTicketNum;
|
||||
int userTicketNumAfterReturn = userMetaMap.addAndGet(TICKET_NUM_KEY, returnTicketNum).intValue();
|
||||
log.info("[bravo] subTicketNum uid {} not enough ticket num, return {} {} after {}", uid, returnNum, returnTicketNum, userTicketNumAfterReturn);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
int userTicketNumAfterReturn = userMetaMap.addAndGet(TICKET_NUM_KEY, superTicketNum).intValue();
|
||||
log.info("[bravo] subTicketNum uid {} not enough ticket num, return all {} after {}", uid, superTicketNum, userTicketNumAfterReturn);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user