From 0dbc7465447164fef24327b5d494870832d798dd Mon Sep 17 00:00:00 2001
From: 李 <344137771@qq.com>
Date: Tue, 26 May 2026 11:15:18 +0800
Subject: [PATCH] 1
---
src/views/home/index.vue | 2006 +++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 1,198 insertions(+), 808 deletions(-)
diff --git a/src/views/home/index.vue b/src/views/home/index.vue
index c267f41..5562108 100644
--- a/src/views/home/index.vue
+++ b/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>
\ No newline at end of file
+</style>
--
Gitblit v1.9.3