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

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

@ -1,7 +1,7 @@
{
"easycom":{
"easycom": {
"autoscan": true,
"custom":{
"custom": {
"^tm-(.*)": "@/tmui/components/tm-$1/tm-$1.vue"
}
},
@ -11,7 +11,7 @@
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
"enablePullDownRefresh": false
}
},
{
@ -19,7 +19,7 @@
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
"enablePullDownRefresh": false
}
},
{
@ -27,7 +27,7 @@
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
"enablePullDownRefresh": false
}
},
{
@ -35,7 +35,7 @@
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
"enablePullDownRefresh": false
}
},
{
@ -43,7 +43,7 @@
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
"enablePullDownRefresh": false
}
},
{
@ -51,7 +51,7 @@
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
"enablePullDownRefresh": false
}
},
{
@ -64,7 +64,7 @@
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
"enablePullDownRefresh": false
}
},
{
@ -72,18 +72,23 @@
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh":false
"enablePullDownRefresh": false
}
},
{
"path": "pages/search/moreResult/moreResultDetail",
"type": "page",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {
"backgroundColor": "#FFFFFF",
"navigationBarBackgroundColor": "#FFFFFF",
"navigationBarTextstyle": "black",
"navigationBarTitleText":""
"navigationBarTitleText": ""
},
"subPackages": []
}

View File

