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.
366 lines
8.9 KiB
366 lines
8.9 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" v-if="isSearched && listData.length === 0">
|
|
<uni-icons style="margin-left: 20px;" custom-prefix="iconfont" type="icon-kongshuju" size="80" color="#ccc"></uni-icons>
|
|
<text style="margin-top: 20px;">没有检索到相关数据</text>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { FetchInitScreenSetting } from '@/api/user';
|
|
import { FetchBookSearch, FetchFindAllBookCollectionByOpenId } from '@/api/book';
|
|
import BookListItem from "@/components/book-list-item/book-list-item.vue";
|
|
import config from '@/utils/config';
|
|
import { getOpenId } from '@/utils/storage';
|
|
|
|
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;
|
|
console.log('this.listData',this.listData)
|
|
} 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();
|
|
},
|
|
|
|
// 进入详情
|
|
async onItemClick(item) {
|
|
console.log('item', item);
|
|
let isCollected = false;
|
|
let collectId = null;
|
|
|
|
try {
|
|
const openId = await getOpenId();
|
|
if (openId) {
|
|
const res = await FetchFindAllBookCollectionByOpenId({
|
|
libcode: config.LIB_CODE,
|
|
openId: openId,
|
|
page: 0,
|
|
size: 100
|
|
});
|
|
|
|
if (res.code === 200) {
|
|
const collectList = res.data.content || [];
|
|
const bookrecno = String(item.bookrecno);
|
|
// 查找匹配的收藏记录
|
|
const matchedItem = collectList.find(collectItem => String(collectItem.bookrecno) === bookrecno);
|
|
if (matchedItem) {
|
|
isCollected = true;
|
|
collectId = matchedItem.id; // 获取收藏记录的 id
|
|
}
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('获取收藏列表失败', err);
|
|
}
|
|
|
|
// 创建包含收藏信息的新对象
|
|
const itemWithCollectInfo = {
|
|
...item,
|
|
id: collectId // 添加收藏记录的 id
|
|
};
|
|
console.log('itemWithCollectInfo',itemWithCollectInfo)
|
|
const isCollectedParam = isCollected ? '&isCollected=true' : '';
|
|
uni.navigateTo({
|
|
url: "/subpkg/pages/book-detail/book-detail?searchData=" + encodeURIComponent(JSON.stringify(itemWithCollectInfo)) + isCollectedParam
|
|
});
|
|
},
|
|
|
|
// 清空搜索
|
|
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 {
|
|
height: 50vh;
|
|
padding-top: 100px;
|
|
}
|
|
</style>
|