Helius
2020-07-02 cbf27426370f1fc9c8ae27b717c8d1f175ea358e
add guiji
8 files added
4 files modified
348 ■■■■■ changed files
src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java 159 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinAddressDao.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinChargeDao.java 11 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/dao/MemberWalletCoinDao.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/member/entity/MemberCoinChargeEntity.java 36 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java 40 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/LogRecordUtils.java 26 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/MemberCoinAddressDao.xml 16 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/MemberCoinChargeDao.xml 15 ●●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/MemberWalletCoinDao.xml 10 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java
New file
@@ -0,0 +1,13 @@
package com.xcong.excoin.modules.coin.service;
public interface BlockCoinService {
    public void updateEthUsdt();
    public void updateEth();
    public void updateBtcUsdt();
    public void updateBtc();
}
src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java
New file
@@ -0,0 +1,159 @@
package com.xcong.excoin.modules.coin.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.xcong.excoin.common.enumerates.CoinTypeEnum;
import com.xcong.excoin.modules.blackchain.service.EthService;
import com.xcong.excoin.modules.coin.service.BlockCoinService;
import com.xcong.excoin.modules.member.dao.MemberCoinAddressDao;
import com.xcong.excoin.modules.member.dao.MemberCoinChargeDao;
import com.xcong.excoin.modules.member.dao.MemberDao;
import com.xcong.excoin.modules.member.dao.MemberWalletCoinDao;
import com.xcong.excoin.modules.member.entity.MemberCoinAddressEntity;
import com.xcong.excoin.modules.member.entity.MemberCoinChargeEntity;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity;
import com.xcong.excoin.utils.LogRecordUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
/**
 * @author wzy
 * @date 2020-07-02
 **/
