10.10综合交易所原始源码_移动端
1
7 days ago 4f9044ae2a9f2db03bbb916bc5f6dfd12916361d
src/views/quotes/Market.vue
@@ -1,21 +1,9 @@
<template>
    <div class="quotes-market-page">
        <!-- Top Tabs -->
        <div class="market-tabs">
            <!-- <div class="tab-item" :class="{ active: activeTab === 'optional' }" @click="activeTab = 'optional'">
                {{ $t('自选') }}
            </div> -->
            <div class="tab-item" :class="{ active: activeTab === 'forex' }" @click="activeTab = 'forex'">
                {{ $t('外汇') }}
            </div>
            <div class="tab-item" :class="{ active: activeTab === 'crypto' }" @click="activeTab = 'crypto'">
        <div class="market-tabs market-tabs--single">
            <div class="tab-item active">
                {{ $t('加密货币') }}
            </div>
            <div class="tab-item" :class="{ active: activeTab === 'stock' }" @click="activeTab = 'stock'">
                {{ $t('股票') }}
            </div>
            <div class="tab-item" :class="{ active: activeTab === 'etf' }" @click="activeTab = 'etf'">
                ETF
            </div>
        </div>
@@ -24,18 +12,10 @@
            <van-list v-model:loading="marketLoading" :finished="marketFinished" :immediate-check="false"
                :scroll-target="marketListRef" :finished-text="$t('没有更多了') || '没有更多了'" @load="loadMoreMarket">
                <div class="pair-item" v-for="pair in tradingPairs" :key="pair.symbol"
                    @click="goToOptions(pair.symbol, pair.type)">
                    @click="goToOptions(pair.symbol)">
                    <div class="pair-header">
                        <div class="pair-symbol">
                            <template v-if="activeTab === 'forex' && getPairIconUrl(pair)">
                                <div class="pair-symbol-icon-wrap">
                                    <img :src="getPairIconUrl(pair)" alt=""
                                        class="pair-symbol-icon pair-symbol-icon--large" />
                                    <img v-if="getPairIconUrlSm(pair)" :src="getPairIconUrlSm(pair)" alt=""
                                        class="pair-symbol-icon pair-symbol-icon--sm" />
                                </div>
                            </template>
                            <img v-else-if="getPairIconUrl(pair)" :src="getPairIconUrl(pair)" alt=""
                            <img v-if="getPairIconUrl(pair)" :src="getPairIconUrl(pair)" alt=""
                                class="pair-symbol-icon" />
                            {{ pair.symboltxt.toUpperCase() }}
                        </div>
@@ -63,7 +43,7 @@
</template>
<script setup>
import { ref, onMounted, watch, onBeforeUnmount, nextTick } from 'vue'
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { List as VanList } from 'vant'
@@ -74,15 +54,6 @@
import { OPCIONA_LIST } from '@/store/types.store'
import { IMG_PATH } from '@/config'
import MiniKlineChart from '@/components/MiniKlineChart/index.vue'
// 外汇货币代码 -> 国旗图国家/地区代码(与首页一致)
const CURRENCY_TO_FLAG = {
    eur: 'eu', usd: 'us', gbp: 'gb', jpy: 'jp', chf: 'ch', aud: 'au', cad: 'ca', nzd: 'nz',
    cny: 'cn', cnh: 'cn', hkd: 'hk', sgd: 'sg', nok: 'no', sek: 'se', dkk: 'dk', mxn: 'mx',
    zar: 'za', try: 'tr', pln: 'pl', inr: 'in', krw: 'kr', thb: 'th', myr: 'my', idr: 'id',
    php: 'ph', brl: 'br', rub: 'ru', czk: 'cz', huf: 'hu', ron: 'ro', bgn: 'bg', hrk: 'hr'
}
const FLAG_CDN = 'https://flagcdn.com/w40'
const { t } = useI18n()
const router = useRouter()
@@ -99,42 +70,11 @@
const marketInitialLoading = ref(false) // tab 切换时首屏请求中,避免 @load 重复请求 pageNo=1
const MARKET_PAGE_SIZE = 10
// 从外汇对取基础货币代码,与首页一致
function getForexBaseCurrency(symbol) {
    if (!symbol || typeof symbol !== 'string') return ''
    const s = symbol.trim()
    if (s.includes('/')) return s.split('/')[0].trim().toLowerCase()
    return s.slice(0, 3).toLowerCase()
}
// 从外汇对取计价货币代码,如 EUR/USD -> usd(右下角小图用)
function getForexQuoteCurrency(symbol) {
    if (!symbol || typeof symbol !== 'string') return ''
    const s = symbol.trim()
    if (s.includes('/')) return s.split('/')[1]?.trim().toLowerCase() || ''
    return s.length > 3 ? s.slice(3, 6).toLowerCase() : ''
}
// 列表项图标地址:外汇用国旗,加密货币用 symbol 图;股票、ETF 不展示图标;自选按 type 判断
function getPairIconUrl(pair) {
    if (!pair) return ''
    const tab = activeTab.value
    if (tab === 'stock' || tab === 'etf') return ''
    if (tab === 'optional' && (pair.type === 'US-stocks' || pair.type === 'indices')) return ''
    if (tab === 'forex') {
        const code = CURRENCY_TO_FLAG[getForexBaseCurrency(pair.symbol)]
        return code ? `${FLAG_CDN}/${code}.png` : ''
    }
    return pair.iconImg ? `${IMG_PATH}/symbol/${pair.iconImg}.png` : ''
}
// 小图用名字后面3位(计价货币)的国旗,仅外汇有效
function getPairIconUrlSm(pair) {
    if (!pair || activeTab.value !== 'forex') return ''
    const quote = getForexQuoteCurrency(pair.symbol)
    if (!quote) return ''
    const code = CURRENCY_TO_FLAG[quote]
    return code ? `${FLAG_CDN}/${code}.png` : ''
}
// 根据当前价与涨跌幅生成小型 K 线数据,与首页一致
@@ -261,36 +201,13 @@
// 获取交易数据;pageNo 页码,append 是否追加
const fetchTradingData = async (pageNo = 1, append = false) => {
    let type = ''
    let category = null
    switch (activeTab.value) {
        case 'crypto':
            type = 'cryptos'
            break
        case 'etf':
            type = 'indices'
            break
        case 'stock':
            type = 'US-stocks'
            break
        case 'forex':
            type = 'forex'
            category = 'forex'
            break
        default:
            type = 'forex'
            category = 'forex'
    }
    const type = 'cryptos'
    try {
        const params = {
            type: type,
            pageNo: pageNo,
            pageSize: MARKET_PAGE_SIZE
        }
        if (category) {
            params.category = category
        }
        const data = await _getRealtimeByType(params)
@@ -367,13 +284,11 @@
}
// 跳转到交易页 Options,与首页一致:/trade/options?symbol=xxx&activeTab=xxx
function goToOptions(symbol, type) {
function goToOptions(symbol) {
    if (!symbol) return
    const tabMap = { crypto: 'cryptos', etf: 'indices', stock: 'US-stocks', forex: 'forex', optional: 'optional' }
    const activeTabValue = type || tabMap[activeTab.value] || 'cryptos'
    router.push({
        path: '/trade/options',
        query: { symbol, activeTab: activeTabValue }
        query: { symbol, activeTab: 'cryptos' }
    })
}
@@ -403,11 +318,6 @@
        marketInitialLoading.value = false
    }
}
// 监听 tab 切换
watch(activeTab, () => {
    fetchData()
})
// 处理列表项点击
const handleItemClick = (pair) => {