图书馆小程序
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.
 
 
 
 
 

148 lines
3.5 KiB

<template>
<view class="container">
<!-- 图书列表 -->
<view class="list-box">
<book-list-item
v-for="(item, index) in bookList"
:key="index"
:data="item"
:ranking="index + 1"
@click="goToDetail(item)"
/>
</view>
<!-- 加载提示 -->
<view class="load-tip" v-if="loading">加载中...</view>
<view class="load-tip" v-if="noMore">没有更多了</view>
</view>
</template>
<script>
import bookListItem from "@/components/book-list-item/book-list-item.vue";
import { FetchInitScreenBookRecommend } from '@/api/book';
import config from '@/utils/config';
export default {
components: {
bookListItem
},
data() {
return {
bookList: [],
loading: false,
noMore: false,
baseUrl: config.baseUrl
};
},
onLoad() {
this.getBookRecommendList();
},
onPullDownRefresh() {
this.refresh();
},
methods: {
urlToBase64(url) {
return new Promise((resolve, reject) => {
uni.request({
url,
method: 'GET',
responseType: 'arraybuffer',
success: (res) => {
try {
const buffer = new Uint8Array(res.data);
let binary = '';
for (let i = 0; i < buffer.length; i++) {
binary += String.fromCharCode(buffer[i]);
}
const base64 = uni.arrayBufferToBase64(res.data);
const dataUri = 'data:image/jpeg;base64,' + base64;
resolve(dataUri);
} catch (e) {
reject(e);
}
},
fail: reject
});
});
},
// 刷新
refresh() {
this.bookList = [];
this.noMore = false;
this.getBookRecommendList();
},
async getBookRecommendList() {
this.loading = true;
try {
const res = await FetchInitScreenBookRecommend({ libcode: config.LIB_CODE });
let books = res.data || [];
// 1. 先显示列表(图片为空,显示默认图)
books = books.map(item => {
item.base64Cover = '';
return item;
});
this.bookList = books;
this.noMore = true;
this.loading = false;
uni.stopPullDownRefresh();
// 2. 延迟一点点,等页面渲染完
setTimeout(() => {
this.loadImagesOneByOne(); // 挨个加载图片
}, 200);
} catch (err) {
console.error(err);
this.loading = false;
uni.stopPullDownRefresh();
}
},
async loadImagesOneByOne() {
for (let i = 0; i < this.bookList.length; i++) {
let item = this.bookList[i];
if (!item.imgPath) continue;
// 加载当前这张
const url = this.baseUrl + '/api/fileRelevant/getImg?imgType=2&imgId=' + item.imgPath;
const base64 = await this.urlToBase64(url);
if (base64) {
item.base64Cover = base64;
this.$set(this.bookList, i, item); // 强制更新视图
}
}
},
goToDetail(item) {
uni.navigateTo({
url: "/subpkg/pages/book-detail/book-detail?bookData=" + encodeURIComponent(JSON.stringify(item)) + "&fromRecommend=true"
})
},
}
};
</script>
<style lang="scss" scoped>
.container {
padding: 10px;
background-color: #f5f5f5;
min-height: 100vh;
}
.list-box {
display: flex;
flex-direction: column;
gap: 8px;
}
.load-tip {
text-align: center;
padding: 15px;
font-size: 14px;
color: #999;
}
</style>