@Slf4j
@Service
public class BlockCoinServiceImpl implements BlockCoinService {
    @Resource
    private MemberCoinAddressDao memberCoinAddressDao;
    @Resource
    private MemberDao memberDao;
    @Resource
    private MemberCoinChargeDao memberCoinChargeDao;
    @Resource
    private MemberWalletCoinDao memberWalletCoinDao;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateEthUsdt() {
        List<MemberCoinAddressEntity> list = memberCoinAddressDao.selectAllBlockAddressBySymbolAndTag(CoinTypeEnum.USDT.name(), "ERC20");
        if (CollUtil.isNotEmpty(list)) {
            EthService ethService = new EthService();
            for (MemberCoinAddressEntity addressEntity : list) {
                String address = addressEntity.getAddress();
                Long memberId = addressEntity.getMemberId();
                if (StrUtil.isNotBlank(address)) {
                    continue;
                }
                BigDecimal balance = ethService.tokenGetBalance(address);
                if (balance != null && balance.compareTo(new BigDecimal("0.1")) > 0) {
                    balance = balance.setScale(8, RoundingMode.CEILING);
                    BigDecimal early = BigDecimal.ZERO;
                    MemberCoinChargeEntity chargeEntity = memberCoinChargeDao.selectNewestChargeRecord(memberId, CoinTypeEnum.USDT.name(), "ERC20");
                    if (chargeEntity != null) {
                        BigDecimal lastAmount = chargeEntity.getLastAmount();
                        if (lastAmount != null) {
                            early = lastAmount;
                        }
                    }
                    MemberWalletCoinEntity walletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.USDT.name());
                    if (walletCoinEntity == null) {
                        continue;
                    }
                    if (balance.compareTo(early) > 0) {
                        BigDecimal newBalance = balance.subtract(early);
                        memberWalletCoinDao.updateBlockBalance(memberId, newBalance, balance, 0);
                        insertCoinCharge(address, memberId, newBalance, CoinTypeEnum.USDT.name(), "ERC20", balance);
                        // TODO 钉钉发送, 短信提醒
                    }
                }
            }
        }
    }
    @Override
    public void updateEth() {
        List<MemberCoinAddressEntity> list = memberCoinAddressDao.selectAllBlockAddressBySymbol(CoinTypeEnum.ETH.name());
        if (CollUtil.isNotEmpty(list)) {
            for (MemberCoinAddressEntity coinAddressEntity : list) {
                String address = coinAddressEntity.getAddress();
                Long memberId = coinAddressEntity.getMemberId();
                BigDecimal balance = EthService.getEthBlance(address);
                if (balance != null && new BigDecimal("0.008").compareTo(balance) < 0) {
                    MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, CoinTypeEnum.ETH.name());
                    if (walletCoin == null) {
                        continue;
                    }
                    BigDecimal early = BigDecimal.ZERO;
                    MemberCoinChargeEntity coinChargeEntity = memberCoinChargeDao.selectNewestChargeRecord(memberId, CoinTypeEnum.ETH.name(), null);
                    if (coinChargeEntity != null) {
                        BigDecimal lastAmount = coinChargeEntity.getLastAmount();
                        if (lastAmount != null) {
                            early = lastAmount;
                        }
                    }
                    balance = balance.setScale(8, RoundingMode.CEILING);
                    if (balance.compareTo(early) > 0) {
                        log.info("#ETH更新:{},{},{}#", memberId, balance, early);
                        BigDecimal newBalance = balance.subtract(early);
                        memberWalletCoinDao.updateBlockBalance(memberId, newBalance, balance, 0);
                        insertCoinCharge(address, memberId, newBalance, CoinTypeEnum.ETH.name(), null, balance);
                        // 插入财务记录
                        LogRecordUtils.insertMemberAccountMoneyChange(memberId, "转入", newBalance, CoinTypeEnum.ETH.name(), 1, 1);
                        // TODO 钉钉消息, 短信提醒
                    }
                }
            }
        }
    }
    @Override
    public void updateBtcUsdt() {
    }
    @Override
    public void updateBtc() {
    }
    private String generateNo() {
        // 生成订单号
        Long timestamp = System.currentTimeMillis();
        // 随机数
        int random = (int) (Math.random() * 10);
        return String.valueOf(timestamp).substring(2) + random;
    }
    public void insertCoinCharge(String address, Long memberId, BigDecimal newBalance, String symbol, String tag, BigDecimal lastAmount) {
        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.setOrderCode(generateNo());
        memberCoinChargeDao.insert(memberCoinChargeEntity);
    }
}
src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinAddressDao.java
@@ -12,10 +12,14 @@
    MemberCoinAddressEntity selectAddressByMemberIdAndSymbol(Long memberId, String symbol);
    
    MemberCoinAddressEntity selectBlockAddressWithTag(@Param("memberId")Long memberId, @Param("symbol")String symbol, @Param("tag")String tag);
    MemberCoinAddressEntity selectBlockAddress(@Param("memberId")Long memberId, @Param("symbol")String symbol);
    List<MemberCoinAddressEntity> selectCoinAddressListByMap(@Param("symbol")String symbol, @Param("memberId")Long memberId);
    List<MemberCoinAddressEntity> selectAllBlockAddressBySymbolAndTag(@Param("symbol") String symbol, @Param("tag") String tag);
    List<MemberCoinAddressEntity> selectAllBlockAddressBySymbol(@Param("symbol") String symbol);
}
src/main/java/com/xcong/excoin/modules/member/dao/MemberCoinChargeDao.java
New file
@@ -0,0 +1,11 @@
package com.xcong.excoin.modules.member.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xcong.excoin.modules.member.entity.MemberCoinChargeEntity;
import org.apache.ibatis.annotations.Param;
public interface MemberCoinChargeDao extends BaseMapper<MemberCoinChargeEntity> {
    public MemberCoinChargeEntity selectNewestChargeRecord(@Param("memberId") Long memberId, @Param("symbol") String symbol, @Param("tag") String tag);
}
src/main/java/com/xcong/excoin/modules/member/dao/MemberWalletCoinDao.java
@@ -20,4 +20,6 @@
    int updateFrozenBalance(@Param("memberId")Long memberId,@Param("id")Long id,@Param("amount")BigDecimal amount);
    
    int subFrozenBalance(@Param("memberId")Long memberId,@Param("id")Long id,@Param("amount")BigDecimal amount);
    int updateBlockBalance(@Param("memberId") Long memberId, @Param("availableBalance") BigDecimal availableBalance, @Param("earlyBalance") BigDecimal earlyBalance, @Param("blockNumber") Integer blockNumber);
}
src/main/java/com/xcong/excoin/modules/member/entity/MemberCoinChargeEntity.java
New file
@@ -0,0 +1,36 @@
package com.xcong.excoin.modules.member.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xcong.excoin.common.system.base.BaseEntity;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @author wzy
 * @date 2020-07-02
 **/
