首次完整推送,

V:1.20240808.006
This commit is contained in:
fm453
2024-08-13 18:32:37 +08:00
parent 15be3e9373
commit c62d15b288
939 changed files with 111777 additions and 0 deletions

View File

@ -0,0 +1,752 @@
<template>
<view class="container">
<view class="search-container">
<!-- 搜索框 -->
<view class="search-container-bar">
<!-- #ifdef APP-PLUS -->
<uni-icons class="search-icons" :color="iconColor" size="22" type="mic-filled" @click="speech" />
<!-- #endif -->
<!-- :cancelText="keyBoardPopup ? '取消' : '搜索'" -->
<uni-search-bar ref="searchBar" style="flex:1;" radius="100" v-model="searchText" :focus="focus"
:placeholder="hotWorld" clearButton="auto" cancelButton="none" @clear="cancel" @confirm="confirm"
@cancel="cancel" />
<uni-icons class="scan-icons" :color="iconColor" size="22" type="scan" @click="scanEvent"></uni-icons>
</view>
</view>
<view class="search-body">
<unicloud-db ref='listUdb' v-slot:default="{ pagination, hasMore, loading, error, options }"
@error="onqueryerror" :collection="colList" :page-size="10" orderby="publish_date desc" @load="onDbLoad"
loadtime="manual">
<template v-if="!isLoadData">
<!-- 搜索历史 -->
<view class="word-container" v-if="localSearchList.length">
<view class="word-container_header">
<text class="word-container_header-text">搜索历史</text>
<uni-icons v-if="!localSearchListDel" @click="localSearchListDel = true" class="search-icons"
style="padding-right: 0;" :color="iconColor" size="18" type="trash"></uni-icons>
<view v-else class="flex-center flex-row"
style="font-weight: 500;justify-content: space-between;">
<text
style="font-size: 22rpx;color: #666;padding-top:4rpx;padding-bottom:4rpx;padding-right:20rpx;"
@click="LocalSearchListClear">全部删除</text>
<text
style="font-size: 22rpx;color: #c0402b;padding-top:4rpx;padding-bottom:4rpx;padding-left:20rpx;"
@click="localSearchListDel = false">完成</text>
</view>
</view>
<view class="word-container_body">
<view class="flex-center flex-row word-container_body-text"
v-for="(word, index) in localSearchList" :key="index"
@click="LocalSearchlistItemClick(word, index)">
<text class="word-display" :key="word">{{ word }}</text>
<uni-icons v-if="localSearchListDel" size="12" type="closeempty" />
</view>
</view>
</view>
<!-- 搜索发现 -->
<view class="word-container">
<view class="word-container_header">
<view class="flex-center flex-row">
<text class="word-container_header-text">搜索发现</text>
<uni-icons v-if="!netHotListIsHide" class="search-icons" :color="iconColor" size="14"
type="reload" @click="searchHotRefresh"></uni-icons>
</view>
<uni-icons class="search-icons" style="padding-right: 0;" :color="iconColor" size="18"
:type="netHotListIsHide ? 'eye-slash' : 'eye'"
@click="netHotListIsHide = !netHotListIsHide"></uni-icons>
</view>
<unicloud-db ref="udb" #default="{ data, loading, error, options }" field="content"
collection="opendb-search-hot" orderby="create_date desc,count desc" page-data="replace"
:page-size="10">
<text v-if="loading && !netHotListIsHide" class="word-container_body-info">正在加载...</text>
<view v-else class="word-container_body">
<template v-if="!netHotListIsHide">
<text v-if="error" class="word-container_body-info">{{ error.message }}</text>
<template v-else>
<text v-for="(word, index) in data" class="word-container_body-text" :key="index"
@click="search(word.content)">{{ word.content }}</text>
</template>
</template>
<view v-else style="flex:1;">
<text class="word-container_body-info">当前搜索发现已隐藏</text>
</view>
</view>
</unicloud-db>
</view>
</template>
<uni-list v-else class="uni-list" :border="false" :style="{ height: listHeight }">
<!-- 列表渲染 -->
<uni-list-item :to="'/uni_modules/uni-cms-article/pages/detail/detail?id=' + item._id"
v-for="(item, index) in searchList" :key="index">
<!-- 通过header插槽定义列表左侧图片 -->
<template v-slot:header>
<image class="thumbnail" :src="item.thumbnail" mode="aspectFill"></image>
</template>
<!-- 通过body插槽定义布局 -->
<template v-slot:body>
<view class="main">
<text class="title">{{ item.title }}</text>
<view class="info">
<text class="author">{{ item.user_id[0] ? item.user_id[0].nickname : '' }}</text>
<text class="publish_date">{{ publishTime(item.publish_date) }}</text>
<!-- -->
<!-- <uni-dateformat class="publish_date" :date="item.publish_date"-->
<!-- format="yyyy-MM-dd" :threshold="[60000, 2592000000]"/>-->
</view>
</view>
</template>
</uni-list-item>
<!-- 加载状态:上拉加载更多,加载中,没有更多数据了,加载错误 -->
<!-- #ifdef APP-PLUS -->
<uni-list-item>
<template v-slot:body>
<!-- #endif -->
<uni-load-state @networkResume="refresh" :state="{ data: searchList, pagination, hasMore, loading, error }"
@loadMore="loadMore">
</uni-load-state>
<!-- #ifdef APP-PLUS -->
</template>
</uni-list-item>
<!-- #endif -->
</uni-list>
</unicloud-db>
</view>
<!-- 搜索联想 -->
<view class="search-associative" v-if="associativeShow">
<uni-list>
<uni-list-item v-for="(item, index) in associativeList" :key="item._id" :ellipsis="1" :title="item.title"
@click="associativeClick(item)" show-extra-icon clickable
:extra-icon="{ size: 18, color: iconColor, type: 'search' }">
</uni-list-item>
</uni-list>
</view>
</view>
</template>
<script>
/**
* 云端一体搜索模板
* @description uniCloud云端一体搜索模板自带下拉候选、历史搜索、热搜。无需再开发服务器代码
*/
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time";
import parseScanResult from "@/uni_modules/uni-cms-article/common/parse-scan-result";
import {parseImageUrl} from "@/uni_modules/uni-cms-article/common/parse-image-url";
const searchLogDbName = 'opendb-search-log'; // 搜索记录数据库
const articleDbName = 'uni-cms-articles'; // 文章数据库
const associativeSearchField = 'title'; // 联想时,搜索框值检索数据库字段名
const associativeField = '_id,title'; // 联想列表每一项携带的字段
const localSearchListKey = '__local_search_history'; // 本地历史存储字段名
const db = uniCloud.database();
const articleDBName = 'uni-cms-articles'
const userDBName = 'uni-id-users'
// 数组去重
const arrUnique = arr => {
for (let i = arr.length - 1; i >= 0; i--) {
const curIndex = arr.indexOf(arr[i]);
const lastIndex = arr.lastIndexOf(arr[i])
curIndex != lastIndex && arr.splice(lastIndex, 1)
}
return arr
} // 节流
// 防抖
function debounce(fn, interval, isFirstAutoRun) {
/**
*
* @param {要执行的函数} fn
* @param {在操作多长时间后可再执行,第一次立即执行} interval
*/
var _self = fn;
var timer = null;
var first = true;
if (isFirstAutoRun) {
_self();
}
return function () {
var args = arguments;
var _me = this;
if (first) {
first = false;
_self.apply(_me, args);
}
if (timer) {
clearTimeout(timer)
// return false;
}
timer = setTimeout(function () {
clearTimeout(timer);
timer = null;
_self.apply(_me, args);
}, interval || 200);
}
}
export default {
// 组件数据
data() {
return {
// 文章数据库名称
articleDbName,
// 搜索记录数据库名称
searchLogDbName,
// 状态栏高度
statusBarHeight: '0px',
// 本地搜索列表
localSearchList: uni.getStorageSync(localSearchListKey),
// 是否删除本地搜索列表
localSearchListDel: false,
// 是否隐藏网络热搜列表
netHotListIsHide: false,
// 搜索文本
searchText: '',
// 图标颜色
iconColor: '#999999',
// 联想列表
associativeList: [],
// 是否弹出键盘
keyBoardPopup: false,
// 搜索热词
hotWorld: 'DCloud', // 搜索热词,如果没有输入即回车,则搜索热词,但是不会加入搜索记录
// 是否自动聚焦
focus: true,
// 语音识别引擎
speechEngine: 'iFly', // 语音识别引擎 iFly 讯飞 baidu 百度
// 是否正在加载数据
isLoadData: false,
// 数据库查询条件
where: '"article_status" == 1',
// 列表高度
listHeight: 0,
// 是否显示联想列表
associativeShow: false,
// 是否显示无联想列表
noAssociativeShow: false,
// 搜索结果列表
searchList: []
}
},
// 组件创建时执行
created() {
// 初始化数据库
this.db = uniCloud.database();
this.searchLogDb = this.db.collection(this.searchLogDbName);
this.articleDbName = this.db.collection(this.articleDbName);
// #ifndef H5
// 监听键盘高度变化
uni.onKeyboardHeightChange((res) => {
this.keyBoardPopup = res.height !== 0;
})
// #endif
},
// 计算属性
computed: {
colList() {
// 返回文章和用户列表
return [
db.collection(articleDBName).where(this.where).field('thumbnail,title,publish_date,user_id').getTemp(),
db.collection(userDBName).field('_id,nickname').getTemp()
]
}
},
// 页面初次渲染完成时执行
onReady() {
// #ifdef APP-NVUE
/* 可用窗口高度 - 搜索框高 - 状态栏高 */
this.listHeight = uni.getSystemInfoSync().windowHeight + 'px';
// #endif
// #ifndef APP-NVUE
this.listHeight = 'auto'
// #endif
},
// 页面加载时执行
onLoad() {
//#ifdef APP-PLUS
// 获取状态栏高度
this.statusBarHeight = `${uni.getSystemInfoSync().statusBarHeight}px`;
//#endif
},
// 组件方法
methods: {
// 清空搜索框
clear(res) {
console.log("res: ", res);
},
// 确认搜索
confirm(res) {
// 键盘确认
this.search(res.value);
},
// 取消搜索
cancel(res) {
uni.hideKeyboard();
this.searchText = '';
this.isLoadData = false
this.associativeShow = false
// this.loadList();
},
// 执行搜索
search(value) {
if (!value && !this.hotWorld) {
return;
}
if (value) {
if (this.searchText !== value) {
this.searchText = value
}
this.localSearchListManage(value);
this.searchLogDbAdd(value)
} else if (this.hotWorld) {
this.searchText = this.hotWorld
}
uni.hideKeyboard();
this.loadList(this.searchText);
},
// 管理本地搜索列表
localSearchListManage(word) {
let list = uni.getStorageSync(localSearchListKey);
if (list.length) {
this.localSearchList.unshift(word);
arrUnique(this.localSearchList);
if (this.localSearchList.length > 10) {
this.localSearchList.pop();
}
} else {
this.localSearchList = [word];
}
uni.setStorageSync(localSearchListKey, this.localSearchList);
},
// 清空本地搜索列表
LocalSearchListClear() {
uni.showModal({
content: "确认清空搜索历史吗",
confirmText: "删除",
confirmColor: 'red',
cancelColor: '#808080',
success: res => {
if (res.confirm) {
this.localSearchListDel = false;
this.localSearchList = [];
uni.removeStorageSync(localSearchListKey)
}
}
});
},
// 点击本地搜索列表项
LocalSearchlistItemClick(word, index) {
if (this.localSearchListDel) {
this.localSearchList.splice(index, 1);
uni.setStorageSync(localSearchListKey, this.localSearchList);
if (!this.localSearchList.length) {
this.localSearchListDel = false;
}
return;
}
this.noAssociativeShow = true;
this.search(word);
},
// 刷新搜索热词
searchHotRefresh() {
this.$refs.udb.refresh();
},
// 语音搜索
speech() {
// #ifdef APP-PLUS
plus.speech.startRecognize({
engine: this.speechEngine,
punctuation: false, // 标点符号
timeout: 10000
}, word => {
word = word instanceof Array ? word[0] : word;
this.search(word)
}, err => {
console.error("语音识别错误: ", err);
});
// #endif
},
// 添加搜索记录
searchLogDbAdd(value) {
/*
在此处存搜索记录,如果登录则需要存 user_id若未登录则存device_id
*/
this.getDeviceId().then(device_id => {
this.searchLogDb.add({
// user_id: device_id,
device_id,
content: value,
create_date: Date.now()
})
})
},
// 获取设备ID
getDeviceId() {
return new Promise((resolve, reject) => {
// 从本地缓存中获取uni_id
const uniId = uni.getStorageSync('uni_id');
// 如果uni_id不存在则获取设备信息
if (!uniId) {
// #ifdef APP-PLUS
plus.device.getInfo({
success: (deviceInfo) => {
resolve(deviceInfo.uuid)
},
fail: () => {
// 如果获取设备信息失败,则返回一个随机字符串
resolve(uni.getSystemInfoSync().system + '_' + Math.random().toString(36).substr(2))
}
});
// #endif
// #ifndef APP-PLUS
// 如果不是APP-PLUS则返回一个随机字符串
resolve(uni.getSystemInfoSync().system + '_' + Math.random().toString(36).substr(2))
// #endif
} else {
// 如果uni_id存在则直接返回uni_id
resolve(uniId)
}
})
},
// 点击联想词
associativeClick(item) {
/**
* 注意:这里用户根据自己的业务需要,选择跳转的页面即可
*/
console.log("associativeClick: ", item, item.title);
// 隐藏联想词
this.noAssociativeShow = true;
// 将搜索框的文本设置为联想词的标题
this.searchText = item.title;
// 加载列表
this.loadList(item.title);
},
// 加载列表
loadList(text = '') {
// 设置查询条件
let where = '"article_status" == 1 '
if (text) {
this.where = where + `&& /${text}/.test(title)`;
} else {
this.where = where;
}
// 隐藏联想词
this.associativeList = [];
this.associativeShow = false;
this.searchList = []
this.isLoadData = true
// 延迟0ms后加载数据
setTimeout(() => {
this.$refs.listUdb.loadData({
clear: true
})
}, 0)
},
// 数据库加载完成
async onDbLoad(data) {
console.log('onDbLoad')
// 设置数据已加载标志
this.isLoadData = true
// 显示联想词
this.noAssociativeShow = false;
for (const article of data) {
const parseImages = await parseImageUrl(article.thumbnail)
article.thumbnail = parseImages ? parseImages.map(image => image.src): []
}
this.searchList = data
},
// 查询错误
onqueryerror(e) {
console.error(e);
},
// 刷新
refresh() {
// 刷新数据
this.$refs.listUdb.loadData({
clear: true
}, () => {
// 停止下拉刷新
uni.stopPullDownRefresh()
// #ifdef APP-NVUE
// 隐藏刷新按钮
this.showRefresh = false
// #endif
})
},
// 加载更多
loadMore() {
// 加载更多数据
this.$refs.listUdb.loadMore()
},
// 格式化发布时间
publishTime(timestamp) {
return translatePublishTime(timestamp)
},
scanEvent () {
uni.scanCode({
onlyFromCamera: true,
scanType: ["qrCode"],
success: (e) => parseScanResult(e.result),
fail: (e) => {
console.error(e)
}
})
}
},
onReachBottom() {
// 当滚动到底部时,加载更多数据
this.loadMore()
},
watch: {
searchText: debounce(function (value, oldValue) {
// 当搜索框的文本发生变化时,执行以下操作
if (value === oldValue) return
if (this.noAssociativeShow) return
if (value) {
// 根据搜索框的文本,查询联想词
this.articleDbName.where({
[associativeSearchField]: new RegExp(value, 'gi'),
}).field(associativeField).get().then(res => {
// 将查询结果赋值给联想词列表,并显示联想词
this.associativeList = res.result.data;
this.associativeShow = true
})
} else {
// 如果搜索框的文本为空,则清空联想词列表
this.associativeList = [];
}
}, 100)
}
}
</script>
<style>
/* #ifndef APP-NVUE */
page {
height: 100%;
flex: 1;
}
/* #endif */
</style>
<style lang="scss" scoped>
$search-bar-height: 52px;
$word-container_header-height: 72rpx;
.status-bar {
background-color: #fff;
}
.container {
/* #ifndef APP-NVUE */
height: 100%;
/* #endif */
flex: 1;
background-color: #f7f7f7;
}
.search-body {
background-color: #fff;
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
}
@mixin uni-flex {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
}
@mixin words-display {
font-size: 26rpx;
color: #666;
}
.flex-center {
@include uni-flex;
justify-content: center;
align-items: center;
}
.flex-row {
@include uni-flex;
flex-direction: row;
}
/* #ifdef APP-PLUS */
/* #ifndef APP-NVUE || VUE3*/
::v-deep
/* #endif */
.uni-searchbar {
padding-left: 0;
}
/* #endif */
/* #ifndef APP-NVUE || VUE3*/
::v-deep
/* #endif */
.uni-searchbar__box {
border-width: 0;
}
/* #ifndef APP-NVUE || VUE3 */
::v-deep
/* #endif */
.uni-input-placeholder {
font-size: 28rpx;
}
.search-container {
height: $search-bar-height;
@include uni-flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
background-color: #fff;
@at-root {
#{&}-bar {
@include uni-flex;
flex-direction: row;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
}
}
}
.search-associative {
/* #ifndef APP-NVUE */
overflow-y: auto;
/* #endif */
position: absolute;
top: $search-bar-height;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
margin-top: 10rpx;
padding-left: 10rpx;
padding-right: 10rpx;
}
.search-icons, .scan-icons {
padding: 16rpx;
}
.scan-icons {
padding-left: 0;
}
.word-display {
@include words-display;
}
.word-container {
padding: 20rpx;
@at-root {
#{&}_header {
@include uni-flex;
height: $word-container_header-height;
line-height: $word-container_header-height;
flex-direction: row;
justify-content: space-between;
align-items: center;
@at-root {
#{&}-text {
color: #3e3e3e;
font-size: 30rpx;
font-weight: bold;
}
}
}
#{&}_body {
@include uni-flex;
flex-wrap: wrap;
flex-direction: row;
@at-root {
#{&}-text {
@include uni-flex;
@include words-display;
justify-content: center;
align-items: center;
background-color: #f6f6f6;
padding: 10rpx 20rpx;
margin: 20rpx 30rpx 0 0;
border-radius: 30rpx;
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
text-align: center;
}
#{&}-info {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
flex: 1;
text-align: center;
font-size: 26rpx;
color: #808080;
margin-top: 20rpx;
}
}
}
}
}
.thumbnail {
width: 240rpx;
height: 160rpx;
margin-right: 20rpx;
border-radius: 8rpx;
}
.main {
justify-content: space-between;
flex: 1;
}
.title {
font-size: 32rpx;
}
.info {
flex-direction: row;
justify-content: space-between;
}
.author,
.publish_date {
font-size: 28rpx;
color: #999999;
}
</style>

View File

@ -0,0 +1,363 @@
<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>