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 b2c73ec..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('recharge'), 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