package com.xcong.excoin.modules.fish.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.UUID; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xcong.excoin.common.LoginUserUtils; import com.xcong.excoin.common.enumerates.CoinTypeEnum; import com.xcong.excoin.common.response.Result; import com.xcong.excoin.modules.coin.service.CoinService; import com.xcong.excoin.modules.fish.dao.CannonAccountMoneyChangeDao; import com.xcong.excoin.modules.fish.dao.CannonOwnRecordDao; import com.xcong.excoin.modules.fish.dao.CannonSettingDao; import com.xcong.excoin.modules.fish.dao.MemberAccountGoldDao; import com.xcong.excoin.modules.fish.dto.CannonExchangeDto; import com.xcong.excoin.modules.fish.dto.CoinGoldExchangeDto; import com.xcong.excoin.modules.fish.dto.GetCannonsDto; import com.xcong.excoin.modules.fish.dto.GoldExchangeDto; import com.xcong.excoin.modules.fish.entity.*; import com.xcong.excoin.modules.fish.service.MemberCannonService; import com.xcong.excoin.modules.fish.vo.CannonSettingVo; import com.xcong.excoin.modules.member.dao.MemberWalletCoinDao; import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity; import com.xcong.excoin.utils.RedisUtils; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.List; @Service public class MemberCannonServiceImpl extends ServiceImpl implements MemberCannonService { @Resource CannonSettingDao cannonSettingDao; @Resource MemberAccountGoldDao memberAccountGoldDao; @Resource CannonAccountMoneyChangeDao cannonAccountMoneyChangeDao; @Resource MemberWalletCoinDao memberWalletCoinDao; @Resource CannonOwnRecordDao cannonOwnRecordDao; @Resource RedisUtils redisUtils; @Resource private CoinService coinService; @Resource private MemberCannonService memberCannonService; @Override public Result coinGoldExchange(CoinGoldExchangeDto coinGoldExchangeDto) { BigDecimal balance = coinGoldExchangeDto.getBalance(); if (balance.compareTo(BigDecimal.ZERO) <= 0) { return Result.fail("兑换金额不能小于或等于0"); } Long memberId = LoginUserUtils.getAppLoginUser().getId(); //获取兑换比例 List cannonExchangeRatios = cannonSettingDao.selectCannonExchangeRatio(); if(CollUtil.isEmpty(cannonExchangeRatios)){ return Result.fail("系统繁忙请稍候重试"); } CannonExchangeRatio cannonExchangeRatio = cannonExchangeRatios.get(0); Integer type = coinGoldExchangeDto.getType(); //1:金币兑换1代币 2:1代币兑换金币 if(type == 1){ MemberAccountGold memberAccountGold = memberAccountGoldDao.selectAccountGoldByMemberId(memberId); MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.XCT.name()); if(balance.compareTo(memberAccountGold.getAvailableBalance()) > 0){ return Result.fail("金币不足"); } BigDecimal coinRatio = cannonExchangeRatio.getCoinRatio(); BigDecimal divide = balance.divide(coinRatio).setScale(8,BigDecimal.ROUND_DOWN); //金币账户减少 memberCannonService.updateTotalBalanceAndAvailableBalance(memberAccountGold.getId(),balance.negate(),balance.negate(),null); //代币账户增加 coinService.updateWalletBalance(memberWalletCoinEntity.getId(),divide,divide,null); }else if(type == 2){ MemberAccountGold memberAccountGold = memberAccountGoldDao.selectAccountGoldByMemberId(memberId); MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.XCT.name()); if(balance.compareTo(memberWalletCoinEntity.getAvailableBalance()) > 0){ return Result.fail("代币不足"); } BigDecimal coinRatio = cannonExchangeRatio.getCoinRatio(); BigDecimal multiply = balance.multiply(coinRatio); //金币账户增加 memberCannonService.updateTotalBalanceAndAvailableBalance(memberAccountGold.getId(),multiply,multiply,null); //代币账户减少 coinService.updateWalletBalance(memberWalletCoinEntity.getId(),balance.negate(),balance.negate(),null); } return Result.ok("兑换成功"); } @Override public void updateTotalBalanceAndAvailableBalance(Long id, BigDecimal availableBalance, BigDecimal totalBalance,BigDecimal frozenBalance) { if(id==null){ return; } // 这里需要加锁 保证同一个时间只有一个线程操作一个钱包 String key = "UPDATE_MEMBER_GOLD_"+id; while (true){ boolean b = redisUtils.setNotExist(key, 1, 2); if(b){ //System.out.println("我拿到了锁"); // 拿到了锁才能扣 memberAccountGoldDao.updateTotalBalanceAndAvailableBalance(id,availableBalance,totalBalance,frozenBalance); // 扣完释放锁 redisUtils.del(key); break; }else { } } } @Override public Result getCannons(GetCannonsDto getCannonsDto) { Long memberId = LoginUserUtils.getAppLoginUser().getId(); Page page = new Page<>(getCannonsDto.getPageNum(), getCannonsDto.getPageSize()); CannonSetting cannonSetting = new CannonSetting(); IPage list = cannonSettingDao.findCannonSettingInPage(page, cannonSetting); return Result.ok(list); } @Override public Result cannonExchange(CannonExchangeDto cannonExchangeDto) { Long memberId = LoginUserUtils.getAppLoginUser().getId(); Long cannonId = cannonExchangeDto.getCannonId(); CannonSetting cannonSetting = cannonSettingDao.selectById(cannonId); BigDecimal exchangePrice = cannonSetting.getExchangePrice(); if(ObjectUtil.isEmpty(cannonSetting)){ return Result.fail("炮塔不存在"); } List cannonOwnRecords = cannonOwnRecordDao.selectCannonOwnRecordsByMemberIdAndCannonCode(memberId,cannonSetting.getCode()); if(CollUtil.isNotEmpty(cannonOwnRecords)){ return Result.fail("炮塔已拥有"); } //获取用户的USDT账户,可用余额总金额减少 MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.USDT.name()); if(exchangePrice.compareTo(memberWalletCoinEntity.getAvailableBalance()) > 0){ return Result.fail("可用余额不足"); } coinService.updateWalletBalance(memberWalletCoinEntity.getId(),exchangePrice.negate(),exchangePrice.negate(),null); //增加一条拥有记录【cannon_own_record】 CannonOwnRecord cannonOwnRecord = new CannonOwnRecord(); cannonOwnRecord.setMemberId(memberId); cannonOwnRecord.setCannonUuid(UUID.randomUUID().toString()); cannonOwnRecord.setCannonCode(cannonSetting.getCode()); cannonOwnRecord.setCannonName(cannonSetting.getName()); cannonOwnRecord.setCannonPrice(cannonSetting.getExchangePrice()); cannonOwnRecord.setType(1); cannonOwnRecordDao.insert(cannonOwnRecord); //增加一条买卖记录 CannonAccountMoneyChange cannonAccountMoneyChange = new CannonAccountMoneyChange(); cannonAccountMoneyChange.setMemberId(memberId); cannonAccountMoneyChange.setAmount(exchangePrice); cannonAccountMoneyChange.setType(2); cannonAccountMoneyChange.setChangeBalance(exchangePrice); cannonAccountMoneyChange.setChangeBefore(memberWalletCoinEntity.getAvailableBalance()); cannonAccountMoneyChange.setChangeAfter(memberWalletCoinEntity.getAvailableBalance().subtract(exchangePrice)); cannonAccountMoneyChangeDao.insert(cannonAccountMoneyChange); return Result.ok("购买成功"); } @Override public Result goldExchange(GoldExchangeDto goldExchangeDto) { Long memberId = LoginUserUtils.getAppLoginUser().getId(); BigDecimal balance = goldExchangeDto.getBalance(); if (balance.compareTo(BigDecimal.ZERO) <= 0) { return Result.fail("兑换金额不能小于或等于0"); } //获取兑换比例 List cannonExchangeRatios = cannonSettingDao.selectCannonExchangeRatio(); if(CollUtil.isEmpty(cannonExchangeRatios)){ return Result.fail("系统繁忙请稍候重试"); } CannonExchangeRatio cannonExchangeRatio = cannonExchangeRatios.get(0); //金币账户增加 MemberAccountGold memberAccountGold = memberAccountGoldDao.selectAccountGoldByMemberId(memberId); BigDecimal goldRatio = cannonExchangeRatio.getGoldRatio(); BigDecimal multiply = balance.multiply(goldRatio); memberCannonService.updateTotalBalanceAndAvailableBalance(memberAccountGold.getId(),multiply,multiply,null); //获取用户的USDT账户,可用余额总金额减少 MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.USDT.name()); if(balance.compareTo(memberWalletCoinEntity.getAvailableBalance()) > 0){ return Result.fail("可用余额不足"); } coinService.updateWalletBalance(memberWalletCoinEntity.getId(),balance.negate(),balance.negate(),null); return Result.ok("兑换成功"); } public static void main(String[] args) { System.out.println(UUID.randomUUID().toString()); } }