接入聊天APP的全局搜索组件,包括搜索列表、搜索项和高亮等
This commit is contained in:
parent
7544b3d324
commit
701d878f7d
70
src/components/search/highLightText.vue
Normal file
70
src/components/search/highLightText.vue
Normal file
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<span>
|
||||
<template v-for="(part, index) in parts" :key="index">
|
||||
<span v-if="part.highlighted" :class="highlightClass">
|
||||
{{ part.text }}
|
||||
</span>
|
||||
<span v-else>{{ part.text }}</span>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
text: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
searchText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
highlightClass: {
|
||||
type: String,
|
||||
default: 'highlight',
|
||||
},
|
||||
})
|
||||
|
||||
const escapedSearchText = computed(() =>
|
||||
String(props.searchText).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),
|
||||
)
|
||||
|
||||
const pattern = computed(() => new RegExp(escapedSearchText.value, 'gi'))
|
||||
|
||||
const parts = computed(() => {
|
||||
if (!props.searchText || !props.text)
|
||||
return [{ text: props.text, highlighted: false }];
|
||||
|
||||
const result = [];
|
||||
let currentIndex = 0;
|
||||
const escapedSearchTextValue = escapedSearchText.value;
|
||||
const searchPattern = new RegExp(`(${escapedSearchTextValue})`, 'gi');
|
||||
|
||||
props.text.replace(searchPattern, (match, p1, offset) => {
|
||||
// 添加非高亮文本
|
||||
if (currentIndex < offset) {
|
||||
result.push({ text: props.text.slice(currentIndex, offset), highlighted: false });
|
||||
}
|
||||
// 添加高亮文本
|
||||
result.push({ text: p1, highlighted: true });
|
||||
// 更新当前索引
|
||||
currentIndex = offset + p1.length;
|
||||
return p1; // 这个返回值不影响最终结果,只是replace方法的要求
|
||||
});
|
||||
|
||||
// 添加剩余的非高亮文本(如果有的话)
|
||||
if (currentIndex < props.text.length) {
|
||||
result.push({ text: props.text.slice(currentIndex), highlighted: false });
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.highlight {
|
||||
color: #7a58de;
|
||||
}
|
||||
</style>
|
337
src/components/search/searchItem.vue
Normal file
337
src/components/search/searchItem.vue
Normal file
@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<div
|
||||
class="search-item"
|
||||
:class="props?.conditionType ? 'search-item-condition' : ''"
|
||||
v-if="resultName"
|
||||
:style="props.searchResultKey === 'talk_record_infos_receiver' ? 'margin: 12px 0 0' : ''"
|
||||
>
|
||||
<div class="search-item-avatar">
|
||||
<avatarModule
|
||||
:mode="props.searchItem?.group_type === 0 ? 1 : 2"
|
||||
:avatar="avatarImg"
|
||||
:userName="resultName"
|
||||
:groupType="props.searchItem?.group_type"
|
||||
:customStyle="{
|
||||
width: props?.conditionType ? '32px' : '42px',
|
||||
height: props?.conditionType ? '32px' : '42px',
|
||||
margin: props?.conditionType ? '0 9px 0 0' : '0 10px 0 0'
|
||||
}"
|
||||
:customTextStyle="{
|
||||
fontSize: props?.conditionType ? '10px' : '14px',
|
||||
fontWeight: 'bold',
|
||||
color: '#fff',
|
||||
lineHeight: '24px'
|
||||
}"
|
||||
></avatarModule>
|
||||
<div
|
||||
class="info-tag"
|
||||
v-if="resultType && !searchRecordDetail"
|
||||
:style="'border-color:' + resultTypeColor"
|
||||
>
|
||||
<span class="text-[10px] font-medium" :style="'color:' + resultTypeColor">
|
||||
{{ resultType }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="result-info">
|
||||
<div class="info-name" :class="searchRecordDetail ? 'info-name-searchRecordDetail' : ''">
|
||||
<HighlightText
|
||||
:class="
|
||||
props?.conditionType
|
||||
? 'text-[14px] font-medium'
|
||||
: searchRecordDetail
|
||||
? 'text-[12px] font-medium'
|
||||
: 'text-[14px] font-bold'
|
||||
"
|
||||
:text="resultName"
|
||||
:searchText="props.searchText"
|
||||
/>
|
||||
<div class="info_num" v-if="groupNum">
|
||||
<span class="text-[14px] font-medium">
|
||||
{{ '(' + groupNum + ')' }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="searchRecordDetail && chatRecordCreatedAt">
|
||||
<span class="text-[12px] font-medium">
|
||||
{{ chatRecordCreatedAt }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="info-detail"
|
||||
v-if="resultDetail"
|
||||
:class="searchRecordDetail ? 'info-detail-searchRecordDetail' : ''"
|
||||
>
|
||||
<HighlightText
|
||||
class="text-[12px] 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 { beautifyTime } from '@/utils/datetime'
|
||||
import { ChatMsgTypeMapping } from '@/constant/message'
|
||||
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'
|
||||
},
|
||||
search_by_member_condition: {
|
||||
avatar: 'avatar',
|
||||
name: 'nickname',
|
||||
created_at: 'created_at',
|
||||
msg_type: 'msg_type',
|
||||
detailKey: 'chatMessageType'
|
||||
}
|
||||
}
|
||||
//获取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: '部门',
|
||||
result_type_color: '#377EC6'
|
||||
},
|
||||
3: {
|
||||
result_type: '项目',
|
||||
result_type_color: '#C1681C'
|
||||
},
|
||||
4: {
|
||||
result_type: '公司',
|
||||
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 + '条聊天记录'
|
||||
break
|
||||
case 'user_name':
|
||||
result_detail = '包含:' + result_detail
|
||||
break
|
||||
case 'extra':
|
||||
result_detail = props.searchItem?.extra
|
||||
break
|
||||
case 'chatMessageType':
|
||||
result_detail =
|
||||
props.searchItem?.msg_type === 1
|
||||
? props.searchItem?.extra?.content
|
||||
: ChatMsgTypeMapping[props.searchItem?.msg_type]
|
||||
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: 11px 0 12px;
|
||||
border-bottom: 1px solid #f8f8f8;
|
||||
|
||||
.search-item-avatar{
|
||||
position: relative;
|
||||
.info-tag {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0px 6px;
|
||||
border: 1px solid #000;
|
||||
border-radius: 3px;
|
||||
flex-shrink: 0;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 4px;
|
||||
span {
|
||||
line-height: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.result-info {
|
||||
width: 100%;
|
||||
.info-name {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
span {
|
||||
color: #191919;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
.info-name-searchRecordDetail {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
span {
|
||||
color: #999999;
|
||||
line-height: 17px;
|
||||
}
|
||||
}
|
||||
.info-detail {
|
||||
span {
|
||||
color: #999999;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
.info-detail-searchRecordDetail {
|
||||
span {
|
||||
color: #191919;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
.search-item-pointer {
|
||||
width: 5.5px;
|
||||
height: 9px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.search-item-condition {
|
||||
border: 0;
|
||||
}
|
||||
</style>
|
743
src/components/search/searchList.vue
Normal file
743
src/components/search/searchList.vue
Normal file
@ -0,0 +1,743 @@
|
||||
<template>
|
||||
<div class="search-list">
|
||||
<div class="search-result">
|
||||
<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-[14px] 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-[14px] font-regular">
|
||||
{{ getHasMoreResult(searchResultKey) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <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="searchNoData"
|
||||
:empty-view-text="'检索您要查找的内容吧~'"
|
||||
:empty-view-img-style="{ width: '238px', height: '131px' }"
|
||||
:empty-view-title-style="{
|
||||
color: '#999999',
|
||||
margin: '-10px 0 0',
|
||||
'line-height': '20px',
|
||||
'font-size': '14px',
|
||||
'font-weight': 400,
|
||||
}"
|
||||
:refresher-enabled="false"
|
||||
>
|
||||
<template #top>
|
||||
<div class="searchRoot">
|
||||
<customInput
|
||||
:searchText="state.searchText"
|
||||
:first_talk_record_infos="state.first_talk_record_infos"
|
||||
@inputSearchText="inputSearchText"
|
||||
></customInput>
|
||||
<span
|
||||
class="searchRoot_cancelBtn text-[16px] font-medium"
|
||||
@click="cancelSearch"
|
||||
>
|
||||
取消
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
class="search-record-detail"
|
||||
v-if="props.searchRecordDetail && !props?.hideFirstRecord"
|
||||
>
|
||||
<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>
|
||||
</ZPaging> -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
// import searchNoData from '@/static/image/search/search-no-data.png'
|
||||
// import customInput from '@/components/custom-input/custom-input.vue'
|
||||
// import pointerIconSrc from '@/static/image/search/search-item-pointer.png'
|
||||
// import lodash from 'lodash'
|
||||
// import { useUserStore } from '@/store'
|
||||
// const userStore = useUserStore()
|
||||
|
||||
// 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'
|
||||
// const zPaging = ref()
|
||||
// useZPaging(zPaging)
|
||||
|
||||
import searchItem from './searchItem.vue'
|
||||
import { ref, reactive, defineEmits, defineProps, onMounted } from 'vue'
|
||||
|
||||
const emits = defineEmits(['toMoreResultPage', 'lastIdChange', 'clickSearchItem'])
|
||||
|
||||
const state = reactive({
|
||||
searchText: '', //搜索内容
|
||||
searchResultList: [], //搜素结果列表
|
||||
searchResult: null, //搜索结果
|
||||
pageNum: 1, //当前请求数据页数
|
||||
uid: 1496 //当前用户id
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
searchResultPageSize: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}, //搜索结果每页数据量
|
||||
listLimit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}, //是否限制列表内数据数量
|
||||
apiParams: {
|
||||
type: String,
|
||||
default: ''
|
||||
}, //请求参数
|
||||
apiRequest: Function, //请求
|
||||
searchText: {
|
||||
type: String,
|
||||
default: ''
|
||||
}, //搜索内容
|
||||
isPagination: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}, //是否分页
|
||||
searchRecordDetail: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}, //是否是搜索聊天记录的详情
|
||||
first_talk_record_infos: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
}
|
||||
}, //接受者信息
|
||||
hideFirstRecord: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
} //是否隐藏前缀及搜索群/用户主体信息
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (props.searchText) {
|
||||
state.searchText = props.searchText
|
||||
queryAllSearch(1, 10)
|
||||
}
|
||||
})
|
||||
|
||||
//输入搜索文本
|
||||
const inputSearchText = (e) => {
|
||||
if (e.trim() != state.searchText.trim()) {
|
||||
state.pageNum = 1
|
||||
state.searchResult = null // 清空搜索结果
|
||||
emits('lastIdChange', 0, 0, 0)
|
||||
}
|
||||
state.searchText = e.trim()
|
||||
if (!e.trim()) {
|
||||
state.searchResult = null // 清空搜索结果
|
||||
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 data = {
|
||||
user_infos: [
|
||||
{
|
||||
id: 127,
|
||||
mobile: '17706200252',
|
||||
nickname: '测试-王溢韬',
|
||||
avatar:
|
||||
'https://dci-file-new.bj.bcebos.com/fonchain-main/test/runtime/image/avatar/40/b8ed6fea-6662-416d-8bb3-1fd8a8197061.jpg',
|
||||
created_at: '2025-03-28 11:33:13',
|
||||
erp_user_id: 18282
|
||||
},
|
||||
{
|
||||
id: 103,
|
||||
mobile: '13814969538',
|
||||
nickname: '王静测试',
|
||||
avatar: '',
|
||||
created_at: '2025-03-27 14:44:23',
|
||||
erp_user_id: 2639
|
||||
},
|
||||
{
|
||||
id: 57,
|
||||
mobile: '13862027511',
|
||||
nickname: '王西',
|
||||
avatar:
|
||||
'https://dci-file-new.bj.bcebos.com/fonchain-main/test/runtime/image/avatar/40/b8ed6fea-6662-416d-8bb3-1fd8a8197061.jpg',
|
||||
created_at: '2025-03-27 14:44:23',
|
||||
erp_user_id: 18229
|
||||
}
|
||||
],
|
||||
user_count: 9,
|
||||
group_infos: null,
|
||||
group_member_infos: [
|
||||
{
|
||||
id: 79,
|
||||
group_id: 1,
|
||||
group_name: '泰丰国际',
|
||||
group_type: 4,
|
||||
group_avatar: '',
|
||||
group_num: 103,
|
||||
user_id: 103,
|
||||
user_name: '王静',
|
||||
user_card: '',
|
||||
created_at: '2025-03-27 14:44:24'
|
||||
},
|
||||
{
|
||||
id: 55,
|
||||
group_id: 1,
|
||||
group_name: '泰丰国际',
|
||||
group_type: 4,
|
||||
group_avatar: '',
|
||||
group_num: 103,
|
||||
user_id: 57,
|
||||
user_name: '王西',
|
||||
user_card: '',
|
||||
created_at: '2025-03-27 14:44:24'
|
||||
},
|
||||
{
|
||||
id: 35,
|
||||
group_id: 1,
|
||||
group_name: '泰丰国际',
|
||||
group_type: 4,
|
||||
group_avatar: '',
|
||||
group_num: 103,
|
||||
user_id: 37,
|
||||
user_name: '王雯婷',
|
||||
user_card: '',
|
||||
created_at: '2025-03-27 14:44:24'
|
||||
}
|
||||
],
|
||||
group_count: 9,
|
||||
general_infos: [
|
||||
{
|
||||
receiver_id: 40,
|
||||
receiver_name: '孙志远',
|
||||
receiver_avatar:
|
||||
'https://dci-file-new.bj.bcebos.com/fonchain-main/test/runtime/image/avatar/40/b8ed6fea-6662-416d-8bb3-1fd8a8197061.jpg',
|
||||
group_num: 0,
|
||||
talk_type: 1,
|
||||
count: 3,
|
||||
group_type: 0
|
||||
},
|
||||
{
|
||||
receiver_id: 2,
|
||||
receiver_name: '吹牛个人群',
|
||||
receiver_avatar: '',
|
||||
group_num: 4,
|
||||
talk_type: 2,
|
||||
count: 2,
|
||||
group_type: 3
|
||||
},
|
||||
{
|
||||
receiver_id: 3,
|
||||
receiver_name: '丰链30自己人',
|
||||
receiver_avatar:
|
||||
'https://e-cdn.fontree.cn/fonchain-main/prod/image/default/fonchain-chat/3d273326-d2a5-4ad4-a974-32d020c6b3f9.jpg?width=1080&height=2412',
|
||||
group_num: 8,
|
||||
talk_type: 2,
|
||||
count: 2,
|
||||
group_type: 3
|
||||
}
|
||||
],
|
||||
record_count: 3
|
||||
}
|
||||
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) {
|
||||
let receiverInfo = JSON.parse(JSON.stringify(data.talk_record_infos[0]))
|
||||
if (receiverInfo.talk_type === 1) {
|
||||
//单聊才需此判断
|
||||
if (receiverInfo.user_id === state.uid) {
|
||||
//发送人是自己,接收人不需要变
|
||||
}
|
||||
if (receiverInfo.receiver_id === state.uid) {
|
||||
//接收人是自己,这里需要变成对方
|
||||
let temp_id = receiverInfo.receiver_id
|
||||
let temp_name = receiverInfo.receiver_name
|
||||
let temp_avatar = receiverInfo.receiver_avatar
|
||||
receiverInfo.receiver_id = receiverInfo.user_id
|
||||
receiverInfo.receiver_name = receiverInfo.user_name
|
||||
receiverInfo.receiver_avatar = receiverInfo.user_avatar
|
||||
receiverInfo.user_id = temp_id
|
||||
receiverInfo.user_name = temp_name
|
||||
receiverInfo.user_avatar = temp_avatar
|
||||
}
|
||||
}
|
||||
state.first_talk_record_infos = Object.assign({}, state.first_talk_record_infos, receiverInfo)
|
||||
;(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) {
|
||||
// 第一页请求且为空,清空结果
|
||||
state.searchResult = null
|
||||
// zPaging.value?.complete([])
|
||||
} else {
|
||||
// 加载更多且为空,保持原列表不变
|
||||
// zPaging.value?.complete(state.searchResult ? [state.searchResult] : [])
|
||||
}
|
||||
} else {
|
||||
if (props.isPagination) {
|
||||
if (pageNum === 1) {
|
||||
// 第一页请求,直接设置新数据
|
||||
state.searchResult = data
|
||||
} else {
|
||||
// 加载更多,合并数据
|
||||
if (
|
||||
paginationKey &&
|
||||
Array.isArray((state?.searchResult && state?.searchResult[paginationKey]) || [])
|
||||
) {
|
||||
data[paginationKey] = state.searchResult[paginationKey].concat(data[paginationKey])
|
||||
}
|
||||
state.searchResult = data
|
||||
}
|
||||
|
||||
emits(
|
||||
'lastIdChange',
|
||||
data.last_id,
|
||||
data.last_group_id,
|
||||
data.last_member_id,
|
||||
data.last_receiver_user_name,
|
||||
data.last_receiver_group_name
|
||||
)
|
||||
let total = data.count
|
||||
if (props.searchRecordDetail) {
|
||||
if (state?.first_talk_record_infos?.talk_type === 1) {
|
||||
total = data.user_record_count
|
||||
} else if (state?.first_talk_record_infos?.talk_type === 2) {
|
||||
total = data.group_record_count
|
||||
}
|
||||
}
|
||||
// zPaging.value?.completeByTotal([data], total)
|
||||
} else {
|
||||
state.searchResult = data
|
||||
// zPaging.value?.complete([data])
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
// let receiverInfo = JSON.parse(JSON.stringify(data.talk_record_infos[0]))
|
||||
// if (receiverInfo.talk_type === 1) {
|
||||
// //单聊才需此判断
|
||||
// if (receiverInfo.user_id === state.uid) {
|
||||
// //发送人是自己,接收人不需要变
|
||||
// }
|
||||
// if (receiverInfo.receiver_id === state.uid) {
|
||||
// //接收人是自己,这里需要变成对方
|
||||
// let temp_id = receiverInfo.receiver_id
|
||||
// let temp_name = receiverInfo.receiver_name
|
||||
// let temp_avatar = receiverInfo.receiver_avatar
|
||||
// receiverInfo.receiver_id = receiverInfo.user_id
|
||||
// receiverInfo.receiver_name = receiverInfo.user_name
|
||||
// receiverInfo.receiver_avatar = receiverInfo.user_avatar
|
||||
// receiverInfo.user_id = temp_id
|
||||
// receiverInfo.user_name = temp_name
|
||||
// receiverInfo.user_avatar = temp_avatar
|
||||
// }
|
||||
// }
|
||||
// state.first_talk_record_infos = Object.assign(
|
||||
// {},
|
||||
// state.first_talk_record_infos,
|
||||
// receiverInfo,
|
||||
// )
|
||||
// ;(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) {
|
||||
// // 第一页请求且为空,清空结果
|
||||
// state.searchResult = null
|
||||
// zPaging.value?.complete([])
|
||||
// } else {
|
||||
// // 加载更多且为空,保持原列表不变
|
||||
// zPaging.value?.complete(state.searchResult ? [state.searchResult] : [])
|
||||
// }
|
||||
// } else {
|
||||
// if (props.isPagination) {
|
||||
// if (pageNum === 1) {
|
||||
// // 第一页请求,直接设置新数据
|
||||
// state.searchResult = data
|
||||
// } else {
|
||||
// // 加载更多,合并数据
|
||||
// if (
|
||||
// paginationKey &&
|
||||
// Array.isArray(
|
||||
// (state?.searchResult && state?.searchResult[paginationKey]) || [],
|
||||
// )
|
||||
// ) {
|
||||
// data[paginationKey] = state.searchResult[paginationKey].concat(
|
||||
// data[paginationKey],
|
||||
// )
|
||||
// }
|
||||
// state.searchResult = data
|
||||
// }
|
||||
|
||||
// emits(
|
||||
// 'lastIdChange',
|
||||
// data.last_id,
|
||||
// data.last_group_id,
|
||||
// data.last_member_id,
|
||||
// data.last_receiver_user_name,
|
||||
// data.last_receiver_group_name,
|
||||
// )
|
||||
// let total = data.count
|
||||
// if (props.searchRecordDetail) {
|
||||
// if (state?.first_talk_record_infos?.talk_type === 1) {
|
||||
// total = data.user_record_count
|
||||
// } else if (state?.first_talk_record_infos?.talk_type === 2) {
|
||||
// total = data.group_record_count
|
||||
// }
|
||||
// }
|
||||
// zPaging.value?.completeByTotal([data], total)
|
||||
// } else {
|
||||
// state.searchResult = data
|
||||
// zPaging.value?.complete([data])
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// if (pageNum === 1) {
|
||||
// // 第一页请求失败,清空结果
|
||||
// state.searchResult = null
|
||||
// zPaging.value?.complete([])
|
||||
// } else {
|
||||
// // 加载更多失败,保持原列表不变
|
||||
// zPaging.value?.complete(state.searchResult ? [state.searchResult] : [])
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
// resp.catch(() => {
|
||||
// if (pageNum === 1) {
|
||||
// // 第一页请求异常,清空结果
|
||||
// state.searchResult = null
|
||||
// zPaging.value?.complete([])
|
||||
// } else {
|
||||
// // 加载更多异常,保持原列表不变
|
||||
// zPaging.value?.complete(state.searchResult ? [state.searchResult] : [])
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
//点击取消搜索
|
||||
const cancelSearch = () => {
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 1) {
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
} else {
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//获取key对应值
|
||||
const getResultKeysValue = (keys) => {
|
||||
let resultKey = ''
|
||||
switch (keys) {
|
||||
case 'user_infos':
|
||||
resultKey = '通讯录'
|
||||
break
|
||||
case 'group_infos':
|
||||
resultKey = '群聊'
|
||||
break
|
||||
case 'group_member_infos':
|
||||
resultKey = '群聊'
|
||||
break
|
||||
case 'combinedGroup':
|
||||
resultKey = '群聊'
|
||||
break
|
||||
case 'general_infos':
|
||||
resultKey = '聊天记录'
|
||||
break
|
||||
case 'talk_record_infos':
|
||||
resultKey = '相关聊天记录'
|
||||
break
|
||||
default:
|
||||
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 = '更多通讯录'
|
||||
}
|
||||
break
|
||||
case 'group_infos':
|
||||
if (state.searchResult['group_count'] && state.searchResult['group_count'] > 3) {
|
||||
has_more_result = '更多群聊'
|
||||
}
|
||||
break
|
||||
case 'group_member_infos':
|
||||
if (state.searchResult['group_count'] && state.searchResult['group_count'] > 3) {
|
||||
has_more_result = '更多群聊'
|
||||
}
|
||||
break
|
||||
case 'combinedGroup':
|
||||
if (state.searchResult['group_count'] && state.searchResult['group_count'] > 3) {
|
||||
has_more_result = '更多群聊'
|
||||
}
|
||||
break
|
||||
case 'general_infos':
|
||||
if (state.searchResult['record_count'] && state.searchResult['record_count'] >= 3) {
|
||||
has_more_result = '更多聊天记录'
|
||||
}
|
||||
break
|
||||
default:
|
||||
}
|
||||
return has_more_result
|
||||
}
|
||||
|
||||
//点击跳转到更多结果页面
|
||||
const toMoreResultPage = (searchResultKey) => {
|
||||
emits('toMoreResultPage', searchResultKey, state.searchText)
|
||||
}
|
||||
|
||||
//点击了搜索结果项
|
||||
const clickSearchItem = (searchResultKey, searchItem) => {
|
||||
console.log(searchResultKey, searchItem)
|
||||
let talk_type = searchItem.talk_type
|
||||
let receiver_id = searchItem.receiver_id
|
||||
if (searchResultKey === 'user_infos') {
|
||||
talk_type = 1
|
||||
receiver_id = searchItem.id
|
||||
} else if (searchResultKey === 'combinedGroup') {
|
||||
talk_type = searchItem.type || 2
|
||||
receiver_id = searchItem.group_id || searchItem.id
|
||||
} else if (searchResultKey === 'general_infos') {
|
||||
if (searchItem.talk_type === 1) {
|
||||
if (searchItem.user_id === state.uid) {
|
||||
//发送人是自己,接收人不需要变
|
||||
}
|
||||
if (searchItem.receiver_id === state.uid) {
|
||||
//接收人是自己,这里需要变成对方
|
||||
let temp_id = searchItem.receiver_id
|
||||
let temp_name = searchItem.receiver_name
|
||||
let temp_avatar = searchItem.receiver_avatar
|
||||
searchItem.receiver_id = searchItem.user_id
|
||||
searchItem.receiver_name = searchItem.user_name
|
||||
searchItem.receiver_avatar = searchItem.user_avatar
|
||||
searchItem.user_id = temp_id
|
||||
searchItem.user_name = temp_name
|
||||
searchItem.user_avatar = temp_avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
emits(
|
||||
'clickSearchItem',
|
||||
state.searchText,
|
||||
searchResultKey,
|
||||
talk_type,
|
||||
receiver_id,
|
||||
encodeURIComponent(JSON.stringify(searchItem))
|
||||
)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.search-list {
|
||||
.searchRoot {
|
||||
padding: 10px 24px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
.searchRoot_cancelBtn {
|
||||
line-height: 22px;
|
||||
color: #46299d;
|
||||
margin: 0 0 0 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
.search-record-detail {
|
||||
padding: 0 25px;
|
||||
}
|
||||
.search-result {
|
||||
width: 100%;
|
||||
padding: 0 10px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
|
||||
.search-result-list {
|
||||
width: 100%;
|
||||
// padding: 0 9px;
|
||||
|
||||
.search-result-part {
|
||||
margin: 18px 0 0;
|
||||
|
||||
.result-title {
|
||||
padding: 0 0 5px;
|
||||
border-bottom: 1px solid #f8f8f8;
|
||||
span {
|
||||
line-height: 20px;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
.result-has-more {
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #f8f8f8;
|
||||
span {
|
||||
color: #191919;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -35,6 +35,7 @@ import xSearchForm from '@/components/x-naive-ui/x-search-form/index.vue'
|
||||
import xNDataTable from '@/components/x-naive-ui/x-n-data-table/index.vue'
|
||||
import flTree from '@/components/flnlayout/tree/flnindex.vue'
|
||||
import { processError, processSuccess } from '@/utils/helper/message.js'
|
||||
import chatAppSearchList from '@/components/search/searchList.vue'
|
||||
|
||||
const currentInstance = getCurrentInstance()
|
||||
const $request = currentInstance?.appContext.config.globalProperties?.$request
|
||||
@ -54,6 +55,48 @@ const searchKeyword = ref('')
|
||||
const topItems = computed((): ISession[] => talkStore.topItems)
|
||||
const unreadNum = computed(() => talkStore.talkUnreadNum)
|
||||
|
||||
//自定义搜索
|
||||
const renderChatAppSearch = () => {
|
||||
return h(
|
||||
chatAppSearchList,
|
||||
{
|
||||
// searchResultKey: 'user_infos',
|
||||
// searchItem: {
|
||||
// avatar:
|
||||
// 'https://e-cdn.fontree.cn/fonchain-main/prod/image/18248/avatar/a0b2bee7-947f-465a-986e-10a1b2b87032.png',
|
||||
// created_at: '2025-03-27 14:44:23',
|
||||
// erp_user_id: 18248,
|
||||
// id: 44,
|
||||
// mobile: '18994430450',
|
||||
// nickname: '周俊耀'
|
||||
// },
|
||||
// searchText: '周'
|
||||
searchResultPageSize: 3,
|
||||
listLimit: true,
|
||||
apiRequest: ServeSeachQueryAll,
|
||||
searchText: '王',
|
||||
onClickSearchItem: (searchText, searchResultKey, talk_type, receiver_id, res) => {
|
||||
console.log(searchText, searchResultKey, talk_type, receiver_id)
|
||||
const result = JSON.parse(decodeURIComponent(res))
|
||||
console.log(result)
|
||||
}
|
||||
},
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
//ES搜索聊天记录-主页搜索什么都有、指定用户、指定群、群与用户概览
|
||||
const ServeSeachQueryAll = () => {
|
||||
let url = '/api/v1/elasticsearch/query-all'
|
||||
let params = {}
|
||||
let config = {
|
||||
baseURL: import.meta.env.VITE_BASE_API
|
||||
}
|
||||
return $request.HTTP.components.postDataByParams(url, params, config).then((res) => {
|
||||
console.log(res)
|
||||
})
|
||||
}
|
||||
|
||||
const state = reactive({
|
||||
isShowAddressBookModal: false, // 是否显示通讯录模态框
|
||||
customModalStyle: {
|
||||
@ -176,6 +219,13 @@ const state = reactive({
|
||||
groupChatListPageSize: 10, // 群聊列表表格每页条数
|
||||
groupChatListTotal: 0, // 群聊列表表格总条数
|
||||
groupChatListSearchGroupName: '', // 群聊列表搜索条件-群聊名称
|
||||
chatSearchOptions: [
|
||||
{
|
||||
key: 'chatSearch',
|
||||
type: 'render',
|
||||
render: renderChatAppSearch
|
||||
}
|
||||
] // 聊天搜索选项
|
||||
})
|
||||
|
||||
const items = computed((): ISession[] => {
|
||||
@ -388,7 +438,6 @@ const handleGroupChatListPaginationSize = (value) => {
|
||||
console.log(value, 'value')
|
||||
state.groupChatListPageSize = value
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -406,25 +455,30 @@ const handleGroupChatListPaginationSize = (value) => {
|
||||
<section class="el-container is-vertical height100">
|
||||
<!-- 工具栏目 -->
|
||||
<header class="el-header header-tools">
|
||||
<n-input
|
||||
placeholder="搜索好友 / 群聊"
|
||||
v-model:value.trim="searchKeyword"
|
||||
round
|
||||
clearable
|
||||
style="width: 78%;"
|
||||
<n-dropdown
|
||||
trigger="click"
|
||||
:options="state.chatSearchOptions"
|
||||
style="width: 248px; height: 677px; overflow-y: scroll;"
|
||||
>
|
||||
<template #prefix>
|
||||
<n-icon :component="Search" />
|
||||
</template>
|
||||
</n-input>
|
||||
|
||||
<n-input
|
||||
placeholder="搜索好友 / 群聊"
|
||||
v-model:value.trim="searchKeyword"
|
||||
round
|
||||
clearable
|
||||
style="width: 78%;"
|
||||
>
|
||||
<template #prefix>
|
||||
<n-icon :component="Search" />
|
||||
</template>
|
||||
</n-input>
|
||||
</n-dropdown>
|
||||
<n-button circle @click="isShowGroup = true">
|
||||
<template #icon>
|
||||
<n-icon :component="Plus" />
|
||||
</template>
|
||||
</n-button>
|
||||
<img
|
||||
style="width: 19px; height: 20px;cursor: pointer;"
|
||||
style="width: 19px; height: 20px; cursor: pointer;"
|
||||
src="@/assets/image/chatList/addressBook.png"
|
||||
alt=""
|
||||
@click="showAddressBookModal"
|
||||
@ -499,7 +553,11 @@ const handleGroupChatListPaginationSize = (value) => {
|
||||
<template #content>
|
||||
<div class="custom-modal-content">
|
||||
<n-card style="padding: 0 12px;">
|
||||
<n-tabs type="line" @update:value="handleAddressBookTabChange" tab-style="font-size: 16px; font-weight: 600;color: #8B8B8B;">
|
||||
<n-tabs
|
||||
type="line"
|
||||
@update:value="handleAddressBookTabChange"
|
||||
tab-style="font-size: 16px; font-weight: 600;color: #8B8B8B;"
|
||||
>
|
||||
<n-tab name="employeeAddressBook">员工通讯录</n-tab>
|
||||
<n-tab name="groupChatList">群聊列表</n-tab>
|
||||
</n-tabs>
|
||||
@ -696,7 +754,7 @@ html[theme-mode='dark'] {
|
||||
width: 100%;
|
||||
padding: 0 12px;
|
||||
:deep(.n-tabs-tab--active) {
|
||||
color: #46299d!important;
|
||||
color: #46299d !important;
|
||||
}
|
||||
.addressBook-content {
|
||||
display: flex;
|
||||
|
Loading…
Reference in New Issue
Block a user