Skip to content

Commit 334c024

Browse files
author
puhui999
committed
【新增】:mall 客服会话右键菜单实现会话相关操作
1 parent 9ab367e commit 334c024

File tree

1 file changed

+123
-3
lines changed

1 file changed

+123
-3
lines changed

src/views/mall/promotion/kefu/components/KeFuConversationBox.vue

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
<div
44
v-for="(item, index) in conversationList"
55
:key="item.id"
6-
:class="{ active: index === activeConversationIndex }"
7-
class="kefu-conversation flex justify-between items-center"
6+
:class="{ active: index === activeConversationIndex, pinned: item.adminPinned }"
7+
class="kefu-conversation flex items-center"
88
@click="openRightMessage(item, index)"
9+
@contextmenu.prevent="rightClick($event as PointerEvent, item)"
910
>
1011
<div class="flex justify-center items-center w-100%">
1112
<div class="flex justify-center items-center" style="width: 50px; height: 50px">
@@ -40,21 +41,67 @@
4041
</div>
4142
</div>
4243
</div>
44+
<!-- 通过右击获取到的坐标定位 -->
45+
<ul v-show="showRightMenu" :style="rightMenuStyle" class="right-menu-ul">
46+
<li
47+
v-show="!selectedConversation.adminPinned"
48+
class="flex items-center"
49+
@click.stop="updateConversationPinned(true)"
50+
>
51+
<Icon class="mr-5px" icon="ep:top" />
52+
置顶会话
53+
</li>
54+
<li
55+
v-show="selectedConversation.adminPinned"
56+
class="flex items-center"
57+
@click.stop="updateConversationPinned(false)"
58+
>
59+
<Icon class="mr-5px" icon="ep:bottom" />
60+
取消置顶
61+
</li>
62+
<li class="flex items-center" @click.stop="deleteConversation">
63+
<Icon class="mr-5px" color="red" icon="ep:delete" />
64+
删除会话
65+
</li>
66+
<li class="flex items-center" @click.stop="closeRightMenu">
67+
<Icon class="mr-5px" color="red" icon="ep:close" />
68+
取消
69+
</li>
70+
</ul>
4371
</div>
4472
</template>
4573

4674
<script lang="ts" setup>
4775
import { KeFuConversationApi, KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation'
4876
import { useEmoji } from './tools/emoji'
49-
import { formatDate } from '@/utils/formatTime'
77+
import { formatDate, getNowDateTime } from '@/utils/formatTime'
5078
import { KeFuMessageContentTypeEnum } from './tools/constants'
5179
5280
defineOptions({ name: 'KeFuConversationBox' })
81+
const message = useMessage()
5382
const { replaceEmoji } = useEmoji()
5483
const activeConversationIndex = ref(-1) // 选中的会话
5584
const conversationList = ref<KeFuConversationRespVO[]>([]) // 会话列表
5685
const getConversationList = async () => {
5786
conversationList.value = await KeFuConversationApi.getConversationList()
87+
// 测试数据
88+
for (let i = 0; i < 5; i++) {
89+
conversationList.value.push({
90+
id: 1,
91+
userId: 283,
92+
userAvatar:
93+
'https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKMezSxtOImrC9lbhwHiazYwck3xwrEcO7VJfG6WQo260whaeVNoByE5RreiaGsGfOMlIiaDhSaA991w/132',
94+
userNickname: '辉辉鸭' + i,
95+
lastMessageTime: getNowDateTime(),
96+
lastMessageContent:
97+
'[爱心][爱心]你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇',
98+
lastMessageContentType: 1,
99+
adminPinned: false,
100+
userDeleted: false,
101+
adminDeleted: false,
102+
adminUnreadMessageCount: i
103+
})
104+
}
58105
}
59106
defineExpose({ getConversationList })
60107
const emits = defineEmits<{
@@ -84,6 +131,54 @@ const getContentType = computed(() => (lastMessageContentType: number) => {
84131
return ''
85132
}
86133
})
134+
135+
//======================= 右键菜单 =======================
136+
const showRightMenu = ref(false) // 显示右键菜单
137+
const rightMenuStyle = ref<any>({}) // 右键菜单 Style
138+
const selectedConversation = ref<KeFuConversationRespVO>({} as KeFuConversationRespVO) // 右键选中的会话对象
139+
// 右键菜单
140+
const rightClick = (mouseEvent: PointerEvent, item: KeFuConversationRespVO) => {
141+
selectedConversation.value = item
142+
// 显示右键菜单
143+
showRightMenu.value = true
144+
rightMenuStyle.value = {
145+
top: mouseEvent.clientY - 110 + 'px',
146+
left: mouseEvent.clientX - 80 + 'px'
147+
}
148+
}
149+
// 关闭菜单
150+
const closeRightMenu = () => {
151+
showRightMenu.value = false
152+
}
153+
// 置顶会话
154+
const updateConversationPinned = async (adminPinned: boolean) => {
155+
// 1. 会话置顶/取消置顶
156+
await KeFuConversationApi.updateConversationPinned({
157+
id: selectedConversation.value.id,
158+
adminPinned
159+
})
160+
// TODO puhui999: 快速操作两次提示只会提示一次看看怎么优雅解决
161+
message.success(adminPinned ? '置顶成功' : '取消置顶成功')
162+
// 2. 关闭右键菜单,更新会话列表
163+
closeRightMenu()
164+
await getConversationList()
165+
}
166+
// 删除会话
167+
const deleteConversation = async () => {
168+
// 1. 删除会话
169+
await message.confirm('您确定要删除该会话吗?')
170+
await KeFuConversationApi.deleteConversation(selectedConversation.value.id)
171+
// 2. 关闭右键菜单,更新会话列表
172+
closeRightMenu()
173+
await getConversationList()
174+
}
175+
watch(showRightMenu, (val) => {
176+
if (val) {
177+
document.body.addEventListener('click', closeRightMenu)
178+
} else {
179+
document.body.removeEventListener('click', closeRightMenu)
180+
}
181+
})
87182
</script>
88183

89184
<style lang="scss" scoped>
@@ -106,5 +201,30 @@ const getContentType = computed(() => (lastMessageContentType: number) => {
106201
border-left: 5px #3271ff solid;
107202
background-color: #eff0f1;
108203
}
204+
205+
.pinned {
206+
background-color: #eff0f1;
207+
}
208+
209+
.right-menu-ul {
210+
position: absolute;
211+
background-color: #fff;
212+
padding: 10px;
213+
margin: 0;
214+
list-style-type: none; /* 移除默认的项目符号 */
215+
border-radius: 12px;
216+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 阴影效果 */
217+
width: 130px;
218+
219+
li {
220+
padding: 8px 16px;
221+
cursor: pointer;
222+
border-radius: 12px;
223+
transition: background-color 0.3s; /* 平滑过渡 */
224+
&:hover {
225+
background-color: #e0e0e0; /* 悬停时的背景颜色 */
226+
}
227+
}
228+
}
109229
}
110230
</style>

0 commit comments

Comments
 (0)