新增搜索聊天结果详情页面;处理页面与组件间的联动与传参

This commit is contained in:
wangyifeng 2024-12-31 17:01:18 +08:00
parent 82d6d529ba
commit bfde37b111
8 changed files with 595 additions and 481 deletions

View File

@ -74,16 +74,21 @@
"navigationStyle": "custom", "navigationStyle": "custom",
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
},
{
"path": "pages/search/moreResult/moreResultDetail",
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
} }
], ],
"globalStyle": { "globalStyle": {
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"navigationBarBackgroundColor": "#FFFFFF", "navigationBarBackgroundColor": "#FFFFFF",
"navigationBarTextstyle": "black", "navigationBarTextstyle": "black",
"navigationBarTitleText": "" "navigationBarTitleText": ""
}, },
"subPackages": [] "subPackages": []
} }

View File

@ -1,5 +1,13 @@
<template> <template>
<div class="search-item" v-if="resultName"> <div
class="search-item"
v-if="resultName"
:style="
props.searchResultKey === 'talk_record_infos_receiver'
? 'margin: 24rpx 0 0'
: ''
"
>
<div class="avatar-img"> <div class="avatar-img">
<img v-if="avatarImg !== 'textImg'" :src="avatarImg" /> <img v-if="avatarImg !== 'textImg'" :src="avatarImg" />
<span v-if="avatarImg === 'textImg'" class="text-[32rpx] font-bold"> <span v-if="avatarImg === 'textImg'" class="text-[32rpx] font-bold">
@ -7,9 +15,16 @@
</span> </span>
</div> </div>
<div class="result-info"> <div class="result-info">
<div class="info-name"> <div
class="info-name"
:class="searchRecordDetail ? 'info-name-searchRecordDetail' : ''"
>
<HighlightText <HighlightText
class="text-[32rpx] font-medium" :class="
searchRecordDetail
? 'text-[24rpx] font-medium'
: 'text-[32rpx] font-medium'
"
:text="resultName" :text="resultName"
:searchText="props.searchText" :searchText="props.searchText"
/> />
@ -20,7 +35,7 @@
</div> </div>
<div <div
class="info-tag" class="info-tag"
v-if="resultType" v-if="resultType && !searchRecordDetail"
:style="'border-color:' + resultTypeColor" :style="'border-color:' + resultTypeColor"
> >
<span <span
@ -30,8 +45,17 @@
{{ resultType }} {{ resultType }}
</span> </span>
</div> </div>
<div v-if="searchRecordDetail && chatRecordCreatedAt">
<span class="text-[24rpx] font-medium">
{{ chatRecordCreatedAt }}
</span>
</div> </div>
<div class="info-detail" v-if="resultDetail"> </div>
<div
class="info-detail"
v-if="resultDetail"
:class="searchRecordDetail ? 'info-detail-searchRecordDetail' : ''"
>
<HighlightText <HighlightText
class="text-[28rpx] font-regular" class="text-[28rpx] font-regular"
:text="resultDetail" :text="resultDetail"
@ -39,6 +63,9 @@
/> />
</div> </div>
</div> </div>
<div class="search-item-pointer" v-if="pointerIconSrc">
<img :src="pointerIconSrc" />
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
@ -46,14 +73,25 @@ import zu4992 from '@/static/image/chatList/zu4992@2x.png'
import zu4991 from '@/static/image/chatList/zu4991@2x.png' import zu4991 from '@/static/image/chatList/zu4991@2x.png'
import zu4989 from '@/static/image/chatList/zu4989@2x.png' import zu4989 from '@/static/image/chatList/zu4989@2x.png'
import zu5296 from '@/static/image/chatList/zu5296@2x.png' import zu5296 from '@/static/image/chatList/zu5296@2x.png'
import { ref, watch, computed, onMounted, onUnmounted, reactive } from 'vue' import {
ref,
watch,
computed,
onMounted,
onUnmounted,
reactive,
defineProps,
} from 'vue'
import HighlightText from './highLightText.vue' import HighlightText from './highLightText.vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { beautifyTime } from '@/utils/datetime'
const { t } = useI18n() const { t } = useI18n()
const props = defineProps({ const props = defineProps({
searchItem: Object | Number, searchItem: Object | Number,
searchResultKey: String, searchResultKey: String,
searchText: String, searchText: String, //
searchRecordDetail: Boolean, //
pointerIconSrc: String, //
}) })
// - // -
const keyMapping = { const keyMapping = {
@ -99,12 +137,23 @@ const keyMapping = {
detailKey: 'count', detailKey: 'count',
group_num: 'group_num', group_num: 'group_num',
}, },
talk_record_infos: {
avatar: 'user_avatar',
name: 'user_name',
detailKey: 'extra',
created_at: 'created_at',
},
talk_record_infos_receiver: {
avatar: 'receiver_avatar',
name: 'receiver_name',
group_num: 'group_num',
},
} }
//key //key
const getKeyValue = (keys) => { const getKeyValue = (keys) => {
let keyValue = '' let keyValue = ''
if (keys) { if (keys) {
keyValue = props.searchItem[keys] keyValue = props?.searchItem ? props?.searchItem[keys] : ''
} }
return keyValue return keyValue
} }
@ -162,6 +211,11 @@ const resultType = computed(() => {
const resultTypeColor = computed(() => { const resultTypeColor = computed(() => {
return groupTypeMapping[props.searchItem?.group_type]?.result_type_color return groupTypeMapping[props.searchItem?.group_type]?.result_type_color
}) })
//-
const chatRecordCreatedAt = computed(() => {
let created_at = getKeyValue(keyMapping[props.searchResultKey]?.created_at)
return beautifyTime(created_at)
})
// //
const resultDetail = computed(() => { const resultDetail = computed(() => {
let result_detail = let result_detail =
@ -173,6 +227,9 @@ const resultDetail = computed(() => {
case 'user_name': case 'user_name':
result_detail = t('search.result.include') + result_detail result_detail = t('search.result.include') + result_detail
break break
case 'extra':
result_detail = JSON.parse(props.searchItem?.extra).content
break
default: default:
result_detail = '' result_detail = ''
} }
@ -202,6 +259,7 @@ const resultDetail = computed(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: linear-gradient(to right, #674bbc, #46299d); background: linear-gradient(to right, #674bbc, #46299d);
flex-shrink: 0;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -212,6 +270,7 @@ const resultDetail = computed(() => {
} }
} }
.result-info { .result-info {
width: 100%;
.info-name { .info-name {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -234,12 +293,39 @@ const resultDetail = computed(() => {
} }
} }
} }
.info-name-searchRecordDetail {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
span {
color: $theme-hint-text;
line-height: 34rpx;
}
}
.info-detail { .info-detail {
span { span {
color: $theme-hint-text; color: $theme-hint-text;
line-height: 40rpx; line-height: 40rpx;
} }
} }
.info-detail-searchRecordDetail {
span {
color: $theme-text;
}
}
}
.search-item-pointer {
width: 11rpx;
height: 18rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
img {
width: 100%;
height: 100%;
}
} }
} }
</style> </style>

View File

@ -1,18 +1,77 @@
<template> <template>
<div class="search-list"> <div class="search-list">
<ZPaging
ref="zPaging"
:show-scrollbar="false"
v-model="state.searchResultList"
@query="queryAllSearch"
:default-page-no="state.pageNum"
:default-page-size="props.searchResultPageSize"
:loading-more-default-as-loading="true"
:inside-more="true"
:empty-view-img="'/src/static//image/search/search-no-data.png'"
:empty-view-text="$t('search.hint')"
:empty-view-img-style="{ width: '476rpx', height: '261rpx' }"
:empty-view-title-style="{
color: '#999999',
margin: '-20rpx 0 0',
'line-height': '40rpx',
'font-size': '28rpx',
'font-weight': 400,
}"
>
<template #top>
<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>
</template>
<div class="search-record-detail" v-if="props.searchRecordDetail">
<searchItem
@click="
clickSearchItem(
'talk_record_infos_receiver',
state?.first_talk_record_infos,
)
"
searchResultKey="talk_record_infos_receiver"
:searchItem="state?.first_talk_record_infos"
:pointerIconSrc="pointerIconSrc"
></searchItem>
</div>
<div
class="search-result"
:style="
!state.searchText ? 'align-items:center;justify-content:center;' : ''
"
>
<div class="search-result-list"> <div class="search-result-list">
<div <div
class="search-result-each-part" class="search-result-each-part"
v-for="(searchResultValue, v-for="(searchResultValue,
searchResultKey, searchResultKey,
searchResultIndex) in props.searchResult" searchResultIndex) in state.searchResult"
:key="searchResultKey" :key="searchResultKey"
> >
<div <div
class="search-result-part" class="search-result-part"
v-if=" v-if="
Array.isArray(props?.searchResult[searchResultKey]) && Array.isArray(state?.searchResult[searchResultKey]) &&
props?.searchResult[searchResultKey].length > 0 && state?.searchResult[searchResultKey].length > 0 &&
searchResultKey !== 'group_infos' && searchResultKey !== 'group_infos' &&
searchResultKey !== 'group_member_infos' searchResultKey !== 'group_member_infos'
" "
@ -25,14 +84,16 @@
<div class="result-list"> <div class="result-list">
<div <div
class="result-list-each" class="result-list-each"
v-for="(item, index) in props?.searchResult[searchResultKey]" v-for="(item, index) in state?.searchResult[searchResultKey]"
:key="index" :key="index"
> >
<searchItem <searchItem
@click="clickSearchItem(searchResultKey, item)"
v-if="(props.listLimit && index < 3) || !props.listLimit" v-if="(props.listLimit && index < 3) || !props.listLimit"
:searchResultKey="searchResultKey" :searchResultKey="searchResultKey"
:searchItem="item" :searchItem="item"
:searchText="props.searchText" :searchText="state.searchText"
:searchRecordDetail="props.searchRecordDetail"
></searchItem> ></searchItem>
</div> </div>
</div> </div>
@ -49,17 +110,173 @@
</div> </div>
</div> </div>
</div> </div>
</ZPaging>
</div>
</template> </template>
<script setup> <script setup>
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import searchItem from './searchItem.vue' import searchItem from './searchItem.vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const props = defineProps({ import { ref, reactive, defineEmits, defineProps, onMounted } from 'vue'
searchResult: Object, import pointerIconSrc from '@/static/image/search/search-item-pointer.png'
searchText: String,
listLimit: Boolean, const zPaging = ref()
useZPaging(zPaging)
const emits = defineEmits([
'toMoreResultPage',
'lastIdChange',
'clickSearchItem',
])
const state = reactive({
searchText: '', //
searchResultList: [], //
searchResult: null, //
pageNum: 1, //
}) })
const props = defineProps({
searchResultPageSize: Number, //
listLimit: Boolean, //
apiParams: String, //
apiRequest: Function, //
searchText: String, //
isPagination: Boolean, //
searchRecordDetail: Boolean, //
first_talk_record_infos: Object, //
})
const { t } = useI18n() const { t } = useI18n()
onMounted(() => {
if (props.searchText) {
state.searchText = props.searchText
}
})
//
const inputSearchText = (e) => {
// console.log(e)
if (e.trim() != state.searchText.trim()) {
state.pageNum = 1
emits('lastIdChange', 0, 0, 0)
}
state.searchText = e.trim()
if (!e.trim()) {
emits('lastIdChange', 0, 0, 0)
}
zPaging.value?.reload()
}
// ES-
const queryAllSearch = (pageNum, searchResultPageSize) => {
let params = {
key: state.searchText, //
size: searchResultPageSize,
}
if (props.apiParams) {
let apiParams = JSON.parse(decodeURIComponent(props.apiParams))
params = Object.assign({}, params, apiParams)
}
const resp = props.apiRequest(params)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
if ((data.user_infos || []).length > 0) {
;(data.user_infos || []).forEach((item) => {
item.group_type = 0
})
}
if ((data.group_infos || []).length > 0) {
;(data.group_infos || []).forEach((item) => {
item.group_type = item.type
item.groupTempType = 'group_infos'
})
}
if ((data.group_member_infos || []).length > 0) {
;(data.group_member_infos || []).forEach((item) => {
item.groupTempType = 'group_member_infos'
})
}
if ((data.talk_record_infos || []).length > 0) {
state.first_talk_record_infos = Object.assign(
{},
state.first_talk_record_infos,
data.talk_record_infos[0],
)
;(data.talk_record_infos || []).forEach((item) => {
item.group_type = 0
})
}
let tempGeneral_infos = Array.isArray(data.general_infos)
? [...data.general_infos]
: data.general_infos
delete data.general_infos
data.combinedGroup = (data.group_infos || []).concat(
data.group_member_infos || [],
)
data.general_infos = tempGeneral_infos
let isEmpty = true
let dataKeys = Object.keys(data)
let paginationKey = ''
dataKeys.forEach((item) => {
if (Array.isArray(data[item]) && data[item].length > 0) {
paginationKey = item
isEmpty = false
}
})
if (isEmpty) {
if (pageNum == 1) {
zPaging.value?.complete([])
} else {
data = state.searchResult
zPaging.value?.complete([data])
}
} else {
if (props.isPagination) {
if (
paginationKey &&
Array.isArray(
(state?.searchResult && state?.searchResult[paginationKey]) || [],
) &&
((state?.searchResult && state?.searchResult[paginationKey]) || [])
.length > 0
) {
data[paginationKey] = state.searchResult[paginationKey].concat(
data[paginationKey],
)
}
emits(
'lastIdChange',
data.last_id,
data.last_group_id,
data.last_member_id,
)
zPaging.value?.completeByTotal([data], data.count)
} else {
zPaging.value?.complete([data])
}
}
state.searchResult = data
} else {
zPaging.value?.complete([])
}
})
resp.catch(() => {
zPaging.value?.complete([])
})
}
//
const cancelSearch = () => {
uni.navigateBack({
delta: 1,
})
}
//key //key
const getResultKeysValue = (keys) => { const getResultKeysValue = (keys) => {
let resultKey = '' let resultKey = ''
@ -79,6 +296,9 @@ const getResultKeysValue = (keys) => {
case 'general_infos': case 'general_infos':
resultKey = t('chat.type.record') resultKey = t('chat.type.record')
break break
case 'talk_record_infos':
resultKey = t('search.result.relevant') + t('chat.type.record')
break
default: default:
resultKey = '' resultKey = ''
} }
@ -91,32 +311,32 @@ const getHasMoreResult = (searchResultKey) => {
switch (searchResultKey) { switch (searchResultKey) {
case 'user_infos': case 'user_infos':
if ( if (
props.searchResult['user_count'] && state.searchResult['user_count'] &&
props.searchResult['user_count'] > 3 state.searchResult['user_count'] > 3
) { ) {
has_more_result = t('has_more') + t('index.mine.addressBook') has_more_result = t('has_more') + t('index.mine.addressBook')
} }
break break
case 'group_infos': case 'group_infos':
if ( if (
props.searchResult['group_count'] && state.searchResult['group_count'] &&
props.searchResult['group_count'] > 3 state.searchResult['group_count'] > 3
) { ) {
has_more_result = t('has_more') + t('chat.type.group') has_more_result = t('has_more') + t('chat.type.group')
} }
break break
case 'group_member_infos': case 'group_member_infos':
if ( if (
props.searchResult['group_count'] && state.searchResult['group_count'] &&
props.searchResult['group_count'] > 3 state.searchResult['group_count'] > 3
) { ) {
has_more_result = t('has_more') + t('chat.type.group') has_more_result = t('has_more') + t('chat.type.group')
} }
break break
case 'combinedGroup': case 'combinedGroup':
if ( if (
props.searchResult['group_count'] && state.searchResult['group_count'] &&
props.searchResult['group_count'] > 3 state.searchResult['group_count'] > 3
) { ) {
has_more_result = t('has_more') + t('chat.type.group') has_more_result = t('has_more') + t('chat.type.group')
} }
@ -130,22 +350,50 @@ const getHasMoreResult = (searchResultKey) => {
// //
const toMoreResultPage = (searchResultKey) => { const toMoreResultPage = (searchResultKey) => {
uni.navigateTo({ emits('toMoreResultPage', searchResultKey, state.searchText)
url: }
'/pages/search/moreResult/moreResult?searchResultKey=' +
searchResultKey + //
'&searchText=' + const clickSearchItem = (searchResultKey, searchItem) => {
props.searchText, emits(
}) 'clickSearchItem',
state.searchText,
searchResultKey,
searchItem.talk_type,
searchItem.receiver_id,
)
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.search-list { .search-list {
width: 100%; .searchRoot {
padding: 20rpx 48rpx;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: 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-record-detail {
padding: 0 50rpx;
}
.search-result {
width: 100%;
padding: 0 32rpx;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
.search-result-list { .search-result-list {
width: 100%; width: 100%;
padding: 0 18rpx; padding: 0 18rpx;
@ -171,4 +419,5 @@ const toMoreResultPage = (searchResultKey) => {
} }
} }
} }
}
</style> </style>

View File

@ -1,179 +1,50 @@
<template> <template>
<div class="outer-layer search-page"> <div class="outer-layer search-page">
<div class="root"> <div class="root">
<ZPaging
ref="zPaging"
:show-scrollbar="false"
v-model="state.searchResultList"
@query="queryAllSearch"
:empty-view-img="'/src/static//image/search/search-no-data.png'"
:empty-view-text="$t('search.hint')"
:empty-view-img-style="{ width: '476rpx', height: '261rpx' }"
:empty-view-title-style="{
color: '#999999',
margin: '-20rpx 0 0',
'line-height': '40rpx',
'font-size': '28rpx',
'font-weight': 400,
}"
>
<template #top>
<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>
</template>
<div
class="search-result"
:style="
!state.searchText
? 'align-items:center;justify-content:center;'
: ''
"
>
<searchList <searchList
:searchResult="state.searchResult" :searchResultPageSize="3"
:searchText="state.searchText"
:listLimit="true" :listLimit="true"
:apiRequest="ServeSeachQueryAll"
@toMoreResultPage="toMoreResultPage"
@clickSearchItem="clickSearchItem"
></searchList> ></searchList>
</div> </div>
</ZPaging>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import searchList from './components/searchList.vue' import searchList from './components/searchList.vue'
import { ServeSeachQueryAll } from '@/api/search/index' import { ServeSeachQueryAll } from '@/api/search/index'
import { ref, watch, computed, onMounted, onUnmounted, reactive } from 'vue'
import { useAuth } from '@/store/auth'
import { nextTick } from 'process'
const zPaging = ref() //
useZPaging(zPaging) const toMoreResultPage = (searchResultKey, searchText) => {
uni.navigateTo({
const state = reactive({ url:
searchText: '', // '/pages/search/moreResult/moreResult?searchResultKey=' +
searchResultList: [], // searchResultKey +
searchResult: null, // '&searchText=' +
searchResultPageSize: 3, // searchText,
})
//
const inputSearchText = (e) => {
// console.log(e)
state.searchText = e
zPaging.value?.reload()
}
// ES-
const queryAllSearch = () => {
let params = {
key: state.searchText, //
size: state.searchResultPageSize,
}
const resp = ServeSeachQueryAll(params)
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
if ((data.user_infos || []).length > 0) {
;(data.user_infos || []).forEach((item) => {
item.group_type = 0
})
}
if ((data.group_infos || []).length > 0) {
;(data.group_infos || []).forEach((item) => {
item.group_type = item.type
item.groupTempType = 'group_infos'
})
}
if ((data.group_member_infos || []).length > 0) {
;(data.group_member_infos || []).forEach((item) => {
item.groupTempType = 'group_member_infos'
})
}
let tempGeneral_infos = Array.isArray(data.general_infos)
? [...data.general_infos]
: data.general_infos
delete data.general_infos
data.combinedGroup = (data.group_infos || []).concat(
data.group_member_infos || [],
)
data.general_infos = tempGeneral_infos
state.searchResult = data
let isEmpty = true
let dataKeys = Object.keys(data)
dataKeys.forEach((item) => {
if (Array.isArray(data[item]) && data[item].length > 0) {
console.log(data[item])
isEmpty = false
}
})
if (isEmpty) {
zPaging.value?.complete([])
} else {
zPaging.value?.complete([data])
}
} else {
zPaging.value?.complete([])
}
})
resp.catch(() => {
zPaging.value?.complete([])
}) })
} }
// //
const cancelSearch = () => { const clickSearchItem = (
uni.navigateBack({ searchText,
delta: 1, searchResultKey,
talk_type,
receiver_id,
) => {
console.log(searchResultKey)
if (searchResultKey === 'general_infos') {
uni.navigateTo({
url:
'/pages/search/moreResult/moreResultDetail?searchText=' +
searchText +
'&talk_type=' +
talk_type +
'&receiver_id=' +
receiver_id,
}) })
} }
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss"></style>
.search-page {
.searchRoot {
padding: 20rpx 48rpx;
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%;
padding: 0 32rpx;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
}
}
</style>

View File

@ -1,65 +1,20 @@
<template> <template>
<div class="outer-layer search-page"> <div class="outer-layer search-page">
<div class="root"> <div class="root">
<ZPaging
ref="zPaging"
:show-scrollbar="false"
v-model="state.searchResultList"
@query="queryAllSearch"
:empty-view-img="'/src/static//image/search/search-no-data.png'"
:empty-view-text="$t('search.hint')"
:empty-view-img-style="{ width: '476rpx', height: '261rpx' }"
:empty-view-title-style="{
color: '#999999',
margin: '-20rpx 0 0',
'line-height': '40rpx',
'font-size': '28rpx',
'font-weight': 400,
}"
:default-page-no="1"
:default-page-size="state.searchResultPageSize"
>
<template #top>
<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>
</template>
<div
class="search-result"
:style="
!state.searchText
? 'align-items:center;justify-content:center;'
: ''
"
>
<searchList <searchList
:searchResult="state.searchResult" :searchResultPageSize="10"
:searchText="state.searchText"
:listLimit="false" :listLimit="false"
:apiRequest="state.apiRequest"
:apiParams="state.apiParams"
:searchText="state.searchText"
:isPagination="true"
@lastIdChange="lastIdChange"
@clickSearchItem="clickSearchItem"
></searchList> ></searchList>
</div> </div>
</ZPaging>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import ZPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import useZPaging from '@/uni_modules/z-paging/components/z-paging/js/hooks/useZPaging.js'
import searchList from '../components/searchList.vue' import searchList from '../components/searchList.vue'
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import { import {
@ -67,177 +22,72 @@ import {
ServeQueryGroup, ServeQueryGroup,
ServeTalkRecord, ServeTalkRecord,
} from '@/api/search/index' } from '@/api/search/index'
import { ref, watch, computed, onMounted, onUnmounted, reactive } from 'vue' import { reactive } from 'vue'
import { useAuth } from '@/store/auth'
import { nextTick } from 'process'
const zPaging = ref()
useZPaging(zPaging)
const state = reactive({ const state = reactive({
searchText: '', // apiRequest: Function,
searchResultList: [], // apiParams: String,
searchResult: null, // searchText: String,
searchResultPageSize: 10, //
searchResultKey: '',
}) })
onLoad((options) => { onLoad((options) => {
console.log(options) console.log(options)
if (options.searchResultKey) { if (options.searchResultKey) {
state.searchResultKey = options.searchResultKey if (options.searchResultKey === 'user_infos') {
state.apiParams = encodeURIComponent(
JSON.stringify({
last_id: 0, //id
}),
)
state.apiRequest = ServeQueryUser
} else if (options.searchResultKey === 'combinedGroup') {
state.apiParams = encodeURIComponent(
JSON.stringify({
last_group_id: 0, //id
last_member_id: 0, //id
}),
)
state.apiRequest = ServeQueryGroup
} else if (options.searchResultKey === 'general_infos') {
state.apiParams = encodeURIComponent(
JSON.stringify({
talk_type: 0, //12
receiver_id: 0, //
last_group_id: 0, //id
last_member_id: 0, //id
}),
)
state.apiRequest = ServeTalkRecord
}
} }
if (options.searchText) { if (options.searchText) {
state.searchText = options.searchText state.searchText = options.searchText
} }
}) })
// //id
const inputSearchText = (e) => { const lastIdChange = (last_id, last_group_id, last_member_id) => {
// console.log(e) let idChanges = {
state.searchText = e last_id,
zPaging.value?.reload() last_group_id,
last_member_id,
} }
state.apiParams = encodeURIComponent(
// ES- JSON.stringify(
const queryAllSearch = () => { Object.assign(
let params = {} {},
let resp = null JSON.parse(decodeURIComponent(state.apiParams)),
if (state.searchResultKey === 'user_infos') { idChanges,
params = { ),
size: state.searchResultPageSize, // ),
key: state.searchText, //
last_id: 0, //id
}
resp = ServeQueryUser(params)
} else if (state.searchResultKey === 'combinedGroup') {
params = {
size: state.searchResultPageSize, //
key: state.searchText, //
last_group_id: 0, //id
last_member_id: 0, //id
}
resp = ServeQueryGroup(params)
} else if (state.searchResultKey === 'general_infos') {
params = {
talk_type: 0, //12
key: state.searchText, //
size: state.searchResultPageSize, //
receiver_id: 0, //
last_group_id: 0, //id
last_member_id: 0, //id
}
resp = ServeTalkRecord(params)
}
resp.then(({ code, data }) => {
console.log(data)
if (code == 200) {
if ((data.user_infos || []).length > 0) {
;(data.user_infos || []).forEach((item) => {
item.group_type = 0
})
}
if ((data.group_infos || []).length > 0) {
;(data.group_infos || []).forEach((item) => {
item.group_type = item.type
item.groupTempType = 'group_infos'
})
}
if ((data.group_member_infos || []).length > 0) {
;(data.group_member_infos || []).forEach((item) => {
item.groupTempType = 'group_member_infos'
})
}
let tempGeneral_infos = Array.isArray(data.general_infos)
? [...data.general_infos]
: data.general_infos
delete data.general_infos
data.combinedGroup = (data.group_infos || []).concat(
data.group_member_infos || [],
) )
data.general_infos = tempGeneral_infos
state.searchResult = data
let isEmpty = true
let dataKeys = Object.keys(data)
dataKeys.forEach((item) => {
if (Array.isArray(data[item]) && data[item].length > 0) {
console.log(data[item])
isEmpty = false
}
})
if (isEmpty) {
zPaging.value?.complete([])
} else {
zPaging.value?.complete([data])
}
} else {
zPaging.value?.complete([])
}
})
resp.catch(() => {
zPaging.value?.complete([])
})
} }
// //
const cancelSearch = () => { const clickSearchItem = (searchText) => {
uni.navigateBack({ uni.navigateTo({
delta: 1, url: '/pages/search/moreResult/moreResultDetail?searchText=' + searchText,
}) })
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss"></style>
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: 20rpx 48rpx;
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;
padding: 0 32rpx;
min-height: 0;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
}
}
</style>

View File

@ -0,0 +1,52 @@
<template>
<div class="outer-layer search-page">
<div class="root">
<searchList
:searchResultPageSize="10"
:listLimit="false"
:apiRequest="ServeTalkRecord"
:apiParams="state.apiParams"
:searchText="state.searchText"
:isPagination="true"
:searchRecordDetail="true"
></searchList>
</div>
</div>
</template>
<script setup>
import searchList from '../components/searchList.vue'
import { onLoad } from '@dcloudio/uni-app'
import { ServeTalkRecord } from '@/api/search/index'
import { reactive } from 'vue'
const state = reactive({
apiParams: String,
searchText: String,
})
onLoad((options) => {
console.log(options)
let talk_type = 0
if (options.talk_type) {
talk_type = Number(options.talk_type)
}
let receiver_id = 0
if (options.receiver_id) {
receiver_id = Number(options.receiver_id)
}
state.apiParams = encodeURIComponent(
JSON.stringify({
talk_type: talk_type, //12
receiver_id: receiver_id, //
last_group_id: 0, //id
last_member_id: 0, //id
}),
)
if (options.searchText) {
state.searchText = options.searchText
}
console.log(JSON.parse(decodeURIComponent(state.apiParams)))
})
</script>
<style scoped lang="scss"></style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

View File

@ -81,5 +81,6 @@
"chat.type.record": "聊天记录", "chat.type.record": "聊天记录",
"search.result.include": "包含:", "search.result.include": "包含:",
"has_more": "更多", "has_more": "更多",
"index.type.company": "公司" "index.type.company": "公司",
"search.result.relevant": "相关"
} }