1
1
<template >
2
2
<div class =" kefu" >
3
3
<div
4
- v-for =" ( item, index) in conversationList"
4
+ v-for =" item in conversationList"
5
5
:key =" item.id"
6
- :class =" { active: index === activeConversationIndex , pinned: item.adminPinned }"
6
+ :class =" { active: item.id === activeConversationId , pinned: item.adminPinned }"
7
7
class =" kefu-conversation flex items-center"
8
- @click =" openRightMessage(item, index )"
8
+ @click =" openRightMessage(item)"
9
9
@contextmenu.prevent =" rightClick($event as PointerEvent, item)"
10
10
>
11
11
<div class =" flex justify-center items-center w-100%" >
12
- <!-- TODO style 换成 unocss -->
13
- <div class =" flex justify-center items-center" style =" width : 50px ; height : 50px " >
12
+ <div class =" flex justify-center items-center w-50px h-50px" >
14
13
<!-- 头像 + 未读 -->
15
14
<el-badge
16
15
:hidden =" item.adminUnreadMessageCount === 0"
27
26
{{ formatDate(item.lastMessageTime) }}
28
27
</span >
29
28
</div >
30
- <!-- 文本消息 -->
31
- <template v-if =" KeFuMessageContentTypeEnum .TEXT === item .lastMessageContentType " >
32
- <div
33
- v-dompurify-html =" replaceEmoji(item.lastMessageContent)"
34
- class =" last-message flex items-center color-[#989EA6]"
35
- ></div >
36
- </template >
37
- <!-- 图片消息 -->
38
- <template v-else >
39
- <div class =" last-message flex items-center color-[#989EA6]" >
40
- {{ getContentType(item.lastMessageContentType) }}
41
- </div >
42
- </template >
29
+ <!-- 最后聊天内容 -->
30
+ <div
31
+ v-dompurify-html ="
32
+ getConversationDisplayText(item.lastMessageContentType, item.lastMessageContent)
33
+ "
34
+ class =" last-message flex items-center color-[#989EA6]"
35
+ ></div >
43
36
</div >
44
37
</div >
45
38
</div >
46
39
47
40
<!-- 右键,进行操作(类似微信) -->
48
41
<ul v-show =" showRightMenu" :style =" rightMenuStyle" class =" right-menu-ul" >
49
42
<li
50
- v-show =" !selectedConversation .adminPinned"
43
+ v-show =" !rightClickConversation .adminPinned"
51
44
class =" flex items-center"
52
45
@click.stop =" updateConversationPinned(true)"
53
46
>
54
47
<Icon class =" mr-5px" icon =" ep:top" />
55
48
置顶会话
56
49
</li >
57
50
<li
58
- v-show =" selectedConversation .adminPinned"
51
+ v-show =" rightClickConversation .adminPinned"
59
52
class =" flex items-center"
60
53
@click.stop =" updateConversationPinned(false)"
61
54
>
@@ -79,64 +72,71 @@ import { KeFuConversationApi, KeFuConversationRespVO } from '@/api/mall/promotio
79
72
import { useEmoji } from ' ./tools/emoji'
80
73
import { formatDate } from ' @/utils/formatTime'
81
74
import { KeFuMessageContentTypeEnum } from ' ./tools/constants'
75
+ import { useAppStore } from ' @/store/modules/app'
82
76
83
- defineOptions ({ name: ' KeFuConversationBox ' })
77
+ defineOptions ({ name: ' KeFuConversationList ' })
84
78
85
79
const message = useMessage () // 消息弹窗
86
-
80
+ const appStore = useAppStore ()
87
81
const { replaceEmoji } = useEmoji ()
88
82
const conversationList = ref <KeFuConversationRespVO []>([]) // 会话列表
89
- const activeConversationIndex = ref (- 1 ) // 选中的会话 index 位置 TODO @puhui999:这个可以改成 activeConversationId 么?因为一般是选中的对话编号
83
+ const activeConversationId = ref (- 1 ) // 选中的会话
84
+ const collapse = computed (() => appStore .getCollapse ) // 折叠菜单
90
85
91
86
/** 加载会话列表 */
92
87
const getConversationList = async () => {
93
- conversationList .value = await KeFuConversationApi .getConversationList ()
88
+ const list = await KeFuConversationApi .getConversationList ()
89
+ list .sort ((a : KeFuConversationRespVO , _ ) => (a .adminPinned ? - 1 : 1 ))
90
+ conversationList .value = list
94
91
}
95
92
defineExpose ({ getConversationList })
96
93
97
94
/** 打开右侧的消息列表 */
98
95
const emits = defineEmits <{
99
96
(e : ' change' , v : KeFuConversationRespVO ): void
100
97
}>()
101
- const openRightMessage = (item : KeFuConversationRespVO , index : number ) => {
102
- activeConversationIndex .value = index
98
+ const openRightMessage = (item : KeFuConversationRespVO ) => {
99
+ activeConversationId .value = item . id
103
100
emits (' change' , item )
104
101
}
105
102
106
- // TODO @puhui999:这个,是不是改成 getConversationDisplayText,获取会话的展示文本。然后,把文本消息类型,也统一处理(包括上面的 replaceEmoji)。这样,更统一。
107
103
/** 获得消息类型 */
108
- const getContentType = computed (() => (lastMessageContentType : number ) => {
109
- switch (lastMessageContentType ) {
110
- case KeFuMessageContentTypeEnum .SYSTEM :
111
- return ' [系统消息]'
112
- case KeFuMessageContentTypeEnum .VIDEO :
113
- return ' [视频消息]'
114
- case KeFuMessageContentTypeEnum .IMAGE :
115
- return ' [图片消息]'
116
- case KeFuMessageContentTypeEnum .PRODUCT :
117
- return ' [商品消息]'
118
- case KeFuMessageContentTypeEnum .ORDER :
119
- return ' [订单消息]'
120
- case KeFuMessageContentTypeEnum .VOICE :
121
- return ' [语音消息]'
122
- default :
123
- return ' '
104
+ const getConversationDisplayText = computed (
105
+ () => (lastMessageContentType : number , lastMessageContent : string ) => {
106
+ switch (lastMessageContentType ) {
107
+ case KeFuMessageContentTypeEnum .SYSTEM :
108
+ return ' [系统消息]'
109
+ case KeFuMessageContentTypeEnum .VIDEO :
110
+ return ' [视频消息]'
111
+ case KeFuMessageContentTypeEnum .IMAGE :
112
+ return ' [图片消息]'
113
+ case KeFuMessageContentTypeEnum .PRODUCT :
114
+ return ' [商品消息]'
115
+ case KeFuMessageContentTypeEnum .ORDER :
116
+ return ' [订单消息]'
117
+ case KeFuMessageContentTypeEnum .VOICE :
118
+ return ' [语音消息]'
119
+ case KeFuMessageContentTypeEnum .TEXT :
120
+ return replaceEmoji (lastMessageContent )
121
+ default :
122
+ return ' '
123
+ }
124
124
}
125
- } )
125
+ )
126
126
127
127
// ======================= 右键菜单 =======================
128
128
const showRightMenu = ref (false ) // 显示右键菜单
129
129
const rightMenuStyle = ref <any >({}) // 右键菜单 Style
130
- const selectedConversation = ref <KeFuConversationRespVO >({} as KeFuConversationRespVO ) // 右键选中的会话对象 TODO puhui999:这个是不是叫 rightClickConversation 会好点。因为 selected 容易和选中的对话,定义上有点重叠
130
+ const rightClickConversation = ref <KeFuConversationRespVO >({} as KeFuConversationRespVO ) // 右键选中的会话对象
131
131
132
132
/** 打开右键菜单 */
133
133
const rightClick = (mouseEvent : PointerEvent , item : KeFuConversationRespVO ) => {
134
- selectedConversation .value = item
134
+ rightClickConversation .value = item
135
135
// 显示右键菜单
136
136
showRightMenu .value = true
137
137
rightMenuStyle .value = {
138
138
top: mouseEvent .clientY - 110 + ' px' ,
139
- left: mouseEvent .clientX - 80 + ' px'
139
+ left: collapse . value ? mouseEvent .clientX - 80 + ' px ' : mouseEvent . clientX - 210 + ' px'
140
140
}
141
141
}
142
142
/** 关闭右键菜单 */
@@ -148,7 +148,7 @@ const closeRightMenu = () => {
148
148
const updateConversationPinned = async (adminPinned : boolean ) => {
149
149
// 1. 会话置顶/取消置顶
150
150
await KeFuConversationApi .updateConversationPinned ({
151
- id: selectedConversation .value .id ,
151
+ id: rightClickConversation .value .id ,
152
152
adminPinned
153
153
})
154
154
message .notifySuccess (adminPinned ? ' 置顶成功' : ' 取消置顶成功' )
@@ -161,7 +161,7 @@ const updateConversationPinned = async (adminPinned: boolean) => {
161
161
const deleteConversation = async () => {
162
162
// 1. 删除会话
163
163
await message .confirm (' 您确定要删除该会话吗?' )
164
- await KeFuConversationApi .deleteConversation (selectedConversation .value .id )
164
+ await KeFuConversationApi .deleteConversation (rightClickConversation .value .id )
165
165
// 2. 关闭右键菜单,更新会话列表
166
166
closeRightMenu ()
167
167
await getConversationList ()
0 commit comments