修改搜索页面样式及数据接入

This commit is contained in:
wangyifeng 2024-12-30 13:28:29 +08:00
parent 4f43f1a001
commit e5afaf2cd8
4 changed files with 389 additions and 20 deletions

View File

@ -1,7 +1,10 @@
<template> <template>
<div class="search-item" v-if="resultName"> <div class="search-item" v-if="resultName">
<div class="avatar-img"> <div class="avatar-img">
<img :src="avatarImg" /> <img v-if="avatarImg !== 'textImg'" :src="avatarImg" />
<span v-if="avatarImg === 'textImg'" class="text-[32rpx] font-bold">
{{ imgText }}
</span>
</div> </div>
<div class="result-info"> <div class="result-info">
<div class="info-name"> <div class="info-name">
@ -10,8 +13,22 @@
:text="resultName" :text="resultName"
:searchText="props.searchText" :searchText="props.searchText"
/> />
<div class="info-tag" v-if="resultType"> <div class="info_num" v-if="groupNum">
<span class="text-[24rpx] font-medium">{{ resultType }}</span> <span class="text-[32rpx] font-medium">
{{ '' + groupNum + '' }}
</span>
</div>
<div
class="info-tag"
v-if="resultType"
:style="'border-color:' + resultTypeColor"
>
<span
class="text-[24rpx] font-medium"
:style="'color:' + resultTypeColor"
>
{{ resultType }}
</span>
</div> </div>
</div> </div>
<div class="info-detail" v-if="resultDetail"> <div class="info-detail" v-if="resultDetail">
@ -41,16 +58,46 @@ const props = defineProps({
// - // -
const keyMapping = { const keyMapping = {
user_infos: { avatar: 'avatar', name: 'nickname' }, user_infos: { avatar: 'avatar', name: 'nickname' },
group_infos: { avatar: 'avatar', name: 'name' }, group_infos: { avatar: 'avatar', name: 'name', group_num: 'group_num' },
group_member_infos: { group_member_infos: {
avatar: 'group_avatar', avatar: 'group_avatar',
name: 'group_name', name: 'group_name',
detailKey: 'user_name', detailKey: 'user_name',
group_num: 'group_num',
},
combinedGroup: {
avatar: props.searchItem?.groupTempType
? props.searchItem?.groupTempType === 'group_infos'
? 'avatar'
: props.searchItem?.groupTempType === 'group_member_infos'
? 'group_avatar'
: ''
: '',
name: props.searchItem?.groupTempType
? props.searchItem?.groupTempType === 'group_infos'
? 'name'
: props.searchItem?.groupTempType === 'group_member_infos'
? 'group_name'
: ''
: '',
detailKey: props.searchItem?.groupTempType
? props.searchItem?.groupTempType === 'group_member_infos'
? 'user_name'
: ''
: '',
group_num: props.searchItem?.groupTempType
? props.searchItem?.groupTempType === 'group_infos'
? 'group_num'
: props.searchItem?.groupTempType === 'group_member_infos'
? 'group_num'
: ''
: '',
}, },
general_infos: { general_infos: {
avatar: 'receiver_avatar', avatar: 'receiver_avatar',
name: 'receiver_name', name: 'receiver_name',
detailKey: 'count', detailKey: 'count',
group_num: 'group_num',
}, },
} }
//key //key
@ -73,28 +120,48 @@ const avatarImg = computed(() => {
const resultName = computed(() => { const resultName = computed(() => {
return getKeyValue(keyMapping[props.searchResultKey]?.name) return getKeyValue(keyMapping[props.searchResultKey]?.name)
}) })
//
const imgText = computed(() => {
return resultName.value.length >= 2
? resultName.value.slice(-2)
: resultName.value
})
// -groupType // -groupType
const groupTypeMapping = { const groupTypeMapping = {
0: {}, 0: {
defaultImg: 'textImg',
},
1: { 1: {
defaultImg: zu4992, defaultImg: zu4992,
}, },
2: { 2: {
result_type: t('index.mine.department'), result_type: t('index.mine.department'),
result_type_color: '#377EC6',
defaultImg: zu4989, defaultImg: zu4989,
}, },
3: { 3: {
result_type: t('index.mine.project'), result_type: t('index.mine.project'),
result_type_color: '#C1681C',
defaultImg: zu4991, defaultImg: zu4991,
}, },
4: { 4: {
result_type: t('index.type.company'),
result_type_color: '#7A58DE',
defaultImg: zu5296, defaultImg: zu5296,
}, },
} }
//
const groupNum = computed(() => {
return getKeyValue(keyMapping[props.searchResultKey]?.group_num)
})
//tag //tag
const resultType = computed(() => { const resultType = computed(() => {
return groupTypeMapping[props.searchItem?.group_type]?.result_type return groupTypeMapping[props.searchItem?.group_type]?.result_type
}) })
//tag
const resultTypeColor = computed(() => {
return groupTypeMapping[props.searchItem?.group_type]?.result_type_color
})
// //
const resultDetail = computed(() => { const resultDetail = computed(() => {
let result_detail = let result_detail =
@ -130,10 +197,19 @@ const resultDetail = computed(() => {
margin: 0 20rpx 0 0; margin: 0 20rpx 0 0;
border-radius: 50%; border-radius: 50%;
overflow: hidden; overflow: hidden;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
background: linear-gradient(to right, #674bbc, #46299d);
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
span {
color: #fff;
line-height: 44rpx;
}
} }
.result-info { .result-info {
.info-name { .info-name {

View File

@ -0,0 +1,177 @@
<template>
<div class="search-list">
<div class="search-result-list" v-if="props.searchText">
<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="index < 3"
:searchResultKey="searchResultKey"
:searchItem="item"
:searchText="props.searchText"
></searchItem>
</div>
</div>
<div class="result-has-more" v-if="getHasMoreResult(searchResultKey)">
<span class="text-[28rpx] font-regular">
{{ getHasMoreResult(searchResultKey) }}
</span>
</div>
</div>
</div>
</div>
<div class="search-no-result" v-if="!props.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>
</template>
<script setup>
import searchItem from './searchItem.vue'
import { useI18n } from 'vue-i18n'
const props = defineProps({
searchResult: Object,
searchText: String,
})
const { t } = useI18n()
//key
const getResultKeysValue = (keys) => {
let resultKey = ''
switch (keys) {
case 'user_infos':
resultKey = t('index.mine.addressBook')
break
case 'group_infos':
resultKey = t('chat.type.group')
break
case 'group_member_infos':
resultKey = t('chat.type.group')
break
case 'combinedGroup':
resultKey = t('chat.type.group')
break
case 'general_infos':
resultKey = t('chat.type.record')
break
default:
resultKey = ''
}
return resultKey
}
//
const getHasMoreResult = (searchResultKey) => {
let has_more_result = ''
switch (searchResultKey) {
case 'user_infos':
if (
props.searchResult['user_count'] &&
props.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
) {
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
) {
has_more_result = t('has_more') + t('chat.type.group')
}
break
case 'combinedGroup':
if (
props.searchResult['group_count'] &&
props.searchResult['group_count'] > 3
) {
has_more_result = t('has_more') + t('chat.type.group')
}
break
case 'general_infos':
break
default:
}
return has_more_result
}
</script>
<style lang="scss" scoped>
.search-list {
.search-result-list {
width: 100%;
padding: 10rpx 18rpx;
.search-result-each-part {
margin: 46rpx 0 0;
.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;
}
}
}
}
.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

@ -33,19 +33,42 @@
searchResultIndex) in state.searchResult" searchResultIndex) in state.searchResult"
:key="searchResultKey" :key="searchResultKey"
> >
<div class="result-title text-[28rpx] font-regular"> <div
{{ getResultKeysValue(searchResultKey) }} class="search-result-part"
v-if="
Array.isArray(state?.searchResult[searchResultKey]) &&
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
v-if="index < 3"
:searchResultKey="searchResultKey"
:searchItem="item"
:searchText="state.searchText"
></searchItem>
</div>
</div>
<div
class="result-has-more"
v-if="getHasMoreResult(searchResultKey)"
>
<span class="text-[28rpx] font-regular">
{{ getHasMoreResult(searchResultKey) }}
</span>
</div>
</div> </div>
<div class="result-list">
<searchItem
v-for="(item, index) in state?.searchResult[searchResultKey]"
:key="index"
:searchResultKey="searchResultKey"
:searchItem="item"
:searchText="state.searchText"
></searchItem>
</div>
<div class="result-has-more"></div>
</div> </div>
</div> </div>
<div class="search-no-result" v-if="!state.searchText"> <div class="search-no-result" v-if="!state.searchText">
@ -65,6 +88,7 @@ import { ServeSeachQueryAll } from '@/api/search/index'
import { ref, watch, computed, onMounted, onUnmounted, reactive } from 'vue' import { ref, watch, computed, onMounted, onUnmounted, reactive } from 'vue'
import { useAuth } from '@/store/auth' import { useAuth } from '@/store/auth'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { nextTick } from 'process'
const { t } = useI18n() const { t } = useI18n()
const state = reactive({ const state = reactive({
searchText: '', // searchText: '', //
@ -92,6 +116,9 @@ const getResultKeysValue = (keys) => {
case 'group_member_infos': case 'group_member_infos':
resultKey = t('chat.type.group') resultKey = t('chat.type.group')
break break
case 'combinedGroup':
resultKey = t('chat.type.group')
break
case 'general_infos': case 'general_infos':
resultKey = t('chat.type.record') resultKey = t('chat.type.record')
break break
@ -101,6 +128,49 @@ const getResultKeysValue = (keys) => {
return resultKey return resultKey
} }
//
const getHasMoreResult = (searchResultKey) => {
let has_more_result = ''
switch (searchResultKey) {
case 'user_infos':
if (
state.searchResult['user_count'] &&
state.searchResult['user_count'] > 3
) {
has_more_result = t('has_more') + t('index.mine.addressBook')
}
break
case 'group_infos':
if (
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 (
state.searchResult['group_count'] &&
state.searchResult['group_count'] > 3
) {
has_more_result = t('has_more') + t('chat.type.group')
}
break
case 'combinedGroup':
if (
state.searchResult['group_count'] &&
state.searchResult['group_count'] > 3
) {
has_more_result = t('has_more') + t('chat.type.group')
}
break
case 'general_infos':
break
default:
}
return has_more_result
}
// ES- // ES-
const queryAllSearch = (searchText) => { const queryAllSearch = (searchText) => {
let params = { let params = {
@ -111,6 +181,40 @@ const queryAllSearch = (searchText) => {
resp.then(({ code, data }) => { resp.then(({ code, data }) => {
console.log(data) console.log(data)
if (code == 200) { if (code == 200) {
// data.group_infos = [
// {
// id: 888898,
// type: 4,
// name: '',
// avatar: '', //
// created_at: '2024-10-31 14:31:11',
// group_num: 730,
// },
// ]
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 state.searchResult = data
} else { } else {
} }
@ -186,9 +290,19 @@ page {
margin: 46rpx 0 0; margin: 46rpx 0 0;
.result-title { .result-title {
line-height: 40rpx;
padding: 0 0 10rpx; padding: 0 0 10rpx;
color: $theme-hint-text; 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;
}
} }
} }
} }

View File

@ -79,5 +79,7 @@
"index.mine.project": "项目", "index.mine.project": "项目",
"chat.type.group": "群聊", "chat.type.group": "群聊",
"chat.type.record": "聊天记录", "chat.type.record": "聊天记录",
"search.result.include": "包含:" "search.result.include": "包含:",
"has_more": "更多",
"index.type.company": "公司"
} }