From ef52095f5e9f0a9fe2da779bb1573947d77d75b6 Mon Sep 17 00:00:00 2001
From: jhzh <1628036192@qq.com>
Date: Fri, 22 May 2026 10:53:01 +0800
Subject: [PATCH] 1
---
src/views/homePage/index.vue | 767 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 685 insertions(+), 82 deletions(-)
diff --git a/src/views/homePage/index.vue b/src/views/homePage/index.vue
index c5cc3d2..db29886 100644
--- a/src/views/homePage/index.vue
+++ b/src/views/homePage/index.vue
@@ -1,5 +1,5 @@
<template>
- <div class="home_page mainBackground textColor">
+ <div class="home_page textColor" style="background-color: #f6f5fa;">
<Head @search="onSearch"></Head>
<!-- <div class="home_logo flex justify-center"><img src="@/assets/imgs/home/home_logo.png" alt=""></div> -->
@@ -9,10 +9,14 @@
<van-swipe-item><img src="@/assets/imgs/home/Slider-3.jpg" alt=""></van-swipe-item>
<van-swipe-item><img src="@/assets/imgs/home/Slider-4.jpg" alt=""></van-swipe-item>
</van-swipe> -->
-
- <video autoplay loop muted playsinline class="home_logo">
- <source src="@/assets/video/home_1.mp4" type="video/mp4">
- </video>
+ <div class="flex flex-col items-center justify-center home-kyc-block" @click="toPage('/certificationCenter')">
+ <img style="width: 65%;" src="@/assets/imgs/new/kyc-reward.png" alt="">
+ <div style="font-size: 25px;">{{ $t('kycLotteryBroadcast') }}</div>
+ <div style="font-size: 12px;">{{ $t('kycLotterySubtitle') }}</div>
+ </div>
+ <!-- <video autoplay loop muted playsinline class="home_logo"> -->
+ <!-- <source src="@/assets/video/home_1.mp4" type="video/mp4"> -->
+ <!-- </video> -->
<!-- <div class="text-center font-bold mt-8 logo_text">{{ $t('复制财富,從此刻開始') }}</div>
<div class="text-center mt-2 logo_text_small">{{ $t('超6000種熱門交易類別,立即註冊领取5000USDT') }}!</div> -->
@@ -24,29 +28,38 @@
<div class="login_but_d text-center" @click="toPage('/login')">{{ $t('登录') }}</div>
</div>
- <div class="home_grid flex justify-start flex-wrap">
- <div class="grid_item pt-10" v-for="value in tabbers" :key="value.key" @click="toPage(value.path)">
+ <!-- 轮播图:使用本地两张图片,带圆角 -->
+ <div class="home_banner mp-20">
+ <van-swipe
+ class="home_banner_swipe"
+ :autoplay="4000"
+ :show-indicators="false"
+ @change="onBannerChange"
+ >
+ <van-swipe-item
+ v-for="(item, index) in bannerImages"
+ :key="index"
+ class="home_banner_item"
+ @click="onBannerClick(item)"
+ >
+ <img :src="item.img" :alt="item.alt" class="home_banner_img" />
+ </van-swipe-item>
+ </van-swipe>
+ <div class="home_banner_indicator">
+ <span
+ v-for="(_, i) in bannerImages"
+ :key="i"
+ class="home_banner_dot"
+ :class="{ active: currentBanner === i }"
+ />
+ </div>
+ </div>
+ <div class="home_grid flex justify-start flex-wrap home_grid_bg mt-10 pt-8" style="height: 110px;">
+ <div class="grid_item" v-for="value in tabbers" :key="value.key" @click="onGridClick(value)">
<div class="grid_item_img flex justify-center"><img :src="value.icon" alt=""></div>
<div class="text-center mt-2">{{ value.name }}</div>
</div>
</div>
-
- <!-- 新闻 -->
- <van-notice-bar class="font-26 mt-10 index_notice" background="#333" :scrollable="false" wrapable
- color="#333333">
- <van-swipe vertical class="notice-swipe" :autoplay="2000" :show-indicators="false">
- <van-swipe-item v-for="item in announceList" :key="item.id" @click="toAnnounceDetail(item.uuid)">
- <div class="flex justify-start items-center">
- <img :src="item.imgUrl" alt="" class="notice_img mr-5">
- <div class="notice_content">
- <div>{{ item.startTime }}</div>
- <div>{{ item.title }}</div>
- </div>
- </div>
- </van-swipe-item>
- </van-swipe>
- </van-notice-bar>
-
<!-- <div class="flex justify-between mt-10">
<van-swipe class="home_swipe_1" :autoplay="2000">
<van-swipe-item v-for="value in swipe1" :key="value.key" class="flex justify-center items-center">
@@ -78,8 +91,110 @@
</div>
</div> -->
- <div id="cryptos" class="pt-10">
- <list-quatation :listData="qList" :tabShow="false" :tabActive="2" />
+ <!-- 列表区:Favorites / Markets 切换 -->
+ <div id="cryptos" class="pt-10 home-list-section">
+ <div class="home-list-tabs">
+ <span class="home-list-tab" :class="{ active: listMode === 'favorites' }" @click="listMode = 'favorites'">{{ $t('favorites') }}</span>
+ <span class="home-list-tab" :class="{ active: listMode === 'markets' }" @click="listMode = 'markets'">{{ $t('markets') }}</span>
+ </div>
+ <list-quatation :listData="displayedList" :tabShow="false" :tabActive="2" />
+ <div
+ v-if="!showMoreList && currentList.length > listInitialCount"
+ class="home-list-more"
+ @click="showMoreList = true"
+ >
+ {{ $t('展示更多') }}
+ </div>
+
+ <!-- HOT COINS:横向滚动卡片 -->
+ <div class="home-hot-coins">
+ <div class="home-hot-title">{{ $t('HOT COINS') }}</div>
+ <div class="home-hot-subtitle">{{ $t('The popular cryptocurrency') }}</div>
+ <div class="home-hot-scroll">
+ <div
+ v-for="item in hotCoinsList"
+ :key="item.symbol_data"
+ class="home-hot-card"
+ @click="toQuote(item)"
+ >
+ <img :src="item.symbol ? `${HOST_URL}/symbol/${item.symbol_data}.png` : ''" alt="" class="home-hot-logo" />
+ <div class="home-hot-symbol">{{ (item.symbol_data || '').toUpperCase() }}</div>
+ <div class="home-hot-pct" :class="(item.change_ratio || 0) >= 0 ? 'up' : 'down'">
+ {{ (item.change_ratio || 0) >= 0 ? '↗' : '↘' }} {{ (item.change_ratio != null ? item.change_ratio : 0).toFixed(2) }}%
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Trend / Follow / News / IPO 切换 -->
+ <div class="home-trend-tabs">
+ <span class="home-trend-tab" :class="{ active: trendTab === 'trend' }" @click="trendTab = 'trend'">{{ $t('trend') }}</span>
+ <span class="home-trend-tab" :class="{ active: trendTab === 'follow' }" @click="trendTab = 'follow'">{{ $t('follow') }}</span>
+ <span class="home-trend-tab" :class="{ active: trendTab === 'news' }" @click="trendTab = 'news'">{{ $t('news') }}</span>
+ <span class="home-trend-tab" :class="{ active: trendTab === 'ipo' }" @click="trendTab = 'ipo'">{{ $t('ipo') }}</span>
+ </div>
+ <!-- Trend:riseBg.jpg 背景 + 3 条数据 -->
+ <div v-if="trendTab === 'trend'" class="home-trend-card home-trend-card--bg">
+ <div class="home-trend-card-inner">
+ <div class="home-trend-heading">{{ $t('trend') }}</div>
+ <div class="home-trend-subtitle">{{ $t('trendSubtitle') }}</div>
+ <div class="home-trend-list">
+ <div
+ v-for="item in trendList"
+ :key="item.symbol_data"
+ class="home-trend-item"
+ @click="toQuote(item)"
+ >
+ <img :src="item.iconUrl || ''" alt="" class="home-trend-logo" />
+ <div class="home-trend-info">
+ <span class="home-trend-name">{{ item.symbol_data }}</span>
+ </div>
+ <div class="home-trend-right">
+ <span class="home-trend-price">{{ (item.close || 0).toFixed(3) }}</span>
+ <span class="home-trend-pct up">↗ {{ (item.change_ratio != null ? item.change_ratio : 0).toFixed(2) }}%</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- News:news!getUsHeadNews.action -->
+ <div v-else-if="trendTab === 'news'" class="home-trend-card home-trend-card--news">
+ <div class="home-trend-card-inner">
+ <div class="home-trend-heading home-trend-heading--dark">{{ $t('news') }}</div>
+ <div v-if="newsLoading" class="home-trend-card--empty-inner">
+ <van-loading type="spinner" size="24" />
+ <div class="home-empty-text mt-8">{{ $t('加载中...') }}</div>
+ </div>
+ <div v-else-if="newsListForTab.length" class="home-news-list">
+ <div
+ v-for="(item, index) in newsListForTab"
+ :key="(item.url || item.uuid) || index"
+ class="home-news-item"
+ @click="onNewsItemClick(item)"
+ >
+ <div v-if="item.urlToImage" class="home-news-thumb">
+ <img :src="item.urlToImage" alt="" />
+ </div>
+ <div class="home-news-body">
+ <div class="home-news-title textColor">{{ item.title }}</div>
+ <div class="home-news-meta">
+ <div class="home-news-date text-grey">{{ item.author }}</div>
+ <span class="home-news-detail text-grey">{{ $t('详情') }}</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div v-else class="home-trend-card--empty-inner">
+ <img :src="emptyImg" alt="" class="home-empty-img" />
+ <div class="home-empty-text">{{ $t('暂无数据') }}</div>
+ </div>
+ </div>
+ </div>
+ <!-- Follow / IPO:empty.png 暂无数据 -->
+ <div v-else class="home-trend-card home-trend-card--empty">
+ <img :src="emptyImg" alt="" class="home-empty-img" />
+ <div class="home-empty-text">{{ $t('暂无数据') }}</div>
+ </div>
</div>
<van-popup v-model:show="item.showPopUp" style="border-radius:10px;" :close-on-click-overlay="false"
@@ -94,20 +209,41 @@
</van-button>
</div>
</van-popup>
+
+ <!-- 新闻详情弹层(站内展示,不跳外链) -->
+ <van-popup v-model:show="showNewsDetailPopup" round position="bottom" :style="{ height: '88%' }" class="news-detail-popup">
+ <div class="news-detail-inner" v-if="selectedNewsDetail">
+ <div class="news-detail-drag-bar" />
+ <div class="news-detail-header">
+ <span class="news-detail-source">{{ selectedNewsDetail.sourceName || '' }}</span>
+ </div>
+ <h2 class="news-detail-title textColor">{{ selectedNewsDetail.title }}</h2>
+ <div class="news-detail-img-wrap" v-if="selectedNewsDetail.urlToImage">
+ <img :src="selectedNewsDetail.urlToImage" alt="" class="news-detail-img" />
+ </div>
+ <div class="news-detail-content textColor">
+ {{ selectedNewsDetail.description || selectedNewsDetail.content || '' }}
+ </div>
+ <van-button color="#1194F7" class="news-detail-close" block round @click="showNewsDetailPopup = false">
+ {{ $t('关闭') }}
+ </van-button>
+ </div>
+ </van-popup>
</div>
</template>
<script setup>
import Head from './components/head.vue'
import { useI18n } from "vue-i18n";
-import { ref, computed, onBeforeUnmount } from 'vue';
+import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
import { useRouter } from 'vue-router';
import ListQuatation from "@/components/Transform/list-quotation/index.vue";
import { _getHomeList } from '@/service/cryptos.api'
-import { _getNewsList1, _getPopupNews } from '@/service/user.api'
+import { _getNewsList1, _getPopupNews, _getUsHeadNews } from '@/service/user.api'
import { useStore } from "vuex";
-import { TIME_OUT, customerServiceUrl } from "@/config";
+import { TIME_OUT, HOST_URL } from "@/config";
import { useUserStore } from '@/store/user';
+import { showToast } from 'vant';
import { setStorage, getStorage } from '@/utils/index.js';
let catchSymbol = getStorage('symbol')
if (!catchSymbol) {
@@ -119,27 +255,26 @@
const store = useStore();
const tabbers = [
- // { key: 1, name: t('跟单'), icon: new URL('@/assets/imgs/home/home_1.png', import.meta.url) },
- // { key: 3, name: `C2C ${t('交易')}`, icon: new URL('@/assets/imgs/home/home_3.png', import.meta.url) },
- // { key: 4, name: t('邀请好友'), icon: new URL('@/assets/imgs/home/home_4.png', import.meta.url) },
- // { key: 5, name: t('合约'), icon: new URL('@/assets/imgs/home/home_5.png', import.meta.url), path: '/trade/index' },
- // { key: 6, name: t('现货'), icon: new URL('@/assets/imgs/home/home_5.png', import.meta.url), path: '/cryptos/trade/btcusdt' },
- { key: 2, name: t('储值'), icon: new URL('@/assets/imgs/home/home_2.png', import.meta.url), path: '/cryptos/recharge/rechargeList?isForeign=true' },
- // { key: 7, name: t('提现'), icon: new URL('@/assets/imgs/home/home_6.png', import.meta.url), path: '/exchange/withdraw-usdt' }
- { key: 7, name: t('提现'), icon: new URL('@/assets/imgs/home/home_6.png', import.meta.url), path: '/cryptos/Withdraw/withdrawPage' },
- // { key: 8, name: t('卡券中心'), icon: new URL('@/assets/imgs/home/home_7.png', import.meta.url) },
- // { key: 9, name: t('闪兑'), icon: new URL('@/assets/imgs/home/home_8.png', import.meta.url), path: '/cryptos/exchangePage' },
- // { key: 9, name: t('划转'), icon: new URL('@/assets/imgs/home/home_8.png', import.meta.url), path: '/my/transfer' },
- // { key: 10, name: t('更多'), icon: new URL('@/assets/imgs/home/home_9.png', import.meta.url) },
-
- // { key: 11, name: "STO", icon: new URL('@/assets/imgs/home/home_1.png', import.meta.url), path: '/ICO/ico' },
- // { key: 12, name: "C2C", icon: new URL('@/assets/imgs/home/home_1.png', import.meta.url), path: '/wantBuy' },
- // { key: 13, name: t('质押'), icon: new URL('@/assets/imgs/home/home_1.png', import.meta.url), path: '' },
- { key: 14, name: t('onLineService'), icon: new URL('@/assets/imgs/home/home_10.png', import.meta.url), path: '/customerService' },
- { key: 15, name: 'DXCM PDF', icon: new URL('@/assets/imgs/home/home_1.png', import.meta.url), path: 'https://www.dexm-whitepaper.com/' },
+ { key: 2, name: t('recharge'), icon: new URL('@/assets/imgs/new/quick-function2.png', import.meta.url), path: '/cryptos/recharge/rechargeList?isForeign=true' },
+ { key: 7, name: t('提现'), icon: new URL('@/assets/imgs/new/quick-function1.png', import.meta.url), path: '/cryptos/Withdraw/withdrawPage' },
+ { key: 5, name: t('合约'), icon: new URL('@/assets/imgs/new/index-function5.png', import.meta.url), path: '/trade/index' },
+ { key: 14, name: t('客服'), icon: new URL('@/assets/imgs/new/index-function3.png', import.meta.url), path: '/customerService' },
]
-// 获取公告数据
+// 轮播图:使用本地两张图片(swiper_1、swiper_2 放在 src/assets/imgs/new/ 下)
+const bannerImages = [
+ { img: new URL('@/assets/imgs/new/swiper_1.png', import.meta.url).href, alt: 'Banner 1' },
+ { img: new URL('@/assets/imgs/new/swiper_2.png', import.meta.url).href, alt: 'Banner 2' },
+]
+const currentBanner = ref(0)
+const onBannerChange = (index) => {
+ currentBanner.value = index
+}
+const onBannerClick = (item) => {
+ if (item.link) router.push(item.link)
+}
+
+// 获取公告数据(用作轮播图)
const announceList = ref([])
_getNewsList1({
language: useI18n().locale.value,
@@ -168,9 +303,34 @@
// 跳转公告详情
const toAnnounceDetail = (announceId) => {
if (announceId) {
- router.push({ path: '/cryptos/AnnounceDetail', query: { id: announceId } })
+ router.push({ path: '/cryptos/announceDetail', query: { id: announceId } })
}
}
+
+// 新闻项点击:站内弹层展示详情(不跳外链);公告项仍走公告详情页
+const onNewsItemClick = (item) => {
+ if (item && item.url) {
+ selectedNewsDetail.value = item
+ showNewsDetailPopup.value = true
+ } else if (item && item.uuid) {
+ toAnnounceDetail(item.uuid)
+ }
+}
+
+// 新闻日期展示:ISO 取前 10 位
+const formatNewsDate = (publishedAt) => {
+ if (!publishedAt) return ''
+ return String(publishedAt).substring(0, 10)
+}
+
+// 首页四个按钮点击:无 path 时提示暂未开放
+const onGridClick = (value) => {
+ if (!value.path) {
+ showToast(t('notOpenYet'));
+ return;
+ }
+ toPage(value.path);
+};
// 跳转页面
const toPage = (path) => {
@@ -182,16 +342,7 @@
return;
}
- if (path == '/customerService') {
- // 客服链接,有值的话就会跳转到客服外链
- if (customerServiceUrl()) {
- window.location.href = customerServiceUrl();
- } else {
- router.push(path)
- }
- } else {
- router.push(path)
- }
+ router.push(path)
}
// 轮播图数据
@@ -206,12 +357,76 @@
{ key: 3, img: new URL('@/assets/imgs/home/home_3.png', import.meta.url) },
])
+// 列表区:Favorites / Markets 切换
+const listMode = ref('markets') // 'favorites' | 'markets'
+const listInitialCount = 8 // 竖列表默认展示条数,点击「展示更多」后显示全部
+const showMoreList = ref(false)
+const favoritesList = ref([
+ { symbol: 'btcusdt', symbol_data: 'BTC', name: 'BTC/USDT', close: 43250.5, change_ratio: 2.18, amount: 12345678 },
+ { symbol: 'ethusdt', symbol_data: 'ETH', name: 'ETH/USDT', close: 2280.2, change_ratio: -0.85, amount: 8765432 },
+ { symbol: 'xrpusdt', symbol_data: 'XRP', name: 'XRP/USDT', close: 0.62, change_ratio: 1.25, amount: 5678901 },
+])
+
+// HOT COINS / Trend 数据(HOT 用 qList 前几条,Trend 用 mock 3 条)
+const hotCoinsList = ref([])
+// Trend 三条:使用本地图片 a-DOT / a-APT / a-FIL(放在 src/assets/imgs/new/ 下)
+const trendList = ref([
+ { symbol: 'dotusdt', symbol_data: 'DOT', iconUrl: new URL('@/assets/imgs/new/a-DOT.png', import.meta.url).href, name: 'DOT/USDT', close: 1.589, change_ratio: 25.51 },
+ { symbol: 'aptusdt', symbol_data: 'APT', iconUrl: new URL('@/assets/imgs/new/a-APT.png', import.meta.url).href, name: 'APT/USDT', close: 0.958, change_ratio: 14.18 },
+ { symbol: 'filusdt', symbol_data: 'FIL', iconUrl: new URL('@/assets/imgs/new/a-FIL.png', import.meta.url).href, name: 'FIL/USDT', close: 1.005, change_ratio: 12.54 },
+])
+const trendTab = ref('trend') // 'trend' | 'follow' | 'news' | 'ipo'
+const emptyImg = new URL('@/assets/imgs/new/empty.png', import.meta.url).href
+// 新闻 tab:仅使用 news!getUsHeadNews.action 接口数据
+const newsApiList = ref([])
+const newsLoading = ref(false)
+const newsListForTab = computed(() => {
+ const list = newsApiList.value || []
+ if (list.length === 0) return []
+ return list.map((a) => ({
+ title: a.title || '',
+ author: a.author || '',
+ publishedAt: a.publishedAt || '',
+ url: a.url || '',
+ urlToImage: a.urlToImage || '',
+ description: a.description || '',
+ content: a.content || '',
+ sourceName: (a.source && a.source.name) ? a.source.name : '',
+ source: a.source,
+ }))
+})
+
+// 新闻详情弹层(站内展示,不跳外链)
+const showNewsDetailPopup = ref(false)
+const selectedNewsDetail = ref(null)
+
+// 首页新闻:在 onMounted 中请求,避免重复请求、便于统一管理
+function fetchUsHeadNews() {
+ if (newsLoading.value) return
+ newsLoading.value = true
+ _getUsHeadNews()
+ .then((list) => { newsApiList.value = list || [] })
+ .finally(() => { newsLoading.value = false })
+}
+
+// 跳转行情/交易页
+const toQuote = (item) => {
+ if (item && item.symbol) router.push(`/cryptos/trade/${item.symbol}`)
+}
+
//#region 行情数据----------------------------------------
let qList = ref([])
let qListCope = ref([]) // 备份数据
let key = ref('') // 搜索关键词
let timeout = ref(null)
const coinArr = computed(() => store.getters['home/coinArr']);
+
+// 竖列表:当前数据源与展示条数(展示更多前只显示 5 条)
+const currentList = computed(() => (listMode.value === 'markets' ? qList.value : favoritesList.value))
+const displayedList = computed(() => {
+ const list = currentList.value
+ return showMoreList.value ? list : (list || []).slice(0, listInitialCount)
+})
const fetchQList = async () => { // 获取行情
const list = await _getHomeList(coinArr.value.join(',')).catch(() => {
@@ -230,6 +445,8 @@
qList.value = list
}
qListCope.value = list; // 备份数据
+ // HOT COINS 取前 8 条
+ hotCoinsList.value = (list || []).slice(0, 8)
if (timeout.value) {
clearTimeout(timeout.value)
@@ -254,6 +471,9 @@
qList.value = newList
}
+onMounted(() => {
+ fetchUsHeadNews()
+})
onBeforeUnmount(() => {
if (timeout.value) {
clearTimeout(timeout.value)
@@ -265,7 +485,13 @@
<style lang="scss">
@import '@/assets/theme/index.scss';
-
+.mainBackground{
+ background-color: #f6f5fa !important;
+}
+.home-kyc-block {
+ cursor: pointer;
+ width: 100%;
+}
.home_page {
// background: $white;
min-height: 100vh;
@@ -279,31 +505,58 @@
font-size: 1.8rem;
}
- .index_notice {
- height: 100px;
- border-radius: 10px;
+ /* 首页轮播图(BlueWhale 风格) */
+ .home_banner {
+ position: relative;
+ width: 100%;
+ margin: 12px auto;
+ border-radius: 12px;
+ overflow: hidden;
+ background: $crd-b;
+ }
- .notice-swipe {
- height: 82px;
- }
+ .home_banner_swipe {
+ width: 100%;
+ border-radius: 12px;
+ }
- .notice_img {
- height: 80px;
- width: 100px;
- // background-color: $icon-bg;
- }
+ .home_banner_item {
+ width: 100%;
+ border-radius: 12px;
+ overflow: hidden;
+ }
- .notice_content {
- @include themify() {
- color: themed("text_color");
- }
+ .home_banner_img {
+ width: 100%;
+ height: auto;
+ display: block;
+ vertical-align: top;
+ border-radius: 12px;
+ }
- &>div:first-child {
- @include themify() {
- color: themed("text_color1");
- }
- }
- }
+ .home_banner_indicator {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 12px;
+ display: flex;
+ justify-content: center;
+ gap: 8px;
+ z-index: 2;
+ }
+
+ .home_banner_dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 3px;
+ background: rgba(255, 255, 255, 0.4);
+ transition: all 0.3s;
+ }
+
+ .home_banner_dot.active {
+ width: 16px;
+ border-radius: 3px;
+ background: #fff;
}
.home_logo {
@@ -349,6 +602,12 @@
.home_grid {
width: 100%;
+ background-size: 100% 100%;
+ background-repeat: no-repeat;
+
+ &.home_grid_bg {
+ background-image: url('@/assets/imgs/new/index-funbg.png');
+ }
.grid_item {
width: 25%;
@@ -359,7 +618,7 @@
width: 100%;
img {
- width: 6.3rem;
+ width: 5.8rem;
}
}
}
@@ -435,5 +694,349 @@
padding: 1.6rem 1.6rem 2rem 1.6rem;
font-size: 2rem;
}
+
+ /* 列表区 Favorites / Markets 切换(与下方 Trend 等统一样式) */
+ .home-list-section {
+ .home-list-tabs {
+ display: flex;
+ gap: 2.4rem;
+ margin-bottom: 1.2rem;
+ padding: 0 0.8rem;
+ .home-list-tab {
+ font-size: 1.8rem;
+ color: $tab-c;
+ padding: 0.6rem 1.4rem;
+ border-radius: 2rem;
+ &.active {
+ background: #fff;
+ color: #000;
+ font-weight: 600;
+ }
+ }
+ }
+ .home-list-more {
+ text-align: center;
+ padding: 1.2rem;
+ font-size: 2rem;
+ color: #1194F7;
+ margin-top: 0.8rem;
+ }
+ }
+
+ /* HOT COINS 横向滚动卡片:一屏约 3 个,细体 + 色 #29155a */
+ .home-hot-coins {
+ margin-top: 2.4rem;
+ .home-hot-title {
+ font-size: 2.1rem;
+ font-weight: 400;
+ color: #29155a;
+ margin-bottom: 0.4rem;
+ }
+ .home-hot-subtitle {
+ font-size: 1.5rem;
+ font-weight: 400;
+ color: #29155a;
+ margin-bottom: 1rem;
+ opacity: 0.75;
+ }
+ .home-hot-scroll {
+ display: flex;
+ gap: 1.4rem;
+ overflow-x: auto;
+ padding: 0.8rem 0 1.2rem 0;
+ -webkit-overflow-scrolling: touch;
+ &::-webkit-scrollbar { height: 6px; }
+ &::-webkit-scrollbar-thumb { background: #ddd; border-radius: 3px; }
+ }
+ .home-hot-card {
+ flex-shrink: 0;
+ width: calc((100vw ) / 3);
+ min-width: 10rem;
+ padding: 1.4rem 1rem;
+ background: #fff;
+ border-radius: 12px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.06);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 0.6rem;
+ }
+ .home-hot-logo {
+ width: 5rem;
+ height: 5rem;
+ border-radius: 50%;
+ }
+ .home-hot-symbol {
+ font-size: 1.7rem;
+ font-weight: 400;
+ color: #29155a;
+ }
+ .home-hot-pct {
+ font-size: 1.5rem;
+ font-weight: 400;
+ &.up { color: #0ecb81; }
+ &.down { color: #f6465d; }
+ }
+ }
+
+ /* Trend / Follow / News / IPO 切换:左右内外边距加宽 */
+ .home-trend-tabs {
+ display: flex;
+ gap: 3rem;
+ margin-top: 2.4rem;
+ margin-bottom: 1rem;
+ padding: 0 1.8rem;
+ .home-trend-tab {
+ font-size: 1.8rem;
+ color: $tab-c;
+ padding: 0.8rem 2.2rem;
+ border-radius: 2rem;
+ &.active {
+ background: #fff;
+ color: #000;
+ font-weight: 600;
+ }
+ }
+ }
+
+ .home-trend-card {
+ border-radius: 16px;
+ overflow: hidden;
+ min-height: 200px;
+ margin-top: 10px;
+ &.home-trend-card--bg {
+ background: url('@/assets/imgs/new/riseBg.jpg') no-repeat center/cover;
+ background-color: #fff;
+ background-size: 100% 100%;
+ .home-trend-card-inner {
+ padding: 1.6rem;
+ position: relative;
+ z-index: 1;
+ }
+ .home-trend-heading {
+ font-size: 2.8rem;
+ color: #fff;
+ margin-bottom: 0.4rem;
+ margin-top: 30px;
+ padding: 0 2rem;
+
+ }
+ .home-trend-subtitle {
+ padding: 0 2rem;
+ font-size: 1.5rem;
+ color: rgba(255,255,255,0.85);
+ margin-bottom: 1.2rem;
+
+ }
+ .home-trend-list {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ }
+ .home-trend-item {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ padding: 0rem 0rem;
+ margin: 0.5rem 2rem;
+ border-bottom: 1px solid hsla(0, 0%, 100%, .1);
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+ .home-trend-logo {
+ width: 3.6rem;
+ height: 3.6rem;
+ border-radius: 50%;
+ }
+ .home-trend-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
+ }
+ .home-trend-name {
+ font-size: 1.7rem;
+ font-weight: 600;
+ color: #fff;
+ }
+ .home-trend-right {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: 0.3rem;
+ }
+ .home-trend-price {
+ font-size: 1.5rem;
+ color: #fff;
+ }
+ .home-trend-pct {
+ font-size: 1.6rem;
+ font-weight: 600;
+ color: #0ecb81;
+ }
+ }
+ &.home-trend-card--empty {
+ background: #f7f7f7;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 2rem;
+ .home-empty-img {
+ width: 12rem;
+ height: auto;
+ margin-bottom: 1rem;
+ }
+ .home-empty-text {
+ font-size: 1.8rem;
+ color: $tab-c;
+ }
+ }
+ &.home-trend-card--news {
+ background: #fff;
+ .home-trend-card-inner {
+ padding: 1.6rem 1.8rem;
+ }
+ .home-trend-heading--dark {
+ color: #29155a;
+ font-size: 2.2rem;
+ margin-top: 0;
+ padding: 0;
+ }
+ .home-news-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0;
+ }
+ .home-news-item {
+ display: flex;
+ align-items: flex-start;
+ gap: 1rem;
+ padding: 1.2rem 0;
+ border-bottom: 1px solid #eee;
+ cursor: pointer;
+ &:last-child {
+ border-bottom: none;
+ }
+ }
+ .home-news-thumb {
+ flex-shrink: 0;
+ width: 7.2rem;
+ height: 7.2rem;
+ border-radius: 8px;
+ overflow: hidden;
+ background: #f0f0f0;
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+ }
+ .home-news-body {
+ flex: 1;
+ min-width: 0;
+ }
+ .home-news-title {
+ font-size: 1.5rem;
+ line-height: 1.4;
+ margin-bottom: 0.4rem;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ }
+ .home-news-meta {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: 1.2rem;
+ gap: 0.5rem;
+ }
+ .home-news-date {
+ flex: 1;
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ color: #999;
+ }
+ .home-news-detail {
+ flex-shrink: 0;
+ color: #999;
+ }
+ .home-trend-card--empty-inner {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ min-height: 160px;
+ .home-empty-img {
+ width: 10rem;
+ height: 10rem;
+ }
+ .home-empty-text {
+ margin-top: 0.8rem;
+ font-size: 1.4rem;
+ color: #999;
+ }
+ }
+ }
+ }
+}
+
+.news-detail-popup {
+ .news-detail-inner {
+ padding: 0 2rem 2.4rem;
+ overflow-y: auto;
+ max-height: 100%;
+ background: #fff;
+ }
+ .news-detail-drag-bar {
+ width: 3.6rem;
+ height: 4px;
+ margin: 1rem auto 1.2rem;
+ background: #e0e0e0;
+ border-radius: 2px;
+ }
+ .news-detail-header {
+ margin-bottom: 0.6rem;
+ }
+ .news-detail-source {
+ font-size: 1.2rem;
+ color: #999;
+ }
+ .news-detail-title {
+ font-size: 2rem;
+ font-weight: 600;
+ line-height: 1.35;
+ margin: 0 0 1.4rem;
+ color: #1a1a1a;
+ }
+ .news-detail-img-wrap {
+ border-radius: 12px;
+ overflow: hidden;
+ margin-bottom: 1.4rem;
+ background: #f5f5f5;
+ .news-detail-img {
+ width: 100%;
+ display: block;
+ object-fit: cover;
+ max-height: 22rem;
+ }
+ }
+ .news-detail-content {
+ font-size: 1.45rem;
+ line-height: 1.7;
+ color: #333;
+ white-space: pre-wrap;
+ word-break: break-word;
+ margin-bottom: 2rem;
+ }
+ .news-detail-close {
+ margin-top: 0.4rem;
+ height: 4.4rem;
+ font-size: 1.6rem;
+ }
}
</style>
\ No newline at end of file
--
Gitblit v1.9.3