<template>
|
<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> -->
|
<!-- <van-swipe class="home_logo" :autoplay="3000" indicator-color="white">
|
<van-swipe-item><img src="@/assets/imgs/home/Slider-1.jpg" alt=""></van-swipe-item>
|
<van-swipe-item><img src="@/assets/imgs/home/Slider-2.jpg" alt=""></van-swipe-item>
|
<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> -->
|
<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> -->
|
|
|
<div class="login_buts flex justify-between pl-10 pr-10 pt-10"
|
v-if="!(userStore.userInfo && userStore.userInfo.token)">
|
<div class="login_but_z text-center" @click="toPage('/register')">{{ $t('register') }}</div>
|
<div class="login_but_d text-center" @click="toPage('/login')">{{ $t('登录') }}</div>
|
</div>
|
|
<!-- 轮播图:使用本地两张图片,带圆角 -->
|
<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>
|
<!-- <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">
|
<img :src="value.img" alt="" class="swipe-item-img">
|
</van-swipe-item>
|
<template #indicator="{ active, total }">
|
<div class="custom-indicator"><span>{{ active + 1 }}</span>/{{ total }}</div>
|
</template>
|
</van-swipe>
|
|
<div style="width:24rem">
|
<van-swipe class="home_swipe_2" :autoplay="2000">
|
<van-swipe-item v-for="value in swipe2" :key="value.key" class="flex justify-center items-center">
|
<img :src="value.img" alt="" class="swipe-item-img">
|
</van-swipe-item>
|
<template #indicator="{ active, total }">
|
<div class="custom-indicator flex justify-center items-center">
|
<div v-for="value in total" :key="value" class="ml-1"
|
:class="active + 1 === value ? 'active' : ''">
|
</div>
|
</div>
|
</template>
|
</van-swipe>
|
|
<div class="purchase mt-7 font-bold flex justify-between items-center">
|
{{ $t('购买加密货币') }}
|
<van-icon name="arrow" />
|
</div>
|
</div>
|
</div> -->
|
|
<!-- 列表区: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"
|
v-for="item in popupNewsList" :key="item.id">
|
<div class="w-350 p-20 box-border popup_news">
|
<div class="font-700 text-center font-28 textColor">{{ item.title }}</div>
|
<div class="flex justify-center mt-30" v-if="item.imgUrl"><img :src="`${item.imgUrl}`"
|
class="w-200 h-200" alt="" /></div>
|
<div class="py-10 textColor content-title" v-html="item.content"></div>
|
<van-button color="#1194F7" class="w-full h-40 rounded-full" type="info" @click="closePopNotice(item)">
|
{{ $t('我知道了') }}
|
</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, 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, _getUsHeadNews } from '@/service/user.api'
|
import { useStore } from "vuex";
|
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) {
|
setStorage('symbol', 'btcusdt');
|
}
|
const userStore = useUserStore()
|
const { t } = useI18n()
|
const router = useRouter()
|
const store = useStore();
|
|
const tabbers = [
|
{ 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,
|
}).then(res => {
|
announceList.value = res
|
})
|
|
// 获取弹出新闻
|
const popupNewsList = ref([])
|
_getPopupNews({
|
language: useI18n().locale.value,
|
}).then(res => {
|
if (res && res.length > 0) {
|
let list = res
|
list.forEach(item => {
|
item.showPopUp = true
|
})
|
popupNewsList.value = list
|
}
|
})
|
// 关闭弹窗新闻
|
const closePopNotice = (item) => {
|
item.showPopUp = false
|
}
|
|
// 跳转公告详情
|
const toAnnounceDetail = (announceId) => {
|
if (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) => {
|
if (!path) return
|
|
// 如果路径包含 "http",则作为外链跳转
|
if (path && (path.startsWith('http://') || path.startsWith('https://'))) {
|
window.open(path, '_blank');
|
return;
|
}
|
|
router.push(path)
|
}
|
|
// 轮播图数据
|
const swipe1 = ref([
|
{ key: 1, img: new URL('@/assets/imgs/home/home_1.png', import.meta.url) },
|
{ key: 2, img: new URL('@/assets/imgs/home/home_2.png', import.meta.url) },
|
{ key: 3, img: new URL('@/assets/imgs/home/home_3.png', import.meta.url) },
|
])
|
const swipe2 = ref([
|
{ key: 1, img: new URL('@/assets/imgs/home/home_1.png', import.meta.url) },
|
{ key: 2, img: new URL('@/assets/imgs/home/home_2.png', import.meta.url) },
|
{ 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(() => {
|
})
|
|
if (!(list instanceof Array)) {
|
return
|
}
|
|
// 通过关键字进行筛选
|
if (key.value) {
|
qList.value = list.filter(item => {
|
return item.symbol_data.toLowerCase().includes(key.value.toLowerCase()) || item.name.toLowerCase().includes(key.value.toLowerCase())
|
})
|
} else {
|
qList.value = list
|
}
|
qListCope.value = list; // 备份数据
|
// HOT COINS 取前 8 条
|
hotCoinsList.value = (list || []).slice(0, 8)
|
|
if (timeout.value) {
|
clearTimeout(timeout.value)
|
}
|
timeout.value = setTimeout(async () => {
|
await fetchQList()
|
}, TIME_OUT)
|
}
|
fetchQList()
|
|
// 搜索
|
const onSearch = (val) => {
|
key.value = val
|
|
if (!val) {
|
qList.value = qListCope.value
|
return
|
}
|
let newList = qListCope.value.filter(item => {
|
return item.symbol_data.toLowerCase().includes(val.toLowerCase()) || item.name.toLowerCase().includes(val.toLowerCase())
|
})
|
qList.value = newList
|
}
|
|
onMounted(() => {
|
fetchUsHeadNews()
|
})
|
onBeforeUnmount(() => {
|
if (timeout.value) {
|
clearTimeout(timeout.value)
|
}
|
})
|
//#endregion----------------------------------------------
|
|
</script>
|
|
<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;
|
width: 100%;
|
padding: 1rem 1rem 10rem 1rem;
|
// $log-c: #282828;
|
$tab-c: #888;
|
$inp-c: #999;
|
$crd-b: #f7f7f7;
|
.popup_news{
|
font-size: 1.8rem;
|
}
|
|
/* 首页轮播图(BlueWhale 风格) */
|
.home_banner {
|
position: relative;
|
width: 100%;
|
margin: 12px auto;
|
border-radius: 12px;
|
overflow: hidden;
|
background: $crd-b;
|
}
|
|
.home_banner_swipe {
|
width: 100%;
|
border-radius: 12px;
|
}
|
|
.home_banner_item {
|
width: 100%;
|
border-radius: 12px;
|
overflow: hidden;
|
}
|
|
.home_banner_img {
|
width: 100%;
|
height: auto;
|
display: block;
|
vertical-align: top;
|
border-radius: 12px;
|
}
|
|
.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 {
|
width: 48rem;
|
margin: 2rem auto 1rem;
|
border-radius: 1rem;
|
|
img {
|
width: 100%;
|
}
|
}
|
|
.logo_text {
|
color: $log-c;
|
font-size: 2rem;
|
}
|
|
.logo_text_small {
|
color: $inp-c;
|
font-size: 1.5rem;
|
}
|
|
.login_buts {
|
width: 100%;
|
|
&>div {
|
width: 21rem;
|
height: 5rem;
|
line-height: 5rem;
|
border-radius: 2.5rem;
|
font-size: 1.8rem;
|
color: $log-c;
|
}
|
|
.login_but_z {
|
background: $crd-b;
|
}
|
|
.login_but_d {
|
background: $bg_yellow;
|
}
|
}
|
|
.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%;
|
color: $tab-c;
|
font-size: 1.6rem;
|
|
.grid_item_img {
|
width: 100%;
|
|
img {
|
width: 5.8rem;
|
}
|
}
|
}
|
}
|
|
|
.home_swipe_1,
|
.home_swipe_2 {
|
width: 24rem;
|
border-radius: 1rem;
|
}
|
|
.home_swipe_1 {
|
.van-swipe-item {
|
height: 23rem;
|
background-color: $crd-b;
|
|
.swipe-item-img {
|
width: 100%;
|
}
|
}
|
|
.custom-indicator {
|
position: absolute;
|
left: 5px;
|
bottom: 5px;
|
padding: 2px 5px;
|
font-size: 1.8rem;
|
background: rgba(255, 255, 255, 0.5);
|
color: $inp-c;
|
|
span {
|
color: $log-c;
|
}
|
}
|
}
|
|
.home_swipe_2 {
|
.van-swipe-item {
|
height: 15rem;
|
background-color: $crd-b;
|
|
.swipe-item-img {
|
width: 100%;
|
}
|
}
|
|
.custom-indicator {
|
position: absolute;
|
right: 5px;
|
top: 1rem;
|
padding: 2px 5px;
|
|
div {
|
background: $inp-c;
|
width: 0.6rem;
|
height: 0.6rem;
|
border-radius: 0.3rem;
|
transition: 0.3s all;
|
}
|
|
.active {
|
background: $bg_yellow;
|
width: 2rem;
|
}
|
}
|
}
|
|
.purchase {
|
color: $log-c;
|
background: $crd-b;
|
border-radius: 1rem;
|
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>
|