Commit a0601766 authored by shiyu's avatar shiyu

藏家订单加锁避免重复创建订单

parent 9a04e972
...@@ -384,138 +384,146 @@ public class DistributionOrderServiceImpl implements DistributionOrderService { ...@@ -384,138 +384,146 @@ public class DistributionOrderServiceImpl implements DistributionOrderService {
@Override @Override
@Transactional @Transactional
public Result createCollectionOrder(DistributionOrderRequestDto dto) { public Result createCollectionOrder(DistributionOrderRequestDto dto) {
Long itemId = dto.getItemId();
String itemIdKey = "COLLECTION:ORDER:CREATE:" + dto.getItemId();
RLock lock = redissonClient.getLock(itemIdKey);
try { try {
Long itemId = dto.getItemId(); if (lock.tryLock(3, 3, TimeUnit.SECONDS)) {
String shareRecordId = dto.getShareRecordId(); String shareRecordId = dto.getShareRecordId();
if (StringUtils.hasLength(shareRecordId)) { if (StringUtils.hasLength(shareRecordId)) {
//查询分享记录详细信息 //查询分享记录详细信息
CollectionShareRecord collectionShareRecord = collectionShareRecordDao.findById(shareRecordId); CollectionShareRecord collectionShareRecord = collectionShareRecordDao.findById(shareRecordId);
if (collectionShareRecord == null || collectionShareRecord.getType() == DistributionEnum.CollectionShareTypeEnum.PAGE.getCode()) { if (collectionShareRecord == null || collectionShareRecord.getType() == DistributionEnum.CollectionShareTypeEnum.PAGE.getCode()) {
return Result.failed("该分享链接无效"); return Result.failed("该分享链接无效");
}
if (collectionShareRecord.getIsDeleted()) {
return Result.failed("该分享链接已失效");
}
itemId = collectionShareRecord.getShareTargetId();
} }
if (collectionShareRecord.getIsDeleted()) { //查询商品信息,检查商品库存
return Result.failed("该分享链接已失效"); SupplierItem supplierItem = supplierItemDao.findById(itemId);
int stock = supplierItem.getStock();
if (stock <= 0) {
return Result.failed("商品库存不足");
}
//商品限购数量
if (dto.getItemNum() > stock) {
return Result.failed("超出库存");
}
//商品限购数量
int buyLimitNum = supplierItem.getBuyLimitNum() == -1 ? 9999999 : supplierItem.getBuyLimitNum();
//检查该购买者是否超出限购数量
//1.查询购买者对该商品的历史购买记录
List<DistributionOrder> distributionOrders = distributionOrderDao.findValidOrderOfItemIdByBuyerId(dto.getBuyerId(), itemId);
int buyNum = 0;
if (!CollectionUtils.isEmpty(distributionOrders)) {
buyNum = distributionOrders.stream().mapToInt(DistributionOrder::getItemNum).sum();
}
if (buyNum + dto.getItemNum() > buyLimitNum) {
return Result.failed("超出购买上限" + buyLimitNum + "件");
} }
itemId = collectionShareRecord.getShareTargetId();
}
//查询商品信息,检查商品库存
SupplierItem supplierItem = supplierItemDao.findById(itemId);
int stock = supplierItem.getStock();
if (stock <= 0) {
return Result.failed("商品库存不足");
}
//商品限购数量
if (dto.getItemNum() > stock) {
return Result.failed("超出库存");
}
//商品限购数量
int buyLimitNum = supplierItem.getBuyLimitNum() == -1 ? 9999999 : supplierItem.getBuyLimitNum();
//检查该购买者是否超出限购数量
//1.查询购买者对该商品的历史购买记录
List<DistributionOrder> distributionOrders = distributionOrderDao.findValidOrderOfItemIdByBuyerId(dto.getBuyerId(), itemId);
int buyNum = 0;
if (!CollectionUtils.isEmpty(distributionOrders)) {
buyNum = distributionOrders.stream().mapToInt(DistributionOrder::getItemNum).sum();
}
if (buyNum + dto.getItemNum() > buyLimitNum) {
return Result.failed("超出购买上限" + buyLimitNum + "件");
}
String distributionOrderId = IdUtils.getOrderNumber(DISTRIBUTION_ORDER_PREFIX);
DistributionOrderRequestDto prePayDto = new DistributionOrderRequestDto();
prePayDto.setDistributionOrderId(distributionOrderId);
prePayDto.setAmount(String.valueOf(supplierItem.getDistributionPrice() * dto.getItemNum()));
prePayDto.setBuyerOpenid(dto.getBuyerOpenid());
prePayDto.setItemName(supplierItem.getName());
Result prePayResult = wxPayServiceApi.createPrepareOrder(prePayDto);
if (!prePayResult.getSuccess()) {
return Result.failed("购买藏品预下单失败");
}
String prepayId = (String) prePayResult.getData();
//查询该用户介绍人
long introducerId;
IntroduceRecord introduceRecord = introduceRecordDao.findByUserId(dto.getBuyerId());
if (introduceRecord == null) {
introducerId = CommConsts.SYSTEM_ACCOUNT;
IntroduceRecord newRecord = new IntroduceRecord();
newRecord.setUserId(dto.getBuyerId());
newRecord.setIntroducerId(introducerId);
newRecord.setShareRecordId(CommConsts.DEFAULT_SHARE_ID);
newRecord.setCreateTime(new Date());
introduceRecordDao.insert(newRecord);
} else {
introducerId = introduceRecord.getIntroducerId();
}
//查询佣金比例
double rebate = distributorProfitService.getIntroduceRebate(dto.getBuyerId(), introducerId);
DistributionOrder distributionOrder = new DistributionOrder(); String distributionOrderId = IdUtils.getOrderNumber(DISTRIBUTION_ORDER_PREFIX);
distributionOrder.setIntroduceRebate(BigDecimal.valueOf(rebate)); DistributionOrderRequestDto prePayDto = new DistributionOrderRequestDto();
distributionOrder.setIntroducerId(introducerId); prePayDto.setDistributionOrderId(distributionOrderId);
distributionOrder.setItemId(itemId); prePayDto.setAmount(String.valueOf(supplierItem.getDistributionPrice() * dto.getItemNum()));
distributionOrder.setItemNum(dto.getItemNum()); prePayDto.setBuyerOpenid(dto.getBuyerOpenid());
distributionOrder.setShareRecordId(String.valueOf(introducerId));
distributionOrder.setDistributionOrderId(distributionOrderId); prePayDto.setItemName(supplierItem.getName());
distributionOrder.setPrepayId(prepayId); Result prePayResult = wxPayServiceApi.createPrepareOrder(prePayDto);
distributionOrder.setBuyerId(dto.getBuyerId()); if (!prePayResult.getSuccess()) {
distributionOrder.setBuyerOpenid(dto.getBuyerOpenid()); return Result.failed("购买藏品预下单失败");
distributionOrder.setShopId(supplierItem.getCreatorId()); }
distributionOrder.setSellerId(supplierItem.getCreatorId()); String prepayId = (String) prePayResult.getData();
distributionOrder.setAmount(supplierItem.getDistributionPrice() * dto.getItemNum());
distributionOrder.setAddressId(dto.getAddressId());
distributionOrder.setReceiverAddress(dto.getReceiverAddress());
distributionOrder.setReceiverName(dto.getReceiverName());
distributionOrder.setReceiverPhone(dto.getReceiverPhone());
distributionOrder.setCreateTime(new Date());
distributionOrder.setUpdateTime(new Date());
distributionOrder.setType(DistributionEnum.DistributionTypeEnum.COLLECT.getCode());
distributionOrder.setState(DistributionEnum.DistributionOrderStateEnum.PRE_PAY.getCode());
distributionOrderDao.insert(distributionOrder);
Map<String, String> map = new HashMap<>();
map.put("distributionOrderId", distributionOrderId);
map.put("prepayId", prepayId);
//计算分销商的利润
DistributorProfit distributorProfit = new DistributorProfit();
//平台服务费,默认15%
CollectorWhiteList collectorWhiteList = collectorWhiteListDao.findById(supplierItem.getCreatorId());
double channelCostRebate = 0.15;
if (collectorWhiteList != null && collectorWhiteList.getChannelCostRebate() != null) {
BigDecimal channelCost = collectorWhiteList.getChannelCostRebate();
channelCost = PriceUtil.convertToDivide(channelCost);
channelCostRebate = channelCost.doubleValue();
}
logger.info("藏家id:{} 生成新订单,平台服务费比例:{}", supplierItem.getCreatorId(), channelCostRebate);
//实际订单到账金额 //查询该用户介绍人
double realAmount = distributionOrder.getAmount().doubleValue() * (1 - CommConsts.WX_COMMISSION_REBATE); long introducerId;
IntroduceRecord introduceRecord = introduceRecordDao.findByUserId(dto.getBuyerId());
if (introduceRecord == null) {
introducerId = CommConsts.SYSTEM_ACCOUNT;
IntroduceRecord newRecord = new IntroduceRecord();
newRecord.setUserId(dto.getBuyerId());
newRecord.setIntroducerId(introducerId);
newRecord.setShareRecordId(CommConsts.DEFAULT_SHARE_ID);
newRecord.setCreateTime(new Date());
introduceRecordDao.insert(newRecord);
} else {
introducerId = introduceRecord.getIntroducerId();
}
//查询佣金比例
double rebate = distributorProfitService.getIntroduceRebate(dto.getBuyerId(), introducerId);
//平台佣金还要减去微信的服务手续费1%,实际上平台佣金就是订单金额* (平台佣金比例(默认0.15)- 微信手续费(0.01)) DistributionOrder distributionOrder = new DistributionOrder();
//暂时先不考虑 distributionOrder.setIntroduceRebate(BigDecimal.valueOf(rebate));
double channelServiceCost = distributionOrder.getAmount().doubleValue() * channelCostRebate; distributionOrder.setIntroducerId(introducerId);
distributionOrder.setItemId(itemId);
distributionOrder.setItemNum(dto.getItemNum());
distributionOrder.setShareRecordId(String.valueOf(introducerId));
distributionOrder.setDistributionOrderId(distributionOrderId);
distributionOrder.setPrepayId(prepayId);
distributionOrder.setBuyerId(dto.getBuyerId());
distributionOrder.setBuyerOpenid(dto.getBuyerOpenid());
distributionOrder.setShopId(supplierItem.getCreatorId());
distributionOrder.setSellerId(supplierItem.getCreatorId());
distributionOrder.setAmount(supplierItem.getDistributionPrice() * dto.getItemNum());
distributionOrder.setAddressId(dto.getAddressId());
distributionOrder.setReceiverAddress(dto.getReceiverAddress());
distributionOrder.setReceiverName(dto.getReceiverName());
distributionOrder.setReceiverPhone(dto.getReceiverPhone());
distributionOrder.setCreateTime(new Date());
distributionOrder.setUpdateTime(new Date());
distributionOrder.setType(DistributionEnum.DistributionTypeEnum.COLLECT.getCode());
distributionOrder.setState(DistributionEnum.DistributionOrderStateEnum.PRE_PAY.getCode());
distributionOrderDao.insert(distributionOrder);
Map<String, String> map = new HashMap<>();
map.put("distributionOrderId", distributionOrderId);
map.put("prepayId", prepayId);
//计算分销商的利润
DistributorProfit distributorProfit = new DistributorProfit();
//平台服务费,默认15%
CollectorWhiteList collectorWhiteList = collectorWhiteListDao.findById(supplierItem.getCreatorId());
double channelCostRebate = 0.15;
if (collectorWhiteList != null && collectorWhiteList.getChannelCostRebate() != null) {
BigDecimal channelCost = collectorWhiteList.getChannelCostRebate();
channelCost = PriceUtil.convertToDivide(channelCost);
channelCostRebate = channelCost.doubleValue();
}
logger.info("藏家id:{} 生成新订单,平台服务费比例:{}", supplierItem.getCreatorId(), channelCostRebate);
//实际订单到账金额
double realAmount = distributionOrder.getAmount().doubleValue() * (1 - CommConsts.WX_COMMISSION_REBATE);
double introduceCost = distributionOrder.getAmount().doubleValue() * rebate; //平台佣金还要减去微信的服务手续费1%,实际上平台佣金就是订单金额* (平台佣金比例(默认0.15)- 微信手续费(0.01))
distributorProfit.setDistributionOrderId(distributionOrderId); //暂时先不考虑
distributorProfit.setDistributorId(distributionOrder.getSellerId()); double channelServiceCost = distributionOrder.getAmount().doubleValue() * channelCostRebate;
distributorProfit.setItemId(distributionOrder.getItemId()); double introduceCost = distributionOrder.getAmount().doubleValue() * rebate;
distributorProfit.setItemNum(distributionOrder.getItemNum()); distributorProfit.setDistributionOrderId(distributionOrderId);
distributorProfit.setAmount(distributionOrder.getAmount()); distributorProfit.setDistributorId(distributionOrder.getSellerId());
distributorProfit.setRealAmount(PriceUtil.convertPriceFromStr(PriceUtil.convertDoubleToString(realAmount))); distributorProfit.setItemId(distributionOrder.getItemId());
distributorProfit.setItemCost(supplierItem.getSupplyPrice()); distributorProfit.setItemNum(distributionOrder.getItemNum());
distributorProfit.setChannelCost(PriceUtil.convertPriceFromStr(PriceUtil.convertDoubleToString(channelServiceCost))); distributorProfit.setAmount(distributionOrder.getAmount());
distributorProfit.setIntroduceCost(PriceUtil.convertPriceFromStr(PriceUtil.convertDoubleToString(introduceCost))); distributorProfit.setRealAmount(PriceUtil.convertPriceFromStr(PriceUtil.convertDoubleToString(realAmount)));
long profit = distributionOrder.getAmount() - distributorProfit.getChannelCost() - distributorProfit.getIntroduceCost(); distributorProfit.setItemCost(supplierItem.getSupplyPrice());
distributorProfit.setProfit(profit); distributorProfit.setChannelCost(PriceUtil.convertPriceFromStr(PriceUtil.convertDoubleToString(channelServiceCost)));
distributorProfit.setCreateTime(new Date()); distributorProfit.setIntroduceCost(PriceUtil.convertPriceFromStr(PriceUtil.convertDoubleToString(introduceCost)));
distributorProfit.setIsValid(false); long profit = distributionOrder.getAmount() - distributorProfit.getChannelCost() - distributorProfit.getIntroduceCost();
distributorProfit.setType(DistributionEnum.DistributionTypeEnum.COLLECT.getCode()); distributorProfit.setProfit(profit);
distributorProfitDao.insert(distributorProfit); distributorProfit.setCreateTime(new Date());
return Result.success(map); distributorProfit.setIsValid(false);
distributorProfit.setType(DistributionEnum.DistributionTypeEnum.COLLECT.getCode());
distributorProfitDao.insert(distributorProfit);
return Result.success(map);
} else {
return Result.failed("请勿重复提交");
}
} catch (Exception e) { } catch (Exception e) {
logger.error("创建藏品一口价订单失败 error : {}", e); logger.error("创建藏品一口价订单失败 error : {}", e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
} finally {
if (lock != null && lock.isHeldByCurrentThread()) {
lock.unlock();
}
} }
return Result.failed("藏品一口价订单下单失败"); return Result.failed("藏品一口价订单下单失败");
} }
......
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