Browse Source

放开提币和ido修改

jean 1 month ago
parent
commit
2fb59fab9e

+ 8 - 0
doge/core/src/main/java/com/bizzan/bitrade/dao/CoinDao.java

@@ -70,6 +70,14 @@ public interface CoinDao extends JpaRepository<Coin, String>, JpaSpecificationEx
     List<Coin> findAllRechargeParentCoins(@Param("canRecharge") BooleanEnum canRecharge,
                                           @Param("status") CommonStatus status);
 
+    /**
+     * 查询可内部转账的顶级币种(parentCoinName 为空、canTransfer=true、状态正常),按 sort 升序
+     */
+    @Query("select c from Coin c where c.canTransfer = :canTransfer and c.status = :status "
+            + "and (c.parentCoinName is null or c.parentCoinName = '') order by c.sort asc")
+    List<Coin> findAllTransferParentCoins(@Param("canTransfer") BooleanEnum canTransfer,
+                                          @Param("status") CommonStatus status);
+
     /**
      * 查询所有顶级币种名称(parentCoinName 为空),用于"上级币种"下拉选择
      *

+ 25 - 0
doge/core/src/main/java/com/bizzan/bitrade/dao/CoinNetworkConfigDao.java

@@ -91,4 +91,29 @@ public interface CoinNetworkConfigDao extends JpaRepository<CoinNetworkConfig, L
             @Param("networkId") Long networkId,
             @Param("canRecharge") BooleanEnum canRecharge,
             @Param("coinStatus") CommonStatus coinStatus);
+
+    /**
+     * 提币:coin_network 中至少有一条可提币种配置的主网
+     */
+    @Query("select distinct n from CoinNetwork n, CoinNetworkConfig cfg, Coin c "
+            + "where cfg.network.id = n.id and cfg.coinName = c.name "
+            + "and c.canWithdraw = :canWithdraw and c.status = :coinStatus "
+            + "and n.status = :networkStatus "
+            + "order by n.sort asc, n.id asc")
+    List<CoinNetwork> findWithdrawNetworks(
+            @Param("canWithdraw") BooleanEnum canWithdraw,
+            @Param("coinStatus") CommonStatus coinStatus,
+            @Param("networkStatus") CommonStatus networkStatus);
+
+    /**
+     * 提币:指定 coin_network.id 下 coin_network_config 中可提币种
+     */
+    @Query("select cfg from CoinNetworkConfig cfg join fetch cfg.network n "
+            + "where cfg.network.id = :networkId and cfg.coinName in ("
+            + "select c.name from Coin c where c.canWithdraw = :canWithdraw and c.status = :coinStatus"
+            + ") order by cfg.sort asc, cfg.coinName asc")
+    List<CoinNetworkConfig> findWithdrawConfigsByNetwork(
+            @Param("networkId") Long networkId,
+            @Param("canWithdraw") BooleanEnum canWithdraw,
+            @Param("coinStatus") CommonStatus coinStatus);
 }

+ 48 - 0
doge/core/src/main/java/com/bizzan/bitrade/service/CoinNetworkConfigService.java

@@ -11,6 +11,7 @@ import com.bizzan.bitrade.entity.CoinNetworkConfig;
 import com.bizzan.bitrade.service.Base.BaseService;
 import com.bizzan.bitrade.vo.CoinChildWithNetworkVO;
 import com.bizzan.bitrade.vo.CoinRechargeConfigVO;
+import com.bizzan.bitrade.vo.CoinWithdrawConfigVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -117,6 +118,53 @@ public class CoinNetworkConfigService extends BaseService {
         return result;
     }
 
