Helius
2021-11-24 be6f79a634727b59c6a40e3fffa989b5de1b0ec7
src/main/java/com/xcong/excoin/modules/fish/service/impl/MemberCannonServiceImpl.java
New file
@@ -0,0 +1,263 @@
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.*;
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.fish.vo.GoldAccountVo;
import com.xcong.excoin.modules.fish.vo.OwnCannonVo;
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<CannonOwnRecordDao, CannonOwnRecord> 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<CannonExchangeRatio> 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);
            CannonAccountMoneyChange cannonAccountMoneyChange = new CannonAccountMoneyChange();
            cannonAccountMoneyChange.setMemberId(memberId);
            cannonAccountMoneyChange.setAmount(balance.negate());
            cannonAccountMoneyChange.setType(2);
            cannonAccountMoneyChange.setContent("金币兑换");
            cannonAccountMoneyChange.setChangeBalance(balance);
            cannonAccountMoneyChange.setChangeBefore(memberAccountGold.getAvailableBalance());
            cannonAccountMoneyChange.setChangeAfter(memberAccountGold.getAvailableBalance().subtract(balance));
            cannonAccountMoneyChangeDao.insert(cannonAccountMoneyChange);
        }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);
            CannonAccountMoneyChange cannonAccountMoneyChange = new CannonAccountMoneyChange();
            cannonAccountMoneyChange.setMemberId(memberId);
            cannonAccountMoneyChange.setAmount(balance);
            cannonAccountMoneyChange.setType(3);
            cannonAccountMoneyChange.setContent("兑换金币");
            cannonAccountMoneyChange.setChangeBalance(balance);
            cannonAccountMoneyChange.setChangeBefore(memberWalletCoinEntity.getAvailableBalance());
            cannonAccountMoneyChange.setChangeAfter(memberWalletCoinEntity.getAvailableBalance().add(balance));
            cannonAccountMoneyChangeDao.insert(cannonAccountMoneyChange);
        }
        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<CannonSettingVo> page = new Page<>(getCannonsDto.getPageNum(), getCannonsDto.getPageSize());
        CannonSetting cannonSetting = new CannonSetting();
        IPage<CannonSettingVo> 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<CannonOwnRecord> 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(1);
        cannonAccountMoneyChange.setContent("购买炮塔");
        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<CannonExchangeRatio> 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("兑换成功");
    }
    @Override
    public Result getGoldAccount() {
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        MemberAccountGold memberAccountGold = memberAccountGoldDao.selectAccountGoldByMemberId(memberId);
        if(ObjectUtil.isEmpty(memberAccountGold)){
            MemberAccountGold memberAccountGoldNew = new MemberAccountGold();
            memberAccountGoldNew.setMemberId(memberId);
            memberAccountGoldNew.setTotalBalance(BigDecimal.ZERO);
            memberAccountGoldNew.setAvailableBalance(BigDecimal.ZERO);
            memberAccountGoldNew.setFrozenBalance(BigDecimal.ZERO);
            memberAccountGoldDao.insert(memberAccountGoldNew);
        }
        GoldAccountVo goldAccountVo = memberAccountGoldDao.selectAccountGoldVoByMemberId(memberId);
        return Result.ok(goldAccountVo);
    }
    @Override
    public Result getOwnCannon() {
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        List<OwnCannonVo> cannonOwnRecords = cannonOwnRecordDao.selectCannonOwnRecordsByMemberId(memberId);
        return Result.ok(cannonOwnRecords);
    }
    @Override
    public Result fishing(FishingDto fishingDto) {
        Long memberId = LoginUserUtils.getAppLoginUser().getId();
        Integer goldWin = fishingDto.getGoldWin() == null?0:fishingDto.getGoldWin();
        if(goldWin < 0){
            return Result.fail("请求异常,请刷新页面");
        }
        Long cannonOwnId = fishingDto.getCannonOwnId();
        List<CannonOwnRecord> cannonOwnRecords = cannonOwnRecordDao.selectCannonOwnRecordsByIdAndMemberId(cannonOwnId,memberId);
        if(CollUtil.isEmpty(cannonOwnRecords)){
            Result.fail("请求异常,请刷新页面");
        }
        //消耗金币 = 每发炮弹的消耗 - 获得金币;
        CannonOwnRecord cannonOwnRecord = cannonOwnRecords.get(0);
        CannonSetting cannonSetting = cannonSettingDao.selectCannonSettingByCannonCode(cannonOwnRecord.getCannonCode());
        BigDecimal goldConsume = cannonSetting.getGoldConsume().subtract(new BigDecimal(goldWin)).setScale(0,BigDecimal.ROUND_DOWN);
        MemberAccountGold memberAccountGold = memberAccountGoldDao.selectAccountGoldByMemberId(memberId);
        memberCannonService.updateTotalBalanceAndAvailableBalance(memberAccountGold.getId(),goldConsume.negate(),goldConsume.negate(),null);
        return Result.ok("success");
    }
    public static void main(String[] args) {
        System.out.println(UUID.randomUUID().toString());
    }
}