| | |
| | | <template> |
| | | <div id="cryptos"> |
| | | <div class="recharge box-border"> |
| | | <assets-head :title="$t('充值通道')" v-if="!isForeign" :back-func="backFunc"> |
| | | <img src="../../../assets/image/assets-center/exchange.png" alt="exchange-img" class="w-44 h-38" |
| | | @click="goRouter('/cryptos/assetsCenter/rechargeWithdrawRecord')" /> |
| | | </assets-head> |
| | | <assets-head v-else :title="$t('充值通道')"> |
| | | <img src="../../../assets/image/assets-center/exchange.png" alt="exchange-img" class="w-44 h-38" |
| | | @click="goRouter('/cryptos/assetsCenter/rechargeWithdrawRecord')" /> |
| | | </assets-head> |
| | | <div class="pl-36 pr-36"> |
| | | <div class="recharge-title font-35 textColor">{{ $t('请选择充值币种') }}</div> |
| | | <div class="recharge-list flex justify-between"> |
| | | <div class="item-view flex flex-col items-center justify-center text-center w-189 h-220 box-border" |
| | | @click="selectSymbol('usdt')"> |
| | | <img :src="`${HOST_URL}/symbol/usdt.png`" class="w-92 h-92" /> |
| | | <div class="text-grey font-26 mt-32">{{ $t('USDT充值') }}</div> |
| | | </div> |
| | | <div class="item-view flex flex-col items-center justify-center text-center w-189 h-220 box-border" |
| | | @click="selectSymbol('usdc')"> |
| | | <img :src="`${HOST_URL}/symbol/usdc.png`" class="w-92 h-92" /> |
| | | <div class="text-grey font-26 mt-32">{{ $t('USDC充值') }}</div> |
| | | </div> |
| | | <div class="item-view flex flex-col items-center justify-center text-center w-189 h-220 box-border" |
| | | @click="selectSymbol('btc')"> |
| | | <img :src="`${HOST_URL}/symbol/btc.png`" class="w-92 h-92" /> |
| | | <div class="text-grey font-26 mt-32">{{ $t('BTC充值') }}</div> |
| | | </div> |
| | | <div class="item-view flex flex-col items-center justify-center text-center w-189 h-220 box-border" |
| | | @click="selectSymbol('eth')"> |
| | | <img :src="`${HOST_URL}/symbol/eth.png`" class="w-92 h-92" /> |
| | | <div class="text-grey font-26 mt-32">{{ $t('ETH充值') }}</div> |
| | | <div id="cryptos" class="deposit-page"> |
| | | <assets-head :title="$t('订金')" :show-left="true" :back-func="onBack"> |
| | | <template v-if="step === 'list'"> |
| | | <img |
| | | src="../../../assets/image/assets-center/exchange.png" |
| | | alt="" |
| | | class="deposit-head-icon" |
| | | @click="goRouter('/cryptos/assetsCenter/rechargeWithdrawRecord')" |
| | | /> |
| | | </template> |
| | | </assets-head> |
| | | |
| | | <!-- 图一:列表 --> |
| | | <template v-if="step === 'list'"> |
| | | <div class="deposit-body"> |
| | | <div class="deposit-search-wrap"> |
| | | <van-icon name="search" class="deposit-search-icon" /> |
| | | <input |
| | | v-model="searchKeyword" |
| | | type="text" |
| | | class="deposit-search-input" |
| | | :placeholder="$t('search')" |
| | | /> |
| | | </div> |
| | | <div class="deposit-section-title">{{ $t('Popular coins') }}</div> |
| | | <div class="deposit-popular"> |
| | | <div class="deposit-coin-btn" @click="selectCoin('usdt')">USDT</div> |
| | | </div> |
| | | <div class="deposit-section-title">{{ $t('List of coins') }}</div> |
| | | <div class="deposit-coin-list"> |
| | | <div |
| | | v-for="item in filteredCoins" |
| | | :key="item.symbol" |
| | | class="deposit-coin-item" |
| | | @click="selectCoin(item.symbol)" |
| | | > |
| | | <img :src="`${HOST_URL}/symbol/${item.symbol}.png`" alt="" class="deposit-coin-icon" /> |
| | | <span class="deposit-coin-symbol">{{ item.symbol.toUpperCase() }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <div class="reminder">{{ $t('充值提示') }}</div> |
| | | |
| | | <!-- <div class="textColor mt-40"> |
| | | <div class="pl-36 pr-36 h-90 lh-90 border-b-color flex justify-between font-28" v-for="(item, index) in list" |
| | | :key="index" @click="toPath(item.url)"> |
| | | <div class="flex items-center"> |
| | | <img :src="handleImage(item.imgPath)" class="w-44 h-44 rounded-full mr-20" /> |
| | | <span class="textColor">{{ item.name }} {{ $t('官方充值通道') }}</span> |
| | | </div> |
| | | <div> |
| | | <van-icon class="textColor" name="arrow" /> |
| | | <!-- 图二:已选币种 + 选择网络 --> |
| | | <template v-else> |
| | | <div class="deposit-body deposit-body-selected"> |
| | | <div class="deposit-card" @click="step = 'list'"> |
| | | <img :src="`${HOST_URL}/symbol/${selectedSymbol}.png`" alt="" class="deposit-card-icon" /> |
| | | <span class="deposit-card-symbol">{{ selectedSymbol.toUpperCase() }}</span> |
| | | <van-icon name="arrow" class="deposit-card-arrow" /> |
| | | </div> |
| | | <div class="deposit-card deposit-card-network"> |
| | | <div class="deposit-network-label">{{ $t('Deposit network') }}</div> |
| | | <div class="deposit-choice-btn" @click="showNetworkSheet = true"> |
| | | <span class="deposit-choice-text">{{ selectedChain ? selectedChain.blockchain_name : $t('Choice Network') }}</span> |
| | | <van-icon name="arrow-down" class="deposit-choice-arrow" /> |
| | | </div> |
| | | </div> |
| | | </div> --> |
| | | </div> |
| | | |
| | | <!-- 选中网络后下方显示充值详情 --> |
| | | <div v-if="selectedChain && selectedChain.address" class="deposit-detail"> |
| | | <div class="deposit-detail-qr-wrap"> |
| | | <canvas ref="qrcodeCanvas" class="deposit-detail-qr"></canvas> |
| | | </div> |
| | | <div class="deposit-detail-address-label">{{ $t('Deposit address') }}:</div> |
| | | <div class="deposit-detail-address-row"> |
| | | <span class="deposit-detail-address-text">{{ selectedChain.address }}</span> |
| | | <img :src="copyImg" alt="copy" class="deposit-detail-copy-btn" @click="copyAddress" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <!-- 图三:底部弹框 选择充值链 --> |
| | | <van-action-sheet |
| | | v-model:show="showNetworkSheet" |
| | | class="deposit-sheet" |
| | | > |
| | | <div class="deposit-sheet-content"> |
| | | <div class="deposit-sheet-head"> |
| | | <span class="deposit-sheet-title">{{ $t('Choice Network') }}</span> |
| | | <van-icon name="cross" class="deposit-sheet-close" @click="showNetworkSheet = false" /> |
| | | </div> |
| | | <p class="deposit-sheet-tip"> |
| | | {{ $t('Tip: choose a network consistent with the withdraw platform to top up, otherwise you will lose this funds') }} |
| | | </p> |
| | | <div |
| | | v-for="(chain, index) in chainList" |
| | | :key="index" |
| | | class="deposit-sheet-item" |
| | | @click="onSelectChain(chain)" |
| | | > |
| | | {{ chain.blockchain_name }} |
| | | </div> |
| | | </div> |
| | | </van-action-sheet> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import assetsHead from "@/components/Transform/assets-head/index.vue"; |
| | | import { HOST_URL } from '@/config' |
| | | import { Icon } from 'vant'; |
| | | import QRCode from 'qrcode'; |
| | | import { showToast } from 'vant'; |
| | | import assetsHead from '@/components/Transform/assets-head/index.vue'; |
| | | import { HOST_URL } from '@/config'; |
| | | import Axios from '@/service/recharge.js'; |
| | | import copyImg from '@/assets/imgs/new/copy.png'; |
| | | |
| | | const COINS = [ |
| | | { symbol: 'usdt', name: 'USDT' }, |
| | | { symbol: 'usdc', name: 'USDC' }, |
| | | { symbol: 'btc', name: 'BTC' }, |
| | | { symbol: 'eth', name: 'ETH' }, |
| | | ]; |
| | | |
| | | export default { |
| | | name: 'rechageList', |
| | | components: { |
| | | assetsHead, |
| | | [Icon.name]: Icon, |
| | | }, |
| | | components: { assetsHead }, |
| | | data() { |
| | | return { |
| | | list: [ |
| | | { |
| | | name: 'Huobi', |
| | | url: 'https://www.huobi.com/en-us/', |
| | | imgPath: new URL('@/assets/image/huobi.png', import.meta.url), |
| | | }, |
| | | { |
| | | name: 'Binance', |
| | | url: 'https://www.binance.com/en', |
| | | imgPath: new URL('@/assets/image/bian.png', import.meta.url), |
| | | }, |
| | | { |
| | | name: 'Coinbase', |
| | | url: 'https://www.coinbase.com/', |
| | | imgPath: new URL('@/assets/image/coinbase.png', import.meta.url), |
| | | }, |
| | | { |
| | | name: 'Crypto', |
| | | url: 'https://www.crypto.com/', |
| | | imgPath: new URL('@/assets/image/crypto.png', import.meta.url), |
| | | } |
| | | ], |
| | | isForeign: false, |
| | | HOST_URL, |
| | | } |
| | | step: 'list', |
| | | searchKeyword: '', |
| | | selectedSymbol: '', |
| | | chainList: [], |
| | | selectedChain: null, |
| | | showNetworkSheet: false, |
| | | isForeign: false, |
| | | copyImg, |
| | | }; |
| | | }, |
| | | computed: { |
| | | filteredCoins() { |
| | | const k = (this.searchKeyword || '').trim().toLowerCase(); |
| | | if (!k) return COINS; |
| | | return COINS.filter((c) => c.symbol.toLowerCase().includes(k) || c.name.toLowerCase().includes(k)); |
| | | }, |
| | | }, |
| | | created() { |
| | | if (this.$route.query.isForeign) { |
| | | this.isForeign = this.$route.query.isForeign |
| | | this.isForeign = this.$route.query.isForeign; |
| | | } |
| | | }, |
| | | methods: { |
| | | handleImage(url) { |
| | | return new URL(url, import.meta.url).href |
| | | onBack() { |
| | | if (this.step === 'selected') { |
| | | this.step = 'list'; |
| | | this.selectedSymbol = ''; |
| | | this.selectedChain = null; |
| | | this.chainList = []; |
| | | } else { |
| | | this.$router.push('/quotes/index?tabActive=1'); |
| | | } |
| | | }, |
| | | toPath(url) { |
| | | const a = document.createElement('a'); |
| | | a.href = url; |
| | | a.target = "_bank"; |
| | | document.body.append(a); |
| | | a.click(); |
| | | document.body.removeChild(a) |
| | | // if (navigator.userAgent.search('Html5Plus') != -1) { |
| | | // plus.runtime.openURL(url) |
| | | // } else { |
| | | // window.open(url) |
| | | // } |
| | | selectCoin(symbol) { |
| | | this.selectedSymbol = symbol; |
| | | this.selectedChain = null; |
| | | this.chainList = []; |
| | | Axios.getBlock({ coin: symbol }) |
| | | .then((res) => { |
| | | this.chainList = Array.isArray(res) ? res : []; |
| | | this.step = 'selected'; |
| | | }) |
| | | .catch(() => { |
| | | this.chainList = []; |
| | | this.step = 'selected'; |
| | | }); |
| | | }, |
| | | backFunc() { |
| | | this.$router.push('/quotes/index?tabActive=1') |
| | | onSelectChain(chain) { |
| | | this.selectedChain = chain; |
| | | this.showNetworkSheet = false; |
| | | this.$nextTick(() => this.drawQR()); |
| | | }, |
| | | selectSymbol(symbol) { |
| | | this.$router.push({ |
| | | path: "/cryptos/recharge/rechargePage", |
| | | query: { |
| | | 'symbol': symbol |
| | | } |
| | | }); |
| | | drawQR() { |
| | | if (!this.selectedChain || !this.selectedChain.address || !this.$refs.qrcodeCanvas) return; |
| | | const opts = { |
| | | errorCorrectionLevel: 'H', |
| | | width: 200, |
| | | margin: 4, |
| | | color: { dark: '#333333', light: '#fff' }, |
| | | }; |
| | | QRCode.toCanvas(this.$refs.qrcodeCanvas, this.selectedChain.address, opts, () => {}); |
| | | }, |
| | | goRouter(params) { |
| | | this.$router.push({ |
| | | path: params, |
| | | query: { |
| | | back: "1" |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | copyAddress() { |
| | | const address = this.selectedChain?.address; |
| | | if (!address) return; |
| | | if (typeof navigator !== 'undefined' && navigator.clipboard && navigator.clipboard.writeText) { |
| | | navigator.clipboard.writeText(address).then(() => showToast(this.$t('复制成功'))).catch(() => this.copyFallback(address)); |
| | | } else { |
| | | this.copyFallback(address); |
| | | } |
| | | }, |
| | | copyAddressFallback(text) { |
| | | this.copyFallback(text); |
| | | }, |
| | | copyFallback(text) { |
| | | const textarea = document.createElement('textarea'); |
| | | textarea.value = text; |
| | | textarea.style.position = 'fixed'; |
| | | textarea.style.opacity = '0'; |
| | | document.body.appendChild(textarea); |
| | | textarea.select(); |
| | | try { |
| | | document.execCommand('copy'); |
| | | showToast(this.$t('复制成功')); |
| | | } catch (e) {} |
| | | document.body.removeChild(textarea); |
| | | }, |
| | | goRouter(path) { |
| | | this.$router.push({ path, query: { back: '1' } }); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "@/assets/init.scss"; |
| | | .deposit-page { |
| | | min-height: 100vh; |
| | | background: #fff !important; |
| | | padding-bottom: 2.5rem; |
| | | } |
| | | .deposit-head-icon { |
| | | width: 1.375rem; |
| | | height: 1.1875rem; |
| | | } |
| | | |
| | | #cryptos { |
| | | .recharge { |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | .deposit-body { |
| | | padding: 1rem 1.5rem; |
| | | } |
| | | .deposit-body-selected { |
| | | padding-top: 1.5rem; |
| | | } |
| | | |
| | | .recharge-title { |
| | | margin: 86px 0 104px 0; |
| | | } |
| | | /* 图一:搜索 */ |
| | | .deposit-search-wrap { |
| | | display: flex; |
| | | align-items: center; |
| | | height: 3.25rem; |
| | | padding: 0 1rem; |
| | | background: #f5f5f5; |
| | | border-radius: 0.5rem; |
| | | margin-bottom: 1.5rem; |
| | | } |
| | | .deposit-search-icon { |
| | | color: #999; |
| | | font-size: 28px; |
| | | margin-right: 0.75rem; |
| | | } |
| | | .deposit-search-input { |
| | | flex: 1; |
| | | border: none; |
| | | background: transparent; |
| | | font-size: 28px; |
| | | outline: none; |
| | | } |
| | | .deposit-search-input::placeholder { |
| | | color: #9b9b9b; |
| | | } |
| | | |
| | | .recharge-list>div { |
| | | border: 2px solid $bg_dark; |
| | | border-radius: 15px; |
| | | box-sizing: border-box; |
| | | } |
| | | .deposit-section-title { |
| | | font-size: 26px; |
| | | color: #9b9b9b; |
| | | margin-bottom: 0.75rem; |
| | | } |
| | | .deposit-popular { |
| | | margin-bottom: 1.5rem; |
| | | } |
| | | .deposit-coin-btn { |
| | | display: inline-block; |
| | | padding: 0.875rem 1.75rem; |
| | | background: #f5f5f5; |
| | | border-radius: 0.5rem; |
| | | font-size: 28px; |
| | | color: #333; |
| | | cursor: pointer; |
| | | } |
| | | .deposit-coin-list { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 0; |
| | | } |
| | | .deposit-coin-item { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 1.125rem 0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | cursor: pointer; |
| | | } |
| | | .deposit-coin-item:last-child { |
| | | border-bottom: none; |
| | | } |
| | | .deposit-coin-icon { |
| | | width: 3rem; |
| | | height: 3rem; |
| | | border-radius: 50%; |
| | | margin-right: 1rem; |
| | | } |
| | | .deposit-coin-symbol { |
| | | font-size: 28px; |
| | | color: #333; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .reminder { |
| | | font-size: 2rem; |
| | | padding: 2rem; |
| | | } |
| | | /* 图二:卡片 */ |
| | | .deposit-card { |
| | | background: #f6f6f6; |
| | | border-radius: 0.5rem; |
| | | padding: 1.25rem; |
| | | margin-bottom: 1.5rem; |
| | | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06); |
| | | } |
| | | /* 第一个卡片:图标+币种+箭头同一行 */ |
| | | .deposit-card:first-child { |
| | | cursor: pointer; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | .deposit-card:first-child .deposit-card-icon { |
| | | flex-shrink: 0; |
| | | } |
| | | .deposit-card:first-child .deposit-card-symbol { |
| | | flex: 1; |
| | | min-width: 0; |
| | | } |
| | | .deposit-card:first-child .deposit-card-arrow { |
| | | flex-shrink: 0; |
| | | margin-top: 0; |
| | | } |
| | | .deposit-card-network { |
| | | cursor: default; |
| | | } |
| | | .deposit-card-icon { |
| | | width: 3.25rem; |
| | | height: 3.25rem; |
| | | border-radius: 50%; |
| | | margin-right: 1rem; |
| | | vertical-align: middle; |
| | | } |
| | | .deposit-card-symbol { |
| | | font-size: 28px; |
| | | color: #333; |
| | | font-weight: 600; |
| | | vertical-align: middle; |
| | | } |
| | | .deposit-card-arrow { |
| | | color: #999; |
| | | font-size: 28px; |
| | | } |
| | | .deposit-network-label { |
| | | font-size: 26px; |
| | | color: #9b9b9b; |
| | | margin-bottom: 0.625rem; |
| | | } |
| | | .deposit-choice-btn { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 0.875rem 10px; |
| | | border-radius: 10px; |
| | | cursor: pointer; |
| | | background-color: #fff; |
| | | } |
| | | .deposit-choice-text { |
| | | font-size: 28px; |
| | | color: #333; |
| | | } |
| | | .deposit-choice-arrow { |
| | | color: #999; |
| | | font-size: 28px; |
| | | } |
| | | .deposit-next-btn { |
| | | width: 100%; |
| | | height: 3.5rem; |
| | | margin-top: 1.5rem; |
| | | border: none; |
| | | border-radius: 0.5rem; |
| | | background: linear-gradient(90deg, #a443cf, #5e2bc8); |
| | | color: #fff; |
| | | font-size: 28px; |
| | | font-weight: 600; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | /* 图三:底部弹框 */ |
| | | .deposit-sheet-content { |
| | | padding: 0 1.5rem 2rem; |
| | | background-color: #fff; |
| | | } |
| | | .deposit-sheet-head { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 2.5rem 0.75rem; |
| | | margin-bottom: 0.75rem; |
| | | } |
| | | .deposit-sheet-title { |
| | | font-size: 35px; |
| | | font-weight: 600; |
| | | color: #333; |
| | | } |
| | | .deposit-sheet-close { |
| | | font-size: 28px; |
| | | color: #999; |
| | | cursor: pointer; |
| | | } |
| | | .deposit-sheet-tip { |
| | | font-size: 26px; |
| | | line-height: 1.5; |
| | | margin-bottom: 1.75rem; |
| | | padding: 20px 10px; |
| | | background-color: #F6F6F6; |
| | | } |
| | | .deposit-sheet-item { |
| | | padding: 2rem 1.5rem; |
| | | border-radius: 1rem; |
| | | margin-bottom: 0.75rem; |
| | | font-size: 35px; |
| | | color: #333; |
| | | cursor: pointer; |
| | | border: 1px solid #f2f2f2; |
| | | } |
| | | .deposit-sheet-item:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | /* 充值详情:二维码 + 地址(选中网络后下方显示) */ |
| | | .deposit-detail { |
| | | margin-top: 1.5rem; |
| | | padding: 1.5rem 0; |
| | | border-top: 1px solid #f0f0f0; |
| | | text-align: left; |
| | | } |
| | | .deposit-detail-qr-wrap { |
| | | display: flex; |
| | | justify-content: center; |
| | | margin-bottom: 1.25rem; |
| | | } |
| | | .deposit-detail-qr { |
| | | display: block; |
| | | } |
| | | .deposit-detail-address-label { |
| | | font-size: 26px; |
| | | color: #9b9b9b; |
| | | margin-bottom: 0.5rem; |
| | | } |
| | | .deposit-detail-address-row { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | gap: 0.5rem; |
| | | } |
| | | .deposit-detail-address-text { |
| | | flex: 1; |
| | | min-width: 0; |
| | | font-size: 26px; |
| | | color: #333; |
| | | word-break: break-all; |
| | | } |
| | | .deposit-detail-copy-btn { |
| | | width: 2.5rem; |
| | | height: 2.5rem; |
| | | cursor: pointer; |
| | | flex-shrink: 0; |
| | | object-fit: contain; |
| | | } |
| | | </style> |