+    /**
+     * 提币:coin_network 表中有可提币种配置的主网列表
+     */
+    @Transactional(readOnly = true)
+    public List<CoinNetwork> findWithdrawNetworks() {
+        return coinNetworkConfigDao.findWithdrawNetworks(
+                BooleanEnum.IS_TRUE,
+                CommonStatus.NORMAL,
+                CommonStatus.NORMAL);
+    }
+
+    /**
+     * 提币:按 coin_network.id 查询 coin_network_config 下可提子币
+     */
+    @Transactional(readOnly = true)
+    public List<CoinWithdrawConfigVO> findWithdrawConfigsByNetwork(Long networkId) {
+        List<CoinNetworkConfig> configs = coinNetworkConfigDao.findWithdrawConfigsByNetwork(
+                networkId,
+                BooleanEnum.IS_TRUE,
+                CommonStatus.NORMAL);
+        List<CoinWithdrawConfigVO> result = new ArrayList<>();
+        for (CoinNetworkConfig cfg : configs) {
+            CoinNetwork network = cfg.getNetwork();
+            if (network == null || network.getStatus() != CommonStatus.NORMAL) {
+                continue;
+            }
+            Coin coin = coinDao.findOne(cfg.getCoinName());
+            if (coin == null) {
+                continue;
+            }
+            CoinWithdrawConfigVO vo = new CoinWithdrawConfigVO();
+            vo.setCoinName(coin.getName());
+            vo.setUnit(coin.getUnit());
+            vo.setCoinNameCn(coin.getNameCn());
+            vo.setNetworkId(network.getId());
+            vo.setNetworkName(network.getName());
+            vo.setProtocol(network.getProtocol());
+            vo.setMinWithdrawAmount(coin.getMinWithdrawAmount());
+            vo.setMaxWithdrawAmount(coin.getMaxWithdrawAmount());
+            vo.setWithdrawFeeValue(coin.getWithdrawFeeValue());
+            vo.setParentCoinName(coin.getParentCoinName());
+            vo.setSort(cfg.getSort());
+            result.add(vo);
+        }
+        return result;
+    }
+
     /**
      * 查询某币种在某主网下的配置
      *

+ 8 - 0
doge/core/src/main/java/com/bizzan/bitrade/service/CoinService.java

@@ -89,6 +89,14 @@ public class CoinService extends BaseService {
         return coinDao.findAllRechargeParentCoins(IS_TRUE, CommonStatus.NORMAL);
     }
 
+    /**
+     * 查询可内部转账的顶级币种(parentCoinName 为空、canTransfer=true、状态正常),按 sort 升序
+     */
+    @Transactional(readOnly = true)
+    public List<Coin> findAllTransferParentCoins() {
+        return coinDao.findAllTransferParentCoins(IS_TRUE, CommonStatus.NORMAL);
+    }
+
     public Coin findByUnit(String unit) {
         return coinDao.findByUnit(unit);
     }

+ 53 - 0
doge/core/src/main/java/com/bizzan/bitrade/service/MemberWalletService.java

@@ -683,6 +683,59 @@ public class MemberWalletService extends BaseService {
      * @param amount   质押金额
      * @return 操作结果,code=0 表示成功
      */
+    /**
+     * USDT 闪兑为指定币种:扣减资金账户 USDT,按现货价增加目标币种余额(IDO 预售等场景)
+     *
+     * @param memberId       用户ID
+     * @param targetCoinUnit 目标币种 unit,如 IBIT
+     * @param usdtAmount     支付的 USDT 数量
+     * @param price          目标币种对 USDT 单价(1 目标币 = price USDT)
+     * @return 兑换得到的目标币数量放在 data 字段
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public MessageResult flashSwapUsdtToCoin(Long memberId, String targetCoinUnit, BigDecimal usdtAmount,
+                                             BigDecimal price) {
+        if (usdtAmount == null || usdtAmount.compareTo(BigDecimal.ZERO) <= 0) {
+            return MessageResult.error("USDT金额必须大于0");
+        }
+        if (price == null || price.compareTo(BigDecimal.ZERO) <= 0) {
+            return MessageResult.error("行情价格不可用");
+        }
+        Coin targetCoin = coinDao.findByUnit(targetCoinUnit);
+        if (targetCoin == null) {
+            return MessageResult.error("目标币种不存在");
+        }
+        int scale = targetCoin.getWithdrawScale() > 0 ? targetCoin.getWithdrawScale() : 8;
+        BigDecimal coinAmount = usdtAmount.divide(price, scale, java.math.RoundingMode.DOWN);
+        if (coinAmount.compareTo(BigDecimal.ZERO) <= 0) {
+            return MessageResult.error("兑换数量过小");
+        }
+
+        MemberWallet usdtWallet = ensureOrCreateMemberWallet(memberId, "USDT");
+        if (usdtWallet == null) {
+            return MessageResult.error("USDT钱包不存在");
+        }
+        int deductUsdt = memberWalletDao.decreaseBalance(usdtWallet.getId(), usdtAmount);
+        if (deductUsdt <= 0) {
+            return MessageResult.error("USDT余额不足");
+        }
+
+        MemberWallet coinWallet = ensureOrCreateMemberWallet(memberId, targetCoinUnit);
+        if (coinWallet == null) {
+            throw new IllegalStateException("无法创建目标币种钱包: " + targetCoinUnit);
+        }
+        memberWalletDao.increaseBalance(coinWallet.getId(), coinAmount);
+
+        MemberTransaction usdtOut = buildStakingTransferTransaction(memberId, usdtAmount, "USDT", TransactionType.SPOT);
+        transactionService.save(usdtOut);
+        MemberTransaction coinIn = buildStakingTransferTransaction(memberId, coinAmount, targetCoinUnit, TransactionType.SPOT);
+        transactionService.save(coinIn);
+
+        MessageResult ok = MessageResult.success("闪兑成功");
+        ok.setData(coinAmount);
+        return ok;
+    }
+
     @Transactional(rollbackFor = Exception.class)
     public MessageResult stakeFundToLocked(Long memberId, String coinUnit, BigDecimal amount) {
         // 1. 校验金额合法性

+ 57 - 7
doge/core/src/main/java/com/bizzan/bitrade/service/StakingService.java

@@ -10,6 +10,7 @@ import com.bizzan.bitrade.entity.*;
 import com.bizzan.bitrade.entity.MemberWallet;
 import com.bizzan.bitrade.service.Base.BaseService;
 import com.bizzan.bitrade.util.MessageResult;
+import com.bizzan.bitrade.util.RedisManager;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
@@ -71,6 +72,57 @@ public class StakingService extends BaseService {
     @Autowired
     private LocaleMessageSourceService msService;
 
+    @Autowired
+    private CoinService coinService;
+
+    @Autowired
+    private RedisManager redisManager;
+
+    /**
+     * IDO 预售:USDT 按现货价闪兑为质押币后走质押流程
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public MessageResult stakeWithUsdt(Long memberId, Long configId, BigDecimal usdtAmount) {
+        StakingConfig config = stakingConfigDao.findOne(configId);
+        if (config == null || config.getStatus() != 1) {
+            return MessageResult.error(msService.getMessage("STAKING_CONFIG_NOT_FOUND"));
+        }
+        if (usdtAmount == null || usdtAmount.compareTo(BigDecimal.ZERO) <= 0) {
+            return MessageResult.error(msService.getMessage("STAKING_AMOUNT_INVALID"));
+        }
+
+        BigDecimal price = redisManager.getSpotPriceUsdt(config.getCoinUnit());
+        if (price == null || price.compareTo(BigDecimal.ZERO) <= 0) {
+            return MessageResult.error(msService.getMessage("STAKING_PRICE_UNAVAILABLE"));
+        }
+
+        Coin coin = coinService.findByUnit(config.getCoinUnit());
+        if (coin == null) {
+            return MessageResult.error(msService.getMessage("COIN_ILLEGAL"));
+        }
+        int scale = coin.getWithdrawScale() > 0 ? coin.getWithdrawScale() : 8;
+        BigDecimal coinAmount = usdtAmount.divide(price, scale, RoundingMode.DOWN);
+
+        MessageResult validateResult = validateAmount(config, coinAmount);
+        if (validateResult.getCode() != 0) {
+            return validateResult;
+        }
+
+        MemberWallet usdtWallet = memberWalletService.findByCoinUnitAndMemberId("USDT", memberId);
+        BigDecimal usdtBalance = usdtWallet != null ? usdtWallet.getBalance() : BigDecimal.ZERO;
+        if (usdtBalance.compareTo(usdtAmount) < 0) {
+            return MessageResult.error(msService.getMessage("STAKING_USDT_INSUFFICIENT"));
+        }
+
+        MessageResult swapResult = memberWalletService.flashSwapUsdtToCoin(
+                memberId, config.getCoinUnit(), usdtAmount, price);
+        if (swapResult.getCode() != 0) {
+            return swapResult;
+        }
+
+        return executeStake(memberId, configId, config, coinAmount);
+    }
+
     /**
      * 用户质押:冻结余额,创建质押订单和流水
      *
@@ -81,40 +133,38 @@ public class StakingService extends BaseService {
      */
     @Transactional(rollbackFor = Exception.class)
     public MessageResult stake(Long memberId, Long configId, BigDecimal amount) {
-        // 1. 查询质押配置
         StakingConfig config = stakingConfigDao.findOne(configId);
         if (config == null || config.getStatus() != 1) {
             return MessageResult.error(msService.getMessage("STAKING_CONFIG_NOT_FOUND"));
         }
 
-        // 2. 校验质押金额范围
         MessageResult validateResult = validateAmount(config, amount);
         if (validateResult.getCode() != 0) {
             return validateResult;
         }
 
-        // 3. 校验资金账户余额
         MemberWallet fundWallet = memberWalletService.findByCoinUnitAndMemberId(config.getCoinUnit(), memberId);
         BigDecimal currentBalance = fundWallet != null ? fundWallet.getBalance() : BigDecimal.ZERO;
         if (currentBalance.compareTo(amount) < 0) {
             return MessageResult.error(msService.getMessage("STAKING_INSUFFICIENT_BALANCE"));
         }
 
-        // 4. 资金账户 → 质押锁定(原子操作:扣资金、增锁定、记流水)
+        return executeStake(memberId, configId, config, amount);
+    }
+
+    /** 资金账户扣款并创建质押订单(调用前须已完成余额/金额校验) */
+    private MessageResult executeStake(Long memberId, Long configId, StakingConfig config, BigDecimal amount) {
         MessageResult freezeResult = memberWalletService.stakeFundToLocked(memberId, config.getCoinUnit(), amount);
         if (freezeResult.getCode() != 0) {
             return freezeResult;
         }
 
-        // 5. 计算解冻时间
         Date stakingTime = new Date();
         Date unlockTime = calcUnlockTime(stakingTime, config.getLockDays());
 
-        // 6. 创建质押订单
         StakingOrder order = buildStakingOrder(memberId, configId, config.getCoinUnit(), amount, stakingTime, unlockTime);
         stakingOrderDao.save(order);
 
-        // 7. 创建质押流水(type=0 质押:可用转入锁定)
         StakingRecord record = buildStakingRecord(memberId, order.getId(), config.getCoinUnit(), amount, 0, "用户质押");
         stakingRecordDao.save(record);
 

+ 48 - 0
doge/core/src/main/java/com/bizzan/bitrade/vo/CoinWithdrawConfigVO.java

@@ -0,0 +1,48 @@
+package com.bizzan.bitrade.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 提币可选子币种(来自 coin_network_config + coin,按 coin_network.id 筛选)
+ */
+@Data
+@ApiModel("提币子币种主网配置")
+public class CoinWithdrawConfigVO {
+
+    @ApiModelProperty("coin.name,配置表 coin_name")
+    private String coinName;
+
+    @ApiModelProperty("coin.unit,提币接口 unit 参数")
+    private String unit;
+
+    @ApiModelProperty("子币种中文名")
+    private String coinNameCn;
+
+    @ApiModelProperty("coin_network.id")
+    private Long networkId;
+
+    @ApiModelProperty("主网名称 coin_network.name")
+    private String networkName;
+
+    @ApiModelProperty("协议 coin_network.protocol")
+    private String protocol;
+
+    @ApiModelProperty("最小提币额")
+    private BigDecimal minWithdrawAmount;
+
+    @ApiModelProperty("最大提币额")
+    private BigDecimal maxWithdrawAmount;
+
+    @ApiModelProperty("提币手续费")
+    private BigDecimal withdrawFeeValue;
+
+    @ApiModelProperty("上级币种 parent_coin_name")
+    private String parentCoinName;
+
+    @ApiModelProperty("排序")
+    private int sort;
+}

+ 39 - 0
doge/ucenter-api/src/main/java/com/bizzan/bitrade/controller/CoinNetworkController.java

@@ -9,6 +9,7 @@ import com.bizzan.bitrade.service.CoinService;
 import com.bizzan.bitrade.util.MessageResult;
 import com.bizzan.bitrade.vo.CoinChildWithNetworkVO;
 import com.bizzan.bitrade.vo.CoinRechargeConfigVO;
+import com.bizzan.bitrade.vo.CoinWithdrawConfigVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -155,6 +156,44 @@ public class CoinNetworkController extends BaseController {
         return success(coinNetworkConfigService.findRechargeNetworksByParent(coinName));
     }
 
+    /**
+     * 内部转账:可转的顶级币种(coin 表 parentCoinName 为空且 canTransfer=true)
+     */
+    @ApiOperation(value = "内部转账可选主币", notes = "返回 coin 表中 parent_coin_name 为空且 can_transfer=true 的顶级币种")
+    @GetMapping("transfer-parents")
+    public MessageResult listTransferParentCoins() {
+        return success(coinService.findAllTransferParentCoins());
+    }
+
+    /**
+     * 提币:可选主网列表(coin_network 表,且存在可提币种配置)
+     */
+    @ApiOperation(value = "提币可选主网", notes = "来自 coin_network,仅返回已配置可提币种且状态正常的主网")
+    @GetMapping("withdraw-networks")
+    public MessageResult listWithdrawNetworks() {
+        return success(coinNetworkConfigService.findWithdrawNetworks());
+    }
+
+    /**
+     * 提币:按主网 ID 查询 coin_network_config 下可提子币种
+     */
+    @ApiOperation(value = "提币可选子币种", notes = "按 networkId 查询 coin_network_config,币种须 canWithdraw=true")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = "networkId", value = "主网ID coin_network.id", required = true, dataType = "long", paramType = "query")
+    })
+    @GetMapping("withdraw-configs")
+    public MessageResult listWithdrawConfigs(@RequestParam("networkId") Long networkId) {
+        if (networkId == null) {
+            return error("networkId 不能为空");
+        }
+        CoinNetwork network = coinNetworkService.findById(networkId);
+        if (network == null) {
+            return error("主网不存在");
+        }
+        List<CoinWithdrawConfigVO> configs = coinNetworkConfigService.findWithdrawConfigsByNetwork(networkId);
+        return success(configs);
+    }
+
     /**
      * 充值:按主网 ID 从 coin_network_config 查询子币种列表
      */

+ 11 - 2
doge/ucenter-api/src/main/java/com/bizzan/bitrade/controller/StakingController.java

@@ -162,8 +162,17 @@ public class StakingController {
     @PostMapping("/stake")
     public MessageResult stake(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                                @RequestParam Long configId,
-                               @RequestParam BigDecimal amount) {
-        MessageResult result = stakingService.stake(member.getId(), configId, amount);
+                               @RequestParam(required = false) BigDecimal amount,
+                               @RequestParam(required = false) BigDecimal usdtAmount) {
+        MessageResult result;
+        if (usdtAmount != null && usdtAmount.compareTo(BigDecimal.ZERO) > 0) {
+            result = stakingService.stakeWithUsdt(member.getId(), configId, usdtAmount);
+        } else {
+            if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
+                return MessageResult.error(msService.getMessage("STAKING_AMOUNT_INVALID"));
+            }
+            result = stakingService.stake(member.getId(), configId, amount);
+        }
         // 事务提交后发送 MQ 通知,避免消费方读到事务未提交的旧数据
         if (result.getCode() == 0) {
             kafkaTemplate.send("trading-account-change", member.getId() + "");

+ 13 - 13
doge/ucenter-api/src/main/java/com/bizzan/bitrade/controller/WithdrawController.java

@@ -891,13 +891,14 @@ public class WithdrawController extends BaseController {
     public MessageResult transfer(@SessionAttribute(SESSION_MEMBER) AuthMember user, String unit, String address,
                                   BigDecimal amount,String remark,String jyPassword, Integer vtype, String vcode) throws Exception {
         hasText(jyPassword, sourceService.getMessage("MISSING_JYPASSWORD"));
-        unit="USDT";
+        hasText(unit, sourceService.getMessage("COIN_ILLEGAL"));
         Coin coin = coinService.findByUnit(unit);
-        amount.setScale(coin.getWithdrawScale(),BigDecimal.ROUND_DOWN);
         notNull(coin, sourceService.getMessage("COIN_ILLEGAL"));
-        
-
-        //isTrue(coin.getStatus().equals(CommonStatus.NORMAL) && coin.getCanWithdraw().equals(BooleanEnum.IS_TRUE), sourceService.getMessage("COIN_NOT_SUPPORT"));
+        isTrue(coin.getStatus().equals(CommonStatus.NORMAL) && coin.getCanTransfer().equals(BooleanEnum.IS_TRUE),
+                sourceService.getMessage("COIN_NOT_SUPPORT"));
+        isTrue(coin.getParentCoinName() == null || coin.getParentCoinName().trim().isEmpty(),
+                sourceService.getMessage("COIN_NOT_SUPPORT"));
+        amount.setScale(coin.getWithdrawScale(), BigDecimal.ROUND_DOWN);
         //isTrue(compare(fee, new BigDecimal(String.valueOf(coin.getMinTxFee()))), sourceService.getMessage("CHARGE_MIN") + coin.getMinTxFee());
         //isTrue(compare(new BigDecimal(String.valueOf(coin.getMaxTxFee())), fee), sourceService.getMessage("CHARGE_MAX") + coin.getMaxTxFee());
         isTrue(compare(coin.getMaxWithdrawAmount(), amount), sourceService.getMessage("WITHDRAW_MAX") + coin.getMaxWithdrawAmount());
@@ -919,22 +920,21 @@ public class WithdrawController extends BaseController {
         
         String finalUnit;
         MemberWallet memberWallet;
-        if(unit.equals("USDT"))
-        {
+        if ("EUSDT".equalsIgnoreCase(unit) || "TUSDT".equalsIgnoreCase(unit)
+                || "USDT-BEP20".equalsIgnoreCase(unit) || "USDT".equalsIgnoreCase(unit)) {
         	finalUnit = "USDT";
         	memberWallet = memberWalletService.findByCoinAndMemberId(coinService.findByUnit(finalUnit), user.getId());
-        	//memberWallet = InnerInvokeUtil.fineWallet(user.getId(), "USDT");
         	MemberWalletVo memberWalletVo = balanceService.getMemberWalletVo(user.getId());
-        	if (amount.compareTo(memberWalletVo.getWithdrawableBalance())>0)
+        	if (amount.compareTo(memberWalletVo.getTransferableBalance()) > 0) {
         		return MessageResult.error(sourceService.getMessage("INSUFFICIENT_BALANCE"));
-        	//isTrue(compare(memberWalletVo.getWithdrawableBalance(), amount), sourceService.getMessage("INSUFFICIENT_BALANCE"));
+        	}
         } else {
         	finalUnit = coin.getUnit();
         	memberWallet = memberWalletService.findByCoinAndMemberId(coin, user.getId());
-        	//memberWallet = InnerInvokeUtil.fineWallet(user.getId(), unit);
+        	if (amount.compareTo(memberWallet.getBalance()) > 0) {
+        		return MessageResult.error(sourceService.getMessage("INSUFFICIENT_BALANCE"));
+        	}
         }
-        //isTrue(compare(memberWallet.getBalance(), amount), sourceService.getMessage("INSUFFICIENT_BALANCE"));
-//        isTrue(memberAddressService.findByMemberIdAndAddress(user.getId(), address).size() > 0, sourceService.getMessage("WRONG_ADDRESS"));
         isTrue(memberWallet.getIsLock()==BooleanEnum.IS_FALSE,sourceService.getMessage("WALLET_IS_LOCK"));
         Member member = memberService.findOne(user.getId());
         if (member.getIsInternal() != null && member.getIsInternal() == 1) {

+ 2 - 0
doge/ucenter-api/src/main/resources/i18n/messages_en_US.properties

@@ -243,6 +243,8 @@ STAKING_INSUFFICIENT_BALANCE=Insufficient fund account balance
 STAKING_AMOUNT_INVALID=Staking amount must be greater than 0
 STAKING_AMOUNT_BELOW_MIN=Staking amount is below the minimum allowed
 STAKING_AMOUNT_ABOVE_MAX=Staking amount exceeds the maximum allowed
+STAKING_PRICE_UNAVAILABLE=Market price is unavailable. Please try again later
+STAKING_USDT_INSUFFICIENT=Insufficient available USDT balance
 
 # Activity
 ACTIVITY_ATTEND_FAILED=Failed to participate in activity

+ 2 - 0
doge/ucenter-api/src/main/resources/i18n/messages_zh_CN.properties

@@ -244,6 +244,8 @@ STAKING_INSUFFICIENT_BALANCE=\u8D44\u91D1\u8D26\u6237\u4F59\u989D\u4E0D\u8DB3
 STAKING_AMOUNT_INVALID=\u8D28\u62BC\u91D1\u989D\u5FC5\u987B\u5927\u4E8E0
 STAKING_AMOUNT_BELOW_MIN=\u8D28\u62BC\u91D1\u989D\u4F4E\u4E8E\u6700\u4F4E\u9650\u989D
 STAKING_AMOUNT_ABOVE_MAX=\u8D28\u62BC\u91D1\u989D\u8D85\u8FC7\u6700\u9AD8\u9650\u989D
+STAKING_PRICE_UNAVAILABLE=\u6682\u65E0\u884C\u60C5\u4EF7\u683C\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5
+STAKING_USDT_INSUFFICIENT=\u53EF\u7528 USDT \u4F59\u989D\u4E0D\u8DB3
 
 # 活动
 ACTIVITY_ATTEND_FAILED=\u53C2\u4E0E\u6D3B\u52A8\u5931\u8D25