@ -1,5 +1,13 @@
<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">
<img v-if="avatarImg !== 'textImg'" :src="avatarImg" />
<span v-if="avatarImg === 'textImg'" class="text-[32rpx] font-bold">
@ -7,9 +15,16 @@
</span>
</div>
<div class="result-info">
<div class="info-name">
<div
class="info-name"
:class="searchRecordDetail ? 'info-name-searchRecordDetail' : ''"
>
<HighlightText
class="text-[32rpx] font-medium"
:class="
searchRecordDetail
? 'text-[24rpx] font-medium'
: 'text-[32rpx] font-medium'
"
:text="resultName"
:searchText="props.searchText"
/>
@ -20,7 +35,7 @@
</div>
<div
class="info-tag"
v-if="resultType"
v-if="resultType && !searchRecordDetail"
:style="'border-color:' + resultTypeColor"
>
<span
@ -30,8 +45,17 @@
{{ resultType }}
</span>
</div>
<div v-if="searchRecordDetail && chatRecordCreatedAt">
<span class="text-[24rpx] font-medium">
{{ chatRecordCreatedAt }}
</span>
</div>
</div>
<div class="info-detail" v-if="resultDetail">
<div
class="info-detail"
v-if="resultDetail"
:class="searchRecordDetail ? 'info-detail-searchRecordDetail' : ''"
>
<HighlightText
class="text-[28rpx] font-regular"
:text="resultDetail"
@ -39,6 +63,9 @@
/>
</div>
</div>
<div class="search-item-pointer" v-if="pointerIconSrc">
<img :src="pointerIconSrc" />
</div>
</div>
</template>
<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 zu4989 from '@/static/image/chatList/zu4989@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 { useI18n } from 'vue-i18n'
import { beautifyTime } from '@/utils/datetime'
const { t } = useI18n()
const props = defineProps({
searchItem: Object | Number,
searchResultKey: String,
searchText: String,
searchText: String, //
searchRecordDetail: Boolean, //
pointerIconSrc: String, //
})
// -
const keyMapping = {
@ -99,12 +137,23 @@ const keyMapping = {
detailKey: 'count',
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
const getKeyValue = (keys) => {
let keyValue = ''
if (keys) {
keyValue = props.searchItem[keys]
keyValue = props?.searchItem ? props?.searchItem[keys] : ''
}
return keyValue
}
@ -162,6 +211,11 @@ const resultType = computed(() => {
const resultTypeColor = computed(() => {
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(() => {
let result_detail =
@ -173,6 +227,9 @@ const resultDetail = computed(() => {
case 'user_name':
result_detail = t('search.result.include') + result_detail
break
case 'extra':
result_detail = JSON.parse(props.searchItem?.extra).content
break
default:
result_detail = ''
}
@ -202,6 +259,7 @@ const resultDetail = computed(() => {
align-items: center;
justify-content: center;
background: linear-gradient(to right, #674bbc, #46299d);
flex-shrink: 0;
img {
width: 100%;
height: 100%;
@ -212,6 +270,7 @@ const resultDetail = computed(() => {
}
}
.result-info {
width: 100%;
.info-name {
display: flex;
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 {
span {
color: $theme-hint-text;
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>

View File

@ -1,65 +1,282 @@
<template>
<div class="search-list">
<div class="search-result-list">
<div
class="search-result-each-part"
v-for="(searchResultValue,
searchResultKey,
searchResultIndex) in props.searchResult"
:key="searchResultKey"
>
<div
class="search-result-part"
v-if="
Array.isArray(props?.searchResult[searchResultKey]) &&
props?.searchResult[searchResultKey].length > 0 &&
searchResultKey !== 'group_infos' &&
searchResultKey !== 'group_member_infos'
"
>
<div class="result-title">
<span class="text-[28rpx] font-regular">
{{ getResultKeysValue(searchResultKey) }}
</span>
</div>
<div class="result-list">
<div
class="result-list-each"
v-for="(item, index) in props?.searchResult[searchResultKey]"
:key="index"
>
<searchItem
v-if="(props.listLimit && index < 3) || !props.listLimit"
:searchResultKey="searchResultKey"
:searchItem="item"
:searchText="props.searchText"
></searchItem>
</div>
</div>
<div
class="result-has-more"
v-if="getHasMoreResult(searchResultKey)"
@click="toMoreResultPage(searchResultKey)"
<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"
>
<span class="text-[28rpx] font-regular">
{{ getHasMoreResult(searchResultKey) }}
</span>
{{ $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-each-part"
v-for="(searchResultValue,
searchResultKey,
searchResultIndex) in state.searchResult"
:key="searchResultKey"
>
<div
class="search-result-part"
v-if="
Array.isArray(state?.searchResult[searchResultKey]) &&
state?.searchResult[searchResultKey].length > 0 &&
searchResultKey !== 'group_infos' &&
searchResultKey !== 'group_member_infos'
"
>
<div class="result-title">
<span class="text-[28rpx] font-regular">
{{ getResultKeysValue(searchResultKey) }}
</span>
</div>
<div class="result-list">
<div
class="result-list-each"
v-for="(item, index) in state?.searchResult[searchResultKey]"
:key="index"
>
<searchItem
@click="clickSearchItem(searchResultKey, item)"
v-if="(props.listLimit && index < 3) || !props.listLimit"
:searchResultKey="searchResultKey"
:searchItem="item"
:searchText="state.searchText"
:searchRecordDetail="props.searchRecordDetail"
></searchItem>
</div>
</div>
<div
class="result-has-more"
v-if="getHasMoreResult(searchResultKey)"
@click="toMoreResultPage(searchResultKey)"
>
<span class="text-[28rpx] font-regular">
{{ getHasMoreResult(searchResultKey) }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</ZPaging>
</div>
</template>
<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 { useI18n } from 'vue-i18n'
const props = defineProps({
searchResult: Object,
searchText: String,
listLimit: Boolean,
import { ref, reactive, defineEmits, defineProps, onMounted } from 'vue'
import pointerIconSrc from '@/static/image/search/search-item-pointer.png'
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()
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
const getResultKeysValue = (keys) => {
let resultKey = ''
@ -79,6 +296,9 @@ const getResultKeysValue = (keys) => {
case 'general_infos':
resultKey = t('chat.type.record')
break
case 'talk_record_infos':
resultKey = t('search.result.relevant') + t('chat.type.record')
break
default:
resultKey = ''
}
@ -91,32 +311,32 @@ const getHasMoreResult = (searchResultKey) => {
switch (searchResultKey) {
case 'user_infos':
if (
props.searchResult['user_count'] &&
props.searchResult['user_count'] > 3
state.searchResult['user_count'] &&
state.searchResult['user_count'] > 3
) {
has_more_result = t('has_more') + t('index.mine.addressBook')
}
break
case 'group_infos':
if (
props.searchResult['group_count'] &&
props.searchResult['group_count'] > 3
state.searchResult['group_count'] &&
state.searchResult['group_count'] > 3
) {
has_more_result = t('has_more') + t('chat.type.group')
}
break
case 'group_member_infos':
if (
props.searchResult['group_count'] &&
props.searchResult['group_count'] > 3
state.searchResult['group_count'] &&
state.searchResult['group_count'] > 3
) {
has_more_result = t('has_more') + t('chat.type.group')
}
break
case 'combinedGroup':
if (
props.searchResult['group_count'] &&
props.searchResult['group_count'] > 3
state.searchResult['group_count'] &&
state.searchResult['group_count'] > 3
) {
has_more_result = t('has_more') + t('chat.type.group')
}
@ -130,42 +350,71 @@ const getHasMoreResult = (searchResultKey) => {
//
const toMoreResultPage = (searchResultKey) => {
uni.navigateTo({
url:
'/pages/search/moreResult/moreResult?searchResultKey=' +
searchResultKey +
'&searchText=' +
props.searchText,
})
emits('toMoreResultPage', searchResultKey, state.searchText)
}
//
const clickSearchItem = (searchResultKey, searchItem) => {
emits(
'clickSearchItem',
state.searchText,
searchResultKey,
searchItem.talk_type,
searchItem.receiver_id,
)
}
</script>
<style lang="scss" scoped>
.search-list {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
.search-result-list {
.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-record-detail {
padding: 0 50rpx;
}
.search-result {
width: 100%;
padding: 0 18rpx;
padding: 0 32rpx;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
.search-result-list {
width: 100%;
padding: 0 18rpx;
.search-result-part {
margin: 36rpx 0 0;
.search-result-part {
margin: 36rpx 0 0;
.result-title {
padding: 0 0 10rpx;
span {
line-height: 40rpx;
color: $theme-hint-text;
.result-title {
padding: 0 0 10rpx;
span {
line-height: 40rpx;
color: $theme-hint-text;
}
}
}
.result-has-more {
padding: 10px 0;
border-bottom: 1px solid $theme-border-color;
span {
color: #191919;
line-height: 40rpx;
.result-has-more {
padding: 10px 0;
border-bottom: 1px solid $theme-border-color;
span {
color: #191919;
line-height: 40rpx;
}
}
}
}

View File

@ -1,179 +1,50 @@
<template>
<div class="outer-layer search-page">
<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
:searchResult="state.searchResult"
:searchText="state.searchText"
:listLimit="true"
></searchList>
</div>
</ZPaging>
<searchList
:searchResultPageSize="3"
:listLimit="true"
:apiRequest="ServeSeachQueryAll"
@toMoreResultPage="toMoreResultPage"
@clickSearchItem="clickSearchItem"
></searchList>
</div>
</div>
</template>
<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 { 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 state = reactive({
searchText: '', //
searchResultList: [], //
searchResult: null, //
searchResultPageSize: 3, //
})
//
const inputSearchText = (e) => {
// console.log(e)
state.searchText = e
zPaging.value?.reload()
//
const toMoreResultPage = (searchResultKey, searchText) => {
uni.navigateTo({
url:
'/pages/search/moreResult/moreResult?searchResultKey=' +
searchResultKey +
'&searchText=' +
searchText,
})
}
// ES-
const queryAllSearch = () => {
let params = {
key: state.searchText, //
size: state.searchResultPageSize,
//
const clickSearchItem = (
searchText,
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,
})
}
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 = () => {
uni.navigateBack({
delta: 1,
})
}
</script>
<style scoped lang="scss">
.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>
<style scoped lang="scss"></style>

View File

@ -1,65 +1,20 @@
<template>
<div class="outer-layer search-page">
<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
:searchResult="state.searchResult"
:searchText="state.searchText"
:listLimit="false"
></searchList>
</div>
</ZPaging>
<searchList
:searchResultPageSize="10"
:listLimit="false"
:apiRequest="state.apiRequest"
:apiParams="state.apiParams"
:searchText="state.searchText"
:isPagination="true"
@lastIdChange="lastIdChange"
@clickSearchItem="clickSearchItem"
></searchList>
</div>
</div>
</template>
<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 { onLoad } from '@dcloudio/uni-app'
import {
@ -67,177 +22,72 @@ import {
ServeQueryGroup,
ServeTalkRecord,
} 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)
import { reactive } from 'vue'
const state = reactive({
searchText: '', //
searchResultList: [], //
searchResult: null, //
searchResultPageSize: 10, //
searchResultKey: '',
apiRequest: Function,
apiParams: String,
searchText: String,
})
onLoad((options) => {
console.log(options)
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) {
state.searchText = options.searchText
}
})
//
const inputSearchText = (e) => {
// console.log(e)
state.searchText = e
zPaging.value?.reload()
}
// ES-
const queryAllSearch = () => {
let params = {}
let resp = null
if (state.searchResultKey === 'user_infos') {
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)
//id
const lastIdChange = (last_id, last_group_id, last_member_id) => {
let idChanges = {
last_id,
last_group_id,
last_member_id,
}
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([])
})
state.apiParams = encodeURIComponent(
JSON.stringify(
Object.assign(
{},
JSON.parse(decodeURIComponent(state.apiParams)),
idChanges,
),
),
)
}
//
const cancelSearch = () => {
uni.navigateBack({
delta: 1,
//
const clickSearchItem = (searchText) => {
uni.navigateTo({
url: '/pages/search/moreResult/moreResultDetail?searchText=' + searchText,
})
}
</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: 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>
<style scoped lang="scss"></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": "聊天记录",
"search.result.include": "包含:",
"has_more": "更多",
"index.type.company": "公司"
"index.type.company": "公司",
"search.result.relevant": "相关"
}