@Data
@TableName("member_coin_charge")
public class MemberCoinChargeEntity extends BaseEntity {
    private Long memberId;
    private String certificate;
    private BigDecimal amount;
    private BigDecimal lastAmount;
    private int status;
    private String symbol;
    private String address;
    private String tag;
    private String hash;
    private String orderCode;
}
src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java
New file
@@ -0,0 +1,40 @@
package com.xcong.excoin.quartz.job;
import com.xcong.excoin.modules.coin.service.BlockCoinService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * 链上币种同步任务
 *
 * @author wzy
 * @date 2020-07-02
 **/
@Component
@ConditionalOnProperty(prefix = "app", name = "block-job", havingValue = "true")
public class BlockCoinUpdateJob {
    @Resource
    private BlockCoinService blockCoinService;
    /**
     * ETH_USDT 同步
     */
    @Scheduled(cron = "0 0/10 * * * ? ")
    public void ethUsdtUpdate() {
        blockCoinService.updateEthUsdt();
    }
    /**
     * eth 同步
     */
    @Scheduled(cron = "0 1/20 * * * ? ")
    public void ethUpdate() {
        blockCoinService.updateEth();
    }
}
src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java
New file
@@ -0,0 +1,16 @@
package com.xcong.excoin.quartz.job;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
/**
 * 归集定时任务
 *
 * @author wzy
 * @date 2020-07-02
 **/
@Component
@ConditionalOnProperty(prefix = "app", name = "block-job", havingValue = "true")
public class NotionalPoolingJob {
}
src/main/java/com/xcong/excoin/utils/LogRecordUtils.java
New file
@@ -0,0 +1,26 @@
package com.xcong.excoin.utils;
import com.xcong.excoin.modules.coin.dao.MemberAccountMoneyChangeDao;
import com.xcong.excoin.modules.coin.entity.MemberAccountMoneyChange;
import java.math.BigDecimal;
/**
 * 日志记录工具类
 *
 * @author wzy
 * @date 2020-07-02
 **/
public class LogRecordUtils {
    public static void insertMemberAccountMoneyChange(Long memberId,String content, BigDecimal amount, String symbol, Integer status, Integer type) {
        MemberAccountMoneyChange accountRecord = new MemberAccountMoneyChange();
        accountRecord.setContent(content);
        accountRecord.setMemberId(memberId);
        accountRecord.setAmount(amount);
        accountRecord.setStatus(status);
        accountRecord.setSymbol(symbol);
        accountRecord.setType(type);
        SpringContextHolder.getBean(MemberAccountMoneyChangeDao.class).insert(accountRecord);
    }
}
src/main/resources/mapper/member/MemberCoinAddressDao.xml
@@ -51,4 +51,20 @@
         </where>
    </select>
    
    <select id="selectAllBlockAddressBySymbolAndTag" resultType="com.xcong.excoin.modules.member.entity.MemberCoinAddressEntity">
        select * from member_coin_address
        where is_biyict = 1
        <if test="symbol != null  and  symbol  != ''">
            and symbol = #{symbol}
        </if>
        <if test="tag != null  and  tag  != ''">
            and tag = #{tag}
        </if>
    </select>
    <select id="selectAllBlockAddressBySymbol" resultType="com.xcong.excoin.modules.member.entity.MemberCoinAddressEntity">
        select * from member_coin_address
        where symbol=#{symbol}
    </select>
</mapper>
src/main/resources/mapper/member/MemberCoinChargeDao.xml
New file
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.modules.member.dao.MemberCoinChargeDao">
    <select id="selectNewestChargeRecord" resultType="com.xcong.excoin.modules.member.entity.MemberCoinChargeEntity">
        select * from member_coin_charge
        where member_id=#{memberId}
        and symbol=#{symbol}
        <if test="tag !=null and tag != ''">
            and tag = #{tag}
        </if>
        order by create_time desc limit 1
    </select>
</mapper>
src/main/resources/mapper/member/MemberWalletCoinDao.xml
@@ -29,7 +29,15 @@
    </update>
    
    
    <update id="updateBlockBalance">
        update member_wallet_coin
        set
        available_balance = IFNULL(available_balance, 0) + #{availableBalance},
        total_balance = IFNULL(total_balance, 0) + #{availableBalance},
        early_balance = IFNULL(early_balance, 0) + #{earlyBalance},
        block_number  = IFNULL(block_number, 0) + #{blockNumber}
        where id=#{memberId}
    </update>
</mapper>