记得上下班打卡 | git大法好,push需谨慎

Commit c7f82a22 authored by 胡佳晨's avatar 胡佳晨

Merge branch 'hjc_bug_mix_order' into hjc_bug_mix_now_order

parents 65cb2b38 7ebd6a12
...@@ -485,12 +485,22 @@ public class GoblinOrderServiceImpl implements IGoblinOrderService { ...@@ -485,12 +485,22 @@ public class GoblinOrderServiceImpl implements IGoblinOrderService {
payInnerResultVo.setPrice(BigDecimal.valueOf(0)); payInnerResultVo.setPrice(BigDecimal.valueOf(0));
payInnerResultVo.setPayType(preParam.getPayType()); payInnerResultVo.setPayType(preParam.getPayType());
} else if (preParam.getPayType().equals("huifu")) { } else if (preParam.getPayType().equals("huifu")) {
isFree = true; // isFree = true;
preParam.setPayType("huifu"); // preParam.setPayType("huifu");
payCode = "HUIFU_PAY_CODE"; // payCode = "HUIFU_PAY_CODE";
// payInnerResultVo = GoblinPayInnerResultVo.getNew();
// payInnerResultVo.setPrice(preParam.getPriceActual());
// payInnerResultVo.setPayType(preParam.getPayType());
payInnerResultVo = GoblinPayInnerResultVo.getNew(); payInnerResultVo = GoblinPayInnerResultVo.getNew();
payInnerResultVo.setPrice(preParam.getPriceActual()); payInnerResultVo.setCode("HUIFU_PAY_CODE");
payInnerResultVo.setOrderCode(preParam.getOrderMasterCode());
payInnerResultVo.setPayData(null);
payInnerResultVo.setPayType(preParam.getPayType()); payInnerResultVo.setPayType(preParam.getPayType());
payInnerResultVo.setPrice(preParam.getPriceActual());
payInnerResultVo.setMsg("汇付支付");
payCode = payInnerResultVo.getCode();
payInnerResultVo.setShowUrl(preParam.getShowUrl());
payInnerResultVo.setReturnUrl(preParam.getReturnUrl());
} else { } else {
isFree = true; isFree = true;
preParam.setPayType("FREE"); preParam.setPayType("FREE");
......
...@@ -129,7 +129,7 @@ public class MixOrderServiceImpl implements IMixOrderService { ...@@ -129,7 +129,7 @@ public class MixOrderServiceImpl implements IMixOrderService {
initStock(canBuyIds, mixId, isUseLimit, uid); initStock(canBuyIds, mixId, isUseLimit, uid);
return ResponseDto.failure("该商品SPU不存在~"); return ResponseDto.failure("该商品SPU不存在~");
} else { } else {
GoblinGoodsSkuInfoVo boxSkuInfo = nftOrderUtils.lotteryDraw(skuIdList, itemVo.getCount(), nt, mixId); GoblinGoodsSkuInfoVo boxSkuInfo = nftOrderUtils.lotteryDrawUnStatus(skuIdList, itemVo.getCount(), nt, mixId);
if (null == boxSkuInfo) { if (null == boxSkuInfo) {
return ResponseDto.failure("库存不足啦~"); return ResponseDto.failure("库存不足啦~");
} else { } else {
......
...@@ -488,6 +488,37 @@ public class GoblinNftOrderUtils { ...@@ -488,6 +488,37 @@ public class GoblinNftOrderUtils {
} }
} }
// 获取盲盒下藏品的库存 各种状态下不能算库存的排除掉 不考虑状态
public int getSkuAllStatusStockUnStatus(String listId, GoblinGoodsSkuInfoVo info) {
if (
info != null
&& (null == info.getHitRatio() || info.getHitRatio().compareTo(BigDecimal.ZERO) > 0)
) {// 可以返回库存
// 外面只有盲盒才能请求进来 里面只有不是分批购才判断盲盒里藏品的开售时间
if (null == listId) {
return goblinRedisUtils.getSkuStock(listId, info.getSkuId());
} else {
return goblinRedisUtils.getSkuStock(listId, info.getSkuId());
}
} else {// 不计入库存
return 0;
}
}
//不考虑状态
public boolean getSkuAllStatusShowUnStatus(GoblinGoodsSkuInfoVo info) {
if (
info != null
&& info.getSkuType() == 1
&& info.getDelFlg().equals("0")
&& ((info.getUnbox().equals("0") && info.getUpchain() == 1) || info.getUnbox().equals("1"))
) {
return true;
} else {
return false;
}
}
public GoblinGoodsSkuInfoVo lotteryDraw(List<String> skuIdList, int number, LocalDateTime nowTime, String listId) { public GoblinGoodsSkuInfoVo lotteryDraw(List<String> skuIdList, int number, LocalDateTime nowTime, String listId) {
// private HashMap<String, Object> lotteryDraw(List<String> skuIdList, int number, LocalDateTime nowTime) { // private HashMap<String, Object> lotteryDraw(List<String> skuIdList, int number, LocalDateTime nowTime) {
try { try {
...@@ -578,7 +609,112 @@ public class GoblinNftOrderUtils { ...@@ -578,7 +609,112 @@ public class GoblinNftOrderUtils {
// String endListId = newListIds.get(index); // String endListId = newListIds.get(index);
// 判断库存 // 判断库存
int surplusGeneral = goblinRedisUtils.decrSkuStock(listId, goodsSkuInfoVo.getSkuId(), number); int surplusGeneral = goblinRedisUtils.decrSkuStock(listId, goodsSkuInfoVo.getSkuId(), number);
log.error("剩余 skuId = "+surplusGeneral); log.error("剩余 skuId = " + surplusGeneral);
if (surplusGeneral < 0) {
goblinRedisUtils.incrSkuStock(listId, goodsSkuInfoVo.getSkuId(), number);
return lotteryDraw(skuIdList, number, nowTime, listId);
} else {
// HashMap<String, Object> map = CollectionUtil.mapStringObject();
// map.put("goodsSkuInfoVo", goodsSkuInfoVo);
// map.put("listId", endListId);
// return map;
return goodsSkuInfoVo;
}
}
} catch (Exception e) {
log.error("NFT下单-抽盲盒异常", e);
return null;
}
}
// 不判断状态
public GoblinGoodsSkuInfoVo lotteryDrawUnStatus(List<String> skuIdList, int number, LocalDateTime nowTime, String listId) {
try {
ArrayList<GoblinGoodsSkuInfoVo> skuInfoVos = ObjectUtil.cloneArrayGoblinGoodsSkuInfoListVo();
for (String kid : skuIdList) {
HashMap<String, Object> map = goblinRedisUtils.getGoodsSkuInfoVo(nowTime, kid);
GoblinGoodsSkuInfoVo skuInfoVo = (GoblinGoodsSkuInfoVo) map.get("vo");
// 是盲盒的扔掉
if (skuInfoVo.getUnbox().equals("1")) {
continue;
}
// 不能购买的 没库存的 概率是0的 过滤
if (getSkuAllStatusShowUnStatus(skuInfoVo) && getSkuAllStatusStockUnStatus(listId, skuInfoVo) > 0) {
skuInfoVos.add(skuInfoVo);
}
}
if (CollectionUtil.isEmpty(skuInfoVos)) {
return null;
} else {
// 计算总概率 和 剩余没填概率的平均概率
int size = 0;
BigDecimal sumHitRatio = BigDecimal.ZERO;
for (GoblinGoodsSkuInfoVo skuInfoVo : skuInfoVos) {
if (null == skuInfoVo.getHitRatio()) {
size++;
} else {
sumHitRatio = sumHitRatio.add(skuInfoVo.getHitRatio());
}
}
/**
* 剔除掉没库存的商品再去算未设置概率商品的平均概率 会导致未设置概率的商品的概率增加
* 如果不剔除掉没库存的商品去算未设置概率商品的平均概率 会导致总概率小于100 如果随机数还是0-100的话就有可能会中奖溢出
* 想保持概率 1.不剔除无库存商品算平均概率 2.随机数最大值为排序后概率的最后一个值
*/
BigDecimal avgHitRatio = BigDecimal.ZERO;
if (size > 0) {// 说明有未设置抽奖概率的
avgHitRatio = new BigDecimal(100).subtract(sumHitRatio).divide(new BigDecimal(size), 2, RoundingMode.HALF_UP);
}
// 未设置概率的写入概率
ArrayList<GoblinGoodsSkuInfoVo> newSkuInfoVos = ObjectUtil.cloneArrayGoblinGoodsSkuInfoListVo();
// ArrayList<String> newListIds = ObjectUtil.cloneArrayListString();
int skuListSize = skuInfoVos.size();
for (int i = 0; i < skuListSize; i++) {
GoblinGoodsSkuInfoVo infoVo = skuInfoVos.get(i);
if (null == infoVo.getHitRatio() || infoVo.getHitRatio().compareTo(BigDecimal.ZERO) < 0) {
/**
* 算所得平均概率是0 即中不了 剔除掉
* 但是这么处理会导致前端页面显示有库存 买的时候显示没有
* 所以要么概率加起来必须100 要么前端计算盲盒总概率的时候也要同样处理
*/
if (avgHitRatio.compareTo(BigDecimal.ZERO) <= 0) {
continue;
} else {
infoVo.setHitRatio(avgHitRatio);
}
}
// 等于0的最终概率就是设置的值 大于0最终的概率是自己的+上面的
if (i > 0) {
infoVo.setHitRatio(skuInfoVos.get(i - 1).getHitRatio().add(infoVo.getHitRatio()));
}
newSkuInfoVos.add(infoVo);
// newListIds.add(listIds.get(i));
}
if (CollectionUtil.isEmpty(newSkuInfoVos)) {
log.info("该盲盒概率超过100导致不能卖 skuIdList:{}", skuIdList);
return null;
}
// 按照概率排序 按照上面的运算最后一定是最大的不用排序了
// List<GoblinGoodsSkuInfoVo> listSort = newSkuInfoVos.stream().sorted(Comparator.comparing(GoblinGoodsSkuInfoVo::getHitRatio)).collect(Collectors.toList());
List<BigDecimal> hitRatioList = newSkuInfoVos.stream().map(GoblinGoodsSkuInfoVo::getHitRatio).collect(Collectors.toList());
// 根据区块值来获取抽取到的物品索引
double nextDouble = Math.random();
BigDecimal nextDoubleNew = BigDecimal.valueOf(nextDouble);
nextDoubleNew = nextDoubleNew.multiply(hitRatioList.get(hitRatioList.size() - 1)).setScale(4, RoundingMode.HALF_UP);
hitRatioList.add(nextDoubleNew);
Collections.sort(hitRatioList);
int index = hitRatioList.indexOf(nextDoubleNew);
GoblinGoodsSkuInfoVo goodsSkuInfoVo = newSkuInfoVos.get(index);
// String endListId = newListIds.get(index);
// 判断库存
int surplusGeneral = goblinRedisUtils.decrSkuStock(listId, goodsSkuInfoVo.getSkuId(), number);
log.error("剩余 skuId = " + surplusGeneral);
if (surplusGeneral < 0) { if (surplusGeneral < 0) {
goblinRedisUtils.incrSkuStock(listId, goodsSkuInfoVo.getSkuId(), number); goblinRedisUtils.incrSkuStock(listId, goodsSkuInfoVo.getSkuId(), number);
return lotteryDraw(skuIdList, number, nowTime, listId); return lotteryDraw(skuIdList, number, nowTime, listId);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment