|
|
@ -1,26 +1,44 @@ |
|
|
package com.qniao.dam.application.service.virtualaccount; |
|
|
package com.qniao.dam.application.service.virtualaccount; |
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil; |
|
|
|
|
|
import cn.hutool.core.lang.Tuple; |
|
|
import com.qniao.dam.api.command.virtualaccount.user.request.UserConsumeVirtualAccountDto; |
|
|
import com.qniao.dam.api.command.virtualaccount.user.request.UserConsumeVirtualAccountDto; |
|
|
|
|
|
import com.qniao.dam.api.command.virtualaccount.user.request.UserCostIMGiftDto; |
|
|
|
|
|
import com.qniao.dam.api.command.virtualaccount.user.response.CostIMGiftVo; |
|
|
import com.qniao.dam.api.command.virtualaccount.user.response.UserConsumeVirtualAccountVo; |
|
|
import com.qniao.dam.api.command.virtualaccount.user.response.UserConsumeVirtualAccountVo; |
|
|
import com.qniao.dam.domain.aggregate.order.entity.Order; |
|
|
import com.qniao.dam.domain.aggregate.order.entity.Order; |
|
|
import com.qniao.dam.domain.aggregate.order.entity.OrderItem; |
|
|
import com.qniao.dam.domain.aggregate.order.entity.OrderItem; |
|
|
import com.qniao.dam.domain.aggregate.product.entity.Product; |
|
|
import com.qniao.dam.domain.aggregate.product.entity.Product; |
|
|
import com.qniao.dam.domain.aggregate.productspec.entity.ProductSpec; |
|
|
import com.qniao.dam.domain.aggregate.productspec.entity.ProductSpec; |
|
|
|
|
|
import com.qniao.dam.domain.aggregate.revenuereward.entity.RevenueReward; |
|
|
|
|
|
import com.qniao.dam.domain.aggregate.revenuereward.valueobj.RevenueRewardAssociateOrderRecord; |
|
|
|
|
|
import com.qniao.dam.domain.aggregate.revenuereward.valueobj.RevenueRewardRecord; |
|
|
import com.qniao.dam.domain.aggregate.virtualaccount.VirtualAccountAggregate; |
|
|
import com.qniao.dam.domain.aggregate.virtualaccount.VirtualAccountAggregate; |
|
|
import com.qniao.dam.domain.aggregate.virtualaccount.entity.VirtualAccount; |
|
|
import com.qniao.dam.domain.aggregate.virtualaccount.entity.VirtualAccount; |
|
|
|
|
|
import com.qniao.dam.domain.aggregate.walletaccount.entity.WalletAccount; |
|
|
|
|
|
import com.qniao.dam.domain.aggregate.walletaccount.valueobj.WalletAccountRecord; |
|
|
import com.qniao.dam.domain.service.virtualaccount.ConsumeVirtualAccountDomainService; |
|
|
import com.qniao.dam.domain.service.virtualaccount.ConsumeVirtualAccountDomainService; |
|
|
import com.qniao.dam.domian.aggregate.order.constant.OrderBelongingEnum; |
|
|
import com.qniao.dam.domian.aggregate.order.constant.OrderBelongingEnum; |
|
|
import com.qniao.dam.domian.aggregate.order.constant.OrderStatusEnum; |
|
|
import com.qniao.dam.domian.aggregate.order.constant.OrderStatusEnum; |
|
|
import com.qniao.dam.domian.aggregate.order.constant.OrderTypeEnum; |
|
|
import com.qniao.dam.domian.aggregate.order.constant.OrderTypeEnum; |
|
|
|
|
|
import com.qniao.dam.domian.aggregate.virtualaccount.constant.VirtualAccountTradeTypeEnum; |
|
|
|
|
|
import com.qniao.dam.domian.aggregate.walletaccount.constant.IdentityTypeEnum; |
|
|
|
|
|
import com.qniao.dam.domian.aggregate.walletaccount.constant.TradeSceneEnum; |
|
|
import com.qniao.dam.infrastructure.persistent.dao.domain.ProductDao; |
|
|
import com.qniao.dam.infrastructure.persistent.dao.domain.ProductDao; |
|
|
import com.qniao.dam.infrastructure.persistent.dao.domain.ProductSpecDao; |
|
|
import com.qniao.dam.infrastructure.persistent.dao.domain.ProductSpecDao; |
|
|
import com.qniao.dam.infrastructure.utils.SnowFlakeUtil; |
|
|
import com.qniao.dam.infrastructure.utils.SnowFlakeUtil; |
|
|
|
|
|
import com.qniao.dam.query.revenuereward.RevenueRewardQueryService; |
|
|
import com.qniao.dam.query.virtualaccount.VirtualAccountQueryService; |
|
|
import com.qniao.dam.query.virtualaccount.VirtualAccountQueryService; |
|
|
|
|
|
import com.qniao.dam.query.walletaccount.WalletAccountQueryService; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
|
import javax.annotation.Resource; |
|
|
import javax.annotation.Resource; |
|
|
|
|
|
import java.math.BigDecimal; |
|
|
import java.time.LocalDateTime; |
|
|
import java.time.LocalDateTime; |
|
|
|
|
|
import java.util.ArrayList; |
|
|
import java.util.Collections; |
|
|
import java.util.Collections; |
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
import java.util.Objects; |
|
|
|
|
|
|
|
|
@Service |
|
|
@Service |
|
|
public class VirtualAccountApplicationService { |
|
|
public class VirtualAccountApplicationService { |
|
|
@ -30,6 +48,10 @@ public class VirtualAccountApplicationService { |
|
|
@Resource |
|
|
@Resource |
|
|
private VirtualAccountQueryService virtualAccountQueryService; |
|
|
private VirtualAccountQueryService virtualAccountQueryService; |
|
|
@Resource |
|
|
@Resource |
|
|
|
|
|
private WalletAccountQueryService walletAccountQueryService; |
|
|
|
|
|
@Resource |
|
|
|
|
|
private RevenueRewardQueryService revenueRewardQueryService; |
|
|
|
|
|
@Resource |
|
|
private ProductDao productDao; |
|
|
private ProductDao productDao; |
|
|
@Resource |
|
|
@Resource |
|
|
private ProductSpecDao productSpecDao; |
|
|
private ProductSpecDao productSpecDao; |
|
|
@ -58,7 +80,7 @@ public class VirtualAccountApplicationService { |
|
|
ProductSpec productSpec = productSpecDao.selectById(dto.getProductSpecId()); |
|
|
ProductSpec productSpec = productSpecDao.selectById(dto.getProductSpecId()); |
|
|
if (virtualAccount != null && virtualAccount.getBalance() >= productSpec.getUnitSellingPrice().intValue()) { |
|
|
if (virtualAccount != null && virtualAccount.getBalance() >= productSpec.getUnitSellingPrice().intValue()) { |
|
|
//余额充足 创建消费订单+扣除余额 |
|
|
//余额充足 创建消费订单+扣除余额 |
|
|
Order order = handleOrder(dto.getUserId(), productSpec); |
|
|
|
|
|
|
|
|
Order order = handleOrder(dto.getUserId(), productSpec, 1); |
|
|
//虚拟账户处理 |
|
|
//虚拟账户处理 |
|
|
virtualAccountAggregate.handleConsumeData(virtualAccount, order.getSettlementAmount().intValue(), dto.getTradeType()); |
|
|
virtualAccountAggregate.handleConsumeData(virtualAccount, order.getSettlementAmount().intValue(), dto.getTradeType()); |
|
|
//保存 |
|
|
//保存 |
|
|
@ -70,16 +92,17 @@ public class VirtualAccountApplicationService { |
|
|
return vo; |
|
|
return vo; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private Order handleOrder(Long userId, ProductSpec productSpec) { |
|
|
|
|
|
|
|
|
private Order handleOrder(Long userId, ProductSpec productSpec, Integer quantity) { |
|
|
Product product = productDao.selectById(productSpec.getProductId()); |
|
|
Product product = productDao.selectById(productSpec.getProductId()); |
|
|
|
|
|
BigDecimal costAmount = productSpec.getUnitSellingPrice().multiply(new BigDecimal(quantity)); |
|
|
Order order = new Order(); |
|
|
Order order = new Order(); |
|
|
order.setUserId(userId); |
|
|
order.setUserId(userId); |
|
|
order.setOrderBelonging(OrderBelongingEnum.CUSTOMER); |
|
|
order.setOrderBelonging(OrderBelongingEnum.CUSTOMER); |
|
|
order.setName(product.getProductTitle()); |
|
|
order.setName(product.getProductTitle()); |
|
|
order.setOrderType(OrderTypeEnum.VIRTUAL_TYPE); |
|
|
order.setOrderType(OrderTypeEnum.VIRTUAL_TYPE); |
|
|
order.setOrderCode(snowFlakeUtil.getSnowflakeOrderCode()); |
|
|
order.setOrderCode(snowFlakeUtil.getSnowflakeOrderCode()); |
|
|
order.setOriginalAmount(productSpec.getUnitSellingPrice()); |
|
|
|
|
|
order.setSettlementAmount(productSpec.getUnitSellingPrice()); |
|
|
|
|
|
|
|
|
order.setOriginalAmount(costAmount); |
|
|
|
|
|
order.setSettlementAmount(costAmount); |
|
|
order.setPaidTime(LocalDateTime.now()); |
|
|
order.setPaidTime(LocalDateTime.now()); |
|
|
order.setStatus(OrderStatusEnum.COMPLETED); |
|
|
order.setStatus(OrderStatusEnum.COMPLETED); |
|
|
|
|
|
|
|
|
@ -91,12 +114,77 @@ public class VirtualAccountApplicationService { |
|
|
orderItem.setSubCategory(product.getSubCategory()); |
|
|
orderItem.setSubCategory(product.getSubCategory()); |
|
|
orderItem.setProductTitle(product.getProductTitle()); |
|
|
orderItem.setProductTitle(product.getProductTitle()); |
|
|
orderItem.setProductDesc(product.getProductDesc()); |
|
|
orderItem.setProductDesc(product.getProductDesc()); |
|
|
orderItem.setUnitOriginalPrice(productSpec.getUnitSellingPrice()); |
|
|
|
|
|
orderItem.setUnitSettlementPrice(productSpec.getUnitSellingPrice()); |
|
|
|
|
|
orderItem.setQuantity(1); |
|
|
|
|
|
orderItem.setOriginalAmount(productSpec.getUnitSellingPrice()); |
|
|
|
|
|
orderItem.setSettlementAmount(productSpec.getUnitSellingPrice()); |
|
|
|
|
|
|
|
|
orderItem.setUnitOriginalPrice(costAmount); |
|
|
|
|
|
orderItem.setUnitSettlementPrice(costAmount); |
|
|
|
|
|
orderItem.setQuantity(quantity); |
|
|
|
|
|
orderItem.setOriginalAmount(costAmount); |
|
|
|
|
|
orderItem.setSettlementAmount(costAmount); |
|
|
order.setOrderItemList(Collections.singletonList(orderItem)); |
|
|
order.setOrderItemList(Collections.singletonList(orderItem)); |
|
|
return order; |
|
|
return order; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 1.判断虚拟账户余额 |
|
|
|
|
|
* |
|
|
|
|
|
* @param dto |
|
|
|
|
|
* @return |
|
|
|
|
|
*/ |
|
|
|
|
|
public CostIMGiftVo costIMGift(UserCostIMGiftDto dto) { |
|
|
|
|
|
//判断虚拟账户余额 |
|
|
|
|
|
CostIMGiftVo vo = new CostIMGiftVo(); |
|
|
|
|
|
synchronized (dto.getFromUserId().toString().intern()) { |
|
|
|
|
|
VirtualAccount virtualAccount = virtualAccountQueryService.queryBy(dto.getFromUserId()); |
|
|
|
|
|
//找到对应产品 |
|
|
|
|
|
ProductSpec productSpec = productSpecDao.selectById(dto.getProductSpecId()); |
|
|
|
|
|
Integer costBalance = productSpec.getUnitSellingPrice().intValue() * dto.getQuantity(); |
|
|
|
|
|
if (virtualAccount != null && virtualAccount.getBalance() >= costBalance) { |
|
|
|
|
|
//余额充足 创建消费订单+扣除余额 |
|
|
|
|
|
Order order = handleOrder(dto.getFromUserId(), productSpec, dto.getQuantity()); |
|
|
|
|
|
//虚拟账户处理 |
|
|
|
|
|
virtualAccountAggregate.handleConsumeData(virtualAccount, order.getSettlementAmount().intValue(), VirtualAccountTradeTypeEnum.GIFT); |
|
|
|
|
|
//奖励处理 |
|
|
|
|
|
Tuple tuple = handleIMGiftReward(dto.getToUserId(), costBalance); |
|
|
|
|
|
//保存 |
|
|
|
|
|
consumeVirtualAccountDomainService.handle(virtualAccount, order); |
|
|
|
|
|
vo.setFlag(true); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return vo; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Tuple handleIMGiftReward(Long userId, Integer costBalance) { |
|
|
|
|
|
//收益信息 |
|
|
|
|
|
RevenueReward revenueReward = revenueRewardQueryService.queryByUserId(userId); |
|
|
|
|
|
if (Objects.isNull(revenueReward)) { |
|
|
|
|
|
revenueReward = RevenueReward.initUser(userId); |
|
|
|
|
|
} |
|
|
|
|
|
//营收额 |
|
|
|
|
|
BigDecimal revenue = dto.getReceivedAmount(); |
|
|
|
|
|
//服务费用 |
|
|
|
|
|
serviceFee = serviceFeeRewardConfig.calculateReward(revenue); |
|
|
|
|
|
BigDecimal earnings = revenue.subtract(serviceFee); |
|
|
|
|
|
RevenueRewardRecord revenueRewardRecord = RevenueRewardRecord.build(tradeType, TradeSceneEnum.ONLINE, |
|
|
|
|
|
revenue, BigDecimal.valueOf(100), new BigDecimal(serviceFeeRewardConfig.getValue()), earnings, dto.getTotalAssociateOrderAmount()); |
|
|
|
|
|
revenueRewardRecord.handleContent(Collections.singletonList(meetingMi.getNickName())); |
|
|
|
|
|
if (CollUtil.isNotEmpty(dto.getOrderIdRelList())) { |
|
|
|
|
|
List<RevenueRewardAssociateOrderRecord> associateOrderRecordList = new ArrayList<>(); |
|
|
|
|
|
for (Long associateOrderId : dto.getOrderIdRelList()) { |
|
|
|
|
|
Order associateOrder = orderDao.selectById(associateOrderId); |
|
|
|
|
|
RevenueRewardAssociateOrderRecord associateOrderRecord = RevenueRewardAssociateOrderRecord.build(associateOrder.getId(), associateOrder.getSettlementAmount()); |
|
|
|
|
|
revenueRewardRecord.setAssociateOrderRecordList(Collections.singletonList(associateOrderRecord)); |
|
|
|
|
|
associateOrderRecordList.add(associateOrderRecord); |
|
|
|
|
|
} |
|
|
|
|
|
revenueRewardRecord.setAssociateOrderRecordList(associateOrderRecordList); |
|
|
|
|
|
} |
|
|
|
|
|
revenueReward.setRecordList(Collections.singletonList(revenueRewardRecord)); |
|
|
|
|
|
//钱包 |
|
|
|
|
|
WalletAccount walletAccount = walletAccountQueryService.queryByType(dto.getReceiver(), IdentityTypeEnum.INDIVIDUAL); |
|
|
|
|
|
BigDecimal originalBalance = walletAccount.getTotalBalance(); |
|
|
|
|
|
walletAccount.setAvailableBalance(walletAccount.getAvailableBalance().add(earnings)); |
|
|
|
|
|
walletAccount.setTotalBalance(walletAccount.getAvailableBalance().add(walletAccount.getFrozenBalance())); |
|
|
|
|
|
WalletAccountRecord walletAccountRecord = WalletAccountRecord.build(tradeType, earnings, true, originalBalance, walletAccount.getTotalBalance()); |
|
|
|
|
|
walletAccount.setRecordList(Collections.singletonList(walletAccountRecord)); |
|
|
|
|
|
acquireRevenueRewardDomainService.handle(revenueReward, walletAccount); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |