Browse Source

修改首页

st 2 months ago
parent
commit
ad5473cd0e
3 changed files with 431 additions and 512 deletions
  1. 1 1
      src/pages/play/game.vue
  2. 425 422
      src/pages/trophy/wallet.vue
  3. 5 89
      src/types/auto-import.d.ts

+ 1 - 1
src/pages/play/game.vue

@@ -651,7 +651,7 @@ onUnmounted(() => {
     >
       <view v-for="(key, index) in buttons" :key="index">
         <image
-          src="`/static/images/play/tong.png`"
+          src="@/static/images/play/tong.png"
           :style="{ color: pressedKeys[index] ? '#0E0E0E' : '#fff' }"
           :class="[
             'w-150rpx h-175rpx rounded-20rpx flex items-center justify-center text-32rpx fw-550 relative z-[10]',

+ 425 - 422
src/pages/trophy/wallet.vue

@@ -7,426 +7,429 @@
 }
 </route>
 <template>
-  <view class="w-full min-h-screen bg-bgc flex flex-col items-center text-white">
-    <text class="mt-70rpx fw-540 text-[45rpx]">{{ $t('purse.Withdraw') }}</text>
-    <!-- 余额显示 -->
-    <view class="w-690rpx h-538rpx rounded-30rpx bg-[#27272A] flex items-center flex-col mt-45rpx">
-      <!-- TON输入框 -->
-      <view class="custom-input mt-30rpx">
-        <image src="@/static/images/purse/u.png" class="w-70rpx h-70rpx ml-14rpx"></image>
-        <input
-          type="text"
-          v-model="tonInput"
-          @input="handleTonInput"
-          placeholder="0"
-          class="input-field"
-        />
-      </view>
-
-      <!-- 提示信息 -->
-      <text
-        class="text-26rpx text-left w-full mt-30rpx ml-56rpx"
-        :class="{ 'text-red-500': showError }"
-      >
-        {{ errorMessage || i18n.global.t('purse.Minimum') }}
-      </text>
-
-      <!-- 金币输入框 -->
-      <view class="custom-input mt-40rpx">
-        <image src="@/static/images/purse/blackGB.png" class="w-70rpx h-70rpx ml-14rpx"></image>
-        <input
-          type="text"
-          v-model="coinInput"
-          @input="handleCoinInput"
-          placeholder="Enter withdrawal address"
-          class="input-field"
-        />
-      </view>
-
-      <!-- 连接钱包/提现按钮 -->
-      <view
-        @click="triggerConnect"
-        class="w-630rpx h-100rpx rounded-20rpx btn-bg mt-60rpx flex items-center justify-center cursor-pointer"
-      >
-        <text class="text-32rpx text-white">{{ wallet ? 'Withdraw' : 'Connect' }}</text>
-      </view>
-    </view>
-    <!-- 记录刷新区 -->
-    <view class="w-690rpx mt-49rpx flex items-center justify-between">
-      <text>{{ $t('purse.Record') }}</text>
-      <image
-        @click="refreshRecords"
-        src="@/static/images/purse/shuaxin.png"
-        class="w-42rpx h-42rpx"
-      ></image>
-    </view>
-    <view
-      v-for="(record, index) in pcamaignList"
-      :key="index"
-      class="w-690rpx h-130rpx mt-30rpx rounded-20rpx bg-[#13355A] flex items-center justify-between mt-20rpx"
-    >
-      <view class="flex items-center ml-20rpx justify-between w-full">
-        <view>
-          <image src="@/static/images/purse/blackGB.png" class="w-70rpx h-70rpx mr-29rpx" />
-          <text class="text-24rpx text-white mr-20rpx">{{ record.pay_time }}</text>
-        </view>
-
-        <view class="flex items-center">
-          <text class="text-24rpx text-white mr-40rpx">+{{ record.coin_exchange }}</text>
-        </view>
-      </view>
-    </view>
-  </view>
-  <wd-notify />
+  <view>123</view>
 </template>
-
-<script setup lang="ts">
-import {
-  useTonWallet,
-  useTonConnectUI,
-  useTonConnectModal,
-  useTonAddress,
-} from '@townsquarelabs/ui-vue'
-import { useTelegramBackButton } from '@/hooks/useTelegramBackButton'
-import {
-  getCoinAddress,
-  getRecharge,
-  postRechargeCoin,
-  postRechargeCoinReturn,
-  RechargeCoinList,
-} from '@/service/purse'
-import i18n from '@/locale/index'
-import { useNotify } from 'wot-design-uni'
-
-const { showNotify } = useNotify()
-const { open, close } = useTonConnectModal()
-const { isVisible } = useTelegramBackButton(() => {
-  uni.navigateBack()
-})
-const userFriendlyAddress = useTonAddress()
-// 状态管理
-const wallet = useTonWallet()
-const { tonConnectUI } = useTonConnectUI()
-const tonInput = ref('') // TON 输入值
-const coinInput = ref('') // 金币输入值
-const userBalance = ref(0)
-const errorMessage = ref('')
-const showError = ref(false)
-const inputMode = ref('ton') // 当前输入模式: 'ton' | 'coin'
-
-// 计算最小提现金额(以nanoTON为单位)
-const MIN_WITHDRAWAL = 0.1 // 1 TON
-
-let balanceInterval: number | null = null
-
-// 获取钱包余额
-const getWalletBalance = async (address: string) => {
-  try {
-    const response = await fetch(
-      `https://toncenter.com/api/v2/getAddressBalance?address=${address}`,
-    )
-    const data = await response.json()
-
-    if (data.ok) {
-      userBalance.value = Number(data.result) / 1000000000
-      console.log('Wallet balance:', userBalance.value, 'TON')
-    } else {
-      console.error('Failed to get balance, invalid response:', data)
-      userBalance.value = 0
-    }
-  } catch (error) {
-    console.error('Failed to fetch balance:', error)
-    userBalance.value = 0
-  }
-}
-
-// 获取兑换比例
-const proportion = ref(0)
-const getProportion = async () => {
-  const { data } = await getRecharge()
-  proportion.value = data.proportion
-}
-
-// 获取系统充值钱包地址
-const coinAddress = ref()
-const getCoinAddressFn = async () => {
-  const { data } = await getCoinAddress()
-  coinAddress.value = data.coin_address
-}
-
-const formatNumberInput = (value: string) => {
-  // 移除非数字和小数点
-  value = value.replace(/[^\d.]/g, '')
-
-  // 处理前导零
-  if (value.startsWith('0') && value.length > 1 && !value.startsWith('0.')) {
-    value = value.replace(/^0+/, '')
-  }
-
-  // 如果是第一次输入小数点且在开头,自动补0
-  if (value.startsWith('.')) {
-    value = '0' + value
-  }
-
-  // 限制只能有一个小数点
-  if (value.includes('.') && value.split('.').length > 2) {
-    return value.substring(0, value.lastIndexOf('.'))
-  }
-
-  // 限制小数位数为6位
-  if (value.includes('.')) {
-    const [integer, decimal] = value.split('.')
-    return `${integer}.${decimal.slice(0, 6)}`
-  }
-
-  return value
-}
-// 常量定义
-const MIN_TON = 0.1 // 最小兑换数量改为 0.1 TON
-const MAX_TON = 1000000 // 最大 TON 输入限制
-const MAX_DECIMALS_TON = 6 // TON 最大小数位数
-const MAX_DECIMALS_COIN = 2 // 金币最大小数位数
-// 处理 TON 输入
-const handleTonInput = (e: any) => {
-  try {
-    let value = formatNumberInput(e.detail.value)
-    const numValue = Number(value)
-
-    // 检查最大值限制
-    if (numValue > MAX_TON) {
-      value = MAX_TON.toString()
-    }
-
-    // 更新 TON 输入值
-    tonInput.value = value
-
-    // 计算对应的金币数量
-    if (value && proportion.value) {
-      const coins = numValue * proportion.value
-      coinInput.value = Number(coins.toFixed(MAX_DECIMALS_COIN)).toString()
-    } else {
-      coinInput.value = ''
-    }
-
-    // 输入值校验
-    if (!value) {
-      showError.value = false
-      errorMessage.value = ''
-    } else {
-      if (numValue < MIN_TON) {
-        showError.value = true
-        errorMessage.value = i18n.global.t('purse.Minimum') // 'Minimum withdrawal amount is 0.1 TON'
-      } else if (numValue > userBalance.value) {
-        showError.value = true
-        errorMessage.value = i18n.global.t('purse.balance') // 'Insufficient balance'
-      } else {
-        showError.value = false
-        errorMessage.value = ''
-      }
-    }
-  } catch (error) {
-    console.error('Error in handleTonInput:', error)
-  }
-}
-
-// 处理金币输入
-const handleCoinInput = (e: any) => {
-  try {
-    let value = formatNumberInput(e.detail.value)
-    const numValue = Number(value)
-
-    // 检查最大值限制
-    const maxCoins = MAX_TON * proportion.value
-    if (numValue > maxCoins) {
-      value = maxCoins.toString()
-    }
-
-    // 更新金币输入值
-    coinInput.value = value
-
-    // 计算对应的 TON 数量
-    if (value && proportion.value) {
-      const tons = numValue / proportion.value
-      tonInput.value = Number(tons.toFixed(MAX_DECIMALS_TON)).toString()
-
-      // 根据计算出的 TON 值进行验证
-      if (tons < MIN_TON) {
-        showError.value = true
-        errorMessage.value = i18n.global.t('purse.Minimum')
-      } else if (tons > userBalance.value) {
-        showError.value = true
-        errorMessage.value = i18n.global.t('purse.balance')
-      } else {
-        showError.value = false
-        errorMessage.value = ''
-      }
-    } else {
-      tonInput.value = ''
-      showError.value = false
-      errorMessage.value = ''
-    }
-  } catch (error) {
-    console.error('Error in handleCoinInput:', error)
-  }
-}
-
-// 验证金额 - 仅在提交时使用
-const validateAmount = () => {
-  const tonAmount = Number(tonInput.value || 0)
-
-  if (!tonInput.value || tonAmount <= 0) {
-    errorMessage.value = i18n.global.t('purse.amount')
-    showError.value = true
-    return false
-  }
-
-  if (tonAmount < MIN_TON) {
-    errorMessage.value = i18n.global.t('purse.Minimum')
-    showError.value = true
-    return false
-  }
-
-  if (tonAmount > userBalance.value) {
-    errorMessage.value = i18n.global.t('purse.balance')
-    showError.value = true
-    return false
-  }
-
-  return true
-}
-
-// 连接钱包
-const triggerConnect = async () => {
-  if (!wallet.value) {
-    try {
-      await open()
-    } catch (error) {
-      console.error('Connection failed:', error)
-    }
-  } else {
-    handleWithdraw()
-  }
-}
-
-// 处理兑换
-const handleWithdraw = async () => {
-  if (!validateAmount()) {
-    return
-  }
-  if (!coinAddress.value) {
-    return
-  }
-  try {
-    const transaction = {
-      validUntil: Math.floor(Date.now() / 1000) + 60,
-      messages: [
-        {
-          address: coinAddress.value,
-          // 转换为 nanoTON
-          amount: (Number(tonInput.value) * 1000000000).toString(),
-        },
-      ],
-    }
-
-    const result = await tonConnectUI.sendTransaction(transaction)
-
-    if (result) {
-      if (wallet.value?.account?.address) {
-        await getWalletBalance(wallet.value.account.address)
-      }
-      const { code, msg } = await postRechargeCoin({
-        coin: (Number(tonInput.value) * 1000000000).toString(),
-        coin_address: userFriendlyAddress.value,
-        boc: result.boc,
-        favorable: '',
-      })
-      if (code === 1) {
-        showNotify({ type: 'success', message: msg })
-      } else {
-        showNotify({ type: 'warning', message: msg })
-      }
-      tonInput.value = ''
-      coinInput.value = ''
-      showError.value = false
-      errorMessage.value = ''
-      // 刷新记录
-      refreshRecords()
-    }
-  } catch (error) {
-    console.error('Withdrawal failed:', error)
-  }
-}
-const pcamaignList = ref<RechargeCoinList[]>([])
-// 刷新记录
-const refreshRecords = async () => {
-  try {
-    // 这里调用你的API获取最新记录
-    const { data } = await postRechargeCoinReturn()
-    pcamaignList.value = data
-  } catch (error) {
-    console.error('Failed to refresh records:', error)
-  }
-}
-
-// 监听钱包连接状态
-onMounted(async () => {
-  await getProportion()
-  await getCoinAddressFn()
-  await refreshRecords()
-  if (wallet.value?.account?.address) {
-    console.info('🚀 ~ file:index method: line:296 -----', 1111)
-    getWalletBalance(wallet.value.account.address)
-
-    if (balanceInterval) clearInterval(balanceInterval)
-    balanceInterval = setInterval(() => {
-      getWalletBalance(wallet.value.account.address)
-    }, 30000)
-  } else {
-    userBalance.value = 0
-    if (balanceInterval) {
-      clearInterval(balanceInterval)
-      balanceInterval = null
-    }
-  }
-})
-
-onUnmounted(() => {
-  if (balanceInterval) {
-    clearInterval(balanceInterval)
-  }
-  tonConnectUI.removeStatusChangeListener()
-})
-</script>
-
-<style scoped lang="scss">
-.custom-input {
-  display: flex;
-  align-items: center;
-  width: 630rpx;
-  height: 100rpx;
-  padding-right: 20rpx;
-  background-color: white;
-  border-radius: 20rpx;
-}
-
-.input-field {
-  flex: 1;
-  height: 100rpx;
-  padding-right: 20rpx;
-  font-size: 38rpx;
-  line-height: 100rpx;
-  color: black;
-  text-align: right;
-  background: transparent;
-}
-
-/* 修改 placeholder 样式 */
-.input-field::placeholder {
-  font-size: 38rpx;
-  color: #999;
-}
-
-.btn-bg {
-  background: #8ae54a;
-}
-</style>
+<!--<template>-->
+<!--  <view class="w-full min-h-screen bg-bgc flex flex-col items-center text-white">-->
+<!--    <text class="mt-70rpx fw-540 text-[45rpx]">{{ $t('purse.Withdraw') }}</text>-->
+<!--    &lt;!&ndash; 余额显示 &ndash;&gt;-->
+<!--    <view class="w-690rpx h-538rpx rounded-30rpx bg-[#27272A] flex items-center flex-col mt-45rpx">-->
+<!--      &lt;!&ndash; TON输入框 &ndash;&gt;-->
+<!--      <view class="custom-input mt-30rpx">-->
+<!--        <image src="@/static/images/purse/u.png" class="w-70rpx h-70rpx ml-14rpx"></image>-->
+<!--        <input-->
+<!--          type="text"-->
+<!--          v-model="tonInput"-->
+<!--          @input="handleTonInput"-->
+<!--          placeholder="0"-->
+<!--          class="input-field"-->
+<!--        />-->
+<!--      </view>-->
+
+<!--      &lt;!&ndash; 提示信息 &ndash;&gt;-->
+<!--      <text-->
+<!--        class="text-26rpx text-left w-full mt-30rpx ml-56rpx"-->
+<!--        :class="{ 'text-red-500': showError }"-->
+<!--      >-->
+<!--        {{ errorMessage || i18n.global.t('purse.Minimum') }}-->
+<!--      </text>-->
+
+<!--      &lt;!&ndash; 金币输入框 &ndash;&gt;-->
+<!--      <view class="custom-input mt-40rpx">-->
+<!--        <image src="@/static/images/purse/blackGB.png" class="w-70rpx h-70rpx ml-14rpx"></image>-->
+<!--        <input-->
+<!--          type="text"-->
+<!--          v-model="coinInput"-->
+<!--          @input="handleCoinInput"-->
+<!--          placeholder="Enter withdrawal address"-->
+<!--          class="input-field"-->
+<!--        />-->
+<!--      </view>-->
+
+<!--      &lt;!&ndash; 连接钱包/提现按钮 &ndash;&gt;-->
+<!--      <view-->
+<!--        @click="triggerConnect"-->
+<!--        class="w-630rpx h-100rpx rounded-20rpx btn-bg mt-60rpx flex items-center justify-center cursor-pointer"-->
+<!--      >-->
+<!--        <text class="text-32rpx text-white">{{ wallet ? 'Withdraw' : 'Connect' }}</text>-->
+<!--      </view>-->
+<!--    </view>-->
+<!--    &lt;!&ndash; 记录刷新区 &ndash;&gt;-->
+<!--    <view class="w-690rpx mt-49rpx flex items-center justify-between">-->
+<!--      <text>{{ $t('purse.Record') }}</text>-->
+<!--      <image-->
+<!--        @click="refreshRecords"-->
+<!--        src="@/static/images/purse/shuaxin.png"-->
+<!--        class="w-42rpx h-42rpx"-->
+<!--      ></image>-->
+<!--    </view>-->
+<!--    <view-->
+<!--      v-for="(record, index) in pcamaignList"-->
+<!--      :key="index"-->
+<!--      class="w-690rpx h-130rpx mt-30rpx rounded-20rpx bg-[#13355A] flex items-center justify-between mt-20rpx"-->
+<!--    >-->
+<!--      <view class="flex items-center ml-20rpx justify-between w-full">-->
+<!--        <view>-->
+<!--          <image src="@/static/images/purse/blackGB.png" class="w-70rpx h-70rpx mr-29rpx" />-->
+<!--          <text class="text-24rpx text-white mr-20rpx">{{ record.pay_time }}</text>-->
+<!--        </view>-->
+
+<!--        <view class="flex items-center">-->
+<!--          <text class="text-24rpx text-white mr-40rpx">+{{ record.coin_exchange }}</text>-->
+<!--        </view>-->
+<!--      </view>-->
+<!--    </view>-->
+<!--  </view>-->
+<!--  <wd-notify />-->
+<!--</template>-->
+
+<!--<script setup lang="ts">-->
+<!--import {-->
+<!--  useTonWallet,-->
+<!--  useTonConnectUI,-->
+<!--  useTonConnectModal,-->
+<!--  useTonAddress,-->
+<!--} from '@townsquarelabs/ui-vue'-->
+<!--import { useTelegramBackButton } from '@/hooks/useTelegramBackButton'-->
+<!--import {-->
+<!--  getCoinAddress,-->
+<!--  getRecharge,-->
+<!--  postRechargeCoin,-->
+<!--  postRechargeCoinReturn,-->
+<!--  RechargeCoinList,-->
+<!--} from '@/service/purse'-->
+<!--import i18n from '@/locale/index'-->
+<!--import { useNotify } from 'wot-design-uni'-->
+
+<!--const { showNotify } = useNotify()-->
+<!--const { open, close } = useTonConnectModal()-->
+<!--const { isVisible } = useTelegramBackButton(() => {-->
+<!--  uni.navigateBack()-->
+<!--})-->
+<!--const userFriendlyAddress = useTonAddress()-->
+<!--// 状态管理-->
+<!--const wallet = useTonWallet()-->
+<!--const { tonConnectUI } = useTonConnectUI()-->
+<!--const tonInput = ref('') // TON 输入值-->
+<!--const coinInput = ref('') // 金币输入值-->
+<!--const userBalance = ref(0)-->
+<!--const errorMessage = ref('')-->
+<!--const showError = ref(false)-->
+<!--const inputMode = ref('ton') // 当前输入模式: 'ton' | 'coin'-->
+
+<!--// 计算最小提现金额(以nanoTON为单位)-->
+<!--const MIN_WITHDRAWAL = 0.1 // 1 TON-->
+
+<!--let balanceInterval: number | null = null-->
+
+<!--// 获取钱包余额-->
+<!--const getWalletBalance = async (address: string) => {-->
+<!--  try {-->
+<!--    const response = await fetch(-->
+<!--      `https://toncenter.com/api/v2/getAddressBalance?address=${address}`,-->
+<!--    )-->
+<!--    const data = await response.json()-->
+
+<!--    if (data.ok) {-->
+<!--      userBalance.value = Number(data.result) / 1000000000-->
+<!--      console.log('Wallet balance:', userBalance.value, 'TON')-->
+<!--    } else {-->
+<!--      console.error('Failed to get balance, invalid response:', data)-->
+<!--      userBalance.value = 0-->
+<!--    }-->
+<!--  } catch (error) {-->
+<!--    console.error('Failed to fetch balance:', error)-->
+<!--    userBalance.value = 0-->
+<!--  }-->
+<!--}-->
+
+<!--// 获取兑换比例-->
+<!--const proportion = ref(0)-->
+<!--const getProportion = async () => {-->
+<!--  const { data } = await getRecharge()-->
+<!--  proportion.value = data.proportion-->
+<!--}-->
+
+<!--// 获取系统充值钱包地址-->
+<!--const coinAddress = ref()-->
+<!--const getCoinAddressFn = async () => {-->
+<!--  const { data } = await getCoinAddress()-->
+<!--  coinAddress.value = data.coin_address-->
+<!--}-->
+
+<!--const formatNumberInput = (value: string) => {-->
+<!--  // 移除非数字和小数点-->
+<!--  value = value.replace(/[^\d.]/g, '')-->
+
+<!--  // 处理前导零-->
+<!--  if (value.startsWith('0') && value.length > 1 && !value.startsWith('0.')) {-->
+<!--    value = value.replace(/^0+/, '')-->
+<!--  }-->
+
+<!--  // 如果是第一次输入小数点且在开头,自动补0-->
+<!--  if (value.startsWith('.')) {-->
+<!--    value = '0' + value-->
+<!--  }-->
+
+<!--  // 限制只能有一个小数点-->
+<!--  if (value.includes('.') && value.split('.').length > 2) {-->
+<!--    return value.substring(0, value.lastIndexOf('.'))-->
+<!--  }-->
+
+<!--  // 限制小数位数为6位-->
+<!--  if (value.includes('.')) {-->
+<!--    const [integer, decimal] = value.split('.')-->
+<!--    return `${integer}.${decimal.slice(0, 6)}`-->
+<!--  }-->
+
+<!--  return value-->
+<!--}-->
+<!--// 常量定义-->
+<!--const MIN_TON = 0.1 // 最小兑换数量改为 0.1 TON-->
+<!--const MAX_TON = 1000000 // 最大 TON 输入限制-->
+<!--const MAX_DECIMALS_TON = 6 // TON 最大小数位数-->
+<!--const MAX_DECIMALS_COIN = 2 // 金币最大小数位数-->
+<!--// 处理 TON 输入-->
+<!--const handleTonInput = (e: any) => {-->
+<!--  try {-->
+<!--    let value = formatNumberInput(e.detail.value)-->
+<!--    const numValue = Number(value)-->
+
+<!--    // 检查最大值限制-->
+<!--    if (numValue > MAX_TON) {-->
+<!--      value = MAX_TON.toString()-->
+<!--    }-->
+
+<!--    // 更新 TON 输入值-->
+<!--    tonInput.value = value-->
+
+<!--    // 计算对应的金币数量-->
+<!--    if (value && proportion.value) {-->
+<!--      const coins = numValue * proportion.value-->
+<!--      coinInput.value = Number(coins.toFixed(MAX_DECIMALS_COIN)).toString()-->
+<!--    } else {-->
+<!--      coinInput.value = ''-->
+<!--    }-->
+
+<!--    // 输入值校验-->
+<!--    if (!value) {-->
+<!--      showError.value = false-->
+<!--      errorMessage.value = ''-->
+<!--    } else {-->
+<!--      if (numValue < MIN_TON) {-->
+<!--        showError.value = true-->
+<!--        errorMessage.value = i18n.global.t('purse.Minimum') // 'Minimum withdrawal amount is 0.1 TON'-->
+<!--      } else if (numValue > userBalance.value) {-->
+<!--        showError.value = true-->
+<!--        errorMessage.value = i18n.global.t('purse.balance') // 'Insufficient balance'-->
+<!--      } else {-->
+<!--        showError.value = false-->
+<!--        errorMessage.value = ''-->
+<!--      }-->
+<!--    }-->
+<!--  } catch (error) {-->
+<!--    console.error('Error in handleTonInput:', error)-->
+<!--  }-->
+<!--}-->
+
+<!--// 处理金币输入-->
+<!--const handleCoinInput = (e: any) => {-->
+<!--  try {-->
+<!--    let value = formatNumberInput(e.detail.value)-->
+<!--    const numValue = Number(value)-->
+
+<!--    // 检查最大值限制-->
+<!--    const maxCoins = MAX_TON * proportion.value-->
+<!--    if (numValue > maxCoins) {-->
+<!--      value = maxCoins.toString()-->
+<!--    }-->
+
+<!--    // 更新金币输入值-->
+<!--    coinInput.value = value-->
+
+<!--    // 计算对应的 TON 数量-->
+<!--    if (value && proportion.value) {-->
+<!--      const tons = numValue / proportion.value-->
+<!--      tonInput.value = Number(tons.toFixed(MAX_DECIMALS_TON)).toString()-->
+
+<!--      // 根据计算出的 TON 值进行验证-->
+<!--      if (tons < MIN_TON) {-->
+<!--        showError.value = true-->
+<!--        errorMessage.value = i18n.global.t('purse.Minimum')-->
+<!--      } else if (tons > userBalance.value) {-->
+<!--        showError.value = true-->
+<!--        errorMessage.value = i18n.global.t('purse.balance')-->
+<!--      } else {-->
+<!--        showError.value = false-->
+<!--        errorMessage.value = ''-->
+<!--      }-->
+<!--    } else {-->
+<!--      tonInput.value = ''-->
+<!--      showError.value = false-->
+<!--      errorMessage.value = ''-->
+<!--    }-->
+<!--  } catch (error) {-->
+<!--    console.error('Error in handleCoinInput:', error)-->
+<!--  }-->
+<!--}-->
+
+<!--// 验证金额 - 仅在提交时使用-->
+<!--const validateAmount = () => {-->
+<!--  const tonAmount = Number(tonInput.value || 0)-->
+
+<!--  if (!tonInput.value || tonAmount <= 0) {-->
+<!--    errorMessage.value = i18n.global.t('purse.amount')-->
+<!--    showError.value = true-->
+<!--    return false-->
+<!--  }-->
+
+<!--  if (tonAmount < MIN_TON) {-->
+<!--    errorMessage.value = i18n.global.t('purse.Minimum')-->
+<!--    showError.value = true-->
+<!--    return false-->
+<!--  }-->
+
+<!--  if (tonAmount > userBalance.value) {-->
+<!--    errorMessage.value = i18n.global.t('purse.balance')-->
+<!--    showError.value = true-->
+<!--    return false-->
+<!--  }-->
+
+<!--  return true-->
+<!--}-->
+
+<!--// 连接钱包-->
+<!--const triggerConnect = async () => {-->
+<!--  if (!wallet.value) {-->
+<!--    try {-->
+<!--      await open()-->
+<!--    } catch (error) {-->
+<!--      console.error('Connection failed:', error)-->
+<!--    }-->
+<!--  } else {-->
+<!--    handleWithdraw()-->
+<!--  }-->
+<!--}-->
+
+<!--// 处理兑换-->
+<!--const handleWithdraw = async () => {-->
+<!--  if (!validateAmount()) {-->
+<!--    return-->
+<!--  }-->
+<!--  if (!coinAddress.value) {-->
+<!--    return-->
+<!--  }-->
+<!--  try {-->
+<!--    const transaction = {-->
+<!--      validUntil: Math.floor(Date.now() / 1000) + 60,-->
+<!--      messages: [-->
+<!--        {-->
+<!--          address: coinAddress.value,-->
+<!--          // 转换为 nanoTON-->
+<!--          amount: (Number(tonInput.value) * 1000000000).toString(),-->
+<!--        },-->
+<!--      ],-->
+<!--    }-->
+
+<!--    const result = await tonConnectUI.sendTransaction(transaction)-->
+
+<!--    if (result) {-->
+<!--      if (wallet.value?.account?.address) {-->
+<!--        await getWalletBalance(wallet.value.account.address)-->
+<!--      }-->
+<!--      const { code, msg } = await postRechargeCoin({-->
+<!--        coin: (Number(tonInput.value) * 1000000000).toString(),-->
+<!--        coin_address: userFriendlyAddress.value,-->
+<!--        boc: result.boc,-->
+<!--        favorable: '',-->
+<!--      })-->
+<!--      if (code === 1) {-->
+<!--        showNotify({ type: 'success', message: msg })-->
+<!--      } else {-->
+<!--        showNotify({ type: 'warning', message: msg })-->
+<!--      }-->
+<!--      tonInput.value = ''-->
+<!--      coinInput.value = ''-->
+<!--      showError.value = false-->
+<!--      errorMessage.value = ''-->
+<!--      // 刷新记录-->
+<!--      refreshRecords()-->
+<!--    }-->
+<!--  } catch (error) {-->
+<!--    console.error('Withdrawal failed:', error)-->
+<!--  }-->
+<!--}-->
+<!--const pcamaignList = ref<RechargeCoinList[]>([])-->
+<!--// 刷新记录-->
+<!--const refreshRecords = async () => {-->
+<!--  try {-->
+<!--    // 这里调用你的API获取最新记录-->
+<!--    const { data } = await postRechargeCoinReturn()-->
+<!--    pcamaignList.value = data-->
+<!--  } catch (error) {-->
+<!--    console.error('Failed to refresh records:', error)-->
+<!--  }-->
+<!--}-->
+
+<!--// 监听钱包连接状态-->
+<!--onMounted(async () => {-->
+<!--  await getProportion()-->
+<!--  await getCoinAddressFn()-->
+<!--  await refreshRecords()-->
+<!--  if (wallet.value?.account?.address) {-->
+<!--    console.info('🚀 ~ file:index method: line:296 -&#45;&#45;&#45;&#45;', 1111)-->
+<!--    getWalletBalance(wallet.value.account.address)-->
+
+<!--    if (balanceInterval) clearInterval(balanceInterval)-->
+<!--    balanceInterval = setInterval(() => {-->
+<!--      getWalletBalance(wallet.value.account.address)-->
+<!--    }, 30000)-->
+<!--  } else {-->
+<!--    userBalance.value = 0-->
+<!--    if (balanceInterval) {-->
+<!--      clearInterval(balanceInterval)-->
+<!--      balanceInterval = null-->
+<!--    }-->
+<!--  }-->
+<!--})-->
+
+<!--onUnmounted(() => {-->
+<!--  if (balanceInterval) {-->
+<!--    clearInterval(balanceInterval)-->
+<!--  }-->
+<!--  tonConnectUI.removeStatusChangeListener()-->
+<!--})-->
+<!--</script>-->
+
+<!--<style scoped lang="scss">-->
+<!--.custom-input {-->
+<!--  display: flex;-->
+<!--  align-items: center;-->
+<!--  width: 630rpx;-->
+<!--  height: 100rpx;-->
+<!--  padding-right: 20rpx;-->
+<!--  background-color: white;-->
+<!--  border-radius: 20rpx;-->
+<!--}-->
+
+<!--.input-field {-->
+<!--  flex: 1;-->
+<!--  height: 100rpx;-->
+<!--  padding-right: 20rpx;-->
+<!--  font-size: 38rpx;-->
+<!--  line-height: 100rpx;-->
+<!--  color: black;-->
+<!--  text-align: right;-->
+<!--  background: transparent;-->
+<!--}-->
+
+<!--/* 修改 placeholder 样式 */-->
+<!--.input-field::placeholder {-->
+<!--  font-size: 38rpx;-->
+<!--  color: #999;-->
+<!--}-->
+
+<!--.btn-bg {-->
+<!--  background: #8ae54a;-->
+<!--}-->
+<!--</style>-->

+ 5 - 89
src/types/auto-import.d.ts

@@ -98,7 +98,7 @@ declare global {
 // for type re-export
 declare global {
   // @ts-ignore
-  export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
+  export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
   import('vue')
 }
 // for vue template auto import
@@ -162,6 +162,7 @@ declare module 'vue' {
     readonly onUnload: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnload']>
     readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
     readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
+    readonly onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>
     readonly provide: UnwrapRef<typeof import('vue')['provide']>
     readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
     readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
@@ -180,98 +181,13 @@ declare module 'vue' {
     readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
     readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
     readonly useGameTimer: UnwrapRef<typeof import('../hooks/useGameTimer')['useGameTimer']>
+    readonly useId: UnwrapRef<typeof import('vue')['useId']>
     readonly useImgPath: UnwrapRef<typeof import('../hooks/useImgPath')['useImgPath']>
+    readonly useModel: UnwrapRef<typeof import('vue')['useModel']>
     readonly useRequest: UnwrapRef<typeof import('../hooks/useRequest')['default']>
     readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
     readonly useTelegramBackButton: UnwrapRef<typeof import('../hooks/useTelegramBackButton')['useTelegramBackButton']>
-    readonly useUpload: UnwrapRef<typeof import('../hooks/useUpload')['default']>
-    readonly watch: UnwrapRef<typeof import('vue')['watch']>
-    readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
-    readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
-    readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
-  }
-}
-declare module '@vue/runtime-core' {
-  interface GlobalComponents {}
-  interface ComponentCustomProperties {
-    readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
-    readonly computed: UnwrapRef<typeof import('vue')['computed']>
-    readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
-    readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
-    readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
-    readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
-    readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
-    readonly formatAmount: UnwrapRef<typeof import('../hooks/moneyProcessing')['formatAmount']>
-    readonly formatAmountNoFloat: UnwrapRef<typeof import('../hooks/moneyProcessing')['formatAmountNoFloat']>
-    readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
-    readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
-    readonly h: UnwrapRef<typeof import('vue')['h']>
-    readonly inject: UnwrapRef<typeof import('vue')['inject']>
-    readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
-    readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
-    readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
-    readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
-    readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
-    readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
-    readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
-    readonly onAddToFavorites: UnwrapRef<typeof import('@dcloudio/uni-app')['onAddToFavorites']>
-    readonly onBackPress: UnwrapRef<typeof import('@dcloudio/uni-app')['onBackPress']>
-    readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
-    readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
-    readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
-    readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
-    readonly onError: UnwrapRef<typeof import('@dcloudio/uni-app')['onError']>
-    readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
-    readonly onHide: UnwrapRef<typeof import('@dcloudio/uni-app')['onHide']>
-    readonly onLaunch: UnwrapRef<typeof import('@dcloudio/uni-app')['onLaunch']>
-    readonly onLoad: UnwrapRef<typeof import('@dcloudio/uni-app')['onLoad']>
-    readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
-    readonly onNavigationBarButtonTap: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarButtonTap']>
-    readonly onNavigationBarSearchInputChanged: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputChanged']>
-    readonly onNavigationBarSearchInputClicked: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputClicked']>
-    readonly onNavigationBarSearchInputConfirmed: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputConfirmed']>
-    readonly onNavigationBarSearchInputFocusChanged: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputFocusChanged']>
-    readonly onPageNotFound: UnwrapRef<typeof import('@dcloudio/uni-app')['onPageNotFound']>
-    readonly onPageScroll: UnwrapRef<typeof import('@dcloudio/uni-app')['onPageScroll']>
-    readonly onPullDownRefresh: UnwrapRef<typeof import('@dcloudio/uni-app')['onPullDownRefresh']>
-    readonly onReachBottom: UnwrapRef<typeof import('@dcloudio/uni-app')['onReachBottom']>
-    readonly onReady: UnwrapRef<typeof import('@dcloudio/uni-app')['onReady']>
-    readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
-    readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
-    readonly onResize: UnwrapRef<typeof import('@dcloudio/uni-app')['onResize']>
-    readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
-    readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
-    readonly onShareAppMessage: UnwrapRef<typeof import('@dcloudio/uni-app')['onShareAppMessage']>
-    readonly onShareTimeline: UnwrapRef<typeof import('@dcloudio/uni-app')['onShareTimeline']>
-    readonly onShow: UnwrapRef<typeof import('@dcloudio/uni-app')['onShow']>
-    readonly onTabItemTap: UnwrapRef<typeof import('@dcloudio/uni-app')['onTabItemTap']>
-    readonly onThemeChange: UnwrapRef<typeof import('@dcloudio/uni-app')['onThemeChange']>
-    readonly onUnhandledRejection: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnhandledRejection']>
-    readonly onUnload: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnload']>
-    readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
-    readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
-    readonly provide: UnwrapRef<typeof import('vue')['provide']>
-    readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
-    readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
-    readonly ref: UnwrapRef<typeof import('vue')['ref']>
-    readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
-    readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
-    readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
-    readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
-    readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
-    readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
-    readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
-    readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
-    readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
-    readonly unref: UnwrapRef<typeof import('vue')['unref']>
-    readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
-    readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
-    readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
-    readonly useGameTimer: UnwrapRef<typeof import('../hooks/useGameTimer')['useGameTimer']>
-    readonly useImgPath: UnwrapRef<typeof import('../hooks/useImgPath')['useImgPath']>
-    readonly useRequest: UnwrapRef<typeof import('../hooks/useRequest')['default']>
-    readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
-    readonly useTelegramBackButton: UnwrapRef<typeof import('../hooks/useTelegramBackButton')['useTelegramBackButton']>
+    readonly useTemplateRef: UnwrapRef<typeof import('vue')['useTemplateRef']>
     readonly useUpload: UnwrapRef<typeof import('../hooks/useUpload')['default']>
     readonly watch: UnwrapRef<typeof import('vue')['watch']>
     readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>