xiaoyong931011
2023-03-24 a4e2632242680c2af350af9ef4498413aa99dd92
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package cc.mrbird.febs.mall.chain.service;
 
import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
import cc.mrbird.febs.common.enumerates.MallMoneyFlowTypeEnum;
import cc.mrbird.febs.common.utils.AppContants;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.mall.chain.constants.ChainConstants;
import cc.mrbird.febs.mall.chain.enums.ChainEnum;
import cc.mrbird.febs.mall.chain.enums.CoinTypeEnum;
import cc.mrbird.febs.mall.entity.MallMemberWallet;
import cc.mrbird.febs.mall.entity.MallMoneyFlow;
import cc.mrbird.febs.mall.entity.MemberCoinAddressEntity;
import cc.mrbird.febs.mall.entity.MemberCoinChargeEntity;
import cc.mrbird.febs.mall.mapper.MallMemberWalletMapper;
import cc.mrbird.febs.mall.mapper.MemberCoinAddressDao;
import cc.mrbird.febs.mall.mapper.MemberCoinChargeDao;
import cc.mrbird.febs.mall.service.IMallMoneyFlowService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
@Slf4j
@Service
public class BscUsdtContractEvent implements ContractEventService {
 
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private MemberCoinChargeDao memberCoinChargeDao;
    @Resource
    private MemberCoinAddressDao memberCoinAddressDao;
    @Resource
    private MallMemberWalletMapper mallMemberWalletMapper;
    @Resource
    private IMallMoneyFlowService mallMoneyFlowService;
 
    @Override
    public void compile(EthUsdtContract.TransferEventResponse e) {
        if (e.to == null) {
            return;
        }
 
//        redisUtils.set(AppContants.REDIS_KEY_BLOCK_USDT_NUM, e.log.getBlockNumber());
 
        String address = e.to;
        String hash =  e.log.getTransactionHash();
        List<String> tdCoinWallets = memberCoinAddressDao.selectAllSymbolAddress(CoinTypeEnum.USDT.toString(),"ERC20");
//        Set<Object> addressList = redisUtils.sGet(ChainConstants.REDIS_KEY_SYSTEM_ADDRESS);
        // 判断对方打款地址是否为源池地址
        if(CollUtil.isNotEmpty(tdCoinWallets) && tdCoinWallets.contains(address)){
            log.info("触发USDT合约监听事件");
//            redisUtils.set(AppContants.REDIS_KEY_BLOCK_ETH_INCREMENT_NUM, e.log.getBlockNumber());
            // hash没有用过
            Map<String, Object> param = new HashMap<>();
            param.put("hash", hash);
            param.put("address", address);
            List<MemberCoinChargeEntity> memberCoinChargeEntities = memberCoinChargeDao.selectByMap(param);
            if (CollectionUtils.isNotEmpty(memberCoinChargeEntities)) {
                return;
            }
 
            MemberCoinAddressEntity coinAddressEntity = memberCoinAddressDao.selectCoinAddressByAddressAndSymbol(address, CoinTypeEnum.USDT.toString());
            if (coinAddressEntity == null) {
                return;
            }
            Long memberId = coinAddressEntity.getMemberId();
            ContractChainService sourceUsdtInstance = ChainService.getInstance(ChainEnum.BSC_USDT.name());
            int decimals = sourceUsdtInstance.decimals();
            BigInteger tokens = e.tokens;
            BigDecimal amount = new BigDecimal(tokens.toString()).divide(BigDecimal.TEN.pow(decimals), decimals, RoundingMode.HALF_DOWN);
            BigDecimal balance = amount;
            if (balance != null && balance.compareTo(new BigDecimal("0.1")) > 0) {
                balance = balance.setScale(8, RoundingMode.CEILING);
                BigDecimal early = BigDecimal.ZERO;
                // 查询钱包 并更新
                MallMemberWallet mallMemberWallet = mallMemberWalletMapper.selectWalletByMemberId(memberId);
                if (mallMemberWallet == null) {
                    return;
                }
 
                mallMemberWalletMapper.updateBlockBalanceById(mallMemberWallet.getId(), balance);
 
                String orderNo = insertCoinCharge(address, memberId, balance, CoinTypeEnum.USDT.name(), "ERC20", BigDecimal.ZERO, hash);
                // 插入财务记录
 
                Long chargeFlowId = mallMoneyFlowService.addMoneyFlow(
                        memberId,
                        orderNo,
                        balance.setScale(4, BigDecimal.ROUND_DOWN),
                        MallMoneyFlowTypeEnum.CHARGE.getCode(),
                        MallMoneyFlow.STATUS_SUCCESS,
                        MallMoneyFlow.IS_RETURN_Y,
                        memberId,
                        FlowTypeEnum.BALANCE.getValue(),
                        MallMoneyFlowTypeEnum.CHARGE.getName()
                );
            }
        }
    }
 
 
    public String insertCoinCharge(String address, Long memberId, BigDecimal newBalance, String symbol, String tag, BigDecimal lastAmount, String hash) {
        MemberCoinChargeEntity memberCoinChargeEntity = new MemberCoinChargeEntity();
        memberCoinChargeEntity.setAddress(address);
        memberCoinChargeEntity.setMemberId(memberId);
        memberCoinChargeEntity.setAmount(newBalance);
        memberCoinChargeEntity.setSymbol(symbol);
        memberCoinChargeEntity.setTag(tag);
        memberCoinChargeEntity.setStatus(1);
        memberCoinChargeEntity.setLastAmount(lastAmount);
        memberCoinChargeEntity.setHash(hash);
        String orderNo = generateNo();
        memberCoinChargeEntity.setOrderCode(orderNo);
        memberCoinChargeDao.insert(memberCoinChargeEntity);
        return orderNo;
    }
    private String generateNo() {
        // 生成订单号
        Long timestamp = System.currentTimeMillis();
        // 随机数
        int random = (int) (Math.random() * 10);
        return String.valueOf(timestamp).substring(2) + random;
    }
}