1
zj
2025-05-25 370c0e6d54be9222fcaa416fdd605f09e3c49e8a
1
9 files modified
9 files added
1285 ■■■■ changed files
.idea/encodings.xml 1 ●●●● patch | view | raw | blame | history
pom.xml 15 ●●●●● patch | view | raw | blame | history
src/main/java/project/blockchain/AdminRechargeBlockchainOrderService.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/project/blockchain/RechargeBlockchainService.java 1 ●●●● patch | view | raw | blame | history
src/main/java/project/blockchain/internal/AdminRechargeBlockchainOrderServiceImpl.java 9 ●●●● patch | view | raw | blame | history
src/main/java/project/blockchain/internal/RechargeBlockchainServiceImpl.java 552 ●●●● patch | view | raw | blame | history
src/main/java/project/web/admin/AdminRechargeBlockchainOrderController.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/admin/ResultMsg.java 40 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/Address.java 31 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/ApiPath.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/Coin.java 78 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/ResultMsg.java 40 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/UdunApi.java 108 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/UdunClient.java 132 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/UdunException.java 28 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/UdunUtils.java 88 ●●●●● patch | view | raw | blame | history
src/main/java/project/web/api/UserWalletAddressController.java 123 ●●●● patch | view | raw | blame | history
src/main/java/project/web/api/filter/AllRequestFilter.java 1 ●●●● patch | view | raw | blame | history
.idea/encodings.xml
@@ -2,5 +2,6 @@
<project version="4">
  <component name="Encoding">
    <file url="file://$PROJECT_DIR$/../../Backup/Downloads/LocalUserController.class01" charset="GBK" />
    <file url="file://$PROJECT_DIR$/../../Backup/Downloads/RechargeBlockchainServiceImpl.class01" charset="GBK" />
  </component>
</project>
pom.xml
@@ -15,7 +15,22 @@
      <version>8.5.100</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>5.4.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.32</version> <!-- 使用与你的SLF4J版本匹配的版本 -->
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>1.7.32</version> <!-- 或其他绑定,如slf4j-log4j12或slf4j-logback -->
    </dependency>
    <!--springmvc组件-->
    <dependency>
      <groupId>javax.servlet</groupId>
