10.10综合交易所原始源码_移动端
1
2026-05-26 0dbc7465447164fef24327b5d494870832d798dd
src/views/home/index.vue
@@ -1,919 +1,1309 @@
<template>
    <div class="home">
        <!-- 顶部搜索栏 -->
    <div class="home-page">
        <!-- Header -->
        <div class="header">
            <div class="avatar">
                <Icon icon="carbon:user-avatar" width="24" height="24" />
            </div>
            <div class="search-box">
                <Icon icon="ri:search-line" width="20" height="20" color="#999" />
                <input type="text" :placeholder="$t('搜索.占位符')">
            <div class="header-left">
                <img src="@/assets/image/login_logo.png" alt="Wealthinfra" class="logo" />
                <span class="logo-text">Wealthinfra</span>
            </div>
            <div class="header-right">
                <Icon icon="material-symbols:headphones" width="24" height="24" />
                <Icon icon="mdi:bell-outline" width="24" height="24" />
            </div>
        </div>
        <!-- 新人礼包banner -->
        <div class="gift-banner">
            <div class="gift-left">
                <div class="gift-icon">
                    <Icon icon="mdi:gift-outline" width="32" height="32" />
                <div class="lang-selector" @click="$router.push('/language')">
                    <span class="lang-text">{{ currentLangName }}</span>
                </div>
                <div class="gift-info">
                    <div class="gift-amount">1,000USD {{ $t('新人欢迎.礼包') }}</div>
                    <div class="gift-desc">{{ $t('新人欢迎.新用户') }}</div>
                <div class="icon-btn">
                    <img src="@/assets/image/notice.png" alt="notice" />
                </div>
                <div class="icon-btn" @click="$router.push('/my/index')">
                    <img src="@/assets/image/noticeMore.png" alt="menu" />
                </div>
            </div>
            <button class="register-btn">{{ $t('新人欢迎.注册') }}</button>
        </div>
        <!-- 功能导航 -->
        <div class="nav-section">
            <div class="nav-item" v-for="(item, index) in navList" :key="index">
                <Icon :icon="item.icon" width="28" height="28" />
                <span class="nav-name">{{ item.name }}</span>
            </div>
        </div>
        <!-- 广告轮播 -->
        <div class="banner-section">
            <div class="banner-item">
                <div class="banner-left">
                    <div class="banner-tag">
                        <Icon icon="ph:fire-bold" color="#ff6b00" width="16" height="16" />
                        {{ $t('活动.热门') }}
                    </div>
                    <div class="banner-title">JD Trader {{ $t('活动.首次交易') }}</div>
                    <button class="join-btn">
                        {{ $t('活动.参与') }}
                        <Icon icon="material-symbols:chevron-right" width="16" height="16" />
        <!-- Hero Banner -->
        <van-swipe class="hero-section" :autoplay="3000" indicator-color="#92D1FF">
            <!-- 第一张:一应俱全的金融交易体验 -->
            <van-swipe-item>
                <div class="hero-card">
                    <h1 class="hero-title">{{ $t('home.heroTitle1') }}</h1>
                    <p class="hero-desc">{{ $t('home.heroFeatures1') }}</p>
                    <button class="trade-btn" @click="router.push('/trade/options')">
                        {{ $t('立即交易') }}
                        <img src="@/assets/image/but_to.png" alt="play" class="play-icon" />
                    </button>
                    <div class="hero-illustration">
                        <div class="device-illustration">
                            <img src="@/assets/image/home/banner_1.png" alt="">
                        </div>
                    </div>
                </div>
                <div class="banner-right">
                    <img src="@/assets/trader.png" alt="trader">
            </van-swipe-item>
            <!-- 第二张:您可以信赖的经济人 -->
            <van-swipe-item>
                <div class="hero-card">
                    <h1 class="hero-title">{{ $t('home.heroTitle') }}</h1>
                    <p class="hero-desc">{{ $t('home.heroDesc') }}</p>
                    <button class="trade-btn" @click="router.push('/trade/options')">
                        {{ $t('立即交易') }}
                        <img src="@/assets/image/but_to.png" alt="play" class="play-icon" />
                    </button>
                    <div class="hero-illustration">
                        <div class="robot-illustration">
                            <img src="@/assets/image/home/banner_2.png" alt="">
                        </div>
                    </div>
                </div>
            </van-swipe-item>
            <!-- 第三张:顶尖交易技术 -->
            <van-swipe-item>
                <div class="hero-card">
                    <h1 class="hero-title">{{ $t('home.heroTitle2') }}</h1>
                    <p class="hero-desc">{{ $t('home.heroDesc2') }}</p>
                    <button class="trade-btn" @click="router.push('/trade/options')">
                        {{ $t('立即交易') }}
                        <img src="@/assets/image/but_to.png" alt="play" class="play-icon" />
                    </button>
                    <div class="hero-illustration">
                        <div class="crypto-illustration">
                            <img src="@/assets/image/home/banner_3.png" alt="">
                        </div>
                    </div>
                </div>
            </van-swipe-item>
        </van-swipe>
        <div class="no-more-notice">
            <img src="@/assets/image/notice.png" alt="bell" />
            <span>No More</span>
            <img src="@/assets/image/icon-right.png" alt="play" class="arrow" />
        </div>
        <!-- Quick Access -->
        <div class="quick-access">
            <div class="quick-item" @click="$router.push('/cryptos/recharge/rechargeList?isForeign=true')">
                <div class="quick-icon">
                    <img src="@/assets/image/cz.png" alt="recharge" />
                </div>
                <span>{{ $t('recharge') }}</span>
            </div>
            <div class="quick-item" @click="$router.push('/cryptos/withdraw/withdrawPage?type=exchange')">
                <div class="quick-icon">
                    <img src="@/assets/image/tx.png" alt="withdraw" />
                </div>
                <span>{{ $t('withdraw') }}</span>
            </div>
            <div class="quick-item" @click="$router.push('/cryptos/loan')">
                <div class="quick-icon">
                    <img src="@/assets/image/dk.png" alt="loan" />
                </div>
                <span>{{ $t('home.loan') }}</span>
            </div>
            <div class="quick-item" @click="$router.push('/customerService')">
                <div class="quick-icon">
                    <img src="@/assets/image/lxkf.png" alt="service" />
                </div>
                <span>{{ $t('ContactService') }}</span>
            </div>
        </div>
        <!-- 市场行情 -->
        <div class="market-section">
            <div class="market-tabs">
                <div v-for="tab in marketTabs" :key="tab.id" :class="['tab-item', { active: currentTab === tab.id }]"
                    @click="currentTab = tab.id">
                    {{ tab.name }}
                </div>
            </div>
            <div class="market-list">
                <div class="market-item" v-for="item in marketData" :key="item.code">
                    <div class="stock-info">
                        <div class="stock-name">{{ item.name }}</div>
                        <div class="stock-code">{{ item.code }}</div>
                    </div>
                    <div class="stock-price">
                        <div class="current-price">{{ item.price }}</div>
                        <div :class="['price-change', item.change >= 0 ? 'up' : 'down']">
                            {{ item.change >= 0 ? '+' : '' }}{{ item.change }}%
        <!-- Market Overview -->
        <div class="market-overview">
            <div class="currency-cards">
                <div class="currency-card" v-for="pair in currencyPairs" :key="pair.symbol"
                    @click="goToOptions(pair.symbol, pair.type)">
                    <div class="currency-info">
                        <div class="currency-pair-row">
                            <template v-if="activeTab === 'forex' && getPairIconUrl(pair)">
                                <div class="currency-card-icon-wrap">
                                    <img :src="getPairIconUrl(pair)" alt=""
                                        class="currency-card-icon currency-card-icon--large" />
                                    <img v-if="getPairIconUrlSm(pair)" :src="getPairIconUrlSm(pair)" alt=""
                                        class="currency-card-icon currency-card-icon--sm" />
                                </div>
                            </template>
                            <img v-else-if="getPairIconUrl(pair)" :src="getPairIconUrl(pair)" alt=""
                                class="currency-card-icon" />
                            <div class="currency-pair">{{ pair.symboltxt.toUpperCase() }}</div>
                        </div>
                        <div class="currency-price">{{ pair.price }}</div>
                        <div class="currency-change" :class="pair.change >= 0 ? 'up' : 'down'">
                            {{ pair.change >= 0 ? '+' : '' }}{{ pair.change }}%
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- 跟单板块 -->
        <div class="section-block">
            <div class="section-header">
                <h3>{{ $t('板块.跟单') }}</h3>
                <button class="more-btn">
                    {{ $t('通用.更多') }}
                    <Icon icon="material-symbols:chevron-right" width="16" height="16" />
                </button>
        <!-- Trading Instruments -->
        <div class="trading-section">
            <div class="trading-tabs">
                <div class="tab-item" :class="{ active: activeTab === 'forex' }" @click="activeTab = 'forex'">
                    {{ $t('外汇') }}
                </div>
                <div class="tab-item" :class="{ active: activeTab === 'crypto' }" @click="activeTab = 'crypto'">
                    {{ $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>
            <div class="trader-list">
                <div class="trader-card" v-for="trader in traders" :key="trader.id">
                    <div class="trader-info">
                        <img :src="trader.avatar" class="trader-avatar">
                        <div class="trader-detail">
                            <div class="trader-name">{{ trader.name }}</div>
                            <div class="trader-stats">
                                <span>{{ $t('交易员.收益率') }} <b class="up">{{ trader.profit }}%</b></span>
                                <span>{{ $t('交易员.跟随者') }} {{ trader.followers }}</span>
                            </div>
            <div class="trading-pairs">
                <div class="pair-item" v-for="pair in tradingPairs" :key="pair.symbol"
                    @click="goToOptions(pair.symbol, pair.type)">
                    <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=""
                                class="pair-symbol-icon" />
                            {{ pair.symboltxt.toUpperCase() }}
                        </div>
                        <div class="pair-change" :class="pair.change >= 0 ? 'up' : 'down'">
                            {{ pair.change >= 0 ? '+' : '' }}{{ pair.change.toFixed(4) }}%
                        </div>
                    </div>
                    <button class="follow-btn">{{ $t('交易员.跟随') }}</button>
                    <div class="pair-bottom">
                        <button class="sell">
                            <span class="action-price">{{ pair.sellPrice }}</span>
                            <span class="action-label action-btn ">{{ $t('卖出') }}</span>
                        </button>
                        <div class="pair-chart">
                            <MiniKlineChart :key="pair.symbol" :data="pair.klineData || []" :up="pair.change >= 0" />
                        </div>
                        <button class=" buy">
                            <span class="action-price">{{ pair.buyPrice }}</span>
                            <span class="action-label action-btn">{{ $t('买入') }}</span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
        <!-- 理财板块 -->
        <div class="section-block">
            <div class="section-header">
                <h3>{{ $t('板块.理财') }}</h3>
                <button class="more-btn">
                    {{ $t('通用.更多') }}
                    <Icon icon="material-symbols:chevron-right" width="16" height="16" />
                </button>
        <!-- About Us -->
        <div class="about-section">
            <div class="section-header" @click="router.push('/aboutUs')">
                <h2>{{ $t('关于我们') }}</h2>
                <span class="more-link">{{ $t('More') }} ></span>
            </div>
            <div class="finance-list">
                <div class="finance-card" v-for="item in financeProducts" :key="item.id">
                    <div class="finance-info">
                        <div class="finance-name">{{ item.name }}</div>
                        <div class="finance-rate">
                            <span class="rate-num">{{ item.rate }}%</span>
                            <span class="rate-label">{{ $t('理财.年化收益') }}</span>
                        </div>
                        <div class="finance-desc">{{ item.desc }}</div>
                    </div>
                    <button class="invest-btn">{{ $t('理财.投资') }}</button>
            <div class="video-thumbnail" role="button">
                <div class="video-placeholder">
                    <video class="home-video" :src="homeVideoUrl" controls preload="metadata" @click.stop></video>
                </div>
            </div>
            <p class="about-desc">{{ $t('home.aboutDesc') }}</p>
            <ul class="feature-list">
                <li v-for="feature in features" :key="feature">{{ feature }}</li>
            </ul>
        </div>
        <!-- 资讯板块 -->
        <div class="section-block">
            <div class="section-header">
                <h3>{{ $t('板块.资讯') }}</h3>
                <button class="more-btn">
                    {{ $t('通用.更多') }}
                    <Icon icon="material-symbols:chevron-right" width="16" height="16" />
                </button>
        <!-- News Section -->
        <div class="news-section">
            <div class="section-header" @click="router.push('/news')">
                <h2>{{ $t('home.news') }}</h2>
                <span class="more-link">{{ $t('More') }} ></span>
            </div>
            <div class="news-list">
                <div class="news-item" v-for="news in newsList" :key="news.id">
            <div class="news-carousel">
                <div class="news-item" v-for="(item, index) in newsList" :key="item.id || index"
                    @click="router.push('/news')">
                    <img v-if="item.urlToImage" :src="item.urlToImage" alt="" class="news-image" />
                    <div class="news-content">
                        <div class="news-title">{{ news.title }}</div>
                        <div class="news-meta">
                            <span class="news-source">{{ news.source }}</span>
                            <span class="news-time">{{ news.time }}</span>
                        </div>
                        <h3 class="news-title">{{ (item.title || stripHtml(item.description || '')).slice(0, 40) }}{{
                            (item.title || stripHtml(item.description || '')).length > 40 ? '...' : '' }}</h3>
                        <p class="news-excerpt">{{ stripHtml(item.description || '').slice(0, 80) }}{{
                            stripHtml(item.description || '').length > 80 ? '...' : '' }}</p>
                    </div>
                    <img v-if="news.image" :src="news.image" class="news-image">
                </div>
                <div class="news-item news-item--placeholder" v-if="!newsList.length">
                    <div class="news-content">
                        <h3 class="news-title">{{ $t('home.news') }}</h3>
                        <p class="news-excerpt">--</p>
                    </div>
                </div>
            </div>
        </div>
        <!-- 底部导航 -->
        <div class="bottom-nav">
            <div v-for="item in bottomNavs" :key="item.id" :class="['nav-btn', { active: currentNav === item.id }]"
                @click="currentNav = item.id">
                <Icon :icon="item.icon" width="24" height="24" />
                <span>{{ item.name }}</span>
        <!-- Download Section -->
        <div class="download-section">
            <h2>{{ $t('home.tradeGlobalMarkets') }}</h2>
            <p class="download-desc">{{ $t('home.downloadDesc') }}</p>
            <button class="download-btn">
                {{ $t('home.downloadNow') }}
            </button>
            <div class="phone-mockups">
                <!-- Phone mockups placeholder -->
                <img src="@/assets/image/home/download.b711f9a.png" alt="phone-mockups" />
            </div>
        </div>
        <!-- Partners -->
        <div class="partners-section">
            <img src="@/assets/image/home/hezuo@3x.fcc1aa7.png" alt="partners" />
        </div>
        <!-- Footer Info -->
        <div class="footer-info">
            <div class="footer-left">
                <div class="info-section">
                    <h3>{{ $t('home.company') }}</h3>
                    <ul>
                        <li>{{ $t('关于我们') }}</li>
                        <li>{{ $t('home.teamIntro') }}</li>
                        <li>{{ $t('帮助中心') }}</li>
                        <li>{{ $t('home.emailSupport') }}</li>
                        <li>support@wealthinfra.com</li>
                    </ul>
                </div>
                <div class="info-section">
                    <h3>{{ $t('home.statement') }}</h3>
                    <ul>
                        <li>{{ $t('home.riskDisclosure') }}</li>
                        <li>{{ $t('home.privacyStatement') }}</li>
                        <li>{{ $t('home.amlPolicy') }}</li>
                        <li>{{ $t('home.regulatoryLicense') }}</li>
                    </ul>
                </div>
            </div>
            <div class="footer-right">
                <div class="info-section">
                    <h3>{{ $t('home.policy') }}</h3>
                    <ul>
                        <li>{{ $t('home.userAgreement') }}</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { ref, computed, onMounted, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { IMG_PATH } from '@/config'
import homeVideoUrl from '@/assets/video/home_video.mp4'
import { _getRealtimeByType } from '@/service/quotes.api'
import MiniKlineChart from '@/components/MiniKlineChart/index.vue'
const i18n = useI18n()
// 外汇货币代码 -> 国旗图国家/地区代码(用于 flagcdn.com)
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'
import { _getUsHeadNews } from '@/service/user.api'
// import newsPlaceholder from '@/assets/image/news-placeholder.png'
// 使用计算属性来处理动态变化的翻译内容
const navList = computed(() => [
    { name: i18n.t('导航.期权'), icon: 'icon-park-outline:chart-stock' },
    { name: i18n.t('导航.美股'), icon: 'icon-park-outline:dollar' },
    { name: i18n.t('导航.A股'), icon: 'icon-park-outline:chinese' },
    { name: i18n.t('导航.港股'), icon: 'icon-park-outline:hk' },
    { name: i18n.t('导航.加密货币'), icon: 'cryptocurrency:btc' },
    { name: i18n.t('导航.资讯'), icon: 'icon-park-outline:news' },
    { name: i18n.t('导航.理财'), icon: 'icon-park-outline:finance' },
    { name: i18n.t('导航.下载'), icon: 'icon-park-outline:download' }
])
const { t, locale } = useI18n()
const router = useRouter()
const marketTabs = computed(() => [
    { id: 'hot', name: i18n.t('市场.热门') },
    { id: 'us', name: i18n.t('市场.美股') },
    { id: 'a', name: i18n.t('市场.A股') },
    { id: 'hk', name: i18n.t('市场.港股') },
    { id: 'crypto', name: i18n.t('市场.加密货币') },
    { id: 'forex', name: i18n.t('市场.现货') }
])
function stripHtml(html) {
    if (!html || typeof html !== 'string') return ''
    const div = document.createElement('div')
    div.innerHTML = html
    return (div.textContent || div.innerText || '').trim()
}
const bottomNavs = computed(() => [
    { id: 'home', name: i18n.t('底部导航.首页'), icon: 'material-symbols:home-outline' },
    { id: 'market', name: i18n.t('底部导航.市场'), icon: 'material-symbols:analytics-outline' },
    { id: 'trade', name: i18n.t('底部导航.交易'), icon: 'material-symbols:candlestick-chart-outline' },
    { id: 'discover', name: i18n.t('底部导航.发现'), icon: 'material-symbols:explore-outline' },
    { id: 'mine', name: i18n.t('底部导航.我的'), icon: 'material-symbols:person-outline' }
])
// 跳转到交易页 Options,并带上 symbol 与 activeTab
function goToOptions(symbol, type) {
    if (!symbol) return
    router.push({
        path: '/trade/options',
        query: { symbol, activeTab: type || 'cryptos' }
    })
}
const traders = computed(() => [
    {
        id: 1,
        name: i18n.t('交易员.达人A'),
        avatar: "/avatars/trader1.png",
        profit: 289.5,
        followers: "12.5万"
    },
    {
        id: 2,
        name: i18n.t('交易员.达人B'),
        avatar: "/avatars/trader2.png",
        profit: 156.8,
        followers: "8.2万"
const YOUTUBE_LINK = 'https://www.youtube.com/watch?v=eAL5XVQtrxo&source_ve_path=OTY3MTQ&embeds_referring_euri=https%3A%2F%2Fwealthinfra.com%2F'
function openYouTubeLink() {
    window.open(YOUTUBE_LINK, '_blank', 'noopener,noreferrer')
}
// 语言映射表
const langMap = {
    'de': 'Deutsch',
    'en': 'English',
    'es': 'Español',
    'fr': 'Français',
    'Italy': 'Italiano',
    'Japanese': '日本語',
    'Korean': '한국어',
    'pt': 'Português',
    'vi': 'Tiếng Việt',
    'CN': '繁体中文',
    'zh-CN': '简体',
    'gr': 'Ελληνικά',
    'th': 'ไทย'
}
// 获取当前语言名称
const currentLangName = computed(() => {
    return langMap[locale.value] || '简体'
})
const activeTab = ref('forex')
const tradingPairs = ref([])
// 新闻列表,用于横向滚动轮播(与 news/index.vue 同源:_getUsHeadNews)
const newsList = ref([])
// Market Overview 使用 Trading Instruments 的前3条数据(保留完整 pair 用于展示图标)
const currencyPairs = computed(() => tradingPairs.value.slice(0, 3))
// 从外汇对取基础货币代码,如 EUR/USD -> eur,EURUSD -> eur(无斜杠取前3位)
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 不展示图标
function getPairIconUrl(pair) {
    if (!pair) return ''
    if (activeTab.value === 'stock' || activeTab.value === 'etf') return ''
    if (activeTab.value === '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` : ''
}
// 获取交易数据
const fetchTradingData = async () => {
    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'
    }
    try {
        const params = {
            type: type,
            pageNo: 1
        }
        if (category) {
            params.category = category
        }
        const data = await _getRealtimeByType(params)
        if (data && Array.isArray(data)) {
            // 外汇 tab 只展示指定 symbol:EURUSD GBPUSD AUDUSD XAUUSD NZDUSD
            const forexAllowedSymbols = ['EURUSD', 'GBPUSD', 'AUDUSD', 'XAUUSD', 'NZDUSD']
            let list = data
            if (activeTab.value === 'forex') {
                list = data.filter(item => {
                    const raw = (item.symbol || item.enName || '').toString().trim()
                    const normalized = raw.replace(/\//g, '').toUpperCase()
                    return forexAllowedSymbols.includes(normalized)
                })
            }
            // 只取前5条数据,并转换为需要的格式
            tradingPairs.value = list.slice(0, 5).map(item => {
                const basePrice = parseFloat(item.close || item.lastPrice || 0)
                const changeRatio = item.changeRatio || 0
                // 生成小型 K 线图数据 [open, close, low, high] 若干根
                const klineData = generateMiniKlineData(basePrice, changeRatio)
                // 计算买入价和卖出价(买入价略高,卖出价略低)
                const spread = basePrice * 0.0001 // 很小的价差
                const sellPrice = (basePrice - spread).toFixed(4)
                const buyPrice = (basePrice + spread).toFixed(4)
                const symboltxt = item.enName
                const symbolStr = item.symbol || '--'
                const iconImg = item.symbol_data || (symbolStr.includes('/') ? symbolStr.split('/')[0].toLowerCase() : symbolStr.replace(/USDT$/i, '').toLowerCase()) || symbolStr.toLowerCase()
                return {
                    symboltxt: symboltxt,
                    symbol: symbolStr,
                    type: type,
                    iconImg: iconImg,
                    price: basePrice.toFixed(4),
                    change: changeRatio,
                    sellPrice: sellPrice,
                    buyPrice: buyPrice,
                    klineData: klineData
                }
            })
        } else {
            tradingPairs.value = []
        }
    } catch (error) {
        console.error('获取交易数据失败:', error)
        tradingPairs.value = []
    }
}
// 监听 tab 切换
watch(activeTab, () => {
    fetchTradingData()
})
// 根据当前价与涨跌幅生成小型 K 线数据,每根 [open, close, low, high]
function generateMiniKlineData(basePrice, changeRatio) {
    const candleCount = 12
    const startPrice = basePrice / (1 + (changeRatio || 0) / 100)
    const range = basePrice - startPrice
    const candles = []
    let prevClose = startPrice
    for (let i = 0; i < candleCount; i++) {
        const t = (i + 1) / candleCount
        const trend = startPrice + range * t
        const noise = (Math.random() - 0.5) * (Math.abs(range) * 0.15 + basePrice * 0.002)
        const close = i === candleCount - 1 ? basePrice : Math.max(basePrice * 0.001, trend + noise)
        const open = prevClose
        const low = Math.min(open, close) - Math.random() * basePrice * 0.001
        const high = Math.max(open, close) + Math.random() * basePrice * 0.001
        candles.push([open, close, low, high])
        prevClose = close
    }
    return candles
}
// 组件挂载时获取数据
onMounted(() => {
    fetchTradingData()
    _getUsHeadNews().then((data) => {
        const list = Array.isArray(data) ? data : (data && data.articles) ? data.articles : []
        newsList.value = list.slice(0, 10)
    }).catch(() => { })
})
const features = ref([
    t('home.feature1'),
    t('home.feature2'),
    t('home.feature3'),
    t('home.feature4')
])
const financeProducts = computed(() => [
    {
        id: 1,
        name: i18n.t('理财.稳健计划'),
        rate: 12.8,
        desc: i18n.t('理财.稳健描述')
    },
    {
        id: 2,
        name: i18n.t('理财.高收益计划'),
        rate: 25.6,
        desc: i18n.t('理财.高收益描述')
    }
])
const marketData = ref([
    {
        name: '腾讯控股',
        code: 'HK 00700.HK',
        price: '403.800',
        change: 0.00
    },
    {
        name: '英伟达',
        code: 'US NVDA.US',
        price: '146.990',
        change: -0.88
    }
])
const currentTab = ref('hot')
const currentNav = ref('home')
const newsList = ref([
    {
        id: 1,
        title: "比特币突破48000美元,创下年内新高",
        source: "币市快讯",
        time: "10分钟前",
        image: "/news/btc.png"
    },
    {
        id: 2,
        title: "美联储暗示年内可能降息,加密货币市场全线上涨",
        source: "财经日报",
        time: "35分钟前",
        image: "/news/fed.png"
    }
const partners = ref([
    'BINANCE', 'coinbase', 'Stralishit', 'Bitazza',
    'Vanguard', 'ETX Capital', 'Coinb', 'Bitbank Global',
    'FOREX.com', 'Bitget', 'JFX', 'ICDX'
])
</script>
<style lang="scss" scoped>
.home {
.home-page {
    min-height: 100vh;
    background: $main_background;
    padding-bottom: 56px;
    background: #fff;
    padding-bottom: 12rem;
}
/* Header */
.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px;
    background: $main_background;
    position: sticky;
    top: 0;
    z-index: 100;
    border-bottom: 1px solid rgba(118, 128, 143, 0.1);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
}
    padding: 1.5rem;
    background: #fff;
    box-shadow: 0 1px 3px 1.5px #00000020;
.avatar {
    width: 40px;
    height: 40px;
    border-radius: 20px;
    background: rgba(146, 209, 255, 0.08);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s ease;
    &:hover {
        background: rgba(146, 209, 255, 0.12);
        transform: scale(1.05);
    .header-left {
        display: flex;
        align-items: center;
        gap: 1rem;
        .logo {
            width: 4rem;
            height: 4rem;
        }
        .logo-text {
            font-size: 2.25rem;
            font-weight: 700;
            color: $text_color;
        }
    }
}
.search-box {
    flex: 1;
    display: flex;
    align-items: center;
    background: $input_background;
    border-radius: 12px;
    margin: 0 12px;
    padding: 10px 16px;
    height: 40px;
    border: 1px solid rgba(118, 128, 143, 0.1);
    transition: all 0.2s ease;
    &:focus-within {
        border-color: rgba(146, 209, 255, 0.3);
        box-shadow: 0 0 0 3px rgba(146, 209, 255, 0.1);
    }
}
    .header-right {
        display: flex;
        align-items: center;
        gap: 1.5rem;
.search-box input {
    border: none;
    background: transparent;
    margin-left: 8px;
    width: 100%;
    font-size: 14px;
    color: $text_color;
    &::placeholder {
        color: $text_color1;
    }
}
        .lang-selector {
            padding: 0.5rem 1rem;
            background: #f5f5f5;
            border-radius: 0.5rem;
            font-size: 1.5rem;
            cursor: pointer;
            transition: all 0.2s ease;
.header-right {
    display: flex;
    gap: 12px;
    color: $text_color1;
    svg {
        cursor: pointer;
        transition: all 0.2s ease;
        &:hover {
            color: $color_main;
            transform: scale(1.1);
            &:hover {
                background: #e8e8e8;
            }
            .lang-text {
                color: $text_color;
            }
        }
        .icon-btn {
            width: 4rem;
            height: 4rem;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            background: #f5f5f5;
            cursor: pointer;
            img {
                width: 2rem;
                height: 2rem;
            }
        }
    }
}
.gift-banner {
    margin: 16px 20px;
    background: linear-gradient(135deg, rgba(146, 209, 255, 0.1) 0%, rgba(123, 184, 255, 0.05) 100%);
    border-radius: 16px;
    padding: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-shadow: 0 2px 12px rgba(146, 209, 255, 0.08);
    border: 1px solid rgba(146, 209, 255, 0.15);
    transition: all 0.3s ease;
    &:hover {
        box-shadow: 0 4px 20px rgba(146, 209, 255, 0.12);
        transform: translateY(-2px);
    }
}
.gift-left {
    display: flex;
    align-items: center;
    gap: 16px;
}
.gift-icon {
    width: 48px;
    height: 48px;
    border-radius: 12px;
    background: linear-gradient(135deg, #92D1FF 0%, #7BB8FF 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    box-shadow: 0 4px 12px rgba(146, 209, 255, 0.3);
}
.gift-amount {
    font-size: 18px;
    font-weight: 700;
    color: $text_color;
    letter-spacing: -0.3px;
}
.gift-desc {
    font-size: 13px;
    color: $text_color1;
    margin-top: 6px;
}
.register-btn {
    background: linear-gradient(135deg, #92D1FF 0%, #7BB8FF 100%);
    color: #fff;
    border: none;
    padding: 10px 24px;
    border-radius: 12px;
    font-size: 14px;
    font-weight: 600;
    box-shadow: 0 4px 12px rgba(146, 209, 255, 0.3);
    cursor: pointer;
    transition: all 0.3s ease;
    &:hover {
        background: linear-gradient(135deg, #7BB8FF 0%, #6BA8FF 100%);
        box-shadow: 0 6px 16px rgba(146, 209, 255, 0.4);
        transform: translateY(-1px);
    }
    &:active {
        transform: translateY(0);
    }
}
.nav-section {
    background: $main_background;
    padding: 24px 20px;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px 0;
}
.nav-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    padding: 12px;
    border-radius: 12px;
    transition: all 0.2s ease;
    &:hover {
        background: rgba(146, 209, 255, 0.05);
        transform: translateY(-2px);
    }
    svg {
        transition: all 0.2s ease;
    }
    &:hover svg {
        color: $color_main;
        transform: scale(1.1);
    }
}
.nav-name {
    font-size: 13px;
    color: $text_color;
    font-weight: 500;
}
.banner-section {
    margin: 0 20px 16px;
}
.banner-item {
    background: $main_background;
    border-radius: 16px;
    padding: 24px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-shadow: 0 2px 12px rgba(146, 209, 255, 0.08);
    border: 1px solid rgba(118, 128, 143, 0.1);
    transition: all 0.3s ease;
    &:hover {
        box-shadow: 0 4px 20px rgba(146, 209, 255, 0.12);
        transform: translateY(-2px);
    }
}
.banner-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: linear-gradient(135deg, rgba(255, 107, 0, 0.15) 0%, rgba(255, 107, 0, 0.08) 100%);
    color: #ff6b00;
    padding: 6px 12px;
    border-radius: 8px;
    font-size: 12px;
    font-weight: 600;
    border: 1px solid rgba(255, 107, 0, 0.2);
}
.banner-title {
    margin: 16px 0;
    font-size: 18px;
    font-weight: 700;
    color: $text_color;
    letter-spacing: -0.3px;
}
.join-btn {
    border: none;
    background: transparent;
    color: $color_main;
    padding: 6px 0;
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s ease;
    &:hover {
        color: #7BB8FF;
        gap: 8px;
    }
}
.banner-right img {
    width: 120px;
    height: 120px;
    object-fit: contain;
}
.market-section {
    background: $main_background;
    margin-top: 0;
    border-radius: 16px;
    margin: 0 20px 16px;
    box-shadow: 0 2px 12px rgba(146, 209, 255, 0.08);
    border: 1px solid rgba(118, 128, 143, 0.1);
/* Hero Section */
.hero-section {
    border-radius: 2rem;
    overflow: hidden;
}
    margin: 0 auto;
    box-shadow: 0 0.25rem 1.5rem rgba(0, 0, 0, 0.08);
    width: calc(100% - 4rem);
    margin-top: 3rem;
.market-tabs {
    display: flex;
    padding: 0 20px;
    border-bottom: 1px solid rgba(118, 128, 143, 0.1);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    background: $main_background;
}
.market-tabs::-webkit-scrollbar {
    display: none;
}
.tab-item {
    padding: 16px 20px;
    font-size: 14px;
    color: $text_color1;
    position: relative;
    white-space: nowrap;
    cursor: pointer;
    transition: all 0.2s ease;
    font-weight: 500;
}
.tab-item.active {
    color: $color_main;
    font-weight: 700;
}
.tab-item.active::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 24px;
    height: 3px;
    background: $color_main;
    border-radius: 2px;
}
.market-item {
    display: flex;
    justify-content: space-between;
    padding: 20px;
    border-bottom: 1px solid rgba(118, 128, 143, 0.1);
    transition: all 0.2s ease;
    cursor: pointer;
    &:hover {
        background: rgba(146, 209, 255, 0.03);
    :deep(.van-swipe) {
        border-radius: 2rem;
        overflow: hidden;
    }
    &:last-child {
        border-bottom: none;
    :deep(.van-swipe-item) {
        margin: 0 auto;
    }
    :deep(.van-swipe__indicator) {
        background-color: rgba(255, 255, 255, 0.5);
        width: 1rem;
        height: 1rem;
        margin: 0 0.5rem;
    }
    :deep(.van-swipe__indicator--active) {
        background-color: #92D1FF;
    }
    .hero-card {
        background: #fff;
        border-radius: 2rem;
        padding: 3rem;
        min-height: 40rem;
        display: flex;
        flex-direction: column;
        .hero-title {
            font-size: 3.5rem;
            font-weight: 700;
            color: $text_color;
            margin-bottom: 3rem;
            margin-top: 1rem;
        }
        .hero-desc {
            font-size: 2.5rem;
            color: $text_color;
            margin-bottom: 3rem;
            line-height: 1.5;
        }
        .trade-btn {
            background: #0a6bfa;
            color: #fff;
            border: none;
            padding: 1rem 3rem;
            border-radius: 5rem;
            font-size: 3rem;
            font-weight: 300;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 1rem;
            cursor: pointer;
            margin-bottom: 3rem;
            .play-icon {
                width: 4.5rem;
                object-fit: contain;
            }
        }
        .hero-illustration {
            position: relative;
            margin-bottom: 2rem;
            .robot-illustration,
            .device-illustration,
            .crypto-illustration {
                width: 100%;
                border-radius: 1rem;
                img {
                    width: 70%;
                    margin: 0 auto;
                }
            }
        }
    }
}
.stock-name {
    font-size: 16px;
.no-more-notice {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin: 2rem 1.5rem;
    font-size: 2.5rem;
    color: $text_color;
    font-weight: 600;
    letter-spacing: -0.2px;
    padding: 2rem;
    background-color: #f6f6f6;
    border-radius: 2rem;
    img {
        width: 2rem;
        height: 2rem;
    }
    .arrow {
        margin-left: auto;
        width: 2rem;
        height: auto;
    }
}
.stock-code {
    font-size: 12px;
    color: $text_color1;
    margin-top: 6px;
}
.current-price {
    font-size: 16px;
    text-align: right;
    color: $text_color;
    font-weight: 600;
    letter-spacing: -0.2px;
}
.price-change {
    font-size: 13px;
    text-align: right;
    margin-top: 6px;
    font-weight: 600;
}
.up {
    color: $green;
}
.down {
    color: $red;
}
.bottom-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
/* Quick Access */
.quick-access {
    display: flex;
    justify-content: space-around;
    padding: 3rem 0;
    background: #fff;
    display: flex;
    padding: 6px 0;
    border-top: 1px solid #f0f0f0;
}
    box-shadow: 0rem 1rem 4rem 0rem rgba(0, 0, 0, .12);
    margin: 3rem 1.5rem 4rem;
    border-radius: 2rem;
.nav-btn {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    font-size: 12px;
    color: #999;
}
    .quick-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.5rem;
        cursor: pointer;
        width: 25%;
.nav-btn.active {
    color: #000;
}
        .quick-icon {
            width: 5rem;
            height: 5rem;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
.section-block {
    background: $main_background;
    margin: 0 20px 16px;
    padding: 20px;
    border-radius: 16px;
    box-shadow: 0 2px 12px rgba(146, 209, 255, 0.08);
    border: 1px solid rgba(118, 128, 143, 0.1);
}
            img {
                width: 100%;
                object-fit: contain;
            }
        }
.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
}
.section-header h3 {
    font-size: 18px;
    font-weight: 700;
    color: $text_color;
    letter-spacing: -0.3px;
}
.more-btn {
    border: none;
    background: transparent;
    color: $text_color1;
    font-size: 14px;
    display: flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
    transition: all 0.2s ease;
    font-weight: 500;
    &:hover {
        color: $color_main;
        gap: 6px;
        span {
            font-size: 2rem;
            color: $text_color;
        }
    }
}
/* 跟单样式 */
.trader-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
/* Market Overview */
.market-overview {
    padding: 3rem;
    background: #fff;
.trader-card {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px;
    background: $main2_background;
    border-radius: 12px;
    border: 1px solid rgba(118, 128, 143, 0.1);
    transition: all 0.3s ease;
    cursor: pointer;
    &:hover {
        box-shadow: 0 4px 12px rgba(146, 209, 255, 0.08);
        transform: translateY(-2px);
        border-color: rgba(146, 209, 255, 0.2);
    .currency-cards {
        display: flex;
        gap: 1.5rem;
        .currency-card {
            flex: 1;
            padding: 2rem;
            background: #f9f9f9;
            border-radius: 1rem;
            display: flex;
            flex-direction: column;
            gap: 1rem;
            text-align: center;
            .currency-pair-row {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 0.5rem;
                margin-bottom: 0.5rem;
            }
            .currency-card-icon-wrap {
                position: relative;
                flex-shrink: 0;
            }
            .currency-card-icon {
                width: 3rem;
                height: 3rem;
                border-radius: 50%;
                object-fit: cover;
                &--large {
                    width: 3rem;
                    height: 3rem;
                }
                &--sm {
                    position: absolute;
                    right: -0.2rem;
                    bottom: -0.2rem;
                    width: 1.4rem;
                    height: 1.4rem;
                    border-radius: 50%;
                    object-fit: cover;
                    border: 0.15rem solid #fff;
                    box-shadow: 0 0 0.1rem rgba(0, 0, 0, 0.2);
                }
            }
            .currency-pair {
                font-size: 2rem;
                color: $text_color;
                margin-bottom: 0;
            }
            .currency-price {
                font-size: 2.5rem;
                font-weight: 700;
                color: $text_color;
                margin-bottom: 1rem;
            }
            .currency-change {
                font-size: 2rem;
                font-weight: 600;
                &.up {
                    color: $green;
                }
                &.down {
                    color: $red;
                }
            }
        }
    }
}
.trader-info {
    display: flex;
    align-items: center;
    gap: 12px;
/* Trading Section */
.trading-section {
    padding: 3rem;
    background: #fff;
    .trading-tabs {
        display: flex;
        align-items: center;
        gap: 1.6rem;
        margin-bottom: 3rem;
        overflow-x: auto;
        .tab-item {
            padding: 1.3rem 1rem;
            font-size: 2rem;
            color: $text_color;
            white-space: nowrap;
            cursor: pointer;
            border-radius: 999px;
            transition: background-color 0.2s, color 0.2s;
            &.active {
                padding: 1.3rem 3.5rem;
                background: #3478F6;
                color: #fff;
                font-weight: 600;
                box-shadow: 0 0.2rem 0.6rem rgba(52, 120, 246, 0.35);
            }
        }
    }
    .trading-pairs {
        display: flex;
        flex-direction: column;
        gap: 2rem;
        .pair-item {
            display: flex;
            flex-direction: column;
            padding: 2rem;
            background: #fff;
            border-radius: 1rem;
            border: 0.1rem solid #f0f0f0;
            .pair-header {
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                .pair-symbol {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 0.6rem;
                    font-size: 2rem;
                    font-weight: 600;
                    color: $text_color;
                    .pair-symbol-icon-wrap {
                        position: relative;
                        flex-shrink: 0;
                    }
                    .pair-symbol-icon {
                        width: 2.4rem;
                        height: 2.4rem;
                        border-radius: 50%;
                        // object-fit: contain;
                        &--large {
                            width: 3rem;
                            height: 3rem;
                        }
                        &--sm {
                            position: absolute;
                            right: -0.2rem;
                            bottom: -0.2rem;
                            width: 1.6rem;
                            height: 1.6rem;
                            border-radius: 50%;
                            object-fit: cover;
                            border: 0.15rem solid #fff;
                            box-shadow: 0 0 0.1rem rgba(0, 0, 0, 0.2);
                        }
                    }
                }
                .pair-change {
                    font-size: 1.75rem;
                    font-weight: 600;
                    &.up {
                        color: $green;
                    }
                    &.down {
                        color: $red;
                    }
                }
            }
            .pair-bottom {
                display: flex;
                align-items: center;
                gap: 1rem;
                position: relative;
                top: -2.2rem;
                .action-price {
                    font-size: 2rem;
                    font-weight: 600;
                }
                .action-btn {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    justify-content: center;
                    padding: 0.3rem 5rem;
                    border: 0.1rem solid #333;
                    border-radius: 0.2rem;
                    font-size: 1.8rem;
                    background: #fff;
                    cursor: pointer;
                    min-width: 7rem;
                    gap: 0.5rem;
                    flex-shrink: 0;
                    .action-label {
                        font-size: 1.5rem;
                    }
                    &.sell {
                        .action-price {
                            color: $text_color;
                        }
                        .action-label {
                            color: $red;
                        }
                    }
                    &.buy {
                        .action-price {
                            color: $text_color;
                        }
                        .action-label {
                            color: $green;
                        }
                    }
                    &:hover {
                        background: #f9f9f9;
                    }
                }
                .pair-chart {
                    flex: 1;
                    height: 2.5rem;
                    margin: 0 0.5rem;
                    min-width: 6rem;
                }
            }
        }
    }
}
.trader-avatar {
    width: 48px;
    height: 48px;
    border-radius: 24px;
    object-fit: cover;
    border: 2px solid rgba(146, 209, 255, 0.1);
/* About Section */
.about-section {
    padding: 3rem;
    background: #fff;
    .section-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 2rem;
        h2 {
            font-size: 2.25rem;
            font-weight: 700;
            color: $text_color;
        }
        .more-link {
            font-size: 1.75rem;
            cursor: pointer;
        }
    }
    .video-thumbnail {
        margin-bottom: 2rem;
        cursor: pointer;
        .video-placeholder {
            width: 100%;
            background: #1a1a1a;
            border-radius: 1rem;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-bottom: 1rem;
            .home-video {
                width: 100%;
                height: 100%;
                object-fit: cover;
                border-radius: 1rem;
            }
            .play-button {
                width: 6rem;
                height: 6rem;
                background: rgba(255, 255, 255, 0.9);
                border-radius: 50%;
                display: flex;
                align-items: center;
                justify-content: center;
                color: #000;
                font-size: 2rem;
            }
        }
        .video-info {
            .video-title {
                font-size: 1.75rem;
                font-weight: 600;
                color: $text_color;
                margin-bottom: 0.5rem;
            }
            .video-platform {
                font-size: 1.5rem;
                color: $text_color1;
            }
        }
    }
    .about-desc {
        font-size: 1.75rem;
        color: $text_color1;
        line-height: 1.5;
        margin-bottom: 2rem;
    }
    .feature-list {
        list-style: none;
        padding: 0;
        li {
            font-size: 1.75rem;
            color: $text_color1;
            margin-bottom: 1rem;
            padding-left: 3rem;
            position: relative;
            &::before {
                content: '✓';
                position: absolute;
                left: 0;
                color: $green;
                font-weight: 700;
            }
        }
    }
}
.trader-name {
    font-size: 16px;
    font-weight: 600;
    color: $text_color;
    letter-spacing: -0.2px;
/* News Section */
.news-section {
    padding: 3rem;
    background: #fff;
    .section-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 2rem;
        h2 {
            font-size: 2.25rem;
            font-weight: 700;
            color: $text_color;
        }
        .more-link {
            font-size: 1.75rem;
            color: $text-color;
            cursor: pointer;
        }
    }
    .news-carousel {
        display: flex;
        gap: 1.5rem;
        overflow-x: auto;
        overflow-y: hidden;
        padding-bottom: 0.5rem;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        &::-webkit-scrollbar {
            height: 0.4rem;
        }
        &::-webkit-scrollbar-thumb {
            background: #ccc;
            border-radius: 0.2rem;
        }
        .news-item {
            flex-shrink: 0;
            width: 45rem;
            min-width: 28rem;
            display: flex;
            flex-direction: column;
            gap: 1rem;
            padding: 1.5rem;
            background: #f9f9f9;
            border-radius: 1rem;
            scroll-snap-align: start;
            cursor: pointer;
            &.news-item--placeholder {
                min-width: 100%;
            }
            .news-image {
                width: 100%;
                height: 14rem;
                border-radius: 0.5rem;
                object-fit: cover;
            }
            .news-content {
                flex: 1;
                min-width: 0;
                .news-title {
                    font-size: 1.75rem;
                    font-weight: 600;
                    color: $text_color;
                    margin-bottom: 1rem;
                }
                .news-excerpt {
                    font-size: 1.5rem;
                    color: $text_color1;
                    line-height: 1.4;
                }
            }
        }
    }
}
.trader-stats {
    display: flex;
    gap: 16px;
    font-size: 13px;
    color: $text_color1;
    margin-top: 6px;
    b {
/* Download Section */
.download-section {
    padding: 3rem;
    background: #fff;
    text-align: left;
    box-shadow: 0rem .8rem 3.2rem 0rem rgba(0, 0, 0, .12);
    border-radius: 1.6rem;
    margin: 3rem 3rem;
    h2 {
        font-size: 3rem;
        font-weight: 700;
        color: $text_color;
        margin-bottom: 2rem;
    }
    .download-desc {
        font-size: 2.2rem;
        color: $text_color;
        margin-bottom: 3rem;
    }
    .download-btn {
        background: #0a6bfa;
        color: #fff;
        border: none;
        padding: 1.2rem 3rem;
        border-radius: 1rem;
        font-size: 2rem;
        font-weight: 600;
        display: flex;
        align-items: center;
        gap: 1rem;
        cursor: pointer;
        img {
            width: 2.5rem;
            height: 2.5rem;
        }
    }
    .phone-mockups {
        margin-top: 4rem;
        border-radius: 1rem;
        img {
            width: 80%;
            margin: 0 auto;
        }
    }
}
.follow-btn {
    background: linear-gradient(135deg, #92D1FF 0%, #7BB8FF 100%);
    border: none;
    padding: 8px 20px;
    border-radius: 10px;
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    box-shadow: 0 2px 8px rgba(146, 209, 255, 0.3);
    cursor: pointer;
    transition: all 0.3s ease;
    &:hover {
        background: linear-gradient(135deg, #7BB8FF 0%, #6BA8FF 100%);
        box-shadow: 0 4px 12px rgba(146, 209, 255, 0.4);
        transform: translateY(-1px);
    }
    &:active {
        transform: translateY(0);
/* Partners */
.partners-section {
    padding: 3rem;
    background: #fff;
    text-align: center;
    img {
        width: 100%;
        max-width: 100%;
        height: auto;
        display: block;
    }
}
/* 理财样式 */
.finance-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
/* Footer Info */
.footer-info {
    padding: 3rem;
    background: #fff;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
.finance-card {
    padding: 20px;
    background: $main2_background;
    border-radius: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1px solid rgba(118, 128, 143, 0.1);
    transition: all 0.3s ease;
    cursor: pointer;
    &:hover {
        box-shadow: 0 4px 12px rgba(146, 209, 255, 0.08);
        transform: translateY(-2px);
        border-color: rgba(146, 209, 255, 0.2);
    .footer-left {
        display: flex;
        flex-direction: column;
        gap: 4rem;
    }
    .footer-right {
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        position: relative;
    }
    .info-section {
        h3 {
            font-size: 2rem;
            font-weight: 700;
            color: $text_color;
            margin-bottom: 2rem;
        }
        ul {
            list-style: none;
            padding: 0;
            li {
                font-size: 1.75rem;
                color: $text_color1;
                margin-bottom: 1rem;
                cursor: pointer;
            }
        }
    }
}
.finance-name {
    font-size: 16px;
    font-weight: 600;
    color: $text_color;
    letter-spacing: -0.2px;
}
.finance-rate {
    margin: 12px 0;
}
.rate-num {
    font-size: 24px;
    font-weight: 700;
    background: linear-gradient(135deg, #92D1FF 0%, #7BB8FF 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    letter-spacing: -0.5px;
}
.rate-label {
    font-size: 13px;
    color: $text_color1;
    margin-left: 6px;
}
.finance-desc {
    font-size: 13px;
    color: $text_color1;
    margin-top: 4px;
}
.invest-btn {
    background: linear-gradient(135deg, #92D1FF 0%, #7BB8FF 100%);
    color: #fff;
    border: none;
    padding: 10px 24px;
    border-radius: 12px;
    font-size: 14px;
    font-weight: 600;
    box-shadow: 0 4px 12px rgba(146, 209, 255, 0.3);
    cursor: pointer;
    transition: all 0.3s ease;
    &:hover {
        background: linear-gradient(135deg, #7BB8FF 0%, #6BA8FF 100%);
        box-shadow: 0 6px 16px rgba(146, 209, 255, 0.4);
        transform: translateY(-1px);
    }
    &:active {
        transform: translateY(0);
    }
}
/* 资讯样式 */
.news-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.news-item {
    display: flex;
    gap: 16px;
    padding: 16px;
    border-radius: 12px;
    background: $main2_background;
    border: 1px solid rgba(118, 128, 143, 0.1);
    transition: all 0.3s ease;
    cursor: pointer;
    &:hover {
        box-shadow: 0 4px 12px rgba(146, 209, 255, 0.08);
        transform: translateY(-2px);
        border-color: rgba(146, 209, 255, 0.2);
    }
}
.news-content {
    flex: 1;
}
.news-title {
    font-size: 16px;
    color: $text_color;
    line-height: 1.5;
    font-weight: 600;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    letter-spacing: -0.2px;
}
.news-meta {
    margin-top: 10px;
    font-size: 12px;
    color: $text_color1;
    display: flex;
    gap: 16px;
}
.news-image {
    width: 100px;
    height: 70px;
    border-radius: 10px;
    object-fit: cover;
    border: 1px solid rgba(118, 128, 143, 0.1);
}
</style>
</style>