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

337 lines
8.4 KiB
Vue
Raw Normal View History

<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'
: ''
"
>
<avatarModule
:mode="props.searchItem?.group_type === 0 ? 1 : 2"
:avatar="avatarImg"
:userName="resultName"
:groupType="props.searchItem?.group_type"
:customStyle="{
width: props?.conditionType ? '64rpx' : '96rpx',
height: props?.conditionType ? '64rpx' : '96rpx',
margin: props?.conditionType ? '0 18rpx 0 0' : '0 20rpx 0 0',
}"
:customTextStyle="{
fontSize: props?.conditionType ? '20rpx' : '32rpx',
fontWeight: 'bold',
color: '#fff',
lineHeight: '44rpx',
}"
></avatarModule>
<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 avatarModule from '@/components/avatar-module/index.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: {
type: String,
default: '',
},
searchText: {
type: String,
default: '',
}, //搜索内容
searchRecordDetail: {
type: Boolean,
default: false,
}, //是否是搜索聊天记录详情
pointerIconSrc: {
type: String,
default: '',
}, //箭头图标
conditionType: {
type: Number,
default: 0,
}, //搜索类型
})
// 映射表-查找对应结构下的属性名
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 (props?.conditionType) {
avatar = props.searchItem.avatar
}
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: {},
1: {},
2: {
result_type: t('index.mine.department'),
result_type_color: '#377EC6',
},
3: {
result_type: t('index.mine.project'),
result_type_color: '#C1681C',
},
4: {
result_type: t('index.type.company'),
result_type_color: '#7A58DE',
},
}
//群人数
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;
.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;
flex-shrink: 0;
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;
word-break: break-all;
}
}
}
.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>