You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
8.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="library-container">
<view class="search-bar">
<u-search
placeholder="书名/作者"
v-model="keyword"
:show-action="true"
action-text="搜索"
bg-color="#f5f5f5"
border-color="#e0e0e0"
@search="searchBooks"
@clear="clearSearch">
</u-search>
</view>
<view class="tabs-container">
<u-tabs
:list="tabsList"
:is-scroll="true"
:current="currentTab"
@change="tabChange"
active-color="#73685c"
:loading="tabsList.length <= 1">
</u-tabs>
</view>
<view class="book-list">
<!-- 加载状态 -->
<view v-if="loading" class="loading-container">
<view class="loading-text">加载中...</view>
</view>
<!-- 空状态 -->
<view v-else-if="bookList.length === 0" class="empty-container">
<view class="empty-text">暂无图书数据</view>
</view>
<!-- 图书列表 -->
<view v-else>
<view v-for="book in bookList" :key="book.id" class="book-card">
<view class="book-item">
<view class="book-cover">
<u-image :src="book.image" width="180rpx" height="240rpx" border-radius="8"></u-image>
</view>
<view class="book-info">
<text class="book-title">{{ book.title || '暂无标题' }}</text>
<text class="book-author">{{ book.author || '暂无作者' }}</text>
<text class="book-publisher">{{ (book.publisher || '暂无') }} · {{ book.year || '暂无' }}</text>
<view class="tags-container">
<u-tag v-for="(tag, index) in book.tags" :key="index" :text="tag.text" :type="tag.type"
size="mini" shape="circle" mode="light" />
</view>
</view>
</view>
<view class="card-footer">
<view class="detail-button" @click="viewDetails(book.id)"></view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import uSearch from '@/uview-ui/components/u-search/u-search.vue';
import uTabs from '@/uview-ui/components/u-tabs/u-tabs.vue';
import uImage from '@/uview-ui/components/u-image/u-image.vue';
import uTag from '@/uview-ui/components/u-tag/u-tag.vue';
export default {
components: {
uSearch,
uTabs,
uImage,
uTag
},
data() {
return {
keyword: '',
currentTab: 0,
loading: false,
currentPage: 1,
totalPages: 1,
hasMore: true,
tabsList: [{
name: '全部',
value: 'all',
id: 'all'
}],
bookList: []
}
},
onLoad() {
this.loadCategories();
},
onReachBottom() {
if (this.hasMore && !this.loading) {
this.loadMore();
}
},
methods: {
// 加载分类数据
loadCategories() {
this.$u.api.bookOther().then(res => {
if (res && res.category) {
// 构建分类列表,第一个是"全部"
const categories = [{
name: '全部',
value: 'all',
id: 'all'
}];
// 处理返回的分类数据(对象格式:{id: name}
// if (typeof res.category === 'object' && !Array.isArray(res.category)) {
// Object.keys(res.category).forEach(categoryId => {
// const categoryName = res.category[categoryId];
// categories.push({
// name: categoryName,
// value: categoryName,
// id: categoryId
// });
// });
// }
res.category.map((item,index) => {
console.log(item,index)
categories.push({
name: item,
value: item,
id: index
});
});
this.tabsList = categories;
console.log('设置分类列表:', this.tabsList);
}
}).catch(err => {
console.error('获取分类失败:', err);
// 如果获取分类失败,使用默认分类
this.tabsList = [{
name: '全部',
value: 'all',
id: 'all'
}];
}).finally(() => {
// 分类加载完成后,加载图书列表
this.loadBookList();
});
},
// 加载图书列表
loadBookList() {
this.loading = true;
const params = {
page: this.currentPage,
limit: 20
};
// 添加搜索关键词
if (this.keyword.trim()) {
params.keyword = this.keyword.trim();
}
// 添加分类筛选
if (this.currentTab > 0 && this.tabsList[this.currentTab]) {
params.category = this.tabsList[this.currentTab].name;
console.log('使用分类筛选:', this.tabsList[this.currentTab]);
}
console.log('请求参数:', params);
this.$u.api.bookIndex(params).then(res => {
// 处理返回的数据结构
const bookData = res || {};
const newBooks = (bookData.data || []).map(book => {
return {
id: book.id,
title: book.title || '暂无标题',
author: book.author || '暂无作者',
publisher: book.publisher || '暂无',
year: book.publish_year || '暂无',
image: book.cover ? book.cover.url : '',
tags: [
{
text: book.category || '未分类',
type: 'primary'
},
{
text: `ISBN: ${book.isbn || '暂无'}`,
type: 'info'
}
]
};
});
// 如果是第一页,替换数据;否则追加数据
if (this.currentPage === 1) {
this.bookList = newBooks;
} else {
this.bookList = [...this.bookList, ...newBooks];
}
// 设置分页信息
this.currentPage = bookData.current_page || 1;
this.totalPages = bookData.last_page || 1;
this.hasMore = this.currentPage < this.totalPages;
}).catch(err => {
console.error('获取图书列表失败:', err);
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
});
}).finally(() => {
this.loading = false;
});
},
// 搜索图书
searchBooks() {
console.log('搜索关键词:', this.keyword);
this.currentPage = 1;
// 搜索时重置分类选择
this.currentTab = 0;
this.loadBookList();
},
// 清空搜索
clearSearch() {
console.log('清空搜索');
this.keyword = '';
this.currentPage = 1;
this.currentTab = 0;
this.loadBookList();
},
// 分类切换
tabChange(index) {
console.log('切换到分类:', index, this.tabsList[index]);
this.currentTab = index;
this.currentPage = 1;
this.loadBookList();
},
// 查看详情
viewDetails(id) {
console.log('View details for book ID:', id);
uni.navigateTo({
url: `/packages/library/detail?id=${id}`
});
},
// 加载更多数据
loadMore() {
if (this.hasMore && !this.loading) {
this.currentPage += 1;
this.loadBookList();
}
}
}
}
</script>
<style lang="scss" scoped>
.library-container {
background-color: #f5f5f5;
min-height: 100vh;
}
.search-bar {
padding: 20rpx 30rpx;
background-color: #fff;
border-bottom: 1rpx solid #f0f0f0;
}
.tabs-container {
background-color: #fff;
border-bottom: 1rpx solid #f0f0f0;
}
.book-list {
padding: 20rpx;
}
.loading-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 400rpx;
}
.loading-text {
font-size: 28rpx;
color: #999;
}
.empty-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 400rpx;
}
.empty-text {
font-size: 28rpx;
color: #999;
}
.book-card {
background-color: #fff;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
}
.book-item {
display: flex;
margin-bottom: 20rpx;
}
.book-cover {
margin-right: 30rpx;
flex-shrink: 0;
}
.book-info {
display: flex;
flex-direction: column;
justify-content: space-between;
flex: 1;
}
.book-title {
font-size: 34rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.book-author,
.book-publisher {
font-size: 26rpx;
color: #666;
margin-bottom: 10rpx;
}
.tags-container {
display: flex;
flex-wrap: wrap;
gap: 10rpx;
margin-top: 10rpx;
}
.card-footer {
display: flex;
justify-content: center;
margin-top: 20rpx;
padding-top: 20rpx;
border-top: 1rpx solid #eee;
}
.detail-button {
height: 60rpx;
line-height: 60rpx;
display: inline-block;
padding: 0 160rpx;
border-radius: 40rpx;
color: #fff;
font-size: 30rpx;
background-image: linear-gradient(to right, #6a7dfe, #12099a);
text-align: center;
}
</style>