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

333 lines
7.5 KiB

<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>