|
|
<template> <view class="lending-container"> <view class="tab-sticky"> <my-tabs :tabData="tabData" :defaultIndex="currentIndex" :config="{ textColor: '#333' }" @tabClick="tabClick" /> </view>
<swiper class="swiper" :current="currentIndex" :style="{ height: currentSwiperHeight + 'px' }" @animationfinish="onSwiperEnd" @change="onSwiperChange" > <swiper-item v-for="(tabItem, idx) in tabData" :key="idx"> <view class="list-wrapper"> <!-- 首次加载 --> <uni-load-more status="loading" v-if="loadingMap[tabItem.status]" /> <!-- 空数据 --> <view class="empty" v-else-if="!listData[tabItem.status] || listData[tabItem.status].length === 0"> 暂无{{ tabItem.label }}记录 </view> <!-- 列表 --> <block v-else> <lending-list-item :class="'list-item-' + tabItem.status" v-for="(item, index) in listData[tabItem.status]" :key="index" :data="item" :ranking="index + 1" /> </block>
<!-- 上拉加载更多 --> <uni-load-more v-if="listData[tabItem.status] && listData[tabItem.status].length > 0 && !loadingMap[tabItem.status]" :status="loadMoreStatusMap[tabItem.status]" /> </view> </swiper-item> </swiper> </view></template>
<script>import { FetchInitScreenSetting } from '@/api/user';import { FetchHistoryloan, FetchRdloanlist } from '@/api/book';import myTabs from "@/components/my-tabs/my-tabs.vue";import lendingListItem from "@/components/lending-list-item/lending-list-item.vue";
export default { components: { myTabs, lendingListItem }, data() { return { screenConfig: {}, tabData: [ { label: "全部", status: "all", apiStatus: -1 }, { label: "在借中", status: "lending", apiStatus: 0 }, // { label: "将过期", status: "expiring", apiStatus: 1 },
// { label: "已过期", status: "expired", apiStatus: 2 },
], currentIndex: 0, listData: {}, loadingMap: {}, loadMoreStatusMap: {}, pageMap: {}, sizeMap: {}, hasMoreMap: {}, swiperHeightData: {}, currentSwiperHeight: 400, currentPageScrollTop: 0, isRefreshing: false }; },
onLoad() { this.getScreenSetting(); this.initDataStructure(); },
onShow() { const tabIndex = uni.getStorageSync('switch_tab_index'); if (tabIndex !== undefined && tabIndex !== '') { this.currentIndex = Number(tabIndex); uni.removeStorageSync('switch_tab_index'); } },
onPullDownRefresh() { this.isRefreshing = true; const currentTab = this.getCurrentTab(); this.refreshList(currentTab.status); },
onReachBottom() { const currentTab = this.getCurrentTab(); this.loadMoreList(currentTab.status); },
onPageScroll(res) { this.currentPageScrollTop = res.scrollTop; },
methods: { async getScreenSetting() { try { const res = await FetchInitScreenSetting({ libcode: '1201' }); const data = res.data; this.screenConfig = { thirdUrl: data.open_lib_http?.context || '', thirdAppid: data.open_lib_appId?.context || '', thirdSecret: data.open_lib_secret?.context || '', sm4Key: data.sm4_key?.context || '' }; } catch (err) { console.error('获取配置失败:', err); } },
// 获取 在借中 列表(字段已对齐)
async getRealBorrowList(statusKey) { this.loadingMap[statusKey] = true; try { const rdid = uni.getStorageSync('currentReaderCard'); const params = { ...this.screenConfig, rdid }; const res = await FetchRdloanlist(params); const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; let loanList = result.loanlist || [];
// 对齐字段:loandate → loantime,returndate → returntime
loanList = loanList.map(item => { const loantime = item.loandate || ''; const returntime = item.returndate || ''; const now = new Date(); const returnDate = new Date(returntime); const diffDay = Math.ceil((returnDate - now) / (1000 * 3600 * 24));
let returnBook = 0; if (diffDay < 0) { returnBook = 3; } else if (diffDay <= 3) { returnBook = 1; } else { returnBook = 0; }
return { ...item, loantime, returntime, startTime: loantime, returnTime: returntime, returnBook }; }); console.log('当前借阅', loanList); this.listData['lending'] = loanList; this.listData['expiring'] = loanList.filter(i => i.returnBook === 1); this.listData['expired'] = loanList.filter(i => i.returnBook === 3);
this.hasMoreMap[statusKey] = false; this.loadMoreStatusMap[statusKey] = "no-more";
} catch (err) { console.error('获取在借列表失败', err); this.listData[statusKey] = []; } finally { this.loadingMap[statusKey] = false; this.isRefreshing = false; uni.stopPullDownRefresh(); setTimeout(() => this.calcSwiperHeight(statusKey), 0); } },
// 获取 全部/历史 列表
async getHistoryList(statusKey) { this.loadingMap[statusKey] = true; try { const rdid = uni.getStorageSync('currentReaderCard'); const params = { ...this.screenConfig, rdid, logtype:'30002' }; const res = await FetchHistoryloan(params); const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data; let loanList = result.hloanlist || [];
loanList = loanList.map(item => { return { ...item, returnTime: item.returntime || '', startTime: item.loantime || item.optime || '', returnBook: 2 }; }); console.log('历史借阅', loanList); this.listData[statusKey] = loanList; this.hasMoreMap[statusKey] = false; this.loadMoreStatusMap[statusKey] = "no-more";
} catch (err) { console.error('获取历史列表失败', err); this.listData[statusKey] = []; } finally { this.loadingMap[statusKey] = false; this.isRefreshing = false; uni.stopPullDownRefresh(); setTimeout(() => this.calcSwiperHeight(statusKey), 0); } },
initDataStructure() { this.tabData.forEach(tab => { const key = tab.status; this.$set(this.listData, key, []); this.$set(this.loadingMap, key, true); this.$set(this.loadMoreStatusMap, key, ""); this.$set(this.pageMap, key, 1); this.$set(this.sizeMap, key, 10); this.$set(this.hasMoreMap, key, true); }); },
getCurrentTab() { return this.tabData[this.currentIndex]; },
async getListData(statusKey) { if (statusKey === 'all') { await this.getHistoryList(statusKey); } if (statusKey === 'lending') { await this.getRealBorrowList(statusKey); } if (statusKey === 'expiring' || statusKey === 'expired') { await this.getRealBorrowList('lending'); this.loadingMap[statusKey] = false; } },
loadMoreList(statusKey) { this.loadMoreStatusMap[statusKey] = "no-more"; },
refreshList(statusKey) { this.getListData(statusKey); },
calcSwiperHeight(statusKey) { const selector = `.list-item-${statusKey}`; const query = uni.createSelectorQuery().in(this); query.selectAll(selector).boundingClientRect((res) => { let total = 200; if (res?.length) { total = res.reduce((t, h) => t + h.height + 8, 0); } this.swiperHeightData[statusKey] = total; this.currentSwiperHeight = total; }).exec(); },
tabClick(index) { this.currentIndex = index; const tab = this.getCurrentTab(); if (this.currentPageScrollTop > 100) { uni.pageScrollTo({ scrollTop: 0, duration: 100 }); } this.getListData(tab.status); },
onSwiperChange(e) { if (e.detail.source === "touch") { this.currentIndex = e.detail.current; } },
onSwiperEnd() { const tab = this.getCurrentTab(); this.getListData(tab.status); },
goToDetail(item) { uni.navigateTo({ url: `/subpkg/pages/book-detail/book-detail?isbn=${item.isbn}` }); } }};</script>
<style lang="scss" scoped>.lending-container { background-color: #f5f5f5; min-height: 100vh;
.tab-sticky { position: sticky; top: 0; z-index: 99; background: #fff; }
.swiper { width: 100%; min-height: 300px; }
.swiper-item { width: 100%; height: 100%; }
.list-wrapper { padding: 10px; box-sizing: border-box; }
.empty { text-align: center; padding: 100px 0; color: #999; font-size: 14px; }}::v-deep .uni-load-more{ height: auto !important;}</style>
|