From ed86dfe43e1815e6803568b137f8984735186b25 Mon Sep 17 00:00:00 2001 From: Helius <wangdoubleone@gmail.com> Date: Wed, 14 Sep 2022 21:47:48 +0800 Subject: [PATCH] fix --- src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java | 343 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 274 insertions(+), 69 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java b/src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java index 6c2368e..1f8da63 100644 --- a/src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/dapp/service/impl/DappWalletServiceImpl.java @@ -1,25 +1,44 @@ package cc.mrbird.febs.dapp.service.impl; +import cc.mrbird.febs.common.configure.i18n.MessageSourceUtils; import cc.mrbird.febs.common.contants.AppContants; +import cc.mrbird.febs.common.entity.QueryRequest; import cc.mrbird.febs.common.exception.FebsException; +import cc.mrbird.febs.common.utils.FebsUtil; import cc.mrbird.febs.common.utils.LoginUserUtil; -import cc.mrbird.febs.dapp.dto.RecordInPageDto; -import cc.mrbird.febs.dapp.dto.WalletOperateDto; +import cc.mrbird.febs.common.utils.RedisUtils; +import cc.mrbird.febs.dapp.chain.ChainEnum; +import cc.mrbird.febs.dapp.chain.ChainService; +import cc.mrbird.febs.dapp.chain.ContractChainService; +import cc.mrbird.febs.dapp.dto.*; import cc.mrbird.febs.dapp.entity.*; import cc.mrbird.febs.dapp.mapper.*; import cc.mrbird.febs.dapp.service.DappWalletService; +import cc.mrbird.febs.dapp.utils.BoxUtil; +import cc.mrbird.febs.dapp.vo.ActiveNftListVo; import cc.mrbird.febs.dapp.vo.WalletInfoVo; +import cc.mrbird.febs.rabbit.producer.ChainProducer; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateField; +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; -import java.util.List; +import java.math.RoundingMode; +import java.util.*; /** - * @author wzy + * @author * @date 2022-03-18 **/ @Slf4j @@ -32,87 +51,273 @@ private final DappWalletCoinDao dappWalletCoinDao; private final DappFundFlowDao dappFundFlowDao; private final DappAccountMoneyChangeDao dappAccountMoneyChangeDao; + private final RedisUtils redisUtils; + private final DataDictionaryCustomMapper dataDictionaryCustomMapper; + private final DappNftActivationDao dappNftActivationDao; + + private final ChainProducer chainProducer; + private final DappSystemDao dappSystemDao; @Override public WalletInfoVo walletInfo() { DappMemberEntity member = LoginUserUtil.getAppUser(); - DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(member.getId()); - DappWalletMineEntity walletMine = dappWalletMineDao.selectByMemberId(member.getId()); - + DappMemberEntity memberInfo = dappMemberDao.selectById(member.getId()); WalletInfoVo walletInfo = new WalletInfoVo(); - walletInfo.setTotalMine(walletMine.getTotalAmount()); - walletInfo.setAvailableMine(walletMine.getAvailableAmount()); - walletInfo.setAvailableWallet(walletCoin.getAvailableAmount()); - return walletInfo; - } - - @Override - public void change(WalletOperateDto walletOperateDto) { - DappMemberEntity member = LoginUserUtil.getAppUser(); - - BigDecimal ethUsdtPrice = new BigDecimal("1234"); - + List<DappMemberEntity> direct = dappMemberDao.selectChildMemberDirectOrNot(member.getInviteId(), 1, null); + DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(member.getId()); DappWalletMineEntity walletMine = dappWalletMineDao.selectByMemberId(member.getId()); - if (walletOperateDto.getAmount().compareTo(walletMine.getAvailableAmount()) > 0) { - throw new FebsException("可用金额不足"); - } - DappFundFlowEntity fund = new DappFundFlowEntity(member.getId(), walletOperateDto.getAmount().negate(), AppContants.MONEY_TYPE_CHANGE, null); - dappFundFlowDao.insert(fund); - - BigDecimal preEthAmount = walletMine.getAvailableAmount(); - - // TODO 并发加悲观锁 - // 更新eth金额 - walletMine.setAvailableAmount(walletMine.getAvailableAmount().subtract(walletOperateDto.getAmount())); - walletMine.setTotalAmount(walletMine.getTotalAmount().subtract(walletOperateDto.getAmount())); - dappWalletMineDao.updateById(walletMine); - - DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(member.getId()); - BigDecimal preUsdtAmount = walletCoin.getAvailableAmount(); - - // 更新usdt金额 - BigDecimal usdt = walletOperateDto.getAmount().multiply(ethUsdtPrice); - walletCoin.setAvailableAmount(walletCoin.getAvailableAmount().add(usdt)); - walletCoin.setTotalAmount(walletCoin.getTotalAmount().add(usdt)); - dappWalletCoinDao.updateById(walletCoin); - - DappAccountMoneyChangeEntity ethChange = new DappAccountMoneyChangeEntity(member.getId(), preEthAmount, walletOperateDto.getAmount(), walletMine.getTotalAmount(), "ETH兑换USDT-ETH", AppContants.MONEY_TYPE_CHANGE); - DappAccountMoneyChangeEntity usdtChange = new DappAccountMoneyChangeEntity(member.getId(), preUsdtAmount, usdt, walletCoin.getTotalAmount(), "ETH兑换USDT-USDT", AppContants.MONEY_TYPE_CHANGE); - dappAccountMoneyChangeDao.insert(ethChange); - dappAccountMoneyChangeDao.insert(usdtChange); - } - - @Override - public void withdraw(WalletOperateDto walletOperateDto) { - DappMemberEntity member = LoginUserUtil.getAppUser(); - - DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(member.getId()); - if (walletOperateDto.getAmount().compareTo(walletCoin.getAvailableAmount()) > 0) { - throw new FebsException("可用金额不足"); - } - - // TODO 并发加悲观锁 - BigDecimal preAmount = walletCoin.getAvailableAmount(); - walletCoin.setAvailableAmount(walletCoin.getAvailableAmount().subtract(walletOperateDto.getAmount())); - walletCoin.setFrozenAmount(walletCoin.getFrozenAmount().subtract(walletOperateDto.getAmount())); - dappWalletCoinDao.updateById(walletCoin); - - DappFundFlowEntity fund = new DappFundFlowEntity(member.getId(), walletOperateDto.getAmount().negate(), AppContants.MONEY_TYPE_WITHDRAWAL, 1); - dappFundFlowDao.insert(fund); - - DappAccountMoneyChangeEntity usdtChange = new DappAccountMoneyChangeEntity(member.getId(), preAmount, walletOperateDto.getAmount(), walletCoin.getTotalAmount(), "USDT申请提现", AppContants.MONEY_TYPE_WITHDRAWAL); - dappAccountMoneyChangeDao.insert(usdtChange); + DappMineDataEntity mineData = dappSystemDao.selectMineDataForOne(); + walletInfo.setDirectCnt(direct.size()); + walletInfo.setInviteId(member.getActiveStatus() == 1 ? member.getInviteId() : "-"); + walletInfo.setBalance(walletCoin.getAvailableAmount()); + walletInfo.setHasBuy(memberInfo.getActiveStatus()); + walletInfo.setOutCnt(memberInfo.getOutCnt()); + walletInfo.setProfit(dappFundFlowDao.selectProfitAmountByMemberId(member.getId())); + walletInfo.setTfcBalance(walletMine.getAvailableAmount()); + walletInfo.setSafePool(mineData.getSafePool()); + return walletInfo; } @Override public List<DappFundFlowEntity> recordInPage(RecordInPageDto recordInPageDto) { Page<DappFundFlowEntity> page = new Page<>(recordInPageDto.getPageNum(), recordInPageDto.getPageSize()); + DappMemberEntity member = LoginUserUtil.getAppUser(); DappFundFlowEntity dappFundFlowEntity = new DappFundFlowEntity(); - dappFundFlowEntity.setType(recordInPageDto.getType()); + if (recordInPageDto.getType() != null && recordInPageDto.getType() != 0) { + dappFundFlowEntity.setType(recordInPageDto.getType()); + } + dappFundFlowEntity.setMemberId(member.getId()); + dappFundFlowEntity.setStatus(2); + IPage<DappFundFlowEntity> records = dappFundFlowDao.selectInPage(page, dappFundFlowEntity); return records.getRecords(); } + + @Override + public IPage<DappFundFlowEntity> fundFlowInPage(DappFundFlowEntity dappFundFlowEntity, QueryRequest request) { + Page<DappFundFlowEntity> page = new Page<>(request.getPageNum(), request.getPageSize()); + return dappFundFlowDao.selectInPage(page, dappFundFlowEntity); + } + + @Override + public IPage<DappWalletCoinEntity> walletCoinInPage(DappWalletCoinEntity walletCoin, QueryRequest request) { + Page<DappWalletCoinEntity> page = new Page<>(request.getPageNum(), request.getPageSize()); + return dappWalletCoinDao.selectInPage(walletCoin, page); + } + + @Override + public IPage<DappWalletMineEntity> walletMineInPage(DappWalletMineEntity walletMine, QueryRequest request) { + Page<DappWalletMineEntity> page = new Page<>(request.getPageNum(), request.getPageSize()); + return dappWalletMineDao.selectInPage(walletMine, page); + } + + @Override + public IPage<DappAccountMoneyChangeEntity> accountMoneyChangeInPage(DappAccountMoneyChangeEntity change, QueryRequest request) { + Page<DappAccountMoneyChangeEntity> page = new Page<>(request.getPageNum(), request.getPageSize()); + return dappAccountMoneyChangeDao.selectInPage(change, page); + } + + @Override + public Long transfer(TransferDto transferDto) { + DappMemberEntity member = LoginUserUtil.getAppUser(); + + String upgrade = redisUtils.getString("APP_UPGRADE"); + if ("upgrade".equals(upgrade)) { + throw new FebsException("功能升级中"); + } + + if (transferDto.getType() != 2) { + member = dappMemberDao.selectById(member.getId()); + if (member.getActiveStatus() == 1) { + throw new FebsException("Do not repeat purchase"); + } + } + + if (transferDto.getBuyType() == 1) { + DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(member.getId()); + if (transferDto.getAmount().compareTo(walletCoin.getAvailableAmount()) > 0) { + throw new FebsException("Balance Not Enough"); + } + + updateWalletCoinWithLock(transferDto.getAmount(), member.getId(), 2); + + DappFundFlowEntity fundFlow = new DappFundFlowEntity(member.getId(), transferDto.getAmount().negate(), 1, 2, transferDto.getFee(), transferDto.getTxHash()); + dappFundFlowDao.insert(fundFlow); + + chainProducer.sendAchieveTreeMsg(member.getId()); + } else { + int type = 1; + // 1-认购 2-充值tfc + if (transferDto.getType() == 2) { + type = 6; + } + if (transferDto.getId() == null) { + DappFundFlowEntity fundFlow = new DappFundFlowEntity(member.getId(), transferDto.getAmount(), type, 1, transferDto.getFee(), transferDto.getTxHash()); + dappFundFlowDao.insert(fundFlow); + return fundFlow.getId(); + } + + if ("success".equals(transferDto.getFlag())) { + DappFundFlowEntity flow = dappFundFlowDao.selectById(transferDto.getId()); + flow.setFromHash(transferDto.getTxHash()); + dappFundFlowDao.updateById(flow); + } else { + DappFundFlowEntity flow = dappFundFlowDao.selectById(transferDto.getId()); + if (flow.getStatus() == 1) { + dappFundFlowDao.deleteById(transferDto.getId()); + } + } + } + return null; + } + + @Override + public BigDecimal calPrice(PriceDto priceDto) { + String priceStr = redisUtils.getString(AppContants.REDIS_KEY_TFC_NEW_PRICE); + + BigDecimal amount = priceDto.getAmount(); + if (priceDto.getAmount() == null) { + amount = BigDecimal.ZERO; + } + return amount.multiply(new BigDecimal("0.1")).divide(new BigDecimal(priceStr), 2, RoundingMode.HALF_UP); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void withdraw(WithdrawDto withdrawDto) { + DappMemberEntity member = LoginUserUtil.getAppUser(); + + DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(member.getId()); + if (walletCoin.getAvailableAmount().compareTo(withdrawDto.getAmount()) < 0) { + throw new FebsException("Balance Not Enough"); + } + + DappWalletMineEntity walletMine = dappWalletMineDao.selectByMemberId(member.getId()); + if (walletMine.getAvailableAmount().compareTo(withdrawDto.getFee()) < 0) { + throw new FebsException("TFC Not Enough"); + } + + updateWalletCoinWithLock(withdrawDto.getAmount(), member.getId(), 2); + updateWalletMineWithLock(withdrawDto.getFee(), member.getId(), 2); + + DappFundFlowEntity feeFlow = new DappFundFlowEntity(member.getId(), withdrawDto.getFee().negate(), 7, 2, null, null); + dappFundFlowDao.insert(feeFlow); + + DappFundFlowEntity fundFlow = new DappFundFlowEntity(member.getId(), withdrawDto.getAmount().negate(), 5, 2, withdrawDto.getFee(), null); + dappFundFlowDao.insert(fundFlow); + + String hash = ChainService.getInstance(ChainEnum.BSC_USDT.name()).transfer(member.getAddress(), withdrawDto.getAmount()); + fundFlow.setToHash(hash); + dappFundFlowDao.updateById(fundFlow); + + Map<String, Object> map = new HashMap<>(); + map.put("fee", withdrawDto.getFee()); + map.put("address", ChainEnum.BSC_TFC_FEE.getAddress()); + map.put("flow", feeFlow.getId()); + chainProducer.sendTfcFee(JSONObject.toJSONString(map)); + } + + @Override + public void updateWalletCoinWithLock(BigDecimal amount, Long memberId, int type) { + boolean isSuccess = false; + while(!isSuccess) { + DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(memberId); + + // 加 + if (type == 1) { + walletCoin.setTotalAmount(walletCoin.getTotalAmount().add(amount)); + walletCoin.setAvailableAmount(walletCoin.getAvailableAmount().add(amount)); + // 减 + } else { + if (amount.compareTo(walletCoin.getAvailableAmount()) > 0) { + throw new FebsException("Balance Not Enough"); + } + walletCoin.setTotalAmount(walletCoin.getTotalAmount().subtract(amount)); + walletCoin.setAvailableAmount(walletCoin.getAvailableAmount().subtract(amount)); + } + + int i = dappWalletCoinDao.updateWithLock(walletCoin); + if (i > 0) { + isSuccess = true; + } + } + } + + @Override + public void updateWalletMineWithLock(BigDecimal amount, Long memberId, int type) { + boolean isSuccess = false; + while(!isSuccess) { + DappWalletMineEntity walletMine = dappWalletMineDao.selectByMemberId(memberId); + + if (type == 1) { + walletMine.setTotalAmount(walletMine.getTotalAmount().add(amount)); + walletMine.setAvailableAmount(walletMine.getAvailableAmount().add(amount)); + } else { + if (amount.compareTo(walletMine.getAvailableAmount()) > 0) { + throw new FebsException("TFC Not Enough"); + } + walletMine.setTotalAmount(walletMine.getTotalAmount().subtract(amount)); + walletMine.setAvailableAmount(walletMine.getAvailableAmount().subtract(amount)); + } + + int i = dappWalletMineDao.updateWithLock(walletMine); + if (i > 0) { + isSuccess = true; + } + } + } + + @Override + public void addFrozenAmountWithLock(BigDecimal amount, Long memberId) { + boolean isSuccess = false; + while(!isSuccess) { + DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(memberId); + + walletCoin.setTotalAmount(walletCoin.getTotalAmount().add(amount)); + walletCoin.setFrozenAmount(walletCoin.getFrozenAmount().add(amount)); + + int i = dappWalletCoinDao.updateWithLock(walletCoin); + if (i > 0) { + isSuccess = true; + + DappFundFlowEntity frozenAmount = new DappFundFlowEntity(memberId, amount, 9, 2, null, null); + dappFundFlowDao.insert(frozenAmount); + } + } + } + + @Override + public void releaseFrozenAmountWithLock(Long memberId) { + boolean isSuccess = false; + while(!isSuccess) { + DappWalletCoinEntity walletCoin = dappWalletCoinDao.selectByMemberId(memberId); + + if (walletCoin.getFrozenAmount().compareTo(BigDecimal.ZERO) <= 0) { + return; + } + BigDecimal frozen = walletCoin.getFrozenAmount(); + + walletCoin.setAvailableAmount(walletCoin.getAvailableAmount().add(frozen)); + walletCoin.setFrozenAmount(walletCoin.getFrozenAmount().subtract(frozen)); + + int i = dappWalletCoinDao.updateWithLock(walletCoin); + if (i > 0) { + isSuccess = true; + + DappFundFlowEntity releaseFrozen = new DappFundFlowEntity(memberId, frozen, 10, 2, null, null); + dappFundFlowDao.insert(releaseFrozen); + + DappFundFlowEntity releaseFrozenNegate = new DappFundFlowEntity(memberId, frozen.negate(), 9, 2, null, null); + dappFundFlowDao.insert(releaseFrozenNegate); + } + } + } + + @Override + public DappWalletCoinEntity findByMemberId(Long memberId) { + return dappWalletCoinDao.selectByMemberId(memberId); + } } -- Gitblit v1.9.1