| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842 |
- <template>
- <view class="container">
- <!-- 搜索栏 -->
- <view class="search-bar" @click="goToSearch">
- <input class="search-input" placeholder="水浒传" disabled />
- <text class="search-icon">🔍</text>
- </view>
-
- <scroll-view class="scroll-content" scroll-y>
- <!-- 轮播图 -->
- <view class="swiper-container">
- <swiper
- class="swiper"
- :indicator-dots="true"
- :autoplay="true"
- :interval="4000"
- :duration="600"
- indicator-color="rgba(255,255,255,0.5)"
- indicator-active-color="#4FC3F7"
- :circular="true"
- :previous-margin="0"
- :next-margin="0"
- >
- <swiper-item v-for="(item, index) in bannerList" :key="index" @click="handleBannerClick(item)">
- <view class="swiper-item-wrapper">
- <image class="swiper-image" :src="item.image" mode="aspectFill" :lazy-load="true" @error="handleImageError(index)"></image>
- <view class="swiper-overlay">
- <text class="swiper-title">{{ item.title }}</text>
- </view>
- </view>
- </swiper-item>
- </swiper>
- </view>
-
- <!-- 分类导航 -->
- <view class="category-nav">
- <view class="category-item" v-for="(item, index) in categories" :key="index" @click="handleCategoryClick(item, index)">
- <view class="category-icon" :style="{ backgroundColor: item.color }">
- <text class="icon-text">{{ item.icon }}</text>
- </view>
- <text class="category-text">{{ item.name }}</text>
- </view>
- </view>
-
- <!-- 今日推荐 -->
- <view class="section">
- <view class="section-header">
- <text class="section-title">今日推荐</text>
- <text class="section-more" @click.stop="goToMoreBooks('today')">更多></text>
- </view>
- <!-- 加载中 -->
- <view class="loading-state" v-if="isLoading && todayRecommend.length === 0">
- <text class="loading-text">加载中...</text>
- </view>
- <!-- 书籍列表 -->
- <view class="book-grid" v-else-if="todayRecommend.length > 0">
- <view class="book-item" v-for="(book, index) in todayRecommend" :key="book.id || index" @click="goToBookDetail(book)">
- <image class="book-cover" :src="book.image" mode="aspectFill" :lazy-load="true" @error="handleBookImageError(book, 'todayRecommend')"></image>
- <text class="book-name">{{ book.title }}</text>
- </view>
- </view>
- <!-- 空状态 -->
- <view class="empty-state" v-else>
- <text class="empty-text">暂无推荐书籍</text>
- <text class="empty-hint">请检查后端服务是否启动,数据库是否有数据</text>
- </view>
- </view>
-
- <!-- 畅销书籍 -->
- <view class="section">
- <view class="section-header">
- <text class="section-title">畅销书籍</text>
- <text class="section-more" @click.stop="goToMoreBooks('bestseller')">更多></text>
- </view>
- <!-- 加载中 -->
- <view class="loading-state" v-if="isLoading && bestsellers.length === 0">
- <text class="loading-text">加载中...</text>
- </view>
- <!-- 书籍列表 -->
- <view class="book-list" v-else-if="bestsellers.length > 0">
- <view class="book-list-item" v-for="(book, index) in bestsellers" :key="book.id || index" @click="goToBookDetail(book)">
- <image class="book-cover-small" :src="book.image" mode="aspectFill" :lazy-load="true" @error="handleBookImageError(book, 'bestsellers')"></image>
- <view class="book-info">
- <text class="book-title">{{ book.title }}</text>
- <text class="book-desc">{{ book.desc }}</text>
- <text class="book-author">{{ book.author }}</text>
- </view>
- </view>
- </view>
- <!-- 空状态 -->
- <view class="empty-state" v-else>
- <text class="empty-text">暂无畅销书籍</text>
- <text class="empty-hint">请检查后端服务是否启动,数据库是否有数据</text>
- </view>
- </view>
-
- <!-- 精品书单 -->
- <view class="section">
- <view class="section-header">
- <text class="section-title">精品书单</text>
- <text class="section-more" @click.stop="goToMoreBooks('featured')">更多></text>
- </view>
- <view class="loading-state" v-if="featuredLoading">
- <text class="loading-text">加载中...</text>
- </view>
- <scroll-view class="book-list-horizontal" scroll-x v-else-if="featuredList.length > 0">
- <view class="book-item-horizontal" v-for="(book, index) in featuredList" :key="book.id || index" @click="goToBookDetail(book)">
- <image class="book-cover-horizontal" :src="book.image" mode="aspectFill" :lazy-load="true" @error="handleBookImageError(book, 'featuredList')"></image>
- <text class="book-name-horizontal">{{ book.title }}</text>
- </view>
- </scroll-view>
- <view class="empty-state" v-else>
- <text class="empty-text">暂无精品书单</text>
- <text class="empty-hint">请检查后端服务或数据库</text>
- </view>
- </view>
-
- <!-- 更多推荐 -->
- <view class="section">
- <view class="section-header">
- <text class="section-title">更多推荐</text>
- </view>
- <view class="loading-state" v-if="moreLoading">
- <text class="loading-text">加载中...</text>
- </view>
- <view class="book-grid-two" v-else-if="moreRecommend.length > 0">
- <view class="book-item-two" v-for="(book, index) in moreRecommend" :key="book.id || index" @click="goToBookDetail(book)">
- <image class="book-cover-two" :src="book.image" mode="aspectFill" :lazy-load="true" @error="handleBookImageError(book, 'moreRecommend')"></image>
- <text class="book-title-two">{{ book.title }}</text>
- <text class="book-author-two">{{ book.author }}</text>
- </view>
- </view>
- <view class="empty-state" v-else>
- <text class="empty-text">暂无推荐书籍</text>
- <text class="empty-hint">请检查后端服务或数据库</text>
- </view>
- </view>
- </scroll-view>
- </view>
- </template>
- <script>
- import { getTodayRecommend, getBestsellers, getFeaturedList, getMoreRecommend, getBannersByCode } from '../../utils/api.js'
-
- export default {
- data() {
- // 生成高质量、高雅、大气的图书相关图片URL的函数
- const getBookImage = (index) => {
- // 使用更优雅的图书相关关键词,确保图片高雅大气
- const elegantKeywords = [
- 'classic+books+library', // 经典图书图书馆
- 'literature+books+elegant', // 文学书籍优雅
- 'ancient+books+scholarship', // 古籍学术
- 'reading+books+premium', // 阅读书籍高端
- 'bookshelf+library+grand' // 书架图书馆宏伟
- ];
- const keyword = elegantKeywords[index % elegantKeywords.length];
- // 使用 Unsplash 高质量图片,尺寸较大确保清晰度
- // 使用不同的随机数确保每次获取不同的高雅图片
- return `https://source.unsplash.com/1080x600/?${keyword}&sig=${Date.now() + index}`;
- };
-
- return {
- bannerList: [],
- categories: [
- { name: '全部分类', icon: '📄', color: '#81C784' },
- { name: '排行榜', icon: '👑', color: '#FFD54F' },
- { name: '热门书籍', icon: '🔥', color: '#E57373' },
- { name: '新书榜', icon: '📖', color: '#81C784' },
- { name: 'VIP书籍', icon: '📚', color: '#4FC3F7' }
- ],
- todayRecommend: [],
- bestsellers: [],
- featuredList: [],
- moreRecommend: [],
- isLoading: false,
- featuredLoading: false,
- moreLoading: false
- }
- },
- onLoad() {
- this.loadBanners()
- this.loadTodayRecommend()
- this.loadBestsellers()
- this.loadFeaturedList()
- this.loadMoreRecommend()
- },
- onShow() {
- // 页面显示时刷新数据
- this.loadTodayRecommend()
- this.loadBestsellers()
- this.loadFeaturedList()
- this.loadMoreRecommend()
- },
- methods: {
- async loadBanners() {
- try {
- const res = await getBannersByCode('home_banner')
- if (res && res.code === 200 && Array.isArray(res.data)) {
- this.bannerList = res.data.map(b => ({
- image: b.image,
- title: b.title || '',
- targetType: b.targetType,
- targetId: b.targetId,
- link: b.link
- }))
- }
- } catch (e) {
- console.error('加载轮播失败', e)
- }
- },
- // 加载今日推荐
- loadTodayRecommend() {
- console.log('开始加载今日推荐...')
- this.isLoading = true
- getTodayRecommend(8)
- .then((res) => {
- console.log('今日推荐API响应:', res)
- this.isLoading = false
-
- // 检查响应数据
- if (res && res.code === 200) {
- // 检查data是否存在且是数组
- if (res.data && Array.isArray(res.data) && res.data.length > 0) {
- // 处理数据格式,确保图片URL正确
- this.todayRecommend = res.data.map((book) => {
- return {
- id: book.id,
- title: book.title || '未知书名',
- image: book.image || book.cover || 'https://picsum.photos/seed/default/200/300',
- author: book.author || ''
- }
- })
- console.log('今日推荐数据加载成功,共', this.todayRecommend.length, '本')
- } else {
- console.warn('今日推荐数据为空或格式不正确:', res.data)
- this.todayRecommend = []
- }
- } else {
- console.warn('今日推荐API返回错误:', res)
- this.todayRecommend = []
- // 显示错误提示
- uni.showToast({
- title: res.message || '获取推荐失败',
- icon: 'none',
- duration: 2000
- })
- }
- })
- .catch((err) => {
- this.isLoading = false
- console.error('获取今日推荐失败:', err)
- this.todayRecommend = []
- // 显示错误提示
- uni.showToast({
- title: err.message || '网络请求失败,请检查后端服务',
- icon: 'none',
- duration: 3000
- })
- })
- },
- // 加载畅销书籍
- loadBestsellers() {
- console.log('开始加载畅销书籍...')
- this.isLoading = true
- getBestsellers(10)
- .then((res) => {
- console.log('畅销书籍API响应:', res)
- this.isLoading = false
-
- // 检查响应数据
- if (res && res.code === 200) {
- // 检查data是否存在且是数组
- if (res.data && Array.isArray(res.data) && res.data.length > 0) {
- // 处理数据格式,确保图片URL和描述正确
- this.bestsellers = res.data.map((book) => {
- return {
- id: book.id,
- title: book.title || '未知书名',
- desc: book.desc || book.brief || book.introduction || '',
- author: book.author || '',
- image: book.image || book.cover || 'https://picsum.photos/seed/default/200/300'
- }
- })
- console.log('畅销书籍数据加载成功,共', this.bestsellers.length, '本')
- } else {
- console.warn('畅销书籍数据为空或格式不正确:', res.data)
- this.bestsellers = []
- }
- } else {
- console.warn('畅销书籍API返回错误:', res)
- this.bestsellers = []
- // 显示错误提示
- uni.showToast({
- title: res.message || '获取畅销书籍失败',
- icon: 'none',
- duration: 2000
- })
- }
- })
- .catch((err) => {
- this.isLoading = false
- console.error('获取畅销书籍失败:', err)
- this.bestsellers = []
- // 显示错误提示
- uni.showToast({
- title: err.message || '网络请求失败,请检查后端服务',
- icon: 'none',
- duration: 3000
- })
- })
- },
- // 加载精品书单
- loadFeaturedList() {
- console.log('开始加载精品书单...')
- this.featuredLoading = true
- getFeaturedList(4)
- .then((res) => {
- console.log('精品书单API响应:', res)
- this.featuredLoading = false
- if (res && res.code === 200) {
- if (res.data && Array.isArray(res.data) && res.data.length > 0) {
- this.featuredList = res.data.map((book) => {
- return {
- id: book.id,
- title: book.title || '未知书名',
- image: book.image || book.cover || 'https://picsum.photos/seed/featured/200/300'
- }
- })
- console.log('精品书单加载成功,共', this.featuredList.length, '本')
- } else {
- console.warn('精品书单数据为空或格式不正确:', res.data)
- this.featuredList = []
- }
- } else {
- console.warn('精品书单API返回错误:', res)
- this.featuredList = []
- uni.showToast({
- title: res.message || '获取精品书单失败',
- icon: 'none',
- duration: 2000
- })
- }
- })
- .catch((err) => {
- this.featuredLoading = false
- console.error('获取精品书单失败:', err)
- this.featuredList = []
- uni.showToast({
- title: err.message || '网络请求失败,请检查后端服务',
- icon: 'none',
- duration: 3000
- })
- })
- },
- // 加载更多推荐书籍
- loadMoreRecommend() {
- console.log('开始加载更多推荐书籍...')
- this.moreLoading = true
- getMoreRecommend(6)
- .then((res) => {
- console.log('更多推荐API响应:', res)
- this.moreLoading = false
- if (res && res.code === 200) {
- if (res.data && Array.isArray(res.data) && res.data.length > 0) {
- this.moreRecommend = res.data.map((book) => {
- return {
- id: book.id,
- title: book.title || '未知书名',
- author: book.author || '',
- image: book.image || book.cover || 'https://picsum.photos/seed/more/200/300'
- }
- })
- console.log('更多推荐加载成功,共', this.moreRecommend.length, '本')
- } else {
- console.warn('更多推荐数据为空或格式不正确:', res.data)
- this.moreRecommend = []
- }
- } else {
- console.warn('更多推荐API返回错误:', res)
- this.moreRecommend = []
- uni.showToast({
- title: res.message || '获取更多推荐失败',
- icon: 'none',
- duration: 2000
- })
- }
- })
- .catch((err) => {
- this.moreLoading = false
- console.error('获取更多推荐失败:', err)
- this.moreRecommend = []
- uni.showToast({
- title: err.message || '网络请求失败,请检查后端服务',
- icon: 'none',
- duration: 3000
- })
- })
- },
- handleCategoryClick(item, index) {
- if (index === 0) {
- uni.navigateTo({
- url: '/pages/category/category'
- })
- } else if (index === 1) {
- uni.navigateTo({
- url: '/pages/ranking/ranking'
- })
- } else if (index === 2) {
- uni.navigateTo({
- url: '/pages/hot-books/hot-books'
- })
- } else if (index === 3) {
- uni.navigateTo({
- url: '/pages/new-books/new-books'
- })
- } else if (index === 4) {
- uni.navigateTo({
- url: '/pages/vip-books/vip-books'
- })
- }
- },
- goToBookDetail(book) {
- if (!book || !book.id) {
- uni.showToast({
- title: '书籍信息不完整',
- icon: 'none'
- })
- return
- }
- uni.navigateTo({
- url: `/pages/book-detail/book-detail?bookId=${book.id}`
- })
- },
- goToMoreBooks(type) {
- uni.navigateTo({
- url: `/pages/more-books/more-books?type=${type}`
- })
- },
- goToSearch() {
- uni.navigateTo({
- url: '/pages/search/search'
- })
- },
- handleBannerClick(item) {
- if (!item) return
- console.log('轮播图点击:', item)
- // 优先检查 targetType 和 targetId
- if (item.targetType === 'book' && item.targetId) {
- this.goToBookDetail({ id: item.targetId })
- return
- }
- if (item.targetType === 'audiobook' && item.targetId) {
- uni.navigateTo({ url: `/pages/listen-detail/listen-detail?audiobookId=${item.targetId}` })
- return
- }
- // 检查是否为外链跳转
- if (item.targetType === 'url' && item.link) {
- // H5可直接跳转
- // #ifdef H5
- window.location.href = item.link
- // #endif
- // 小程序环境提示
- // #ifdef MP-WEIXIN
- uni.showModal({
- title: '提示',
- content: '此链接需要复制后在浏览器打开',
- confirmText: '复制链接',
- success: (res) => {
- if (res.confirm) {
- uni.setClipboardData({
- data: item.link,
- success: () => {
- uni.showToast({
- title: '链接已复制',
- icon: 'success'
- })
- }
- })
- }
- }
- })
- // #endif
- // APP环境使用浏览器打开
- // #ifdef APP-PLUS
- plus.runtime.openURL(item.link)
- // #endif
- return
- }
- // 如果没有设置跳转类型但有链接,也尝试跳转(兼容旧数据)
- if (item.link && !item.targetType) {
- // #ifdef H5
- window.location.href = item.link
- // #endif
- }
- },
- handleImageError(index) {
- // 图片加载失败时使用备用图片
- const fallbackImages = [
- 'https://picsum.photos/seed/library1/1080/600',
- 'https://picsum.photos/seed/library2/1080/600',
- 'https://picsum.photos/seed/library3/1080/600',
- 'https://picsum.photos/seed/library4/1080/600',
- 'https://picsum.photos/seed/library5/1080/600'
- ];
- if (this.bannerList[index]) {
- this.bannerList[index].image = fallbackImages[index] || fallbackImages[0];
- }
- },
- handleBookImageError(book, listType) {
- // 书籍图片加载失败时使用备用图片
- book.image = 'https://picsum.photos/seed/default/200/300'
- }
- }
- }
- </script>
- <style scoped>
- .container {
- width: 100%;
- height: 100vh;
- background-color: #F5F5F5;
- display: flex;
- flex-direction: column;
- padding-top: 60px;
- box-sizing: border-box;
- }
-
- .search-bar {
- position: relative;
- padding: 20rpx 30rpx;
- background-color: #FFFFFF;
- }
-
- .search-input {
- width: 100%;
- height: 70rpx;
- background-color: #F5F5F5;
- border-radius: 35rpx;
- padding: 0 80rpx 0 30rpx;
- font-size: 28rpx;
- color: #333333;
- }
-
- .search-icon {
- position: absolute;
- right: 50rpx;
- top: 50%;
- transform: translateY(-50%);
- font-size: 32rpx;
- }
-
- .scroll-content {
- flex: 1;
- width: 100%;
- height: 0;
- overflow: hidden;
- }
-
- .swiper-container {
- width: 100%;
- height: 360rpx;
- margin-bottom: 20rpx;
- background-color: #F5F5F5;
- border-radius: 0;
- overflow: hidden;
- }
-
- .swiper {
- width: 100%;
- height: 100%;
- }
-
- .swiper-item-wrapper {
- width: 100%;
- height: 100%;
- position: relative;
- }
-
- .swiper-image {
- width: 100%;
- height: 100%;
- display: block;
- object-fit: cover;
- }
-
- .swiper-overlay {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- background: linear-gradient(to top, rgba(0,0,0,0.6), transparent);
- padding: 60rpx 40rpx 30rpx;
- }
-
- .swiper-title {
- font-size: 36rpx;
- font-weight: bold;
- color: #FFFFFF;
- text-shadow: 0 2rpx 8rpx rgba(0,0,0,0.5);
- }
-
- .category-nav {
- display: flex;
- justify-content: space-around;
- padding: 40rpx 20rpx;
- background-color: #FFFFFF;
- margin-bottom: 20rpx;
- }
-
- .category-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- }
-
- .category-icon {
- width: 90rpx;
- height: 90rpx;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 15rpx;
- }
-
- .icon-text {
- font-size: 44rpx;
- }
-
- .category-text {
- font-size: 24rpx;
- color: #333333;
- }
-
- .section {
- padding: 40rpx 30rpx;
- background-color: #FFFFFF;
- margin-bottom: 20rpx;
- }
-
- .section-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 30rpx;
- }
-
- .section-title {
- font-size: 36rpx;
- font-weight: bold;
- color: #333333;
- }
-
- .section-more {
- font-size: 28rpx;
- color: #999999;
- }
-
- .book-grid {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- }
-
- .book-item {
- width: 160rpx;
- margin-bottom: 30rpx;
- }
-
- .book-cover {
- width: 160rpx;
- height: 220rpx;
- border-radius: 8rpx;
- margin-bottom: 15rpx;
- box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
- background-color: #F5F5F5;
- }
-
- .book-name {
- font-size: 24rpx;
- color: #333333;
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
-
- .book-list {
- display: flex;
- flex-direction: column;
- }
-
- .book-list-item {
- display: flex;
- margin-bottom: 30rpx;
- align-items: center;
- }
-
- .book-cover-small {
- width: 120rpx;
- height: 160rpx;
- border-radius: 8rpx;
- margin-right: 20rpx;
- flex-shrink: 0;
- box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
- background-color: #F5F5F5;
- }
-
- .book-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- min-width: 0;
- }
-
- .book-title {
- font-size: 32rpx;
- font-weight: bold;
- color: #333333;
- margin-bottom: 10rpx;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
-
- .book-desc {
- font-size: 26rpx;
- color: #666666;
- line-height: 1.4;
- margin-bottom: 10rpx;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-line-clamp: 2;
- overflow: hidden;
- }
-
- .book-author {
- font-size: 24rpx;
- color: #999999;
- }
-
- .book-list-horizontal {
- white-space: nowrap;
- width: 100%;
- height: 280rpx;
- }
-
- .book-item-horizontal {
- display: inline-block;
- width: 160rpx;
- margin-right: 20rpx;
- vertical-align: top;
- }
-
- .book-cover-horizontal {
- width: 160rpx;
- height: 220rpx;
- border-radius: 8rpx;
- margin-bottom: 15rpx;
- box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
- background-color: #F5F5F5;
- }
-
- .book-name-horizontal {
- font-size: 24rpx;
- color: #333333;
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
-
- .book-grid-two {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- }
-
- .book-item-two {
- width: calc(50% - 10rpx);
- margin-bottom: 30rpx;
- }
-
- .book-cover-two {
- width: 100%;
- height: 280rpx;
- border-radius: 8rpx;
- margin-bottom: 15rpx;
- box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
- background-color: #F5F5F5;
- }
-
- .book-title-two {
- font-size: 28rpx;
- font-weight: bold;
- color: #333333;
- margin-bottom: 8rpx;
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
-
- .book-author-two {
- font-size: 24rpx;
- color: #999999;
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
-
- .empty-state {
- padding: 60rpx 0;
- text-align: center;
- }
-
- .empty-text {
- font-size: 28rpx;
- color: #999999;
- display: block;
- margin-bottom: 10rpx;
- }
-
- .empty-hint {
- font-size: 24rpx;
- color: #CCCCCC;
- display: block;
- }
-
- .loading-state {
- padding: 60rpx 0;
- text-align: center;
- }
-
- .loading-text {
- font-size: 28rpx;
- color: #999999;
- }
- </style>
|