|
|
<template> <view style="background-color: #fff; padding-bottom:5px;"> <view class="my-search-container"> <view class="my-search-wrapper"> <picker mode="selector" :range="rangeText" :value="selectIndex" @change="onPickerChange" class="picker-select" > <view class="picker-display"> {{ selectValueText || '请选择分类' }} <uni-icons type="arrowdown" size="14" color="#999" style="margin-left: 4px;" /> </view> </picker> <uni-search-bar class="my-search-bar" @confirm="onSearch" @focus="onFocus" @blur="onBlur" @clear="onClear" @cancel="onCancel" @input="onInput" cancelButton="none" bgColor="#f7f7f7" v-model="value" placeholder="请输入搜索内容" > <uni-icons slot="clearIcon" type="clear" color="#999999" /> </uni-search-bar> </view>
<view class="search-btn-container" @click="onSearch"> <button class="search-btn" type="primary">搜索</button> </view>
<view class="filter-container"> <view class="total-reslut" v-if="listData.length > 0"> 搜索到 {{ total }} 条记录,共 {{ totalPage }} 页,当前第 {{ page }} 页 </view> <!-- <view>筛选</view> --> </view> </view>
<view style="padding-top: 154px;" v-if="listData.length > 0"> <scroll-view scroll-y style="height: calc(100vh - 80px);" @scrolltolower="onScrollLower" > <book-list-item class="hot-list-item" v-for="(item, index) in listData" :key="index" :data="item" :ranking="index + 1" @click="onItemClick(item)" ></book-list-item>
<view class="load-more" v-if="total > listData.length"> 上拉加载更多... </view> <view class="load-more" v-if="total <= listData.length && listData.length > 0"> 没有更多数据了 </view> </scroll-view> </view> <!-- 空状态 --> <view class="empty-box" v-if="isSearched && listData.length === 0"> <text>没有检索到相关数据</text> </view> </view></template>
<script>import { FetchInitScreenSetting } from '@/api/user';import { FetchBookSearch } from '@/api/book';import BookListItem from "@/components/book-list-item/book-list-item.vue";import config from '@/utils/config';
export default { components: { BookListItem }, data() { return { selectValue: '', selectValueText: '', selectIndex: 0, value: '', range: [ { value: '', text: "任意词" }, { value: 'title', text: "题名" }, { value: 'title200a', text: "正题名" }, { value: 'author', text: "著者" }, { value: 'isbn', text: "ISBN" }, { value: 'subject', text: "主题" }, { value: 'publisher', text: "出版社" }, { value: 'class', text: "分类号" }, { value: 'ctrlno', text: "控制号" }, { value: 'orderno', text: "订购号" }, { value: 'callno', text: "索书号" }, ], rangeText: [], opacUrl: '', listData: [], size: 10, page: 1, total: 0, totalPage: 0, isSearched: false }; }, onLoad() { this.rangeText = this.range.map(item => item.text); this.selectValue = this.range[0].value; this.selectValueText = this.range[0].text; this.getOpacUrl(); }, // 每次进入页面都会执行
onShow() { // this.resetSearchData();
}, methods: { // 重置搜索数据(每次进入页面清空)
resetSearchData() { this.value = ''; // 清空搜索框
this.listData = []; // 清空列表
this.page = 1; // 重置页码
this.total = 0; // 清空总数
this.totalPage = 0; // 清空总页数
this.isSearched = false; // 重置搜索状态
// 不重置选择器,保留用户习惯
}, // 获取opacUrl
async getOpacUrl() { try { const res = await FetchInitScreenSetting({ libcode: config.LIB_CODE }); this.opacUrl = res.data.opac_url?.context || ''; } catch (err) { console.error('获取配置失败', err); } },
// 切换检索类型
onPickerChange(e) { const index = e.detail.value; this.selectIndex = index; this.selectValue = this.range[index].value; this.selectValueText = this.range[index].text; }, async getBookList() { if (!this.value) { uni.showToast({ title: '请输入搜索内容', icon: 'none' }); return; } if (!this.opacUrl) { uni.showToast({ title: '未获取到检索配置', icon: 'none' }); return; }
uni.showLoading({ title: '搜索中...' });
try { const params = { opacUrl: this.opacUrl, page: this.page.toString(), query: this.value, rows: this.size.toString(), scWay: 'dim', searchWay: this.selectValue, sortOrder: 'desc', sortWay: 'score' };
const res = await FetchBookSearch(params); // console.log('res',res)
// 精准适配你当前返回格式
const apiData = res.data || {}; const list = apiData.bookList || [];
// 赋值总数、总页数
this.total = apiData.totalCount || 0; this.totalPage = Math.ceil(this.total / this.size);
// 分页拼接列表
if (this.page === 1) { this.listData = list; } else { this.listData = [...this.listData, ...list]; }
this.isSearched = true;
} catch (err) { console.error('搜索接口异常', err); this.listData = []; this.isSearched = true; } finally { uni.hideLoading(); } }, // 上拉加载
onScrollLower() { if (this.listData.length >= this.total) return; this.page++; this.getBookList(); },
// 搜索
onSearch() { this.page = 1; this.listData = []; this.getBookList(); },
// 进入详情
onItemClick(item) { uni.navigateTo({ url: "/subpkg/pages/book-detail/book-detail?bookrecno=" + item.bookrecno }) },
// 清空搜索
onClear() { this.value = ''; this.listData = []; this.total = 0; this.totalPage = 0; this.isSearched = false; },
onFocus() {}, onBlur() {}, onCancel() {}, onInput(val) { this.value = val; } }};</script>
<style lang="scss" scoped>.my-search-container { display: flex; flex-direction: column; padding: 15px 20px; background: #fff; position: fixed; top: 0; left: 0; right: 0; z-index: 99; height: 124px;
.my-search-wrapper { display: flex; align-items: center; width: 100%; padding: 5px 0; background-color: #f7f7f7; border-radius: 36px; overflow: hidden; }
.picker-select { width: 60px; border-right: 1px solid #c9c9c9; }
.picker-display { display: flex; align-items: center; justify-content: center; padding: 6px 0; font-size: 14px; color: #333; }
.my-search-bar { flex: 1;
::v-deep .uni-searchbar { padding: 0 !important; background: transparent !important; } }
.search-btn-container { width: 100%; margin-top: 10px;
.search-btn { background-color: #01a4fe; font-size: 15px; border-radius: 20px; } }}
.filter-container { display: flex; justify-content: flex-end; padding-top: 10px; font-size: 13px; color: #666;}
.load-more { text-align: center; padding: 10px; font-size: 13px; color: #999;}
.total-reslut { flex: 1; line-height: 20px; font-size: 13px; color: #01a4fe; font-weight: 400;}
.empty-box { display: flex; justify-content: center; align-items: center; height: 50vh; font-size: 14px; color: #999; padding-top: 100px;}</style>
|