pom.xml
@@ -73,10 +73,17 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <!-- redis连接池 --> <dependency> <groupId>org.apache.commons</groupId> src/main/java/cc/mrbird/febs/common/contants/AppContants.java
@@ -103,10 +103,46 @@ public static final String REDIS_KEY_CHANGE_FEE = "DAPP_CHANGE_FEE"; public static final String REDIS_KEY_SIGN = "LOGIN_SIGN"; /** * 系统启动标志 */ public static final String SYSTEM_START_FLAG = "SYSTEM_START_FLAG"; /** * 中转池容量 */ public static final String REDIS_KEY_TRANSFER_POOL_VOL = "TRANSFER_POOL_VOL"; /** * 中转池剩余量 */ public static final String REDIS_KEY_TRANSFER_POOL_VOL_REMAIN = "TRANSFER_POOL_VOL_REMAIN"; /** * 每日源池出U限制 */ public static final String REDIS_KEY_USDT_OUT_LIMIT = "SOURCE_POOL_USDT_OUT_LIMIT"; /** * 每日源池出U限制 剩余 */ public static final String REDIS_KEY_USDT_OUT_LIMIT_REMAIN = "SOURCE_POOL_USDT_OUT_LIMIT_REMAIN"; public static final String REDIS_KEY_COIN_REMAIN = "COIN_REMAIN"; /** *24小时售币剩余 */ public static final String REDIS_KEY_COIN_REMAIN = "COIN_REMAIN_"; /** * 全网持币量 */ public static final String REDIS_KEY_MINE_ALL_INTERNET_CNT = "MINE_ALL_INTERNET_CNT"; /** * 中转池成交数量 */ public static final String REDIS_KEY_MINE_TRANSFER_POOL_TRADE_CNT = "MINE_TRANSFER_POOL_TRADE_CNT"; public static final String DIC_TYPE_DISTRIBUTE_PROP = "DISTRIBUTE_PROP"; public static final String DIC_TYPE_SYSTEM_SETTING = "SYSTEM_SETTING"; public static final String DIC_TYPE_SLIP_POINT_SETTING = "SLIP_POINT_SETTING"; public static final String DIC_VALUE_MINI_HOLD_COIN_LIMIT = "MINI_HOLD_COIN_LIMIT"; public static final String DESTROY_ADDRESS = "0x0000000000000000000000000000000000000000"; } src/main/java/cc/mrbird/febs/dapp/chain/ChainEnum.java
@@ -46,7 +46,7 @@ * 源池币 */ BSC_TFC_SOURCE("BSC", "0x977a9ddfb965a9a3416fa72ca7f91c4949c18f25", "", "0xefe98e00cd227b6322e892c82fcbd8eadf119c3188b7e574bc624f65405d61bf", "https://bsc-dataseed1.ninicoin.io", "0x6c6835e60e7dbad7a60112a6371271e8eb79ee68", ""), @@ -55,7 +55,7 @@ * 源池U */ BSC_USDT_SOURCE("BSC", "0x977a9ddfb965a9a3416fa72ca7f91c4949c18f25", "", "0xefe98e00cd227b6322e892c82fcbd8eadf119c3188b7e574bc624f65405d61bf", "https://bsc-dataseed1.ninicoin.io", "0x55d398326f99059fF775485246999027B3197955", ""), @@ -67,6 +67,15 @@ "0xefe98e00cd227b6322e892c82fcbd8eadf119c3188b7e574bc624f65405d61bf", "https://bsc-dataseed1.ninicoin.io", "0x6c6835e60e7dbad7a60112a6371271e8eb79ee68", ""), /** * 技术池 */ BSC_TFC_TECH("BSC", "0x977a9ddfb965a9a3416fa72ca7f91c4949c18f25", "", "https://bsc-dataseed1.ninicoin.io", "0x6c6835e60e7dbad7a60112a6371271e8eb79ee68", ""); private String chain; src/main/java/cc/mrbird/febs/dapp/entity/DappMemberEntity.java
@@ -50,4 +50,14 @@ * 链 1-以太坊 2-币安 3-波场 */ private String chainType; /** * 是否节点 1-是 2-否 */ private Integer nodeType; /** * 账号类型 admin normal */ private String accountType; } src/main/java/cc/mrbird/febs/dapp/entity/DappOnlineTransferEntity.java
New file @@ -0,0 +1,66 @@ package cc.mrbird.febs.dapp.entity; import cc.mrbird.febs.common.entity.BaseEntity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.math.BigDecimal; @Data @TableName("dapp_online_transfer") public class DappOnlineTransferEntity extends BaseEntity { public DappOnlineTransferEntity() {} public DappOnlineTransferEntity(String address, BigDecimal amount, Integer type, Integer targetType, String fromType, String symbol, String batchNo) { new DappOnlineTransferEntity(address, amount, type, targetType, symbol, fromType, "BSC", batchNo); } public DappOnlineTransferEntity(String address, BigDecimal amount, Integer type, Integer targetType, String fromType, String symbol, String chain, String batchNo) { this.address = address; this.amount = amount; this.type = type; this.targetType = targetType; this.symbol = symbol; this.chain = chain; this.batchNo = batchNo; this.fromType = fromType; this.hasFinish = 2; } private String address; private BigDecimal amount; /** * 流水类型 1-买入 2-卖出 3-挖矿 4-奖励 */ private Integer type; /** * 对象类型 1-普通账户 2-销毁账户 3-技术账户 */ private Integer targetType; /** * 发送地址类型 枚举类 */ private String fromType; /** * 币种 TFC/USDT */ private String symbol; private String chain; private String batchNo; /** * 是否已转账 1-是 2-否 */ private Integer hasFinish; private String txHash; } src/main/java/cc/mrbird/febs/dapp/entity/DataDictionaryCustom.java
New file @@ -0,0 +1,21 @@ package cc.mrbird.febs.dapp.entity; import cc.mrbird.febs.common.entity.BaseEntity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** * @date 2021-09-25 **/ @Data @TableName("data_dictionary_custom") public class DataDictionaryCustom extends BaseEntity { private String type; private String code; private String value; private String description; } src/main/java/cc/mrbird/febs/dapp/mapper/DappOnlineTransferDao.java
New file @@ -0,0 +1,11 @@ package cc.mrbird.febs.dapp.mapper; import cc.mrbird.febs.dapp.entity.DappOnlineTransferEntity; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import java.util.List; public interface DappOnlineTransferDao extends BaseMapper<DappOnlineTransferEntity> { List<DappOnlineTransferEntity> selectByBatchNo(String batchNo); } src/main/java/cc/mrbird/febs/dapp/mapper/DataDictionaryCustomMapper.java
New file @@ -0,0 +1,20 @@ package cc.mrbird.febs.dapp.mapper; import cc.mrbird.febs.dapp.entity.DataDictionaryCustom; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.apache.ibatis.annotations.Param; import java.util.List; public interface DataDictionaryCustomMapper extends BaseMapper<DataDictionaryCustom> { List<DataDictionaryCustom> selectDicByType(String type); DataDictionaryCustom selectNextAgentLevelInfo(@Param("level") String agentLevel); DataDictionaryCustom selectDicDataByTypeAndCode(@Param("type") String type, @Param("code") String code); int updateDicValueByTypeAndCode(@Param("type") String type, @Param("code") String code, @Param("value") String value); } src/main/java/cc/mrbird/febs/dapp/service/DappSystemService.java
@@ -12,4 +12,18 @@ Map<String, Object> globalSetting(); SystemDto system(); /** * 卖币滑点返利 * * @param id */ void tradeProfitDistribute(Long id); /** * 挖矿 */ void mining(); void onlineTransfer(String batchNo); } src/main/java/cc/mrbird/febs/dapp/service/impl/BscUsdtContractEvent.java
@@ -6,10 +6,14 @@ import cc.mrbird.febs.dapp.chain.*; import cc.mrbird.febs.dapp.entity.DappFundFlowEntity; import cc.mrbird.febs.dapp.entity.DappMemberEntity; import cc.mrbird.febs.dapp.entity.DappOnlineTransferEntity; import cc.mrbird.febs.dapp.mapper.DappFundFlowDao; import cc.mrbird.febs.dapp.mapper.DappMemberDao; import cc.mrbird.febs.dapp.mapper.DappOnlineTransferDao; import cc.mrbird.febs.dapp.service.DappMemberService; import cc.mrbird.febs.rabbit.producer.ChainProducer; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -19,6 +23,8 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; import java.util.HashMap; import java.util.Map; @Slf4j @Service @@ -32,6 +38,12 @@ @Resource private DappFundFlowDao dappFundFlowDao; @Resource private ChainProducer chainProducer; @Resource private DappOnlineTransferDao dappOnlineTransferDao; @Override @@ -65,12 +77,15 @@ // 如果系统会开启,则使用自动打款 if (!"start".equals(hasStart)) { String hash = ChainService.getInstance(ChainEnum.BSC_TFC_MAKE.name()).transfer(e.from, transferAmount); DappOnlineTransferEntity bsc = new DappOnlineTransferEntity(e.from, transferAmount, 1, 1, ChainEnum.BSC_TFC_MAKE.name(), "BSC", fundFlow.getId().toString()); dappOnlineTransferDao.insert(bsc); // 更新为已打款 fundFlow.setStatus(3); fundFlow.setToHash(hash); dappFundFlowDao.updateById(fundFlow); Map<String, String> map = new HashMap<>(); map.put("batchNo", fundFlow.getId().toString()); map.put("type", "flow"); // 发送转账消息 chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map)); } // 若源池中的USDT达到或超过8万U,则启动整个系统 src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java
@@ -7,25 +7,24 @@ import cc.mrbird.febs.dapp.chain.ChainService; import cc.mrbird.febs.dapp.chain.ContractChainService; import cc.mrbird.febs.dapp.dto.SystemDto; import cc.mrbird.febs.dapp.entity.DappMemberEntity; import cc.mrbird.febs.dapp.entity.DappMineDataEntity; import cc.mrbird.febs.dapp.entity.DappReturnRatioEntity; import cc.mrbird.febs.dapp.mapper.DappReturnRatioDao; import cc.mrbird.febs.dapp.mapper.DappSystemDao; import cc.mrbird.febs.dapp.entity.*; import cc.mrbird.febs.dapp.mapper.*; import cc.mrbird.febs.dapp.service.DappSystemService; import cc.mrbird.febs.dapp.vo.RedisTransferPoolVo; import cc.mrbird.febs.dapp.vo.SlipSettingVo; import cc.mrbird.febs.rabbit.producer.ChainProducer; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; 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.math.RoundingMode; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.*; /** * @author @@ -39,6 +38,11 @@ private final DappSystemDao dappSystemDao; private final DappReturnRatioDao dappReturnRatioDao; private final RedisUtils redisUtils; private final DappFundFlowDao dappFundFlowDao; private final DappMemberDao dappMemberDao; private final DataDictionaryCustomMapper dataDictionaryCustomMapper; private final DappOnlineTransferDao dappOnlineTransferDao; private final ChainProducer chainProducer; private final String[] ADDRESS_PREFIX = {"T", "0x"}; @Override @@ -80,13 +84,13 @@ ContractChainService instance = ChainService.getInstance(ChainEnum.BSC_TFC.name()); BigDecimal balance = instance.balanceOf(member.getAddress()); Object o = redisUtils.get(AppContants.REDIS_KEY_COIN_REMAIN); Object o = redisUtils.get(AppContants.REDIS_KEY_COIN_REMAIN + member.getAddress()); BigDecimal coinTotal = balance.multiply(BigDecimal.valueOf(0.3)).setScale(instance.decimals(), RoundingMode.HALF_DOWN); BigDecimal remain; if (o == null) { remain = coinTotal; redisUtils.set(AppContants.REDIS_KEY_COIN_REMAIN, remain); redisUtils.set(AppContants.REDIS_KEY_COIN_REMAIN + member.getAddress(), remain); } else { remain = (BigDecimal) o; } @@ -104,4 +108,162 @@ system.setFeeRatio(BigDecimal.TEN); return system; } @Override @Transactional(rollbackFor = Exception.class) public void tradeProfitDistribute(Long id) { DappFundFlowEntity fundflow = dappFundFlowDao.selectById(id); BigDecimal fee = fundflow.getFee(); DappMemberEntity member = dappMemberDao.selectById(fundflow.getMemberId()); if (StrUtil.isBlank(member.getRefererId()) || "0".equals(member.getRefererId())) { return; } List<String> inviteIds = StrUtil.split(member.getRefererId(), ','); List<DappMemberEntity> parents = dappMemberDao.selectParentsList(inviteIds, 6); DataDictionaryCustom miniHoldCoin = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_SYSTEM_SETTING, AppContants.DIC_VALUE_MINI_HOLD_COIN_LIMIT); DataDictionaryCustom slipPointSetting = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_SLIP_POINT_SETTING, AppContants.DIC_TYPE_SLIP_POINT_SETTING); SlipSettingVo slipSetting = JSONObject.parseObject(slipPointSetting.getValue(), SlipSettingVo.class); // 源池 ContractChainService instance = ChainService.getInstance(ChainEnum.BSC_TFC_SOURCE.name()); BigDecimal destroy = slipSetting.getDestroyPoint().divide(slipSetting.getAllPoint(), 2, RoundingMode.HALF_DOWN).multiply(fee); log.info("销毁数量:{}, 比例:{}", destroy, slipSetting.getDestroyPoint()); // 销毁 // instance.transfer(AppContants.DESTROY_ADDRESS, destroy); DappOnlineTransferEntity destroyRecord = new DappOnlineTransferEntity(AppContants.DESTROY_ADDRESS, destroy, fundflow.getType(), 3, ChainEnum.BSC_TFC_SOURCE.name(), "TFC", fundflow.getId().toString()); dappOnlineTransferDao.insert(destroyRecord); // 总分发金额 BigDecimal distrbAmount = fee.subtract(destroy); // 技术金额 BigDecimal techAmount = distrbAmount.multiply(slipSetting.getTechProp().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP)); // 节点金额 BigDecimal nodeAmount = distrbAmount.subtract(techAmount); log.info("总分发金额:{}, 技术:{}, 节点:{}", distrbAmount, techAmount, nodeAmount); BigDecimal preNode = slipSetting.getNodeProp().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); log.info("每份:{}", preNode); int i = 1; for (DappMemberEntity parent : parents) { BigDecimal balance = instance.balanceOf(parent.getAddress()); log.info("地址:{}, 余额:{}", parent.getAddress(), balance); // 若地址持币少了指定数量 或者 不为创始节点,则不参与节点滑点 if (balance.compareTo(new BigDecimal(miniHoldCoin.getValue())) < 0 || parent.getNodeType() == 2) { return; } DataDictionaryCustom distribDic = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_DISTRIBUTE_PROP, String.valueOf(i)); BigDecimal total = new BigDecimal(distribDic.getValue()).multiply(preNode); // instance.transfer(parent.getAddress(), total); DappOnlineTransferEntity distribRecord = new DappOnlineTransferEntity(parent.getAddress(), total, fundflow.getType(), 1, ChainEnum.BSC_TFC_SOURCE.name(), "TFC", fundflow.getId().toString()); dappOnlineTransferDao.insert(distribRecord); nodeAmount = nodeAmount.subtract(total); } // 若节点金额还有剩余,则进入技术金额 techAmount = techAmount.add(nodeAmount); // instance.transfer(ChainEnum.BSC_TFC_TECH.getAddress(), techAmount); DappOnlineTransferEntity techRecord = new DappOnlineTransferEntity(ChainEnum.BSC_TFC_TECH.getAddress(), techAmount, fundflow.getType(), 2, ChainEnum.BSC_TFC_SOURCE.name(), "TFC", fundflow.getId().toString()); dappOnlineTransferDao.insert(techRecord); Map<String, String> map = new HashMap<>(); map.put("batchNo", fundflow.getId().toString()); map.put("type", "flow"); // 发送转账消息 chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map)); } @Override public void mining() { log.info("挖矿"); Object o = redisUtils.get(AppContants.REDIS_KEY_MINE_ALL_INTERNET_CNT); if (o == null) { return; } Object transferPoolObj = redisUtils.get(AppContants.REDIS_KEY_MINE_TRANSFER_POOL_TRADE_CNT); BigDecimal allInternet = (BigDecimal) o; BigDecimal transferPoll = (BigDecimal) transferPoolObj; List<DappMemberEntity> allMembers = dappMemberDao.selectList(null); if (CollUtil.isEmpty(allMembers)) { return; } DataDictionaryCustom miniHoldCoin = dataDictionaryCustomMapper.selectDicDataByTypeAndCode(AppContants.DIC_TYPE_SYSTEM_SETTING, AppContants.DIC_VALUE_MINI_HOLD_COIN_LIMIT); String batchNo = RandomUtil.randomString(32); ContractChainService instance = ChainService.getInstance(ChainEnum.BSC_TFC.name()); for (DappMemberEntity member : allMembers) { if ("admin".equals(member.getAccountType())) { continue; } BigDecimal balance = instance.balanceOf(member.getAddress()); if (balance.compareTo(new BigDecimal(miniHoldCoin.getValue())) < 1) { continue; } // 挖矿数量 BigDecimal mine = transferPoll.multiply(balance.divide(allInternet, instance.decimals(), RoundingMode.HALF_UP)); if (mine.compareTo(BigDecimal.ZERO) < 1) { continue; } DappOnlineTransferEntity tfc = new DappOnlineTransferEntity(member.getAddress(), mine, 3, 1, "TFC", ChainEnum.BSC_TFC.name(), batchNo); dappOnlineTransferDao.insert(tfc); } Map<String, String> map = new HashMap<>(); map.put("batchNo", batchNo); map.put("type", "batch"); // 发送转账消息 chainProducer.sendOnlineTransfer(JSONObject.toJSONString(map)); } @Override public void onlineTransfer(String str) { JSONObject jsonObject = JSONObject.parseObject(str); String batchNo = jsonObject.getString("batchNo"); List<DappOnlineTransferEntity> transferList = dappOnlineTransferDao.selectByBatchNo(batchNo); if (CollUtil.isEmpty(transferList)) { return; } for (DappOnlineTransferEntity transfer : transferList) { if (transfer.getHasFinish() == 1) { continue; } // TODO 线上转账,已注释 // String txHash = ChainService.getInstance(transfer.getFromType()).transfer(transfer.getAddress(), transfer.getAmount()); // transfer.setTxHash(txHash); transfer.setHasFinish(1); transfer.setUpdateTime(new Date()); dappOnlineTransferDao.updateById(transfer); if ("flow".equals(jsonObject.getString("type"))) { DappFundFlowEntity fundFlow = dappFundFlowDao.selectById(Long.parseLong(batchNo)); fundFlow.setStatus(3); // fundFlow.setToHash(txHash); dappFundFlowDao.updateById(fundFlow); } } } } src/main/java/cc/mrbird/febs/dapp/vo/SlipSettingVo.java
New file @@ -0,0 +1,38 @@ package cc.mrbird.febs.dapp.vo; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2022-05-31 **/ @Data public class SlipSettingVo { /** * 交易滑点 8% */ private BigDecimal allPoint; /** * 销毁滑点 8% 中 的八分之一 */ private BigDecimal destroyPoint; /** * 分发滑点 8% 中的 八分之七 */ private BigDecimal distrbPoint; /** * 技术比例 分发滑点中的 20% */ private BigDecimal techProp; /** * 创始方比例 分发滑点中的 80% */ private BigDecimal nodeProp; } src/main/java/cc/mrbird/febs/job/SystemTradeJob.java
@@ -4,6 +4,7 @@ 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.service.DappSystemService; import cc.mrbird.febs.dapp.vo.RedisTransferPoolVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -23,6 +24,8 @@ @Autowired private RedisUtils redisUtils; @Autowired private DappSystemService systemService; // 最低容量(百分比) private final BigDecimal volProp = new BigDecimal("0.5"); @@ -51,11 +54,16 @@ transferPool.setFinishCnt(0); redisUtils.set(AppContants.REDIS_KEY_TRANSFER_POOL_VOL, transferPool); redisUtils.set(AppContants.REDIS_KEY_TRANSFER_POOL_VOL_REMAIN, total); redisUtils.set(AppContants.REDIS_KEY_MINE_TRANSFER_POOL_TRADE_CNT, BigDecimal.ZERO); return; } RedisTransferPoolVo transferPool = (RedisTransferPoolVo) o; BigDecimal remain = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_TRANSFER_POOL_VOL_REMAIN); // 设置当日成交量 redisUtils.set(AppContants.REDIS_KEY_MINE_TRANSFER_POOL_TRADE_CNT, transferPool.getTodayVol().subtract(remain)); // 全卖了 if (remain.compareTo(BigDecimal.ZERO) == 0) { @@ -107,4 +115,15 @@ redisUtils.set(AppContants.REDIS_KEY_USDT_OUT_LIMIT, total); redisUtils.set(AppContants.REDIS_KEY_USDT_OUT_LIMIT_REMAIN, total); } /** * 挖矿 * * 以中转池成交数1:1出矿(中转池卖出多少,矿池则1:1出币),每个地址所得=出币量*(单个地址持币量/全网持币量) */ @Scheduled(cron = "0 0 2 * * ?") public void mineJob() { systemService.mining(); } } src/main/java/cc/mrbird/febs/rabbit/QueueConstants.java
New file @@ -0,0 +1,10 @@ package cc.mrbird.febs.rabbit; /** * @author wzy * @date 2022-05-31 **/ public class QueueConstants { public static final String ONLINE_TRANSFER = "queue_online_transfer"; } src/main/java/cc/mrbird/febs/rabbit/QueueEnum.java
New file @@ -0,0 +1,22 @@ package cc.mrbird.febs.rabbit; import lombok.Data; import lombok.Getter; @Getter public enum QueueEnum { ONLINE_TRANSFER("exchange_online_transfer", "route_key_online_transfer", "queue_online_transfer"); private String exchange; private String route; private String queue; QueueEnum(String exchange, String route, String queue) { this.exchange = exchange; this.route = route; this.queue = queue; } } src/main/java/cc/mrbird/febs/rabbit/RabbitConfiguration.java
New file @@ -0,0 +1,46 @@ package cc.mrbird.febs.rabbit; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.DirectExchange; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import javax.annotation.Resource; /** * @author wzy * @date 2022-05-31 **/ @Configuration public class RabbitConfiguration { @Resource private ConnectionFactory connectionFactory; @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public RabbitTemplate rabbitTemplate() { return new RabbitTemplate(connectionFactory); } @Bean public DirectExchange onlineTransferExchange() { return new DirectExchange(QueueEnum.ONLINE_TRANSFER.getExchange()); } @Bean public Queue onlineTransferQueue() { return new Queue(QueueEnum.ONLINE_TRANSFER.getQueue()); } @Bean public Binding defaultBind() { return BindingBuilder.bind(onlineTransferQueue()).to(onlineTransferExchange()).with(QueueEnum.ONLINE_TRANSFER.getRoute()); } } src/main/java/cc/mrbird/febs/rabbit/consumer/ChainConsumer.java
New file @@ -0,0 +1,30 @@ package cc.mrbird.febs.rabbit.consumer; import cc.mrbird.febs.dapp.service.DappSystemService; import cc.mrbird.febs.rabbit.QueueConstants; import com.rabbitmq.client.Channel; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; /** * @author wzy * @date 2022-05-31 **/ @Slf4j @Component @ConditionalOnProperty(prefix = "system", name = "online-transfer", havingValue = "true") public class ChainConsumer { @Autowired private DappSystemService dappSystemService; @RabbitListener(queues = QueueConstants.ONLINE_TRANSFER) public void onlineTransfer(String batchNo) { log.info("收到链上转账消息:{}", batchNo); dappSystemService.onlineTransfer(batchNo); } } src/main/java/cc/mrbird/febs/rabbit/producer/ChainProducer.java
New file @@ -0,0 +1,41 @@ package cc.mrbird.febs.rabbit.producer; import cc.mrbird.febs.rabbit.QueueEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.UUID; /** * @author wzy * @date 2022-05-31 **/ @Slf4j @Component public class ChainProducer implements RabbitTemplate.ConfirmCallback { /** * 配置中配置的RabbitTemplate的是prototype类型,不能直接注入 */ private RabbitTemplate rabbitTemplate; @Autowired public ChainProducer(RabbitTemplate rabbitTemplate) { this.rabbitTemplate = rabbitTemplate; rabbitTemplate.setConfirmCallback(this); } @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { } public void sendOnlineTransfer(String batchNo) { log.info("发送链上转账消息:{}", batchNo); CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); rabbitTemplate.convertAndSend(QueueEnum.ONLINE_TRANSFER.getExchange(), QueueEnum.ONLINE_TRANSFER.getRoute(), batchNo, correlationData); } } src/main/resources/application-dev.yml
@@ -2,7 +2,7 @@ datasource: dynamic: # 是否开启 SQL日志输出,生产环境建议关闭,有性能损耗 p6spy: true p6spy: false hikari: connection-timeout: 30000 max-lifetime: 1800000 @@ -15,10 +15,10 @@ datasource: # 数据源-1,名称为 base base: username: sys_lab password: sys_lab!@#123 username: ct_test password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://154.91.195.148:3306/sys_lab?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8 url: jdbc:mysql://120.27.238.55:3306/db_tfc?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8 redis: # Redis数据库索引(默认为 0) @@ -41,3 +41,12 @@ max-wait: 10000 # 连接超时时间(毫秒) timeout: 5000 rabbitmq: host: 120.27.238.55 port: 5672 username: ct_rabbit password: 123456 publisher-confirm-type: correlated system: online-transfer: false src/main/resources/application-test.yml
@@ -41,3 +41,12 @@ max-wait: 10000 # 连接超时时间(毫秒) timeout: 5000 rabbitmq: host: 120.27.238.55 port: 5672 username: ct_rabbit password: 123456 publisher-confirm-type: correlated system: online-transfer: true src/main/resources/application.yml
@@ -5,7 +5,7 @@ spring: profiles: active: test active: dev thymeleaf: cache: false src/main/resources/mapper/dapp/DappMemberDao.xml
@@ -72,5 +72,6 @@ <if test="size != null"> limit ${size} </if> order by id desc </select> </mapper> src/main/resources/mapper/dapp/DappOnlineTransferDao.xml
New file @@ -0,0 +1,10 @@ <?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="cc.mrbird.febs.dapp.mapper.DappOnlineTransferDao"> <select id="selectByBatchNo" resultType="cc.mrbird.febs.dapp.entity.DappTransferRecordEntity"> select * from dapp_online_transfer where batch_no=#{batchNo} </select> </mapper> src/main/resources/mapper/dapp/DataDictionaryCustomMapper.xml
New file @@ -0,0 +1,36 @@ <?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="cc.mrbird.febs.dapp.mapper.DataDictionaryCustomMapper"> <select id="selectDicByType" resultType="cc.mrbird.febs.dapp.entity.DataDictionaryCustom"> select * from data_dictionary_custom where type=#{type} </select> <select id="selectNextAgentLevelInfo" resultType="cc.mrbird.febs.dapp.entity.DataDictionaryCustom"> select * from data_dictionary_custom x where x.type='AGENT_LEVEL_REQUIRE' and x.code = ( select a.code from data_dictionary_custom a where a.type='AGENT_LEVEL' and a.value > (select b.value from data_dictionary_custom b where b.type='AGENT_LEVEL' and b.code=#{level}) order by a.value limit 1 ) </select> <select id="selectDicDataByTypeAndCode" resultType="cc.mrbird.febs.dapp.entity.DataDictionaryCustom"> select * from data_dictionary_custom a where a.type=#{type} and a.code=#{code} </select> <update id="updateDicValueByTypeAndCode"> update data_dictionary_custom set value=#{value} <where> 1=1 <if test="code != null and code != ''"> and code = #{code} </if> <if test="type != null and type != ''"> and type = #{type} </if> </where> </update> </mapper>