140 lines
3.0 KiB
Vue
140 lines
3.0 KiB
Vue
<template>
|
|
<z-paging ref="paging" v-model="bookList" auto-show-back-to-top class="my-book-page" @query="loadBookList">
|
|
<template #top>
|
|
<!-- 自定义导航栏 -->
|
|
<nav-bar :title="$t('book.myBook')"></nav-bar>
|
|
</template>
|
|
|
|
<!-- 书籍列表 -->
|
|
<view v-if="(bookList && bookList.length > 0)" class="book-list">
|
|
<BookCard
|
|
v-for="item in bookList"
|
|
:key="item.id"
|
|
:book="item"
|
|
@click="goToDetail(item.id)"
|
|
@read="goToReader(item.id)"
|
|
@listen="goToListen(item.id)"
|
|
@review="goToReview(item.id)"
|
|
/>
|
|
</view>
|
|
|
|
<!-- 空状态 -->
|
|
<view v-else-if="!loading && !firstLoad" class="empty-state">
|
|
<image src="@/static/null_img.png" mode="aspectFit" />
|
|
<text class="empty-text">{{ $t('book.nullText') }}</text>
|
|
<wd-button type="primary" @click="goToBuy">
|
|
{{ $t('book.choose') }}
|
|
</wd-button>
|
|
</view>
|
|
</z-paging>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { bookApi } from '@/api/modules/book'
|
|
import type { IBook } from '@/types/book'
|
|
import BookCard from '@/components/book/BookCard.vue'
|
|
|
|
const { t } = useI18n()
|
|
const paging = ref<any>()
|
|
|
|
// 数据状态
|
|
const bookList = ref<IBook[]>([])
|
|
const loading = ref(false)
|
|
const firstLoad = ref(true)
|
|
|
|
// 加载书单列表
|
|
async function loadBookList(pageNo: number, pageSize: number) {
|
|
loading.value = true
|
|
try {
|
|
const res = await bookApi.getMyBooks(pageNo, pageSize)
|
|
paging.value.complete(res.page.records)
|
|
} catch (error) {
|
|
paging.value.complete(false)
|
|
console.error('Failed to load book list:', error)
|
|
} finally {
|
|
firstLoad.value = false
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// 页面跳转
|
|
function goToDetail(bookId: number) {
|
|
uni.navigateTo({
|
|
url: `/pages/book/detail?id=${bookId}`
|
|
})
|
|
}
|
|
|
|
function goToReader(bookId: number) {
|
|
uni.navigateTo({
|
|
url: `/pages/book/reader?isBuy=1&bookId=${bookId}`
|
|
})
|
|
}
|
|
|
|
function goToListen(bookId: number) {
|
|
uni.navigateTo({
|
|
url: `/pages/book/listen/index?bookId=${bookId}`
|
|
})
|
|
}
|
|
|
|
function goToReview(bookId: number) {
|
|
uni.navigateTo({
|
|
url: `/pages/book/review?bookId=${bookId}&page=0`
|
|
})
|
|
}
|
|
|
|
function goToBuy() {
|
|
uni.switchTab({
|
|
url: '/pages/book/index'
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.my-book-page {
|
|
background: #f7faf9;
|
|
min-height: 100vh;
|
|
|
|
.book-scroll {
|
|
.book-list {
|
|
padding: 0 20rpx 10rpx;
|
|
}
|
|
}
|
|
|
|
.load-tip {
|
|
font-size: 30rpx;
|
|
text-align: center;
|
|
padding: 40rpx 0;
|
|
color: #ccc;
|
|
}
|
|
|
|
.empty-state {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding-top: 200rpx;
|
|
|
|
image {
|
|
width: 400rpx;
|
|
height: 300rpx;
|
|
margin-bottom: 40rpx;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
margin-bottom: 50rpx;
|
|
}
|
|
|
|
button {
|
|
width: 180rpx;
|
|
height: 60rpx;
|
|
font-size: 28rpx;
|
|
border-radius: 50rpx;
|
|
}
|
|
}
|
|
}
|
|
</style>
|