新增搜索页面,并接入部分接口

This commit is contained in:
wangyifeng 2024-12-26 17:02:48 +08:00
parent f9d97f642b
commit ad658710f7
10 changed files with 456 additions and 76 deletions

View File

@ -18,6 +18,7 @@ init()
</script> </script>
<style lang="scss"> <style lang="scss">
@import "@/static/css/color.scss"; @import "@/static/css/color.scss";
@import "@/static/css/font.scss";
/* #ifdef APP-NVUE */ /* #ifdef APP-NVUE */
@import '@/uni_modules/tmui/scss/nvue.css'; @import '@/uni_modules/tmui/scss/nvue.css';
/* #endif */ /* #endif */

11
src/api/search/index.js Normal file
View File

@ -0,0 +1,11 @@
import request from '@/service/index.js'
import qs from 'qs'
// ES搜索聊天记录-主页搜索什么都有
export const ServeSeachQueryAll = (data) => {
return request({
url: '/api/v1/elasticsearch/query-all',
method: 'POST',
data,
})
}

View File

@ -58,6 +58,14 @@
"path": "pages/login/index", "path": "pages/login/index",
"type": "page", "type": "page",
"style": {} "style": {}
},
{
"path": "pages/search/index",
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
}
} }

View File

@ -57,7 +57,7 @@
</tm-navbar> </tm-navbar>
</div> </div>
<div class="root"> <div class="root">
<div class="searchRoot"> <div class="searchRoot" @click="toSearchPage">
<tm-input <tm-input
placeholder="请输入…" placeholder="请输入…"
color="#F9F9FD" color="#F9F9FD"
@ -111,6 +111,12 @@ const creatGroupChat = () => {
}); });
}; };
const toSearchPage = () => {
uni.navigateTo({
url: "/pages/search/index",
});
};
watch( watch(
() => talkStore, () => talkStore,
(newValue, oldValue) => { (newValue, oldValue) => {

View File

@ -0,0 +1,166 @@
<template>
<div class="search-item" v-if="resultName">
<div class="avatar-img">
<img :src="avatarImg" />
</div>
<div class="result-info">
<div class="info-name">
<span class="text-[32rpx] font-medium">
{{ resultName }}
</span>
<div class="info-tag" v-if="resultType">
<span class="text-[24rpx] font-medium">{{ resultType }}</span>
</div>
</div>
<div class="info-detail" v-if="resultDetail">
<span class="text-[28rpx] font-regular">
{{ resultDetail }}
</span>
</div>
</div>
</div>
</template>
<script setup>
import zu4992 from '@/static/image/chatList/zu4992@2x.png'
import zu4991 from '@/static/image/chatList/zu4991@2x.png'
import zu4989 from '@/static/image/chatList/zu4989@2x.png'
import {
ref,
watch,
computed,
onMounted,
onUnmounted,
reactive,
getCurrentInstance,
} from 'vue'
const { proxy } = getCurrentInstance()
const props = defineProps({
searchItem: Object | Number,
searchResultKey: String,
})
const avatarImg = computed(() => {
let srcT = ''
switch (props.searchItem?.group_type) {
case 0:
srcT = zu5296
break
case 1:
srcT = zu4992
break
case 2:
srcT = zu4991
break
case 3:
srcT = zu4989
break
default:
srcT = zu4992
}
return srcT
})
const resultName = computed(() => {
let data_key = ''
switch (props.searchResultKey) {
case 'user_infos':
data_key = props.searchItem?.nickname
break
case 'group_member_infos':
data_key = props.searchItem?.group_name
break
case 'general_infos':
data_key = props.searchItem?.receiver_name
break
default:
data_key = ''
}
return data_key
})
const resultType = computed(() => {
let result_type = ''
switch (props.searchItem?.group_type) {
case 0:
result_type = ''
break
case 1:
result_type = ''
break
case 2:
result_type = proxy.$t('index.mine.department')
break
case 3:
result_type = proxy.$t('index.mine.project')
break
case 4:
result_type = ''
break
default:
result_type = ''
}
return result_type
})
const resultDetail = computed(() => {
let data_key = ''
switch (props.searchResultKey) {
case 'user_infos':
data_key = ''
break
case 'group_member_infos':
data_key = ''
break
case 'general_infos':
data_key = props.searchItem?.count + proxy.$t('search.chat.count')
break
default:
data_key = ''
}
return data_key
})
</script>
<style lang="scss" scoped>
.search-item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
.avatar-img {
width: 96rpx;
height: 96rpx;
margin: 0 20rpx 0 0;
img {
width: 100%;
height: 100%;
}
}
.result-info {
.info-name {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
span {
color: $theme-text;
line-height: 44rpx;
}
.info-tag {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 2rpx 14rpx;
border: 2rpx solid #000;
border-radius: 6rpx;
span {
line-height: 34rpx;
}
}
}
.info-detail {
span {
color: $theme-hint-text;
line-height: 40rpx;
}
}
}
}
</style>

179
src/pages/search/index.vue Normal file
View File

@ -0,0 +1,179 @@
<template>
<div class="outer-layer search-page">
<div class="root">
<div class="searchRoot">
<tm-input
class="searchRoot_input"
placeholder="请输入…"
color="#F9F9FD"
:round="1"
prefix="tmicon-search"
prefixColor="#46299D"
v-model.lazy="state.searchText"
@input="inputSearchText"
></tm-input>
<span
class="searchRoot_cancelBtn text-[32rpx] font-medium"
@click="cancelSearch"
>
{{ $t('cancel') }}
</span>
</div>
<div
class="search-result"
:style="
!state.searchText ? 'align-items:center;justify-content:center;' : ''
"
>
<div class="search-result-list">
<div
class="search-result-each-part"
v-for="(searchResultValue,
searchResultKey,
searchResultIndex) in state.searchResult"
:key="searchResultKey"
>
<div class="result-title"></div>
<div class="result-list">
<searchItem
v-for="(item, index) in state?.searchResult[searchResultKey]"
:key="index"
:searchResultKey="searchResultKey"
:searchItem="item"
></searchItem>
</div>
<div class="result-has-more"></div>
</div>
</div>
<div class="search-no-result" v-if="!state.searchText">
<img
src="/src/static//image/search/search-no-data.png"
mode="widthFix"
/>
<span class="text-[28rpx] font-regular">{{ $t('search.hint') }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import searchItem from './components/searchItem.vue'
import { ServeSeachQueryAll } from '@/api/search/index'
import { ref, watch, computed, onMounted, onUnmounted, reactive } from 'vue'
import { useAuth } from '@/store/auth'
const state = reactive({
searchText: '', //
searchResult: null, //
searchResultPageSize: 3, //
})
//
const inputSearchText = (e) => {
console.log(e)
let searchText = e
queryAllSearch(searchText)
}
// ES-
const queryAllSearch = (searchText) => {
let params = {
key: searchText, //
size: state.searchResultPageSize,
}
const resp = ServeSeachQueryAll(params)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
state.searchResult = data
} else {
}
})
resp.catch(() => {})
}
//
const cancelSearch = () => {
uni.navigateBack({
delta: 1,
})
}
</script>
<style scoped lang="scss">
uni-page-body,
page {
height: 100%;
}
.outer-layer {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.root {
flex: 1;
padding: 20rpx 32rpx;
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.search-page {
.searchRoot {
padding: 0 16rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
.searchRoot_input {
width: 100%;
}
.searchRoot_cancelBtn {
line-height: 44rpx;
color: $theme-primary;
margin: 0 0 0 20rpx;
flex-shrink: 0;
}
}
.search-result {
width: 100%;
flex: 1;
min-height: 0;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
.search-result-list {
padding: 10rpx 18rpx;
}
.search-no-result {
width: 476rpx;
height: 261rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
img {
width: 100%;
height: 100%;
}
span {
color: $theme-hint-text;
margin: -20rpx 0 0;
line-height: 40rpx;
}
}
}
}
</style>

View File

@ -1 +1,3 @@
$theme-primary: #46299D; $theme-primary: #46299d;
$theme-text: #191919;
$theme-hint-text: #999999;

3
src/static/css/font.scss Normal file
View File

@ -0,0 +1,3 @@
.font-regular {
font-weight: 400;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -72,5 +72,9 @@
"message.action.text": "进行注销操作", "message.action.text": "进行注销操作",
"index.mine.upload": "点击上传", "index.mine.upload": "点击上传",
"index.mine.reUpload": "重新上传", "index.mine.reUpload": "重新上传",
"index.mine.loading":"载入中" "index.mine.loading": "载入中",
"cancel": "取消",
"search.hint": "检索您要查找的内容吧~",
"search.chat.count": "条相关聊天记录",
"index.mine.project": "项目"
} }