Files
ctms-client/pages/uni-starter/news/search/search.uvue
fm453 c62d15b288 首次完整推送,
V:1.20240808.006
2024-08-13 18:32:37 +08:00

364 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<view class="search">
<uni-cms-article-search-bar
ref="searchBar"
v-model="searchVal"
:show-placeholder="false"
:focus="true"
@clear="showSearchResultPanel = false"
@confirm="search"
></uni-cms-article-search-bar>
</view>
<view class="search-result" v-if="showSearchResultPanel">
<uni-cms-article-list
ref="articleList"
:collectionList="colList"
:refresherEnabled="false"
loadTime="manual"
style="flex: 1;"
></uni-cms-article-list>
</view>
<template v-else>
<view class="panel history-panel" v-if="searchHistory.length > 0">
<view class="panel__title">
<view class="panel__title-text">
<text class="text">搜索历史</text>
</view>
<view class="delete-history-btns" v-if="deleteHistoryLoading">
<text class="text" @click="deleteAllSearchHistory">全部删除</text>
<text class="text danger" @click="deleteHistoryLoading = false">完成</text>
</view>
<uni-cms-article-icons
class="panel__after-icon"
type="trash"
:size="18"
color="#999"
@click="deleteHistoryLoading = true"
v-else
></uni-cms-article-icons>
</view>
<view class="panel__list">
<view class="panel__list-item" v-for="text in searchHistory">
<text class="text" @click="search(text)">{{text}}</text>
<uni-cms-article-icons
class="icon"
type="closeempty"
:size="12"
color="#999"
v-if="deleteHistoryLoading"
@click="deleteSearchHistory(text)"
></uni-cms-article-icons>
</view>
</view>
</view>
<unicloud-db ref="udb" #default="{ data, loading, error }" field="content"
collection="opendb-search-hot" orderby="create_date desc,count desc" page-data="replace"
:page-size="10">
<view class="panel recommend-panel">
<view class="panel__title">
<view class="panel__title-text">
<text class="text">搜索发现</text>
<uni-cms-article-icons
class="icon"
type="reload"
:size="14"
color="#999"
v-if="!hideSearchRecommend"
@click="reLoadSearchRecommend"
></uni-cms-article-icons>
</view>
<uni-cms-article-icons
class="panel__after-icon"
:type="hideSearchRecommend ? 'eye-slash': 'eye'"
:size="18"
color="#999"
@click="hideSearchRecommend = !hideSearchRecommend"
></uni-cms-article-icons>
</view>
<view class="panel__list">
<view class="panel__list-tip" v-if="loading">
<text class="text">正在加载...</text>
</view>
<view class="panel__list-tip" v-else-if="error != null">
<text class="text">{{error.message}}</text>
</view>
<view class="panel__list-tip" v-else-if="hideSearchRecommend">
<text class="text">当前搜索发现已隐藏</text>
</view>
<template v-else>
<view
class="panel__list-item"
v-for="(word, index) in data"
:key="index"
@click="search(word.getString('content')!)"
>
<text class="text">{{ word.getString('content') }}</text>
</view>
</template>
</view>
</view>
</unicloud-db>
</template>
</view>
</template>
<script lang="uts">
type ArticleAuthor = {
_id: string
nickname: string
}
type ArticleItem = {
_id: string
title: string
publish_date: number
thumbnail: string[]
user_id: ArticleAuthor[]
}
const db = uniCloud.databaseForJQL()
const searchLogDB = db.collection('opendb-search-log')
const cmsArticleDB = db.collection('uni-cms-articles')
const uniIdUsersDB = db.collection('uni-id-users')
const localSearchHistoryKey = '__local_search_history'; // 本地历史存储字段名
const localSearchRecommendHiddenKey = '__local_search_recommend_hidden'; // 本地搜索发现开关字段名
const localSearchHistoryMax = 10; // 本地历史存储最大值
export default {
data() {
const localSearchRecommendHidden = uni.getStorageSync(localSearchRecommendHiddenKey)
return {
searchVal: "",
searchHistory: [] as string[],
searchRecommend: [] as string[],
deleteHistoryLoading: false,
hideSearchRecommend: (localSearchRecommendHidden == "" ? false : localSearchRecommendHidden) as boolean,
showSearchResultPanel: false,
searchResult: [] as ArticleItem[]
}
},
watch: {
hideSearchRecommend(newValue) {
uni.setStorageSync(localSearchRecommendHiddenKey, newValue)
}
},
computed: {
hasSearchValue(): boolean {
return this.searchVal != ""
},
where(): string {
let where = "\"article_status\" == 1"
if (this.searchVal != "") {
where += `&& /${this.searchVal}/.test(title)`
}
return where
},
colList(): any[] {
// 返回文章和用户列表
return [
cmsArticleDB.where(this.where).field('thumbnail,title,publish_date,user_id').getTemp(),
uniIdUsersDB.field('_id,nickname').getTemp()
]
}
},
mounted() {
// 本地历史存储
const localSearchHistory = uni.getStorageSync(localSearchHistoryKey)
this.searchHistory = (localSearchHistory == "" ? [] as string[] : localSearchHistory) as string[]
},
methods: {
deleteAllSearchHistory() {
uni.showModal({
title: "确定清空搜索历史吗",
confirmText: "删除",
success: (res) => {
if (res.confirm) {
this.deleteSearchHistory(null)
}
}
})
},
deleteSearchHistory(searchText: string | null) {
let history: string[] = []
if (searchText != null) {
history = this.searchHistory.filter((item: string): boolean => item != searchText)
}
this.searchHistory = history
uni.setStorageSync(localSearchHistoryKey, history)
console.log(history.length, 'history.length')
if (history.length <= 0) {
this.deleteHistoryLoading = false
}
},
search(searchText: string) {
searchText = searchText.trim()
if (searchText == "" || this.deleteHistoryLoading) return
// 隐藏键盘
;(this.$refs['searchBar'] as UniCmsArticleSearchBarComponentPublicInstance)!.hideKeyboard()
// 保存搜索历史
this.setLocalSearchHistory(searchText)
// 显示搜索结果Panel
this.showSearchResultPanel = true
// 搜索
this.loadSearchResult(searchText)
// 添加搜索记录
this.addSearchRecord(searchText)
},
loadSearchResult(searchText: string) {
// 设置查询条件
this.searchVal = searchText
// 延迟0ms后加载数据
setTimeout(() => {
(this.$refs['articleList'] as UniCmsArticleListComponentPublicInstance)!.reLoadList()
}, 0)
},
addSearchRecord(searchText: string) {
const systemInfo = uni.getSystemInfoSync()
/*
在此处存搜索记录,如果登录则需要存 user_id若未登录则存device_id
*/
searchLogDB.add({
// user_id: device_id,
device_id: systemInfo.deviceId,
// device_uuid: systemInfo.deviceId,
content: searchText,
create_date: Date.now()
})
},
setLocalSearchHistory(searchText: string) {
const history = this.searchHistory.filter((item: string): boolean => item != searchText)
history.unshift(searchText)
if (history.length > localSearchHistoryMax) {
history.pop()
}
this.searchHistory = history
this.deleteHistoryLoading = false
uni.setStorageSync(localSearchHistoryKey, history)
},
reLoadSearchRecommend() {
(this.$refs['udb'] as UniCloudDBElement)!.loadData({
clear: true
})
}
}
}
</script>
<style lang="scss">
.container {
display: flex;
flex-direction: column;
height: 100%;
.search-result {
flex: 1;
display: flex;
flex-direction: column;
}
}
.panel {
margin-top: 40rpx;
padding: 10rpx 20rpx;
&__title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
&-text {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
.text {
color: #3e3e3e;
font-size: 30rpx;
line-height: 36rpx;
font-weight: bold;
}
.icon {
margin-left: 10rpx;
}
}
}
&__after-icon {
margin-left: 10rpx;
}
&__list {
margin-top: 30rpx;
display: flex;
flex-direction: row;
flex-wrap: wrap;
&-item {
background-color: #f6f6f6;
border-radius: 30rpx;
padding: 10rpx 20rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-right: 10rpx;
margin-bottom: 10rpx;
.text {
font-size: 26rpx;
color: #666;
}
.icon {
margin-left: 10rpx;
}
}
&-tip {
display: flex;
flex-direction: row;
justify-content: center;
flex: 1;
margin-top: 20rpx;
.text {
font-size: 26rpx;
color: #808080;
}
}
}
}
.delete-history-btns {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
.text {
color: #666;
font-size: 22rpx;
margin-left: 20rpx;
&.danger {
color: #c0402b;
}
}
}
</style>