Compare commits
No commits in common. "b04d25a24395b023fbf891a9549db094a5eeda3e" and "478336c2fedff0ec95370e091e6f05d60c689ea5" have entirely different histories.
b04d25a243
...
478336c2fe
@ -32,8 +32,6 @@
|
|||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
"quill-image-uploader": "^1.3.0",
|
"quill-image-uploader": "^1.3.0",
|
||||||
"quill-mention": "^4.1.0",
|
"quill-mention": "^4.1.0",
|
||||||
"sortablejs": "^1.15.6",
|
|
||||||
"viewerjs": "^1.11.7",
|
|
||||||
"vue": "^3.3.11",
|
"vue": "^3.3.11",
|
||||||
"vue-cropper": "^1.1.1",
|
"vue-cropper": "^1.1.1",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
|
@ -62,12 +62,6 @@ importers:
|
|||||||
quill-mention:
|
quill-mention:
|
||||||
specifier: ^4.1.0
|
specifier: ^4.1.0
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
sortablejs:
|
|
||||||
specifier: ^1.15.6
|
|
||||||
version: 1.15.6
|
|
||||||
viewerjs:
|
|
||||||
specifier: ^1.11.7
|
|
||||||
version: 1.11.7
|
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.3.11
|
specifier: ^3.3.11
|
||||||
version: 3.5.13(typescript@5.2.2)
|
version: 3.5.13(typescript@5.2.2)
|
||||||
@ -2933,9 +2927,6 @@ packages:
|
|||||||
sortablejs@1.14.0:
|
sortablejs@1.14.0:
|
||||||
resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==}
|
resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==}
|
||||||
|
|
||||||
sortablejs@1.15.6:
|
|
||||||
resolution: {integrity: sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==}
|
|
||||||
|
|
||||||
source-map-js@1.2.1:
|
source-map-js@1.2.1:
|
||||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -3220,9 +3211,6 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^3.0.11
|
vue: ^3.0.11
|
||||||
|
|
||||||
viewerjs@1.11.7:
|
|
||||||
resolution: {integrity: sha512-0JuVqOmL5v1jmEAlG5EBDR3XquxY8DWFQbFMprOXgaBB0F7Q/X9xWdEaQc59D8xzwkdUgXEMSSknTpriq95igg==}
|
|
||||||
|
|
||||||
vite-hot-client@2.0.4:
|
vite-hot-client@2.0.4:
|
||||||
resolution: {integrity: sha512-W9LOGAyGMrbGArYJN4LBCdOC5+Zwh7dHvOHC0KmGKkJhsOzaKbpo/jEjpPKVHIW0/jBWj8RZG0NUxfgA8BxgAg==}
|
resolution: {integrity: sha512-W9LOGAyGMrbGArYJN4LBCdOC5+Zwh7dHvOHC0KmGKkJhsOzaKbpo/jEjpPKVHIW0/jBWj8RZG0NUxfgA8BxgAg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -6532,8 +6520,6 @@ snapshots:
|
|||||||
|
|
||||||
sortablejs@1.14.0: {}
|
sortablejs@1.14.0: {}
|
||||||
|
|
||||||
sortablejs@1.15.6: {}
|
|
||||||
|
|
||||||
source-map-js@1.2.1: {}
|
source-map-js@1.2.1: {}
|
||||||
|
|
||||||
source-map-resolve@0.5.3:
|
source-map-resolve@0.5.3:
|
||||||
@ -6822,8 +6808,6 @@ snapshots:
|
|||||||
evtd: 0.2.4
|
evtd: 0.2.4
|
||||||
vue: 3.5.13(typescript@5.2.2)
|
vue: 3.5.13(typescript@5.2.2)
|
||||||
|
|
||||||
viewerjs@1.11.7: {}
|
|
||||||
|
|
||||||
vite-hot-client@2.0.4(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)):
|
vite-hot-client@2.0.4(vite@4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)):
|
||||||
dependencies:
|
dependencies:
|
||||||
vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
|
vite: 4.5.14(@types/node@18.19.99)(less@4.3.0)(sass@1.88.0)(terser@5.39.0)
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<slot name="content"></slot>
|
<slot name="content"></slot>
|
||||||
<template #footer v-if="actionBtns.cancelBtn || actionBtns.confirmBtn">
|
<template #footer>
|
||||||
<div class="custom-modal-btns">
|
<div class="custom-modal-btns">
|
||||||
<customBtn
|
<customBtn
|
||||||
color="#C7C7C9"
|
color="#C7C7C9"
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
<div class="row items-center">
|
<div class="row items-center">
|
||||||
<div v-if="state.treeData.edit">
|
<div v-if="state.treeData.edit">
|
||||||
<n-input v-model:value="state.editTitle"
|
<n-input v-model:value="state.editTitle"
|
||||||
style="max-width:200px" />
|
style="width:120px" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<n-popover trigger="hover"
|
<n-popover trigger="hover"
|
||||||
v-else>
|
v-else>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<div style="max-width:200px"
|
<div style="width:120px"
|
||||||
class="fl-px-sm sf-text-ellipsis">{{ state.treeData.title + '(' + state.treeData.staffNum + ')' }}</div>
|
class="fl-px-sm sf-text-ellipsis">{{ state.treeData.title }}</div>
|
||||||
</template>
|
</template>
|
||||||
<div>{{ state.treeData.title }}</div>
|
<div>{{ state.treeData.title }}</div>
|
||||||
</n-popover>
|
</n-popover>
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
<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>
|
|
@ -1,337 +0,0 @@
|
|||||||
<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>
|
|
@ -1,743 +0,0 @@
|
|||||||
<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>
|
|
@ -12,7 +12,6 @@ import {
|
|||||||
} from "vue";
|
} from "vue";
|
||||||
import Sortable from "sortablejs";
|
import Sortable from "sortablejs";
|
||||||
import { debounce } from "lodash-es";
|
import { debounce } from "lodash-es";
|
||||||
import { NDataTable } from "naive-ui";
|
|
||||||
|
|
||||||
// Props 定义
|
// Props 定义
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
144
src/components/x-naive-ui/x-preview-img/index-1.ts
Normal file
144
src/components/x-naive-ui/x-preview-img/index-1.ts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import { createApp, h, ref } from 'vue'
|
||||||
|
import { NImage, NImageGroup } from 'naive-ui'
|
||||||
|
|
||||||
|
interface PreviewOptions {
|
||||||
|
onStart?: () => void
|
||||||
|
onError?: (e: Event) => void
|
||||||
|
showToolbar?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class ImagePreview {
|
||||||
|
private static instance: {
|
||||||
|
app: any
|
||||||
|
container: HTMLElement
|
||||||
|
} | null = null
|
||||||
|
|
||||||
|
static async preview(
|
||||||
|
sources: string | File | (string | File)[],
|
||||||
|
index = 0,
|
||||||
|
options: PreviewOptions = {},
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const urls = await this.normalizeImageSources(
|
||||||
|
Array.isArray(sources) ? sources : [sources]
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!urls.length) {
|
||||||
|
console.warn('[ImagePreview] No valid image sources')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.destroy()
|
||||||
|
options.onStart?.()
|
||||||
|
|
||||||
|
const container = document.createElement('div')
|
||||||
|
container.style.display = 'none'
|
||||||
|
document.body.appendChild(container)
|
||||||
|
|
||||||
|
const app = createApp({
|
||||||
|
setup() {
|
||||||
|
const imageRef = ref<InstanceType<typeof NImage> | null>(null)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (urls.length === 1) {
|
||||||
|
return h(NImage, {
|
||||||
|
ref: imageRef,
|
||||||
|
src: urls[0],
|
||||||
|
previewDisabled: false,
|
||||||
|
preview: true,
|
||||||
|
showToolbar: options.showToolbar ?? true,
|
||||||
|
style: {
|
||||||
|
display: 'none'
|
||||||
|
},
|
||||||
|
onLoad: () => {
|
||||||
|
imageRef.value?.click()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return h(NImageGroup, {
|
||||||
|
showToolbar: options.showToolbar ?? true,
|
||||||
|
currentIndex: index
|
||||||
|
}, {
|
||||||
|
default: () => urls.map((url, i) => {
|
||||||
|
const imgRef = ref<InstanceType<typeof NImage> | null>(null)
|
||||||
|
return h(NImage, {
|
||||||
|
ref: i === index ? imgRef : undefined,
|
||||||
|
src: url,
|
||||||
|
previewDisabled: false,
|
||||||
|
preview: true,
|
||||||
|
style: {
|
||||||
|
display: 'none'
|
||||||
|
},
|
||||||
|
onLoad: i === index ? () => {
|
||||||
|
imgRef.value?.click()
|
||||||
|
} : undefined
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app.mount(container)
|
||||||
|
this.instance = { app, container }
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[ImagePreview] Error:', error)
|
||||||
|
options.onError?.(error as Event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async normalizeImageSources(sources: (string | File)[]): Promise<string[]> {
|
||||||
|
const urls: string[] = []
|
||||||
|
|
||||||
|
for (const source of sources) {
|
||||||
|
try {
|
||||||
|
if (typeof source === 'string') {
|
||||||
|
if (source.startsWith('data:') || source.startsWith('http')) {
|
||||||
|
urls.push(source)
|
||||||
|
} else {
|
||||||
|
console.warn('[ImagePreview] Invalid image source:', source)
|
||||||
|
}
|
||||||
|
} else if (source instanceof File) {
|
||||||
|
const url = await this.fileToUrl(source)
|
||||||
|
urls.push(url)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[ImagePreview] Failed to process source:', source, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return urls
|
||||||
|
}
|
||||||
|
|
||||||
|
private static fileToUrl(file: File): Promise<string> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!file.type.startsWith('image/')) {
|
||||||
|
reject(new Error('Not an image file'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = () => resolve(reader.result as string)
|
||||||
|
reader.onerror = reject
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private static destroy() {
|
||||||
|
if (this.instance) {
|
||||||
|
const { app, container } = this.instance
|
||||||
|
app.unmount()
|
||||||
|
container.remove()
|
||||||
|
this.instance = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static close() {
|
||||||
|
this.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const previewImage = ImagePreview.preview.bind(ImagePreview)
|
||||||
|
export const closePreview = ImagePreview.close.bind(ImagePreview)
|
@ -34,10 +34,6 @@ const props = defineProps({
|
|||||||
loading: {
|
loading: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
|
||||||
customInputPlaceholder: {
|
|
||||||
type: String,
|
|
||||||
default: '请输入',
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -209,7 +205,7 @@ initData()
|
|||||||
<template v-if="item.type === 'input'">
|
<template v-if="item.type === 'input'">
|
||||||
<n-input
|
<n-input
|
||||||
:value="formData[item.key]"
|
:value="formData[item.key]"
|
||||||
:placeholder="customInputPlaceholder"
|
placeholder="请输入"
|
||||||
@input="value => handleInputChange(value, item)"
|
@input="value => handleInputChange(value, item)"
|
||||||
clearable
|
clearable
|
||||||
v-bind="item.props"
|
v-bind="item.props"
|
||||||
|
@ -18,7 +18,7 @@ export function isLoggedIn() {
|
|||||||
*/
|
*/
|
||||||
export function getAccessToken() {
|
export function getAccessToken() {
|
||||||
// return storage.get(AccessToken) || ''
|
// return storage.get(AccessToken) || ''
|
||||||
return JSON.parse(localStorage.getItem('token'))||'79b5c732d96d2b27a48a99dfd4a5566c43aaa5796242e854ebe3ffc198d6876b9628e7b764d9af65ab5dbb2d517ced88170491b74b048c0ba827c0d3741462cb89dc59ed46653a449af837a8262941caaef1334d640773710f8cd96473bacfb190cba595a5d6a9c87d70f0999a3ebb41147213b31b4bdccffca66a56acf3baab5af0154f0dce360079f37709f78e13711036899344bddb0fb4cf0f2890287cb62c3fcbe33368caa5e213624577be8b8420ab75b1f50775ee16142a4321c5d56995f37354a66a969da98d95ba6e65d142ed097e04b411c1ebad2f62866d0ec7e1838420530a9941dbbcd00490199f8b8987a3f4c77465504ba46f90370546f2f3656c248bd63549a43410178becfd0d1888ecbb8e82d291e68cf9da8ec1096e2d8abd4bb9d7edc62d38469e56226683693764f82df03eaa47fe6fd21a9cb83e0e'
|
return JSON.parse(localStorage.getItem('token'))||'46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644ce2108c311309f398ae8ea1b8200bfd490e5cb6e8c52c9e5d493cbabb163368f8351420451a631dbfa749829ee4cda49b77b5ed2d3dced5d0f2b7dd9ee76ba5465c84a17c23af040cd92b6b2a4ea48befbb5c729dcdad0a9c9668befe84074cc24f78899c1d947f8e7f94c7eda5325b8ed698df729e76febb98549ef3482ae942fb4f4a1c92d21836fa784728f0c5483aab2760a991b6b36e6b10c84f840a6433a6ecc31dee36e8f1c6158818bc89d22851b5e2f6cbf01ab4b3da6e3d06b57c8f750e106226a5a4b9d7fc1d381a54cb92375c09ba1fa8e5fde0392d919c2f2cbcc7e4e2eca8d9860749af00374b249f7d04e2bc43a1fa4e7d7384dde0212f0a5'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,27 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import { computed, ref, onMounted, watch, reactive, onBeforeMount, getCurrentInstance } from 'vue'
|
||||||
computed,
|
|
||||||
ref,
|
|
||||||
onMounted,
|
|
||||||
watch,
|
|
||||||
reactive,
|
|
||||||
onBeforeMount,
|
|
||||||
getCurrentInstance,
|
|
||||||
h
|
|
||||||
} from 'vue'
|
|
||||||
import { onBeforeRouteUpdate } from 'vue-router'
|
import { onBeforeRouteUpdate } from 'vue-router'
|
||||||
import { useDialogueStore, useTalkStore } from '@/store'
|
import { useDialogueStore, useTalkStore } from '@/store'
|
||||||
import {
|
import { NDropdown, NIcon, NInput, NPopover, NTabs, NTab, NCard } from 'naive-ui'
|
||||||
NDropdown,
|
|
||||||
NIcon,
|
|
||||||
NInput,
|
|
||||||
NPopover,
|
|
||||||
NTabs,
|
|
||||||
NTab,
|
|
||||||
NCard,
|
|
||||||
NButton,
|
|
||||||
NPagination
|
|
||||||
} from 'naive-ui'
|
|
||||||
import { Search, Plus } from '@icon-park/vue-next'
|
import { Search, Plus } from '@icon-park/vue-next'
|
||||||
import TalkItem from './TalkItem.vue'
|
import TalkItem from './TalkItem.vue'
|
||||||
import Skeleton from './Skeleton.vue'
|
import Skeleton from './Skeleton.vue'
|
||||||
@ -32,13 +13,11 @@ import { ISession } from '@/types/chat'
|
|||||||
import { useSessionMenu } from '@/hooks'
|
import { useSessionMenu } from '@/hooks'
|
||||||
import customModal from '@/components/common/customModal.vue'
|
import customModal from '@/components/common/customModal.vue'
|
||||||
import xSearchForm from '@/components/x-naive-ui/x-search-form/index.vue'
|
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 flTree from '@/components/flnlayout/tree/flnindex.vue'
|
||||||
import { processError, processSuccess } from '@/utils/helper/message.js'
|
import { processError, processSuccess } from '@/utils/helper/message.js'
|
||||||
import chatAppSearchList from '@/components/search/searchList.vue'
|
|
||||||
|
|
||||||
const currentInstance = getCurrentInstance()
|
const currentInstance = getCurrentInstance()
|
||||||
const $request = currentInstance?.appContext.config.globalProperties?.$request
|
const { $request } = currentInstance?.appContext.config.globalProperties
|
||||||
|
|
||||||
const {
|
const {
|
||||||
dropdown,
|
dropdown,
|
||||||
@ -55,48 +34,6 @@ const searchKeyword = ref('')
|
|||||||
const topItems = computed((): ISession[] => talkStore.topItems)
|
const topItems = computed((): ISession[] => talkStore.topItems)
|
||||||
const unreadNum = computed(() => talkStore.talkUnreadNum)
|
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({
|
const state = reactive({
|
||||||
isShowAddressBookModal: false, // 是否显示通讯录模态框
|
isShowAddressBookModal: false, // 是否显示通讯录模态框
|
||||||
customModalStyle: {
|
customModalStyle: {
|
||||||
@ -104,128 +41,20 @@ const state = reactive({
|
|||||||
height: '846px',
|
height: '846px',
|
||||||
backgroundColor: '#F9F9FD'
|
backgroundColor: '#F9F9FD'
|
||||||
}, //自定义模态框样式
|
}, //自定义模态框样式
|
||||||
addressBookSearchConfig: [
|
searchConfig: [
|
||||||
{
|
{
|
||||||
label: '姓名',
|
label: '姓名',
|
||||||
key: 'nickName',
|
key: 'name',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
valueType: 'string'
|
valueType: 'string'
|
||||||
}
|
}
|
||||||
], // 通讯录搜索配置
|
], // 搜索配置
|
||||||
groupChatListSearchConfig: [
|
|
||||||
{
|
|
||||||
label: '群聊名称',
|
|
||||||
key: 'groupName',
|
|
||||||
type: 'input',
|
|
||||||
valueType: 'string'
|
|
||||||
}
|
|
||||||
], // 群聊列表搜索配置
|
|
||||||
treeData: [],
|
treeData: [],
|
||||||
expandedKeys: [],
|
expandedKeys: [],
|
||||||
clickKey: 3,
|
clickKey: '',
|
||||||
treeRefreshCount: 0,
|
treeRefreshCount: 0,
|
||||||
treeSelectData: {},
|
treeSelectData: {}
|
||||||
addressBookColumns: [
|
|
||||||
{
|
|
||||||
title: '姓名 【工号】',
|
|
||||||
field: 'nickName',
|
|
||||||
width: 200,
|
|
||||||
render(row, index) {
|
|
||||||
return row.nickName + '【' + row.jobNum + '】'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '岗位名称',
|
|
||||||
field: 'positionName',
|
|
||||||
width: 400,
|
|
||||||
ellipsis: true,
|
|
||||||
render(row, index) {
|
|
||||||
let positionNames = Array.isArray(row.depPositions)
|
|
||||||
? row.depPositions.flatMap((dep) =>
|
|
||||||
Array.isArray(dep.positions) ? dep.positions.map((pos) => pos.name) : []
|
|
||||||
)
|
|
||||||
: []
|
|
||||||
return positionNames.join(' , ')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
field: 'action',
|
|
||||||
width: 200,
|
|
||||||
align: 'center',
|
|
||||||
fixed: 'right',
|
|
||||||
render(row, index) {
|
|
||||||
return h(
|
|
||||||
NButton,
|
|
||||||
{
|
|
||||||
size: 'small',
|
|
||||||
text: true,
|
|
||||||
color: '#46299d',
|
|
||||||
onClick: () => handleEnterChat(row)
|
|
||||||
},
|
|
||||||
{ default: () => '进入聊天' }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
], // 通讯录表格列
|
|
||||||
groupChatListColumns: [
|
|
||||||
{
|
|
||||||
title: '群聊名称',
|
|
||||||
field: 'groupName',
|
|
||||||
width: 200,
|
|
||||||
render(row, index) {
|
|
||||||
return row.groupName
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '群类型',
|
|
||||||
field: 'groupType',
|
|
||||||
width: 400,
|
|
||||||
ellipsis: true,
|
|
||||||
render(row, index) {
|
|
||||||
return row.groupType
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
field: 'action',
|
|
||||||
width: 200,
|
|
||||||
align: 'center',
|
|
||||||
fixed: 'right',
|
|
||||||
render(row, index) {
|
|
||||||
return h(
|
|
||||||
NButton,
|
|
||||||
{
|
|
||||||
size: 'small',
|
|
||||||
text: true,
|
|
||||||
color: '#46299d',
|
|
||||||
onClick: () => handleEnterChat(row)
|
|
||||||
},
|
|
||||||
{ default: () => '进入聊天' }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
], // 群聊列表表格列
|
|
||||||
addressBookData: [], // 通讯录表格数据
|
|
||||||
groupChatListData: [], // 群聊列表表格数据
|
|
||||||
addressBookTableHeight: 524, // 通讯录表格高度
|
|
||||||
addressBookTableWidth: 800, // 通讯录表格宽度
|
|
||||||
addressBookPage: 1, // 通讯录表格页码
|
|
||||||
addressBookPageSize: 10, // 通讯录表格每页条数
|
|
||||||
addressBookTotal: 0, // 通讯录表格总条数
|
|
||||||
addressBookSearchNickName: '', // 通讯录搜索条件-姓名
|
|
||||||
addressBookCurrentTab: 'employeeAddressBook', // 通讯录当前tab
|
|
||||||
groupChatListPage: 1, // 群聊列表表格页码
|
|
||||||
groupChatListPageSize: 10, // 群聊列表表格每页条数
|
|
||||||
groupChatListTotal: 0, // 群聊列表表格总条数
|
|
||||||
groupChatListSearchGroupName: '', // 群聊列表搜索条件-群聊名称
|
|
||||||
chatSearchOptions: [
|
|
||||||
{
|
|
||||||
key: 'chatSearch',
|
|
||||||
type: 'render',
|
|
||||||
render: renderChatAppSearch
|
|
||||||
}
|
|
||||||
] // 聊天搜索选项
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const items = computed((): ISession[] => {
|
const items = computed((): ISession[] => {
|
||||||
@ -239,31 +68,13 @@ const items = computed((): ISession[] => {
|
|||||||
return keyword.toLowerCase().indexOf(searchKeyword.value.toLowerCase()) != -1
|
return keyword.toLowerCase().indexOf(searchKeyword.value.toLowerCase()) != -1
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
setTimeout(() => {
|
setTimeout(()=>{
|
||||||
console.log('items.value', items.value)
|
console.log('items.value',items.value)
|
||||||
}, 1000)
|
},1000)
|
||||||
watch(
|
watch(() => talkStore, (newValue, oldValue) => {
|
||||||
() => talkStore,
|
console.log(newValue);
|
||||||
(newValue, oldValue) => {
|
|
||||||
console.log(newValue)
|
},{deep:true,immediate:true})
|
||||||
},
|
|
||||||
{ deep: true, immediate: true }
|
|
||||||
)
|
|
||||||
watch(
|
|
||||||
() => state.addressBookSearchNickName,
|
|
||||||
(newValue, oldValue) => {
|
|
||||||
// console.log(newValue, 'newValue')
|
|
||||||
if (newValue) {
|
|
||||||
state.addressBookTableWidth = 1142
|
|
||||||
state.addressBookPage = 1
|
|
||||||
} else {
|
|
||||||
state.addressBookTableWidth = 800
|
|
||||||
state.clickKey = 3
|
|
||||||
state.treeRefreshCount++
|
|
||||||
}
|
|
||||||
getDepPoisUser()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 列表加载状态
|
// 列表加载状态
|
||||||
const loadStatus = computed(() => talkStore.loadStatus)
|
const loadStatus = computed(() => talkStore.loadStatus)
|
||||||
@ -334,11 +145,8 @@ const showAddressBookModal = () => {
|
|||||||
state.isShowAddressBookModal = true
|
state.isShowAddressBookModal = true
|
||||||
}
|
}
|
||||||
const handleTreeClick = ({ selectedKey, tree }) => {
|
const handleTreeClick = ({ selectedKey, tree }) => {
|
||||||
// console.log(tree)
|
|
||||||
state.clickKey = tree.key
|
state.clickKey = tree.key
|
||||||
state.treeSelectData = tree
|
state.treeSelectData = tree
|
||||||
state.addressBookPage = 1
|
|
||||||
getDepPoisUser()
|
|
||||||
}
|
}
|
||||||
const calcTreeData = (data) => {
|
const calcTreeData = (data) => {
|
||||||
for (let item of data) {
|
for (let item of data) {
|
||||||
@ -364,8 +172,29 @@ const getTreeData = () => {
|
|||||||
let data = res.data.nodes
|
let data = res.data.nodes
|
||||||
calcTreeData(data)
|
calcTreeData(data)
|
||||||
state.treeData = data
|
state.treeData = data
|
||||||
|
// // 获取最近点击的部门
|
||||||
|
// let localSelect = Local.get("posimanage_treeSelectData");
|
||||||
|
// if (localSelect && JSON.stringify(localSelect) !== "{}") {
|
||||||
|
// state.treeSelectData = localSelect;
|
||||||
|
// state.expandedKeys = localSelect.pathIds;
|
||||||
|
// state.clickKey = localSelect.key;
|
||||||
|
// } else {
|
||||||
|
// if (JSON.stringify(state.treeSelectData) === "{}") {
|
||||||
|
// state.treeSelectData = data[0];
|
||||||
|
// state.clickKey = data[0].key;
|
||||||
|
// }
|
||||||
|
// if (
|
||||||
|
// state.clickKey === data[0].key &&
|
||||||
|
// !state.expandedKeys.includes(data[0].key)
|
||||||
|
// ) {
|
||||||
|
// state.expandedKeys.push(data[0].key);
|
||||||
|
// }
|
||||||
|
// if (!state.expandedKeys.includes(state.clickKey)) {
|
||||||
|
// state.expandedKeys.push(state.clickKey);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
state.treeRefreshCount++
|
state.treeRefreshCount++
|
||||||
getDepPoisUser()
|
// state.tableConfig.refreshCount++;
|
||||||
} else {
|
} else {
|
||||||
processError(res.msg || '获取失败!')
|
processError(res.msg || '获取失败!')
|
||||||
}
|
}
|
||||||
@ -378,66 +207,6 @@ const getTreeData = () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// 获取部门下的人员
|
|
||||||
const getDepPoisUser = () => {
|
|
||||||
let url = '/user/v2/list'
|
|
||||||
let params = {
|
|
||||||
departmentId: state.addressBookSearchNickName ? undefined : state.clickKey,
|
|
||||||
page: state.addressBookPage,
|
|
||||||
pageSize: state.addressBookPageSize,
|
|
||||||
status: 'notactive',
|
|
||||||
nickName: state.addressBookSearchNickName
|
|
||||||
}
|
|
||||||
$request.HTTP.components.postDataByParams(url, params).then((res) => {
|
|
||||||
// console.log(res)
|
|
||||||
if (res.status === 0 && Array.isArray(res.data.data)) {
|
|
||||||
state.addressBookData = res.data.data || []
|
|
||||||
state.addressBookTotal = res.data.count
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
//点击进入对应的聊天
|
|
||||||
const handleEnterChat = (row) => {
|
|
||||||
console.log(row)
|
|
||||||
}
|
|
||||||
//处理页数变化
|
|
||||||
const handleAddressBookPagination = (page) => {
|
|
||||||
state.addressBookPage = page
|
|
||||||
getDepPoisUser()
|
|
||||||
}
|
|
||||||
//处理每页条数变化
|
|
||||||
const handleAddressBookPaginationSize = (pageSize) => {
|
|
||||||
state.addressBookPageSize = pageSize
|
|
||||||
state.addressBookPage = 1
|
|
||||||
getDepPoisUser()
|
|
||||||
}
|
|
||||||
//处理通讯录搜索
|
|
||||||
const changeAddressBookSearch = (value) => {
|
|
||||||
if (!value.nickName?.trim()) {
|
|
||||||
state.addressBookSearchNickName = ''
|
|
||||||
} else {
|
|
||||||
state.addressBookSearchNickName = value.nickName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//处理通讯录tab切换
|
|
||||||
const handleAddressBookTabChange = (value) => {
|
|
||||||
console.log(value, 'value')
|
|
||||||
state.addressBookCurrentTab = value
|
|
||||||
}
|
|
||||||
//处理群聊列表搜索
|
|
||||||
const changeGroupChatListSearch = (value) => {
|
|
||||||
console.log(value, 'value')
|
|
||||||
}
|
|
||||||
//处理群聊列表页数变化
|
|
||||||
const handleGroupChatListPagination = (value) => {
|
|
||||||
console.log(value, 'value')
|
|
||||||
state.groupChatListPage = value
|
|
||||||
}
|
|
||||||
//处理群聊列表每页条数变化
|
|
||||||
const handleGroupChatListPaginationSize = (value) => {
|
|
||||||
console.log(value, 'value')
|
|
||||||
state.groupChatListPageSize = value
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -455,15 +224,10 @@ const handleGroupChatListPaginationSize = (value) => {
|
|||||||
<section class="el-container is-vertical height100">
|
<section class="el-container is-vertical height100">
|
||||||
<!-- 工具栏目 -->
|
<!-- 工具栏目 -->
|
||||||
<header class="el-header header-tools">
|
<header class="el-header header-tools">
|
||||||
<n-dropdown
|
|
||||||
trigger="click"
|
|
||||||
:options="state.chatSearchOptions"
|
|
||||||
style="width: 248px; height: 677px; overflow-y: scroll;"
|
|
||||||
>
|
|
||||||
<n-input
|
<n-input
|
||||||
placeholder="搜索好友 / 群聊"
|
placeholder="搜索好友 / 群聊"
|
||||||
v-model:value.trim="searchKeyword"
|
v-model:value.trim="searchKeyword"
|
||||||
round
|
|
||||||
clearable
|
clearable
|
||||||
style="width: 78%;"
|
style="width: 78%;"
|
||||||
>
|
>
|
||||||
@ -471,14 +235,14 @@ const handleGroupChatListPaginationSize = (value) => {
|
|||||||
<n-icon :component="Search" />
|
<n-icon :component="Search" />
|
||||||
</template>
|
</template>
|
||||||
</n-input>
|
</n-input>
|
||||||
</n-dropdown>
|
|
||||||
<n-button circle @click="isShowGroup = true">
|
<n-button circle @click="isShowGroup = true">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon :component="Plus" />
|
<n-icon :component="Plus" />
|
||||||
</template>
|
</template>
|
||||||
</n-button>
|
</n-button>
|
||||||
<img
|
<img
|
||||||
style="width: 19px; height: 20px; cursor: pointer;"
|
style="width: 19px; height: 20px;"
|
||||||
src="@/assets/image/chatList/addressBook.png"
|
src="@/assets/image/chatList/addressBook.png"
|
||||||
alt=""
|
alt=""
|
||||||
@click="showAddressBookModal"
|
@click="showAddressBookModal"
|
||||||
@ -486,7 +250,7 @@ const handleGroupChatListPaginationSize = (value) => {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- 置顶栏目 -->
|
<!-- 置顶栏目 -->
|
||||||
<header class="el-header header-top" v-show="loadStatus == 3 && topItems.length > 0">
|
<!-- <header class="el-header header-top" v-show="loadStatus == 3 && topItems.length > 0">
|
||||||
<n-popover v-for="item in topItems" :key="item.index_name" placement="bottom" trigger="hover">
|
<n-popover v-for="item in topItems" :key="item.index_name" placement="bottom" trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<div
|
<div
|
||||||
@ -509,10 +273,10 @@ const handleGroupChatListPaginationSize = (value) => {
|
|||||||
</template>
|
</template>
|
||||||
<span> {{ item.remark || item.name }} </span>
|
<span> {{ item.remark || item.name }} </span>
|
||||||
</n-popover>
|
</n-popover>
|
||||||
</header>
|
</header> -->
|
||||||
|
|
||||||
<!-- 标题栏目 -->
|
<!-- 标题栏目 -->
|
||||||
<header
|
<!-- <header
|
||||||
v-show="loadStatus == 3 && talkStore.talkItems.length > 0"
|
v-show="loadStatus == 3 && talkStore.talkItems.length > 0"
|
||||||
class="el-header header-badge"
|
class="el-header header-badge"
|
||||||
:class="{ shadow: false }"
|
:class="{ shadow: false }"
|
||||||
@ -521,11 +285,12 @@ const handleGroupChatListPaginationSize = (value) => {
|
|||||||
<p>
|
<p>
|
||||||
<span class="badge unread" v-show="unreadNum">{{ unreadNum }}未读</span>
|
<span class="badge unread" v-show="unreadNum">{{ unreadNum }}未读</span>
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header> -->
|
||||||
|
|
||||||
<main id="talk-session-list" class="el-main me-scrollbar me-scrollbar-thumb">
|
<main id="talk-session-list" class="el-main me-scrollbar me-scrollbar-thumb">
|
||||||
<template v-if="loadStatus == 2"><Skeleton /></template>
|
<template v-if="loadStatus == 2"><Skeleton /></template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
|
||||||
<TalkItem
|
<TalkItem
|
||||||
v-for="item in items"
|
v-for="item in items"
|
||||||
:key="item.index_name"
|
:key="item.index_name"
|
||||||
@ -552,34 +317,14 @@ const handleGroupChatListPaginationSize = (value) => {
|
|||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="custom-modal-content">
|
<div class="custom-modal-content">
|
||||||
<n-card style="padding: 0 12px;">
|
<n-card>
|
||||||
<n-tabs
|
<n-tabs type="line">
|
||||||
type="line"
|
|
||||||
@update:value="handleAddressBookTabChange"
|
|
||||||
tab-style="font-size: 16px; font-weight: 600;color: #8B8B8B;"
|
|
||||||
>
|
|
||||||
<n-tab name="employeeAddressBook">员工通讯录</n-tab>
|
<n-tab name="employeeAddressBook">员工通讯录</n-tab>
|
||||||
<n-tab name="groupChatList">群聊列表</n-tab>
|
<n-tab name="groupChatList">群聊列表</n-tab>
|
||||||
</n-tabs>
|
</n-tabs>
|
||||||
<xSearchForm
|
<xSearchForm :search-config="state.searchConfig"></xSearchForm>
|
||||||
v-if="state.addressBookCurrentTab == 'employeeAddressBook'"
|
<div class="addressBook-content">
|
||||||
:search-config="state.addressBookSearchConfig"
|
<div class="addressBook-tree">
|
||||||
customInputPlaceholder="请输入姓名"
|
|
||||||
@change="changeAddressBookSearch"
|
|
||||||
:cols="3"
|
|
||||||
></xSearchForm>
|
|
||||||
<xSearchForm
|
|
||||||
v-if="state.addressBookCurrentTab == 'groupChatList'"
|
|
||||||
:search-config="state.groupChatListSearchConfig"
|
|
||||||
customInputPlaceholder="请输入群聊名称"
|
|
||||||
@change="changeGroupChatListSearch"
|
|
||||||
:cols="3"
|
|
||||||
></xSearchForm>
|
|
||||||
<div
|
|
||||||
class="addressBook-content"
|
|
||||||
v-if="state.addressBookCurrentTab == 'employeeAddressBook'"
|
|
||||||
>
|
|
||||||
<div class="addressBook-tree" v-if="!state.addressBookSearchNickName">
|
|
||||||
<fl-tree
|
<fl-tree
|
||||||
:data="state.treeData"
|
:data="state.treeData"
|
||||||
:expandedKeys="state.expandedKeys"
|
:expandedKeys="state.expandedKeys"
|
||||||
@ -588,58 +333,6 @@ const handleGroupChatListPaginationSize = (value) => {
|
|||||||
@triggerTreeClick="handleTreeClick"
|
@triggerTreeClick="handleTreeClick"
|
||||||
></fl-tree>
|
></fl-tree>
|
||||||
</div>
|
</div>
|
||||||
<div class="addressBook-table">
|
|
||||||
<xNDataTable
|
|
||||||
:columns="state.addressBookColumns"
|
|
||||||
:data="state.addressBookData"
|
|
||||||
:style="{
|
|
||||||
height: `${state.addressBookTableHeight}px`,
|
|
||||||
width: `${state.addressBookTableWidth}px`
|
|
||||||
}"
|
|
||||||
flex-height
|
|
||||||
></xNDataTable>
|
|
||||||
<div class="addressBook-pagination">
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="state.addressBookPage"
|
|
||||||
v-model:page-size="state.addressBookPageSize"
|
|
||||||
:item-count="state.addressBookTotal"
|
|
||||||
show-quick-jumper
|
|
||||||
show-size-picker
|
|
||||||
:page-sizes="[10, 20, 50]"
|
|
||||||
:on-update:page="handleAddressBookPagination"
|
|
||||||
:on-update:page-size="handleAddressBookPaginationSize"
|
|
||||||
>
|
|
||||||
<template #prefix="{ itemCount }"> 共 {{ itemCount }} 条记录 </template>
|
|
||||||
</n-pagination>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="groupChatList-content" v-if="state.addressBookCurrentTab == 'groupChatList'">
|
|
||||||
<div class="groupChatList-table">
|
|
||||||
<xNDataTable
|
|
||||||
:columns="state.groupChatListColumns"
|
|
||||||
:data="state.groupChatListData"
|
|
||||||
:style="{
|
|
||||||
height: '523px',
|
|
||||||
width: '1148px'
|
|
||||||
}"
|
|
||||||
flex-height
|
|
||||||
></xNDataTable>
|
|
||||||
<div class="groupChatList-pagination">
|
|
||||||
<n-pagination
|
|
||||||
v-model:page="state.groupChatListPage"
|
|
||||||
v-model:page-size="state.groupChatListPageSize"
|
|
||||||
:item-count="state.groupChatListTotal"
|
|
||||||
show-quick-jumper
|
|
||||||
show-size-picker
|
|
||||||
:page-sizes="[10, 20, 50]"
|
|
||||||
:on-update:page="handleGroupChatListPagination"
|
|
||||||
:on-update:page-size="handleGroupChatListPaginationSize"
|
|
||||||
>
|
|
||||||
<template #prefix="{ itemCount }"> 共 {{ itemCount }} 条记录 </template>
|
|
||||||
</n-pagination>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</n-card>
|
</n-card>
|
||||||
</div>
|
</div>
|
||||||
@ -753,13 +446,7 @@ html[theme-mode='dark'] {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
:deep(.n-tabs-tab--active) {
|
|
||||||
color: #46299d !important;
|
|
||||||
}
|
|
||||||
.addressBook-content {
|
.addressBook-content {
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 20px;
|
|
||||||
.addressBook-tree {
|
.addressBook-tree {
|
||||||
width: 328px;
|
width: 328px;
|
||||||
height: 524px;
|
height: 524px;
|
||||||
@ -769,37 +456,6 @@ html[theme-mode='dark'] {
|
|||||||
padding: 12px 20px;
|
padding: 12px 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
.addressBook-table {
|
|
||||||
:deep(.n-data-table-th) {
|
|
||||||
background-color: #46299d;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.addressBook-pagination {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
padding: 22px 0 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.groupChatList-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
gap: 20px;
|
|
||||||
.groupChatList-table {
|
|
||||||
:deep(.n-data-table-th) {
|
|
||||||
background-color: #46299d;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.groupChatList-pagination {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
padding: 22px 0 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user