2025-07-22 11:21:01 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<view>
|
|
|
|
|
|
<!-- 搜索框 -->
|
2025-08-04 16:19:03 +08:00
|
|
|
|
<view class="search search-sao">
|
2025-08-18 15:50:40 +08:00
|
|
|
|
<!-- @confirm="handleSearch" @cancel="handleCancel"-->
|
|
|
|
|
|
<uni-search-bar class="custom-search"
|
|
|
|
|
|
radius="28"
|
2025-08-25 16:08:21 +08:00
|
|
|
|
placeholder="请输入搜索条件"
|
2025-08-18 15:50:40 +08:00
|
|
|
|
clearButton="auto"
|
|
|
|
|
|
bgColor="#6FA2F8" textColor="#ffffff"
|
2025-08-04 16:19:03 +08:00
|
|
|
|
v-model="searchText"
|
2025-08-18 15:50:40 +08:00
|
|
|
|
cancelButton="none"
|
|
|
|
|
|
focus
|
2025-08-04 16:19:03 +08:00
|
|
|
|
/>
|
|
|
|
|
|
<text class="search-btn" @click="handleSearch">查询</text>
|
2025-07-22 11:21:01 +08:00
|
|
|
|
</view>
|
2025-08-04 16:19:03 +08:00
|
|
|
|
<view class="white-bg">
|
|
|
|
|
|
|
2025-08-18 15:50:40 +08:00
|
|
|
|
<!-- 类型列表 -->
|
|
|
|
|
|
<view class="search-section" v-if="searchTypeList.length>0">
|
2025-08-04 16:19:03 +08:00
|
|
|
|
<view class="section-header">
|
2025-08-18 15:50:40 +08:00
|
|
|
|
<text class="section-title">{{ searchType.typeName }}</text>
|
2025-08-04 16:19:03 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
<view class="tag-container">
|
2025-08-18 15:50:40 +08:00
|
|
|
|
<view class="search-tag notice-tag" :class="{'notice-check':!searchCheckObj.id}" @click="handleNoticeClick({})">全部</view>
|
|
|
|
|
|
<view class="search-tag notice-tag" :class="{'notice-check':item.id==searchCheckObj.id}"
|
|
|
|
|
|
v-for="(item, index) in searchTypeList"
|
2025-08-04 16:19:03 +08:00
|
|
|
|
:key="'notice-' + index"
|
|
|
|
|
|
@click="handleNoticeClick(item)"
|
|
|
|
|
|
>
|
2025-08-18 15:50:40 +08:00
|
|
|
|
{{ item.name }}
|
2025-08-04 16:19:03 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
2025-07-22 11:21:01 +08:00
|
|
|
|
|
2025-08-18 15:50:40 +08:00
|
|
|
|
<!-- 历史记录 v-if="historyList.length>0" -->
|
2025-08-04 16:19:03 +08:00
|
|
|
|
<view class="search-section">
|
|
|
|
|
|
<view class="section-header">
|
|
|
|
|
|
<text class="section-title">历史搜索</text>
|
|
|
|
|
|
<uni-icons type="trash" size="18" color="#999" @click="clearHistory"></uni-icons>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="tag-container">
|
|
|
|
|
|
<view class="search-tag" v-for="(item, index) in historyList" :key="'history-' + index"
|
|
|
|
|
|
@click="handleHistoryClick(item)">
|
|
|
|
|
|
{{ item }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 搜索结果 -->
|
|
|
|
|
|
<!-- <view class="search-result" v-if="searchResult.length > 0">
|
|
|
|
|
|
<view class="result-item"
|
|
|
|
|
|
v-for="(item, index) in searchResult"
|
|
|
|
|
|
:key="'result-' + index"
|
|
|
|
|
|
@click="handleResultClick(item)"
|
|
|
|
|
|
>
|
|
|
|
|
|
{{ item.name }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view> -->
|
|
|
|
|
|
</view>
|
2025-07-22 11:21:01 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-08-18 15:50:40 +08:00
|
|
|
|
import { ref,watch } from 'vue'
|
2025-07-22 11:21:01 +08:00
|
|
|
|
|
2025-08-04 16:19:03 +08:00
|
|
|
|
const props = defineProps({
|
2025-08-18 15:50:40 +08:00
|
|
|
|
searchKeywords:{//搜索文本
|
|
|
|
|
|
type:String
|
|
|
|
|
|
},
|
2025-08-18 16:11:49 +08:00
|
|
|
|
searchType:{//哪种类型显示对象 typeId:1-首页,2-业务首页,3-消息 之后可以自动添加
|
2025-08-18 15:50:40 +08:00
|
|
|
|
type:Object
|
|
|
|
|
|
},
|
|
|
|
|
|
searchTypeList:{//类型列表
|
|
|
|
|
|
type:Array,
|
|
|
|
|
|
default:[]
|
|
|
|
|
|
},
|
|
|
|
|
|
checkTypeObj:{//选中的类型对象
|
|
|
|
|
|
type:Object
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-08-04 16:19:03 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const searchText = ref('');// 搜索文本
|
2025-08-18 15:50:40 +08:00
|
|
|
|
const searchCheckObj = ref({});//选中的类型对象
|
|
|
|
|
|
|
2025-08-04 16:19:03 +08:00
|
|
|
|
const showCancel = ref(false)// 是否显示取消按钮
|
|
|
|
|
|
const historyList = ref([])// 历史记录列表
|
2025-08-18 15:50:40 +08:00
|
|
|
|
|
2025-08-04 16:19:03 +08:00
|
|
|
|
const searchResult = ref([])// 搜索结果
|
|
|
|
|
|
|
2025-08-18 15:50:40 +08:00
|
|
|
|
// 搜索文本内容
|
|
|
|
|
|
watch(() => props.searchKeywords, (newVal, oldVal) => {
|
|
|
|
|
|
searchText.value = newVal
|
|
|
|
|
|
},{
|
|
|
|
|
|
deep:true, // 深度监听
|
|
|
|
|
|
immediate:true // 立即执行
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 选中类型对象
|
|
|
|
|
|
watch(() => props.checkTypeObj, (newVal, oldVal) => {
|
|
|
|
|
|
searchCheckObj.value = newVal
|
|
|
|
|
|
},{
|
|
|
|
|
|
deep:true, // 深度监听
|
|
|
|
|
|
immediate:true // 立即执行
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用父组件的方法
|
|
|
|
|
|
const emit = defineEmits(['confirm']);
|
|
|
|
|
|
|
2025-08-04 16:19:03 +08:00
|
|
|
|
// 加载历史记录
|
|
|
|
|
|
const loadHistory = () => {
|
2025-08-18 16:11:49 +08:00
|
|
|
|
let typeId = props.searchType?props.searchType.typeId:undefined
|
2025-08-18 15:50:40 +08:00
|
|
|
|
const history = uni.getStorageSync('searchHistory'+typeId) || []
|
2025-08-04 16:19:03 +08:00
|
|
|
|
historyList.value = history
|
|
|
|
|
|
}
|
2025-08-18 15:50:40 +08:00
|
|
|
|
loadHistory();
|
2025-08-04 16:19:03 +08:00
|
|
|
|
|
|
|
|
|
|
// 处理搜索
|
|
|
|
|
|
const handleSearch = () => {
|
2025-08-18 15:50:40 +08:00
|
|
|
|
let txtContent = searchText.value?searchText.value.trim():undefined
|
|
|
|
|
|
if (txtContent) {
|
|
|
|
|
|
// uni.showToast({
|
|
|
|
|
|
// title: '请输入搜索内容',
|
|
|
|
|
|
// icon: 'none'
|
|
|
|
|
|
// })
|
|
|
|
|
|
// return
|
|
|
|
|
|
// 添加到历史记录
|
|
|
|
|
|
addToHistory(txtContent)
|
2025-08-04 16:19:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟搜索请求
|
2025-08-18 15:50:40 +08:00
|
|
|
|
// searchResult.value = [
|
|
|
|
|
|
// { id: 1, name: `${searchText.value} 结果1` },
|
|
|
|
|
|
// { id: 2, name: `${searchText.value} 结果2` },
|
|
|
|
|
|
// { id: 3, name: `${searchText.value} 结果3` }
|
|
|
|
|
|
// ]
|
2025-08-04 16:19:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-08-18 15:50:40 +08:00
|
|
|
|
// 传给父组件
|
|
|
|
|
|
emit('confirm',searchCheckObj,searchText);
|
2025-08-04 16:19:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理输入
|
|
|
|
|
|
const handleInput = () => {
|
|
|
|
|
|
showCancel.value = searchText.value.length > 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清除搜索
|
|
|
|
|
|
const clearSearch = () => {
|
|
|
|
|
|
searchText.value = ''
|
|
|
|
|
|
showCancel.value = false
|
|
|
|
|
|
searchResult.value = []
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加到历史记录
|
|
|
|
|
|
const addToHistory = (keyword) => {
|
|
|
|
|
|
const index = historyList.value.indexOf(keyword)
|
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
|
historyList.value.splice(index, 1)
|
|
|
|
|
|
}
|
|
|
|
|
|
historyList.value.unshift(keyword)
|
|
|
|
|
|
|
|
|
|
|
|
// 限制历史记录数量
|
|
|
|
|
|
if (historyList.value.length > 10) {
|
|
|
|
|
|
historyList.value = historyList.value.slice(0, 10)
|
2025-07-22 11:21:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-18 15:50:40 +08:00
|
|
|
|
let typeId = props.searchType.typeId
|
|
|
|
|
|
uni.setStorageSync('searchHistory'+typeId, historyList.value)
|
2025-07-22 11:21:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-04 16:19:03 +08:00
|
|
|
|
// 清除历史记录
|
|
|
|
|
|
const clearHistory = () => {
|
|
|
|
|
|
uni.showModal({
|
|
|
|
|
|
title: '提示',
|
|
|
|
|
|
content: '确定要清空历史记录吗?',
|
|
|
|
|
|
success: (res) => {
|
|
|
|
|
|
if (res.confirm) {
|
|
|
|
|
|
historyList.value = []
|
2025-08-18 15:50:40 +08:00
|
|
|
|
let typeId = props.searchType.typeId;
|
|
|
|
|
|
uni.removeStorageSync('searchHistory'+typeId)
|
2025-08-04 16:19:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 点击历史记录
|
|
|
|
|
|
const handleHistoryClick = (item) => {
|
|
|
|
|
|
searchText.value = item
|
2025-07-22 11:21:01 +08:00
|
|
|
|
handleSearch()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-04 16:19:03 +08:00
|
|
|
|
// 点击消息类型
|
|
|
|
|
|
const handleNoticeClick = (item) => {
|
2025-08-18 15:50:40 +08:00
|
|
|
|
// searchText.value = item
|
|
|
|
|
|
searchCheckObj.value = item;
|
2025-07-22 11:21:01 +08:00
|
|
|
|
handleSearch()
|
|
|
|
|
|
}
|
2025-08-04 16:19:03 +08:00
|
|
|
|
|
|
|
|
|
|
// 点击搜索结果
|
|
|
|
|
|
const handleResultClick = (item) => {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: `点击了 ${item.name}`,
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
// 实际项目中这里可以跳转到详情页
|
|
|
|
|
|
// uni.navigateTo({ url: `/pages/detail/detail?id=${item.id}` })
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
2025-08-18 15:50:40 +08:00
|
|
|
|
|
2025-08-04 16:19:03 +08:00
|
|
|
|
.search-sao {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.search-sao .custom-search {
|
|
|
|
|
|
/* width:615rpx; */
|
|
|
|
|
|
width: 590rpx;
|
|
|
|
|
|
padding: 0 20rpx;
|
|
|
|
|
|
margin-bottom:15rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.search-sao :deep(.custom-search.uni-searchbar) {
|
|
|
|
|
|
padding-bottom: 15rpx !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.search-sao .search-btn {
|
|
|
|
|
|
margin: 15rpx 30rpx 10rpx 0;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.white-bg {
|
|
|
|
|
|
width: 750rpx;
|
|
|
|
|
|
padding: 40rpx 0;
|
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
|
border-radius: 8px 8px 0 0;
|
|
|
|
|
|
/* #ifdef APP-PLUS */
|
2025-08-27 13:49:03 +08:00
|
|
|
|
height: calc(100vh - 168px);
|
2025-08-04 16:19:03 +08:00
|
|
|
|
/* #endif */
|
|
|
|
|
|
/* #ifndef APP-PLUS */
|
|
|
|
|
|
height: calc(100vh - 150px);
|
|
|
|
|
|
/* #endif */
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.search-section {
|
|
|
|
|
|
margin-bottom: 40rpx;
|
|
|
|
|
|
padding:0 45rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.section-title {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tag-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.search-tag {
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
border:1px solid #E8E8E8;
|
|
|
|
|
|
border-radius: 10rpx;
|
|
|
|
|
|
padding: 10rpx 15rpx;
|
2025-08-27 13:49:03 +08:00
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
|
margin-bottom: 20rpx;
|
2025-08-04 16:19:03 +08:00
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.search-tag.notice-tag{
|
|
|
|
|
|
padding: 10rpx 45rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.notice-tag:nth-child(3n){
|
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-18 15:50:40 +08:00
|
|
|
|
.notice-check{
|
|
|
|
|
|
background-color: #05A3F4;
|
|
|
|
|
|
color:#fff;
|
|
|
|
|
|
border-color:#05A3F4;
|
|
|
|
|
|
}
|
2025-08-04 16:19:03 +08:00
|
|
|
|
.search-result {
|
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
|
padding:0 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.result-item {
|
|
|
|
|
|
padding: 20rpx 0;
|
|
|
|
|
|
border-bottom: 1rpx solid #eee;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|