src/main/java/project/blockchain/AdminRechargeBlockchainOrderService.java
@@ -34,4 +34,6 @@
     * 修改图片信息
     */
    public void saveRechargeImg(String id, String img,String safeword,String userName,String partyId);
    void callback(String timestamp, String nonce, String sign, String body);
}
src/main/java/project/blockchain/RechargeBlockchainService.java
@@ -45,4 +45,5 @@
     */
    public boolean saveReject(RechargeBlockchain recharge);
    void callback(String timestamp, String nonce, String sign, String body);
}
src/main/java/project/blockchain/internal/AdminRechargeBlockchainOrderServiceImpl.java
@@ -219,8 +219,13 @@
        logService.saveSync(log);
    }
    public void updateRechargeBlockchain(RechargeBlockchain recharge) {
    @Override
    public void callback(String timestamp, String nonce, String sign, String body) {
        rechargeBlockchainService.callback(timestamp, nonce, sign,body);
    }
    public void updateRechargeBlockchain(RechargeBlockchain recharge) {
        Object[] jdbcParams = ApplicationUtil.getUpdateStatement(recharge, "WHERE UUID=?", new Object[] {recharge.getId()});
        String updateUserSql = (String)jdbcParams[0];
        Object[] sqlParameters = (Object[])jdbcParams[1];
src/main/java/project/blockchain/internal/RechargeBlockchainServiceImpl.java
@@ -5,14 +5,16 @@
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.ObjectUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import kernel.bo.RecordObjectMapper;
import kernel.exception.BusinessException;
import kernel.util.Arith;
import kernel.web.ApplicationUtil;
import org.springframework.transaction.annotation.Transactional;
import project.Constants;
import project.blockchain.ChannelBlockchain;
import project.blockchain.ChannelBlockchainService;
@@ -27,14 +29,16 @@
import project.log.MoneyLogService;
import project.party.PartyService;
import project.party.model.Party;
import project.redis.RedisHandler;
import project.syspara.Syspara;
import project.syspara.SysparaService;
import project.tip.TipConstants;
import project.tip.TipService;
import project.user.UserDataService;
import project.wallet.*;
import project.wallet.internal.WalletGatherServiceImpl;
import project.wallet.Wallet;
import project.wallet.WalletExtend;
import project.wallet.WalletLog;
import project.wallet.WalletLogService;
import project.wallet.WalletService;
import project.wallet.rate.ExchangeRateService;
import security.SecUser;
import security.internal.SecUserService;
@@ -57,30 +61,9 @@
    protected SysparaService sysparaService;
    protected ChannelBlockchainService channelBlockchainService;
    protected TipService tipService;
    protected RedisHandler redisHandler;
    @Override
    public void save(RechargeBlockchain recharge) {
        List<RechargeBlockchain> oreders = this.findByPartyIdAndSucceeded(recharge.getPartyId(), 0);
        double recharge_only_one = Double.valueOf(sysparaService.find("recharge_only_one").getValue());
        if (oreders != null && recharge_only_one==1) {
            throw new BusinessException("提交失败,当前有未处理订单");
        }
        if (!"ETH".equals(recharge.getSymbol().toUpperCase())) {
            JdbcTemplate jdbcTemplate=ApplicationUtil.getBean(JdbcTemplate.class);
            List<HashMap> list=jdbcTemplate.query("SELECT * FROM T_PARTY_BLOCKCHAIN WHERE ADDRESS =?",RecordObjectMapper.newInstance(HashMap.class),recharge.getChannel_address());
            if(ObjectUtils.isEmpty(list)) {
                ChannelBlockchain channel = channelBlockchainService.findByNameAndCoinAndAdd(recharge.getBlockchain_name(),
                        recharge.getSymbol(), recharge.getChannel_address());
                if (channel == null || !recharge.getSymbol().toUpperCase().equals(channel.getCoin())) {
                    throw new BusinessException("充值链错误");
                }
            }
        }
        DecimalFormat df = new DecimalFormat("#.##");
//        amount = Double.valueOf(df.format(amount));
        double recharge_limit_min = Double.valueOf(sysparaService.find("recharge_limit_min").getValue());
@@ -389,65 +372,75 @@
        tipService.deleteTip(recharge.getId().toString());
    }
    /**
     * 根据ID获取充值订单
     */
    public RechargeBlockchain get(String id) {
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE UUID=?", RecordObjectMapper.newInstance(RechargeBlockchain.class), id);
        if (null != list && list.size() > 0) {
            return list.get(0);
        }
        return null;
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE UUID=?", RecordObjectMapper.newInstance(RechargeBlockchain.class), id);
        if (null != list && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }
    /**
     * 根据区块地址获取充值订单
     */
    public RechargeBlockchain getAddress(String address) {
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE blockchain_name=?", RecordObjectMapper.newInstance(RechargeBlockchain.class), address);
        if (null != list && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }
    @Override
    public RechargeBlockchain findByOrderNo(String order_no) {
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE ORDER_NO=?",
                RecordObjectMapper.newInstance(RechargeBlockchain.class), order_no);
        if (null != list && list.size() > 0) {
            return list.get(0);
        }
        return null;
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE ORDER_NO=?",
                RecordObjectMapper.newInstance(RechargeBlockchain.class), order_no);
        if (null != list && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }
    public List<RechargeBlockchain> findByPartyIdAndToday(Serializable partyId) {
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE PARTY_ID=? AND DateDiff(CREATED,NOW())=0 ",
                RecordObjectMapper.newInstance(RechargeBlockchain.class), partyId);
        if (list.size() > 0) {
            return list;
        }
        return null;
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE PARTY_ID=? AND DateDiff(CREATED,NOW())=0 ",
                RecordObjectMapper.newInstance(RechargeBlockchain.class), partyId);
        if (list.size() > 0) {
            return list;
        }
        return null;
    }
    public List<RechargeBlockchain> findBySucceededAndDay(int succeeded, Integer days) {
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE SUCCEEDED=? AND DateDiff(CREATED,NOW())=-1 ",
                RecordObjectMapper.newInstance(RechargeBlockchain.class), succeeded);
        if (list.size() > 0) {
            return list;
        }
        return null;
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE SUCCEEDED=? AND DateDiff(CREATED,NOW())=-1 ",
                RecordObjectMapper.newInstance(RechargeBlockchain.class), succeeded);
        if (list.size() > 0) {
            return list;
        }
        return null;
    }
    public List<RechargeBlockchain> findByPartyIdAndSucceeded(Serializable partyId, int succeeded) {
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE PARTY_ID=? AND SUCCEEDED=? ",
                RecordObjectMapper.newInstance(RechargeBlockchain.class), partyId, succeeded);
        if (list.size() > 0) {
            return list;
        }
        return null;
        List<RechargeBlockchain> list = jdbcTemplate.query("SELECT * FROM T_RECHARGE_BLOCKCHAIN_ORDER WHERE PARTY_ID=? AND SUCCEEDED=? ",
                RecordObjectMapper.newInstance(RechargeBlockchain.class), partyId, succeeded);
        if (list.size() > 0) {
            return list;
        }
        return null;
    }
    @Override
    public boolean saveSucceeded(String id, String operator, double success_amount) {
        System.out.println("进入saveSucceeded方法,参数operator="+operator+",success_amount="+success_amount);
        // RechargeBlockchain recharge = this.findByOrderNo(order_no);
        RechargeBlockchain recharge = this.get(id);
        String order_no = recharge.getOrder_no();
        if (recharge.getSucceeded() == 1) {
            return false;
        }
        recharge.setReviewTime(new Date());
        recharge.setSucceeded(1);
@@ -461,8 +454,8 @@
            log.setUsername(secUser.getUsername());
            log.setPartyId(recharge.getPartyId());
            log.setCreateTime(new Date());
            log.setLog("管理员修改充值数量,原充值数量["
            + recharge.getVolume() + "],修改后充值数量[" + success_amount + "]。订单号[" + order_no+ "]。");
            log.setLog("管理员修改充值数量,原充值数量["
                    + recharge.getVolume() + "],修改后充值数量[" + success_amount + "]。订单号[" + order_no+ "]。");
            logService.saveSync(log);
            walletLog.setAmount(success_amount);
@@ -476,63 +469,72 @@
        Party party = this.partyService.cachePartyBy(recharge.getPartyId(), false);
        Syspara user_recom_bonus_open = sysparaService.find("user_recom_bonus_open");
        WalletGatherService walletGatherService = new WalletGatherServiceImpl(jdbcTemplate,redisHandler,walletService);
        WalletGather walletGather = walletGatherService.getWalletGatherByPartyId(recharge.getPartyId(),null);
        double amount = recharge.getVolume();
        // 保存资金日志
        MoneyLog moneyLog = new MoneyLog();
        moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
        System.out.println("recharge.getSymbol()===="+recharge.getSymbol());
        if("usdt".equals(recharge.getSymbol())){
            moneyLog.setAmount_before(walletGather.getUsdtMoney());
            moneyLog.setAmount_after(Arith.add(walletGather.getUsdtMoney(), amount));
            moneyLog.setWallettype(Constants.WALLET_GATHER_USDT);
        }else if("btc".equals(recharge.getSymbol())){
            moneyLog.setAmount_before(walletGather.getBtcMoney());
            moneyLog.setAmount_after(Arith.add(walletGather.getBtcMoney(), amount));
            moneyLog.setWallettype(Constants.WALLET_GATHER_BTC);
        }else if("eth".equals(recharge.getSymbol())){
            moneyLog.setAmount_before(walletGather.getEthMoney());
            moneyLog.setAmount_after(Arith.add(walletGather.getEthMoney(), amount));
            moneyLog.setWallettype(Constants.WALLET_GATHER_ETH);
        }else if("usdc".equals(recharge.getSymbol())){
            moneyLog.setAmount_before(walletGather.getUsdcMoney());
            moneyLog.setAmount_after(Arith.add(walletGather.getUsdcMoney(), amount));
            moneyLog.setWallettype(Constants.WALLET_GATHER_USDC);
        }
        if ("usdt".equals(recharge.getSymbol())) {
            double amount = recharge.getVolume();
        moneyLog.setAmount(recharge.getVolume());
        moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
        moneyLog.setPartyId(recharge.getPartyId());
            Wallet wallet = new Wallet();
            wallet = walletService.saveWalletByPartyId(recharge.getPartyId());
        moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
        moneyLog.setCreateTime(new Date());
        moneyLogService.save(moneyLog);
        walletLog.setStatus(recharge.getSucceeded());
        walletLogService.update(walletLog);
            double amount_before = wallet.getMoney();
        //修改资金账户
        walletGatherService.update(walletGather.getPartyId().toString(),recharge.getSymbol(),recharge.getVolume(),"add");
            walletService.update(wallet.getPartyId().toString(), amount);
        this.updateRechargeBlockchain(recharge);
        /**
         * 给他的代理添加充值记录
         */
        userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
        /**
         * 若已开启充值奖励 ,则充值到账后给他的代理用户添加奖金
         */
        if ("true".equals(user_recom_bonus_open.getValue())) {
            rechargeBonusService.saveBounsHandle(recharge, 1);
        }
        /**
         * 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,1不重置,2重置
         */
        double usdt_amount = 0;
        if("usdt".equals(recharge.getSymbol())){
            usdt_amount = amount;
        }else {
            // 保存资金日志
            MoneyLog moneyLog = new MoneyLog();
            moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
            moneyLog.setAmount_before(amount_before);
            moneyLog.setAmount(amount);
            moneyLog.setAmount_after(Arith.add(wallet.getMoney(), amount));
            moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
            moneyLog.setPartyId(recharge.getPartyId());
            moneyLog.setWallettype(Constants.WALLET);
            moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
            moneyLog.setCreateTime(new Date());
            moneyLogService.save(moneyLog);
            walletLog.setStatus(recharge.getSucceeded());
            walletLogService.update(walletLog);
            this.updateRechargeBlockchain(recharge);
            /**
             * 给他的代理添加充值记录
             */
            userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
            /**
             * 若已开启充值奖励 ,则充值到账后给他的代理用户添加奖金
             */
            if ("true".equals(user_recom_bonus_open.getValue())) {
                rechargeBonusService.saveBounsHandle(recharge, 1);
            }
            // 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,
            // 1不重置,2重置
            String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw").getValue();
            if ("1".equals(recharge_sucess_reset_withdraw)) {
                party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), amount));
                if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
                    party.setWithdraw_limit_now_amount(0);
                }
            }
            if ("2".equals(recharge_sucess_reset_withdraw)) {
                double withdraw_limit_turnover_percent = Double
                        .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
                double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
                if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
                    party.setWithdraw_limit_amount(amount);
                    party.setWithdraw_limit_now_amount(0);
                } else {
                    party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), amount));
                }
            }
            partyService.update(party);
        } else {
            List<Realtime> realtime_list = this.dataService.realtime(recharge.getSymbol());
            Realtime realtime = null;
            if (realtime_list.size() > 0) {
@@ -542,31 +544,84 @@
            }
            // 对应usdt价格
            double transfer_usdt = realtime.getClose();
            WalletExtend walletExtend = new WalletExtend();
            walletExtend = walletService.saveExtendByPara(recharge.getPartyId(), recharge.getSymbol());
            double volume = recharge.getVolume();
            double amount_before = walletExtend.getAmount();
            // walletExtend = walletService.saveWalletExtendByParaAndUpdate(String.valueOf(recharge.getPartyId()), recharge.getSymbol(), volume);
            walletService.updateExtend(walletExtend.getPartyId().toString(), walletExtend.getWallettype(), volume);
            this.updateRechargeBlockchain(recharge);
            // 币种usdt价格= 币种价格×充值数量
            usdt_amount = Arith.mul(recharge.getVolume(), transfer_usdt);
        }
        String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw")
                .getValue();
        if ("1".equals(recharge_sucess_reset_withdraw)) {
            party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
            if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
                party.setWithdraw_limit_now_amount(0);
            }
        }
        if ("2".equals(recharge_sucess_reset_withdraw)) {
            double withdraw_limit_turnover_percent = Double
                    .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
            double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
            double usdt_amount = Arith.mul(volume, transfer_usdt);
            if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
                party.setWithdraw_limit_amount(usdt_amount);
                party.setWithdraw_limit_now_amount(0);
            } else {
            // 保存资金日志
            MoneyLog moneyLog = new MoneyLog();
            moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
            moneyLog.setAmount_before(amount_before);
            moneyLog.setAmount(volume);
            moneyLog.setAmount_after(Arith.add(walletExtend.getAmount(), volume));
            moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
            moneyLog.setPartyId(recharge.getPartyId());
            moneyLog.setWallettype(recharge.getSymbol());
            moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
            moneyLog.setCreateTime(new Date());
            moneyLogService.save(moneyLog);
            walletLog.setStatus(recharge.getSucceeded());
            walletLogService.update(walletLog);
            /**
             * 给他的代理添加充值记录
             */
            userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
            /**
             * 买币-币冲充值其他非usdt币时使用
             */
//            userDataService.saveBuy(recharge.getPartyId(), recharge.getSymbol(), recharge.getVolume());
            /**
             * 充值到账后给他的代理用户添加奖金
             */
            if ("true".equals(user_recom_bonus_open.getValue())) {
                rechargeBonusService.saveBounsHandle(recharge, transfer_usdt);
            }
            /**
             * 充值到账后给他增加提现流水限制金额
             */
            /**
             * 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,1不重置,2重置
             */
            String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw")
                    .getValue();
            if ("1".equals(recharge_sucess_reset_withdraw)) {
                party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
                if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
                    party.setWithdraw_limit_now_amount(0);
                }
            }
        }
            if ("2".equals(recharge_sucess_reset_withdraw)) {
                double withdraw_limit_turnover_percent = Double
                        .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
                double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
        partyService.update(party);
                if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
                    party.setWithdraw_limit_amount(usdt_amount);
                    party.setWithdraw_limit_now_amount(0);
                } else {
                    party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
                }
            }
            partyService.update(party);
        }
        Log log = new Log();
        log.setCategory(Constants.LOG_CATEGORY_OPERATION);
