chat-app/src/pages/search/components/searchItem.vue

357 lines
9.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div
class="search-item"
:class="props?.conditionType ? 'search-item-condition' : ''"
v-if="resultName"
:style="
props.searchResultKey === 'talk_record_infos_receiver'
? 'margin: 24rpx 0 0'
: ''
"
>
<div
class="avatar-img"
:class="props?.conditionType ? 'avatar-img-condition' : ''"
>
<img v-if="avatarImg !== 'textImg'" :src="avatarImg" />
<span v-if="avatarImg === 'textImg'" class="text-[32rpx] font-bold">
{{ imgText }}
</span>
</div>
<div class="result-info">
<div
class="info-name"
:class="searchRecordDetail ? 'info-name-searchRecordDetail' : ''"
>
<HighlightText
:class="
props?.conditionType
? 'text-[28rpx] font-medium'
: searchRecordDetail
? 'text-[24rpx] font-medium'
: 'text-[32rpx] font-medium'
"
:text="resultName"
:searchText="props.searchText"
/>
<div class="info_num" v-if="groupNum">
<span class="text-[32rpx] font-medium">
{{ '' + groupNum + '' }}
</span>
</div>
<div
class="info-tag"
v-if="resultType && !searchRecordDetail"
:style="'border-color:' + resultTypeColor"
>
<span
class="text-[24rpx] font-medium"
:style="'color:' + resultTypeColor"
>
{{ 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"
:class="searchRecordDetail ? 'info-detail-searchRecordDetail' : ''"
>
<HighlightText
class="text-[28rpx] font-regular"
:text="resultDetail"
:searchText="props.searchText"
/>
</div>
</div>
<div class="search-item-pointer" v-if="pointerIconSrc">
<img :src="pointerIconSrc" />
</div>
</div>
</template>
<script setup>
import groupDepartment from '@/static/image/chatList/groupDepartment.png'
import groupProject from '@/static/image/chatList/groupProject.png'
import groupNormal from '@/static/image/chatList/groupNormal.png'
import groupCompany from '@/static/image/chatList/groupCompany.png'
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, //搜索内容
searchRecordDetail: Boolean, //是否是搜索聊天记录详情
pointerIconSrc: String, //箭头图标
conditionType: Number, //搜索类型
})
// 映射表-查找对应结构下的属性名
const keyMapping = {
user_infos: { avatar: 'avatar', name: 'nickname' },
group_infos: { avatar: 'avatar', name: 'name', group_num: 'group_num' },
group_member_infos: {
avatar: 'group_avatar',
name: 'group_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: {
avatar: 'receiver_avatar',
name: 'receiver_name',
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 ? props?.searchItem[keys] : ''
}
return keyValue
}
//头像
const avatarImg = computed(() => {
let avatar = getKeyValue(keyMapping[props.searchResultKey]?.avatar)
if (!avatar) {
avatar = groupTypeMapping[props.searchItem?.group_type]?.defaultImg
}
if (props?.conditionType) {
avatar = props.searchItem.avatar
if (!avatar) {
avatar = groupTypeMapping[0]?.defaultImg
}
}
return avatar
})
//名称
const resultName = computed(() => {
let result_name = getKeyValue(keyMapping[props.searchResultKey]?.name)
if (props?.conditionType) {
result_name = props.searchItem.nickname
}
return result_name
})
//文字头像
const imgText = computed(() => {
return resultName.value.length >= 2
? resultName.value.slice(-2)
: resultName.value
})
// 映射表-根据groupType设置对应值
const groupTypeMapping = {
0: {
defaultImg: 'textImg',
},
1: {
defaultImg: groupNormal,
},
2: {
result_type: t('index.mine.department'),
result_type_color: '#377EC6',
defaultImg: groupDepartment,
},
3: {
result_type: t('index.mine.project'),
result_type_color: '#C1681C',
defaultImg: groupProject,
},
4: {
result_type: t('index.type.company'),
result_type_color: '#7A58DE',
defaultImg: groupCompany,
},
}
//群人数
const groupNum = computed(() => {
return getKeyValue(keyMapping[props.searchResultKey]?.group_num)
})
//群类型tag
const resultType = computed(() => {
return groupTypeMapping[props.searchItem?.group_type]?.result_type
})
//群类型tag颜色
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 =
props.searchItem[keyMapping[props.searchResultKey]?.detailKey]
switch (keyMapping[props.searchResultKey]?.detailKey) {
case 'count':
result_detail = result_detail + t('search.chat.count')
break
case 'user_name':
result_detail = t('search.result.include') + result_detail
break
case 'extra':
result_detail = props.searchItem?.extra
break
default:
result_detail = ''
}
return result_detail
})
</script>
<style lang="scss" scoped>
.search-item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 22rpx 0 24rpx;
border-bottom: 1px solid $theme-border-color;
.avatar-img {
width: 96rpx;
height: 96rpx;
margin: 0 20rpx 0 0;
border-radius: 50%;
overflow: hidden;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
background: linear-gradient(to right, #674bbc, #46299d);
flex-shrink: 0;
img {
width: 100%;
height: 100%;
}
span {
color: #fff;
line-height: 44rpx;
}
}
.avatar-img-condition {
width: 64rpx;
height: 64rpx;
margin: 0 18rpx 0 0;
span {
font-size: 20rpx;
}
}
.result-info {
width: 100%;
.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-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%;
}
}
}
.search-item-condition {
border: 0;
}
</style>