@@ -583,6 +638,7 @@
    }
    @Override
    public boolean saveReject(RechargeBlockchain recharge) {
        // 通过后不可驳回
        if (recharge.getSucceeded() == 2 || recharge.getSucceeded() == 1) {
@@ -601,21 +657,221 @@
        return true;
    }
    public void insertRechargeBlockchain(RechargeBlockchain rechargeBlockchain) {
        Object[] jdbcParams = ApplicationUtil.getInsertStatement(rechargeBlockchain);
        String insertUserSql = (String)jdbcParams[0];
        Object[] sqlParameters = (Object[])jdbcParams[1];
        jdbcTemplate.update(insertUserSql, sqlParameters);
    }
    public void updateRechargeBlockchain(RechargeBlockchain rechargeBlockchain) {
        Object[] jdbcParams = ApplicationUtil.getUpdateStatement(rechargeBlockchain, "WHERE UUID=?", new Object[] {rechargeBlockchain.getId()});
        String updateUserSql = (String)jdbcParams[0];
        Object[] sqlParameters = (Object[])jdbcParams[1];
        jdbcTemplate.update(updateUserSql, sqlParameters);
    }
    @Override
    @Transactional
    public void callback(String timestamp, String nonce, String sign, String body) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> map = objectMapper.readValue(body, HashMap.class);
            double amounts = Double.parseDouble(map.get("fee").toString());  // 假设 amount 的值为 1000
            double decimals = Double.parseDouble(map.get("decimals").toString());
            double success_amount  = amounts / Math.pow(10, decimals);
            RechargeBlockchain recharge = this.getAddress(map.get("address").toString());
            String order_no = recharge.getOrder_no();
            if (recharge.getSucceeded() == 1) {
                return ;
            }
            recharge.setReviewTime(new Date());
            recharge.setSucceeded(1);
            WalletLog walletLog = walletLogService.find(Constants.MONEYLOG_CATEGORY_RECHARGE, recharge.getOrder_no());
            SecUser secUser = secUserService.findUserByPartyId(recharge.getPartyId());
            if (success_amount != recharge.getVolume()) {
                Log log = new Log();
                log.setCategory(Constants.LOG_CATEGORY_OPERATION);
                log.setExtra(order_no);
                log.setOperator("自动充值");
                log.setUsername(secUser.getUsername());
                log.setPartyId(recharge.getPartyId());
                log.setCreateTime(new Date());
                log.setLog("管理员修改充值数量,原充值数量["
                        + recharge.getVolume() + "],修改后充值数量[" + success_amount + "]。订单号[" + order_no+ "]。");
                logService.saveSync(log);
                walletLog.setAmount(success_amount);
                recharge.setVolume(success_amount);
            }
            /**
             * 如果是usdt则加入wallet,否则寻找walletExtend里相同币种
             */
            Party party = this.partyService.cachePartyBy(recharge.getPartyId(), false);
            Syspara user_recom_bonus_open = sysparaService.find("user_recom_bonus_open");
            if ("usdt".equals(recharge.getSymbol())) {
                double amount = recharge.getVolume();
                Wallet wallet = new Wallet();
                wallet = walletService.saveWalletByPartyId(recharge.getPartyId());
                double amount_before = wallet.getMoney();
                walletService.update(wallet.getPartyId().toString(), amount);
                // 保存资金日志
                MoneyLog moneyLog = new MoneyLog();
                moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
                moneyLog.setAmount_before(amount_before);
                moneyLog.setAmount(amount);
                moneyLog.setAmount_after(Arith.add(wallet.getMoney(), amount));
                moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
                moneyLog.setPartyId(recharge.getPartyId());
                moneyLog.setWallettype(Constants.WALLET);
                moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
                moneyLog.setCreateTime(new Date());
                moneyLogService.save(moneyLog);
                walletLog.setStatus(recharge.getSucceeded());
                walletLogService.update(walletLog);
                this.updateRechargeBlockchain(recharge);
                /**
                 * 给他的代理添加充值记录
                 */
                userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
                /**
                 * 若已开启充值奖励 ,则充值到账后给他的代理用户添加奖金
                 */
                if ("true".equals(user_recom_bonus_open.getValue())) {
                    rechargeBonusService.saveBounsHandle(recharge, 1);
                }
                // 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,
                // 1不重置,2重置
                String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw").getValue();
                if ("1".equals(recharge_sucess_reset_withdraw)) {
                    party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), amount));
                    if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
                        party.setWithdraw_limit_now_amount(0);
                    }
                }
                if ("2".equals(recharge_sucess_reset_withdraw)) {
                    double withdraw_limit_turnover_percent = Double
                            .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
                    double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
                    if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
                        party.setWithdraw_limit_amount(amount);
                        party.setWithdraw_limit_now_amount(0);
                    } else {
                        party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), amount));
                    }
                }
                partyService.update(party);
            } else {
                List<Realtime> realtime_list = this.dataService.realtime(recharge.getSymbol());
                Realtime realtime = null;
                if (realtime_list.size() > 0) {
                    realtime = realtime_list.get(0);
                } else {
                    throw new BusinessException("系统错误,请稍后重试");
                }
                // 对应usdt价格
                double transfer_usdt = realtime.getClose();
                WalletExtend walletExtend = new WalletExtend();
                walletExtend = walletService.saveExtendByPara(recharge.getPartyId(), recharge.getSymbol());
                double volume = recharge.getVolume();
                double amount_before = walletExtend.getAmount();
                // walletExtend = walletService.saveWalletExtendByParaAndUpdate(String.valueOf(recharge.getPartyId()), recharge.getSymbol(), volume);
                walletService.updateExtend(walletExtend.getPartyId().toString(), walletExtend.getWallettype(), volume);
                this.updateRechargeBlockchain(recharge);
                // 币种usdt价格= 币种价格×充值数量
                double usdt_amount = Arith.mul(volume, transfer_usdt);
                // 保存资金日志
                MoneyLog moneyLog = new MoneyLog();
                moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
                moneyLog.setAmount_before(amount_before);
                moneyLog.setAmount(volume);
                moneyLog.setAmount_after(Arith.add(walletExtend.getAmount(), volume));
                moneyLog.setLog("充值订单[" + recharge.getOrder_no() + "]");
                moneyLog.setPartyId(recharge.getPartyId());
                moneyLog.setWallettype(recharge.getSymbol());
                moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
                moneyLog.setCreateTime(new Date());
                moneyLogService.save(moneyLog);
                walletLog.setStatus(recharge.getSucceeded());
                walletLogService.update(walletLog);
                /**
                 * 给他的代理添加充值记录
                 */
                userDataService.saveRechargeHandle(recharge.getPartyId(), recharge.getVolume(), recharge.getSymbol());
                /**
                 * 买币-币冲充值其他非usdt币时使用
                 */
//            userDataService.saveBuy(recharge.getPartyId(), recharge.getSymbol(), recharge.getVolume());
                /**
                 * 充值到账后给他的代理用户添加奖金
                 */
                if ("true".equals(user_recom_bonus_open.getValue())) {
                    rechargeBonusService.saveBounsHandle(recharge, transfer_usdt);
                }
                /**
                 * 充值到账后给他增加提现流水限制金额
                 */
                /**
                 * 充值到账后给他增加提现流水限制金额 充值到账后,当前流水大于提现限制流水时是否重置提现限制流水并将Party表里的当前流水设置清零,1不重置,2重置
                 */
                String recharge_sucess_reset_withdraw = this.sysparaService.find("recharge_sucess_reset_withdraw")
                        .getValue();
                if ("1".equals(recharge_sucess_reset_withdraw)) {
                    party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
                    if (party.getWithdraw_limit_now_amount() > party.getWithdraw_limit_amount()) {
                        party.setWithdraw_limit_now_amount(0);
                    }
                }
                if ("2".equals(recharge_sucess_reset_withdraw)) {
                    double withdraw_limit_turnover_percent = Double
                            .valueOf(sysparaService.find("withdraw_limit_turnover_percent").getValue());
                    double party_withdraw = Arith.mul(party.getWithdraw_limit_amount(), withdraw_limit_turnover_percent);
                    if (party.getWithdraw_limit_now_amount() >= party_withdraw) {
                        party.setWithdraw_limit_amount(usdt_amount);
                        party.setWithdraw_limit_now_amount(0);
                    } else {
                        party.setWithdraw_limit_amount(Arith.add(party.getWithdraw_limit_amount(), usdt_amount));
                    }
                }
                partyService.update(party);
            }
        } catch (Exception e) {
            e.getMessage();
        }
    }
    public void insertRechargeBlockchain(RechargeBlockchain rechargeBlockchain) {
        Object[] jdbcParams = ApplicationUtil.getInsertStatement(rechargeBlockchain);
        String insertUserSql = (String)jdbcParams[0];
        Object[] sqlParameters = (Object[])jdbcParams[1];
        jdbcTemplate.update(insertUserSql, sqlParameters);
    }
    public void updateRechargeBlockchain(RechargeBlockchain rechargeBlockchain) {
        Object[] jdbcParams = ApplicationUtil.getUpdateStatement(rechargeBlockchain, "WHERE UUID=?", new Object[] {rechargeBlockchain.getId()});
        String updateUserSql = (String)jdbcParams[0];
        Object[] sqlParameters = (Object[])jdbcParams[1];
        jdbcTemplate.update(updateUserSql, sqlParameters);
    }
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
@@ -670,10 +926,6 @@
    public void setTipService(TipService tipService) {
        this.tipService = tipService;
    }
    public void setRedisHandler(RedisHandler redisHandler) {
        this.redisHandler = redisHandler;
    }
}
src/main/java/project/web/admin/AdminRechargeBlockchainOrderController.java
@@ -9,6 +9,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
@@ -156,6 +157,29 @@
        return modelAndView;
    }
    @PostMapping("/rechargeCallback.action")
    public ResultMsg rechargeCallback(HttpServletRequest request){
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String sign = request.getParameter("sign");
        String body = request.getParameter("body");
        logger.info("回调请求参数body{}:",body);
        logger.info("回调请求参数sign{}:",sign);
        try{
            adminRechargeBlockchainOrderService.callback(timestamp,nonce,sign,body);
            logger.info("回调成功");
            ResultMsg resultMsg = new ResultMsg();
            resultMsg.setCode(200);
            return resultMsg;
        }catch (Exception e){
            logger.info("回调异常",e);
            ResultMsg resultMsg = new ResultMsg();
            resultMsg.setCode(500);
            resultMsg.setMessage("回调处理失败");
            return resultMsg;
        }
    }
    /**
     * 驳回充值申请
     */
src/main/java/project/web/admin/ResultMsg.java
New file
@@ -0,0 +1,40 @@
package project.web.admin;
public class ResultMsg {
    private Integer code;
    private String message;
    private String data;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }
    @Override
    public String toString() {
        return "ResultMsg{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", data='" + data + '\'' +
                '}';
    }
}
src/main/java/project/web/api/Address.java
New file
@@ -0,0 +1,31 @@
package project.web.api;
public class Address {
    private String address;
    private int coinType;
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public int getCoinType() {
        return coinType;
    }
    public void setCoinType(int coinType) {
        this.coinType = coinType;
    }
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                ", coinType=" + coinType +
                '}';
    }
}
src/main/java/project/web/api/ApiPath.java
New file
@@ -0,0 +1,12 @@
package project.web.api;
public class ApiPath {
    public final static String CREATE_ADDRESS = "/mch/address/create";
    public final static String WITHDRAW = "/mch/withdraw";
    public final static String TRANSACTION = "/mch/transaction";
    public final static String AUTO_WITHDRAW = "/mch/withdraw/proxypay";
    public final static String SUPPORT_COIN = "/mch/support-coins";
    public final static String CHECK_PROXY = "/mch/check-proxy";
    public final static String CHECK_ADDRESS = "/mch/check/address";
    public final static String CREATE_BATCH_ADDRESS = "/mch/address/create/batch";
}
src/main/java/project/web/api/Coin.java
New file
@@ -0,0 +1,78 @@
package project.web.api;
import java.math.BigDecimal;
public class Coin {
    private String name;
    private String symbol;
    private String mainCoinType;
    private String coinType;
    private String decimals;
    private Integer tokenStatus;
    private String mainSymbol;
    private BigDecimal balance;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSymbol() {
        return symbol;
    }
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }
    public String getMainCoinType() {
        return mainCoinType;
    }
    public void setMainCoinType(String mainCoinType) {
        this.mainCoinType = mainCoinType;
    }
    public String getCoinType() {
        return coinType;
    }
    public void setCoinType(String coinType) {
        this.coinType = coinType;
    }
    public String getDecimals() {
        return decimals;
    }
    public void setDecimals(String decimals) {
        this.decimals = decimals;
    }
    public Integer getTokenStatus() {
        return tokenStatus;
    }
    public void setTokenStatus(Integer tokenStatus) {
        this.tokenStatus = tokenStatus;
    }
    public String getMainSymbol() {
        return mainSymbol;
    }
    public void setMainSymbol(String mainSymbol) {
        this.mainSymbol = mainSymbol;
    }
    public BigDecimal getBalance() {
        return balance;
    }
    public void setBalance(BigDecimal balance) {
        this.balance = balance;
    }
}
src/main/java/project/web/api/ResultMsg.java
New file
@@ -0,0 +1,40 @@
package project.web.api;
public class ResultMsg {
    private Integer code;
    private String message;
    private String data;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }
    @Override
    public String toString() {
        return "ResultMsg{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", data='" + data + '\'' +
                '}';
    }
}
src/main/java/project/web/api/UdunApi.java
New file
@@ -0,0 +1,108 @@
package project.web.api;
import java.math.BigDecimal;
import java.util.List;
public interface UdunApi {
    /**
     * 创建币种地址,别名和钱包编号默认,回调地址使用统一配置
     *
     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
     * @return 地址
     */
    Address createAddress(String mainCoinType)  throws UdunException;
    /**
     * 创建币种地址,别名和钱包编号自定义,回调地址使用统一配置
     *
     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
     * @param alias        地址别名
     * @param walletId     钱包编号
     * @return 地址
     */
    Address createAddress(String mainCoinType, String alias, String walletId)  throws UdunException;
    /**
     * 创建币种地址,别名和钱包编号自定义,回调地址自定义
     *
     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
     * @param alias        地址别名
     * @param walletId     钱包编号
     * @param callUrl      回调地址
     * @return 地址
     */
    Address createAddress(String mainCoinType, String alias, String walletId, String callUrl) throws UdunException;
    /**
     * 提币,回调地址使用统一配置
     *
     * @param address      提币地址
     * @param amount       提币数量
     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
     * @param coinType     子币种编号,使用获取商户币种信息接口
     * @param businessId   业务编号,必须保证该字段在系统内唯一,如果重复,则该笔提币钱包将不会进行接收
     * @param memo         备注,XRP和EOS,这两种币的提币申请该字段可选,其他类型币种不填
     * @return 返回信息
     */
    ResultMsg withdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo);
    /**
     * 提币,回调地址自定义
     *
     * @param address      提币地址
     * @param amount       提币数量
     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
     * @param coinType     子币种编号,使用获取商户币种信息接口
     * @param businessId   业务编号,必须保证该字段在系统内唯一,如果重复,则该笔提币钱包将不会进行接收
     * @param memo         备注,XRP和EOS,这两种币的提币申请该字段可选,其他类型币种不填
     * @param callUrl      回调地址
     * @return 返回信息
     */
    ResultMsg withdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo, String callUrl);
    /**
     * 代付,回调地址使用统一配置
     *
     * @param address      提币地址
     * @param amount       提币数量
     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
     * @param coinType     子币种编号,使用获取商户币种信息接口
     * @param businessId   业务编号,必须保证该字段在系统内唯一,如果重复,则该笔提币钱包将不会进行接收
     * @param memo         备注,XRP和EOS,这两种币的提币申请该字段可选,其他类型币种不填
     * @return 返回信息
     */
    ResultMsg autoWithdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo);
    /**
     * 代付,回调地址自定义
     *
     * @param address      提币地址
     * @param amount       提币数量
     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
     * @param coinType     子币种编号,使用获取商户币种信息接口
     * @param businessId   业务编号,必须保证该字段在系统内唯一,如果重复,则该笔提币钱包将不会进行接收
     * @param memo         备注,XRP和EOS,这两种币的提币申请该字段可选,其他类型币种不填
     * @param callUrl      回调地址
     * @return 返回信息
     */
    ResultMsg autoWithdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo, String callUrl);
    /**
     * 检验地址合法性
     *
     * @param mainCoinType 主币种编号,使用获取商户币种信息接口
     * @param address      币种地址
     * @return 是否合法
     */
    boolean checkAddress(String mainCoinType, String address);
    /**
     * 获取商户支持的币种,以及余额
     *
     * @param showBalance 是否显示余额
     * @return 支持币种列表
     */
    List<Coin> listSupportCoin(boolean showBalance);
}
src/main/java/project/web/api/UdunClient.java
New file
@@ -0,0 +1,132 @@
package project.web.api;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UdunClient implements UdunApi {
    private static Logger logger = LoggerFactory.getLogger(UdunClient.class);
    /**
     * UDUN API Gateway
     */
    private final String gateway;
    /**
     * UDUN Merchant Number
     */
    private final String merchantId;
    /**
     * UDUN Merchant Key
     */
    private final String merchantKey;
    /**
     * Callback to business system
     */
    private final String defaultCallBackUrl;
    public UdunClient(String gateway, String merchantId, String merchantKey, String defaultCallBackUrl) {
        this.gateway = gateway;
        this.merchantId = merchantId;
        this.merchantKey = merchantKey;
        this.defaultCallBackUrl = defaultCallBackUrl;
    }
    @Override
    public Address createAddress(String mainCoinType)  throws UdunException {
        return createAddress(mainCoinType, "", "", defaultCallBackUrl);
    }
    @Override
    public Address createAddress(String mainCoinType, String alias, String walletId)  throws UdunException{
        return createAddress(mainCoinType, alias, walletId, defaultCallBackUrl);
    }
    @Override
    public Address createAddress(String mainCoinType, String alias, String walletId, String callUrl) throws UdunException{
        Map<String, String> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("coinType", mainCoinType);
        params.put("callUrl", callUrl);
        params.put("walletId", walletId);
        params.put("alias", alias);
        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.CREATE_ADDRESS, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
        if (result.getCode() != HttpStatus.HTTP_OK) {
            logger.error("createAddress:{}",JSONUtil.toJsonStr(result));
            throw new UdunException(result.getCode(), result.getMessage());
        }
        return JSONUtil.toBean(result.getData(), Address.class);
    }
    @Override
    public ResultMsg withdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo) {
        return withdraw(address, amount, mainCoinType, coinType, businessId, memo, defaultCallBackUrl);
    }
    @Override
    public ResultMsg withdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo, String callUrl) {
        Map<String, Object> params = new HashMap<>();
        params.put("address", address);
        params.put("amount", amount);
        params.put("merchantId", merchantId);
        params.put("mainCoinType", mainCoinType);
        params.put("coinType", coinType);
        params.put("callUrl", callUrl);
        params.put("businessId", businessId);
        params.put("memo", memo);
        return JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.WITHDRAW, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
    }
    @Override
    public ResultMsg autoWithdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo) {
        return autoWithdraw(address, amount, mainCoinType, coinType, businessId, memo, defaultCallBackUrl);
    }
    @Override
    public ResultMsg autoWithdraw(String address, BigDecimal amount, String mainCoinType, String coinType, String businessId, String memo, String callUrl) {
        Map<String, Object> params = new HashMap<>();
        params.put("address", address);
        params.put("amount", amount);
        params.put("merchantId", merchantId);
        params.put("mainCoinType", mainCoinType);
        params.put("coinType", coinType);
        params.put("callUrl", callUrl);
        params.put("businessId", businessId);
        params.put("memo", memo);
        return JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.AUTO_WITHDRAW, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
    }
    @Override
    public boolean checkAddress(String mainCoinType, String address) {
        Map<String, String> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("mainCoinType", mainCoinType);
        params.put("address", address);
        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.CHECK_ADDRESS, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
        return result.getCode() == HttpStatus.HTTP_OK;
    }
    @Override
    public List<Coin> listSupportCoin(boolean showBalance) {
        Map<String, Object> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("showBalance", showBalance);
        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.SUPPORT_COIN, JSONUtil.toJsonStr(params)), ResultMsg.class);
        if (result.getCode() != HttpStatus.HTTP_OK) {
            Console.error(JSONUtil.toJsonStr(result));
            return null;
        }
        return JSONUtil.toList(JSONUtil.parseArray(result.getData()), Coin.class);
    }
}
src/main/java/project/web/api/UdunException.java
New file
@@ -0,0 +1,28 @@
package project.web.api;
public class UdunException extends RuntimeException {
    private Integer code;
    private String message;
    public UdunException(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    @Override
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}
src/main/java/project/web/api/UdunUtils.java
New file
@@ -0,0 +1,88 @@
package project.web.api;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class UdunUtils {
    private static Logger logger = LoggerFactory.getLogger(UdunUtils.class);
    public static String post(String gateway, String merchantKey, String path, String body) {
        try {
            // 创建 URL 对象
            URL url = new URL(gateway+path);
            // 打开连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 设置请求方法为 POST
            connection.setRequestMethod("POST");
            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "application/json");
            // 启用输入输出流
            connection.setDoOutput(true);
            String rawBody = parseParams(merchantKey, body);
            // 写入请求体
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = rawBody.getBytes("utf-8");
                os.write(input, 0, input.length);
            }
            // 获取响应代码
            int responseCode = connection.getResponseCode();
            // 读取响应
            try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                String inputLine;
                StringBuilder response = new StringBuilder();
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                return response.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String parseParams(String merchantKey, String body) {
        Map<String, String> params = new HashMap<>();
        String timestamp = System.currentTimeMillis() + "";
        String nonce = RandomUtil.randomString(6);
        String sign = sign(merchantKey, timestamp, nonce, body);
        params.put("timestamp", timestamp);
        params.put("nonce", nonce);
        params.put("sign", sign);
        params.put("body", body);
        return JSONUtil.toJsonStr(params);
    }
    public static String sign(String key, String timestamp, String nonce, String body) {
        String raw = body + key + nonce + timestamp;
        return SecureUtil.md5(raw);
    }
    public static boolean checkSign(String key, String timestamp, String nonce, String body, String sign) {
        String checkSign = sign(key, timestamp, nonce, body);
        return checkSign.equals(sign);
    }
}
src/main/java/project/web/api/UserWalletAddressController.java
@@ -7,6 +7,10 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import kernel.exception.BusinessException;
import kernel.util.StringUtils;
import kernel.web.Page;
@@ -14,10 +18,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import com.alibaba.fastjson.JSONObject;
@@ -26,7 +27,6 @@
import project.blockchain.AdminChannelBlockchainService;
import project.user.UserWalletAddress;
import project.user.UserWalletAddressService;
import project.web.admin.AdminChannelBlockchainController;
import javax.servlet.http.HttpServletRequest;
@@ -48,6 +48,13 @@
    @Autowired
    private AdminChannelBlockchainService adminChannelBlockchainService;
    private final String gateway =  "https://sig11.udun.io";
    private final String merchantKey =  "7fd79e4ed59e7c31e1fa2e13d64f7e6c";
    private final String merchantId =  "319563";
    private final String defaultCallBackUrl =  "https://coin.usadeepcoin.com/admin/normal/adminRechargeBlockchainOrderAction!rechargeCallback.action";
    /**
     * 未生成钱包地址的用户
@@ -98,18 +105,20 @@
            page = this.adminChannelBlockchainService.pagedQuery(pageNo, pageSize, name_para, coin_para);
            Map<String, List<Map<String, Object>>> coinMap = getStringListMap();
            List<Map<String, Object>> result = getCoinData(coinMap, coin_para);
            logger.info("--------------result---------------"+result.toString());
            page.setElements(result);
        } catch (BusinessException e) {
            logger.error(" error ", e);
            logger.error(" 获取充值地址报错【BusinessException】:", e);
            resultObject.setCode("1");
            resultObject.setMsg(e.getMessage());
            return resultObject;
        } catch (Throwable t) {
            logger.error(" error ", t);
            logger.error(" 获取充值地址报错【Throwable】: ", t);
            resultObject.setCode("1");
            resultObject.setMsg( t.getMessage());
            return resultObject;
        }
        logger.info("--------------address3---------------"+page.getElements());
        Map<String,Object> map = new HashMap<>();
        map.put("pageNo", pageNo);
        map.put("pageSize", pageSize);
@@ -123,27 +132,82 @@
    }
    @NotNull
    private static Map<String, List<Map<String, Object>>> getStringListMap() {
        List<Map<String, Object>> ethData = new ArrayList<>();
        ethData.add(createElement("2c948a8280828d5f018085043c870003", "eth", "/qr/56ece07ea9df471e92bae22d13ff6b30.png", "0xdbE11ac592416EEEa120Bf9526b16a2F6dBCE0A6","ETH"));
        List<Map<String, Object>> btcData = new ArrayList<>();
        btcData.add(createElement("2c948a8280828d5f018084ff569b0002", "btc", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", "im14x5MUw9PycfD1io7AKBjvTSxfBRUpmPc3zSP","BTC"));
        List<Map<String, Object>> usdtData = new ArrayList<>();
        usdtData.add(createElement("2c948a8280828d5f01808203eacd0004", "usdt", "/qr/c2b42ee106cf408baf7b1ecc877f2dd4.png", "0xdbE11ac592416EEEa120Bf9526b16a2F6dBCE0A6","ERC20"));
        usdtData.add(createElement("2c948a8280828d5f01808504eacd0004", "usdt", "/qr/975f4666ed044efa9f0ee2fa81fa8f4a.png", "TFUtRvjVpRZArFhXGd5n5ZDEX3PrmudQgb","TRC20"));
        List<Map<String, Object>> usdcData = new ArrayList<>();
        usdcData.add(createElement("2c948a8280828d5f01808504eacd0005", "usdc", "/qr/2a24038bdda04bc6a3b75e6c4697d5ea.png", "TFUtRvjVpRZArFhXGd5n5ZDEX3PrmudQgb","TRC20"));
        usdcData.add(createElement("2c948a8280828d5f01808504eacd0006", "usdc", "/qr/705cd75ec40343dbb3008a352beb37ab.png", "0xdbE11ac592416EEEa120Bf9526b16a2F6dBCE0A6","ERC20"));
    private Map<String, List<Map<String, Object>>> getStringListMap() {
        Map<String, List<Map<String, Object>>> coinMap = new HashMap<>();
        coinMap.put("eth", ethData);
        coinMap.put("btc", btcData);
        coinMap.put("usdt", usdtData);
        coinMap.put("usdc", usdcData);
        //获取商户支持币种
        List<Coin> coinList = listSupportCoin("319563",false);
        //创建地址
        coinList.forEach(f->{
            if(f.getName().equals("BTC")){
                Address address3 = createAddress(f.getMainCoinType(),null,null,null);
                List<Map<String, Object>> btcData = new ArrayList<>();
                logger.info("--------------address3---------------"+address3.getAddress());
                btcData.add(createElement("2c948a8280828d5f018084ff569b0002", "btc", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", address3.getAddress(),"BTC"));
                coinMap.put("btc", btcData);
                logger.info("--------------BTC---------------"+coinMap.toString());
            }else if(f.getName().equals("ETH")){
                Address address3 = createAddress(f.getMainCoinType(),null,null,null);
                List<Map<String, Object>> ethData = new ArrayList<>();
                logger.info("--------------address3---------------"+address3.getAddress());
                ethData.add(createElement("2c948a8280828d5f018084ff569b0002", "btc", "/qr/1be19b34fbb9406c8044c1a9b08a87ca.png", address3.getAddress(),"BTC"));
                coinMap.put("eth", ethData);
                logger.info("--------------ETH---------------"+coinMap.toString());
            }else if(f.getName().equals("USDC")){
                Address address3 = createAddress(f.getMainCoinType(),null,null,null);
                List<Map<String, Object>> usdcData = new ArrayList<>();
                logger.info("--------------address3---------------"+address3.getAddress());
                usdcData.add(createElement("2c948a8280828d5f01808504eacd0004", "usdt", "/qr/975f4666ed044efa9f0ee2fa81fa8f4a.png",  address3.getAddress(),"TRC20"));
                coinMap.put("usdc", usdcData);
                logger.info("--------------USDC---------------"+coinMap.toString());
            }else if(f.getName().equals("USDT-ERC20")){
                Address address3 = createAddress(f.getMainCoinType(),null,null,null);
                List<Map<String, Object>> usdtData = new ArrayList<>();
                logger.info("--------------address3---------------"+address3.getAddress());
                usdtData.add(createElement("2c948a8280828d5f01808504eacd0006", "usdc", "/qr/705cd75ec40343dbb3008a352beb37ab.png", address3.getAddress(),"ERC20"));
                coinMap.put("usdt", usdtData);
                logger.info("--------------USDT-ERC20---------------"+coinMap.toString());
            }
        });
        logger.info("----------------总得------------"+coinMap.toString());
        return coinMap;
    }
    public List<Coin> listSupportCoin(String merchantId , boolean showBalance) {
        Map<String, Object> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("showBalance", showBalance);
        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.SUPPORT_COIN, JSONUtil.toJsonStr(params)), ResultMsg.class);
        if (result.getCode() != HttpStatus.HTTP_OK) {
            Console.error(JSONUtil.toJsonStr(result));
            return null;
        }
        return JSONUtil.toList(JSONUtil.parseArray(result.getData()), Coin.class);
    }
    public Address createAddress(String mainCoinType, String alias, String walletId, String callUrl) throws UdunException{
        Map<String, String> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("coinType", mainCoinType);
        params.put("callUrl", defaultCallBackUrl);
        params.put("walletId", walletId);
        params.put("alias", alias);
        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.CREATE_ADDRESS, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
        if (result.getCode() != HttpStatus.HTTP_OK) {
            logger.error("createAddress:{}",JSONUtil.toJsonStr(result));
            throw new UdunException(result.getCode(), result.getMessage());
        }
        return JSONUtil.toBean(result.getData(), Address.class);
    }
    public boolean checkAddress(String mainCoinType, String address) {
        Map<String, String> params = new HashMap<>();
        params.put("merchantId", merchantId);
        params.put("mainCoinType", mainCoinType);
        params.put("address", address);
        ResultMsg result = JSONUtil.toBean(UdunUtils.post(gateway, merchantKey, ApiPath.CHECK_ADDRESS, StrUtil.format("[{}]", JSONUtil.toJsonStr(params))), ResultMsg.class);
        return result.getCode() == HttpStatus.HTTP_OK;
    }
    private static Map<String, Object> createElement(String id, String coin, String img, String address,String blockchain_name) {
@@ -157,6 +221,13 @@
    }
    private static List<Map<String, Object>> getCoinData(Map<String, List<Map<String, Object>>> coinMap, String coin) {
        if (coin == null || coin.isEmpty()) {
            List<Map<String, Object>> allData = new ArrayList<>();
            for (List<Map<String, Object>> coinData : coinMap.values()) {
                allData.addAll(coinData);
            }
            return allData;
        }
        return coinMap.getOrDefault(coin, new ArrayList<>());
    }
src/main/java/project/web/api/filter/AllRequestFilter.java
@@ -244,6 +244,7 @@
        WHITE_URLS.add("/api/user!resetpsw.action");
        WHITE_URLS.add("/api/user!getUserNameVerifTarget.action");
        WHITE_URLS.add("/api/hobi!getDepth.action");
        WHITE_URLS.add("/admin/normal/adminRechargeBlockchainOrderAction!rechargeCallback.action");