Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
9ab367e4
authored
Jul 05, 2024
by
puhui999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【新增】:mall 客服会话未读消息展示和消息已读处理
parent
2b329d33
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
74 additions
and
111 deletions
+74
-111
src/api/mall/promotion/kefu/conversation/index.ts
+12
-49
src/api/mall/promotion/kefu/message/index.ts
+13
-47
src/views/mall/promotion/kefu/components/KeFuChatBox.vue
+7
-3
src/views/mall/promotion/kefu/components/KeFuConversationBox.vue
+32
-3
src/views/mall/promotion/kefu/components/index.ts
+1
-2
src/views/mall/promotion/kefu/index.vue
+9
-7
No files found.
src/api/mall/promotion/kefu/conversation/index.ts
View file @
9ab367e4
import
request
from
'@/config/axios'
// TODO @puhui999:注释要不放在属性后面,避免太长哈
export
interface
KeFuConversationRespVO
{
/**
* 编号
*/
id
:
number
/**
* 会话所属用户
*/
userId
:
number
/**
* 会话所属用户头像
*/
userAvatar
:
string
/**
* 会话所属用户昵称
*/
userNickname
:
string
/**
* 最后聊天时间
*/
lastMessageTime
:
Date
/**
* 最后聊天内容
*/
lastMessageContent
:
string
/**
* 最后发送的消息类型
*/
lastMessageContentType
:
number
/**
* 管理端置顶
*/
adminPinned
:
boolean
/**
* 用户是否可见
*/
userDeleted
:
boolean
/**
* 管理员是否可见
*/
adminDeleted
:
boolean
/**
* 管理员未读消息数
*/
adminUnreadMessageCount
:
number
/**
* 创建时间
*/
createTime
?:
string
id
:
number
// 编号
userId
:
number
// 会话所属用户
userAvatar
:
string
// 会话所属用户头像
userNickname
:
string
// 会话所属用户昵称
lastMessageTime
:
Date
// 最后聊天时间
lastMessageContent
:
string
// 最后聊天内容
lastMessageContentType
:
number
// 最后发送的消息类型
adminPinned
:
boolean
// 管理端置顶
userDeleted
:
boolean
// 用户是否可见
adminDeleted
:
boolean
// 管理员是否可见
adminUnreadMessageCount
:
number
// 管理员未读消息数
createTime
?:
string
// 创建时间
}
// 客服会话 API
...
...
src/api/mall/promotion/kefu/message/index.ts
View file @
9ab367e4
import
request
from
'@/config/axios'
export
interface
KeFuMessageRespVO
{
/**
* 编号
*/
id
:
number
/**
* 会话编号
*/
conversationId
:
number
/**
* 发送人编号
*/
senderId
:
number
/**
* 发送人头像
*/
senderAvatar
:
string
/**
* 发送人类型
*/
senderType
:
number
/**
* 接收人编号
*/
receiverId
:
number
/**
* 接收人类型
*/
receiverType
:
number
/**
* 消息类型
*/
contentType
:
number
/**
* 消息
*/
content
:
string
/**
* 是否已读
*/
readStatus
:
boolean
/**
* 创建时间
*/
createTime
:
Date
id
:
number
// 编号
conversationId
:
number
// 会话编号
senderId
:
number
// 发送人编号
senderAvatar
:
string
// 发送人头像
senderType
:
number
// 发送人类型
receiverId
:
number
// 接收人编号
receiverType
:
number
// 接收人类型
contentType
:
number
// 消息类型
content
:
string
// 消息
readStatus
:
boolean
// 是否已读
createTime
:
Date
// 创建时间
}
// 客服会话 API
...
...
@@ -57,10 +24,9 @@ export const KeFuMessageApi = {
})
},
// 更新客服消息已读状态
updateKeFuMessageReadStatus
:
async
(
data
:
any
)
=>
{
updateKeFuMessageReadStatus
:
async
(
conversationId
:
number
)
=>
{
return
await
request
.
put
({
url
:
'/promotion/kefu-message/update-read-status'
,
data
url
:
'/promotion/kefu-message/update-read-status?conversationId='
+
conversationId
})
},
// 获得消息分页数据
...
...
src/views/mall/promotion/kefu/components/KeFuChatBox.vue
View file @
9ab367e4
...
...
@@ -18,12 +18,12 @@
{{
formatDate
(
item
.
createTime
)
}}
</div>
<!-- 系统消息 -->
<
view
<
div
v-if=
"item.contentType === KeFuMessageContentTypeEnum.SYSTEM"
class=
"system-message"
>
{{
item
.
content
}}
</
view
>
</
div
>
</div>
<div
:class=
"[
...
...
@@ -154,9 +154,10 @@ const handleSendMessage = async () => {
// 发送消息 【共用】
const
sendMessage
=
async
(
msg
:
any
)
=>
{
// 发送消息
await
KeFuMessageApi
.
sendKeFuMessage
(
msg
)
message
.
value
=
''
//
3.
加载消息列表
// 加载消息列表
await
getMessageList
(
keFuConversation
.
value
)
// 滚动到最新消息处
await
scrollToBottom
()
...
...
@@ -166,8 +167,11 @@ const innerRef = ref<HTMLDivElement>()
const
scrollbarRef
=
ref
<
InstanceType
<
typeof
ElScrollbarType
>>
()
// 滚动到底部
const
scrollToBottom
=
async
()
=>
{
// 1. 滚动到最新消息
await
nextTick
()
scrollbarRef
.
value
!
.
setScrollTop
(
innerRef
.
value
!
.
clientHeight
)
// 2. 消息已读
await
KeFuMessageApi
.
updateKeFuMessageReadStatus
(
keFuConversation
.
value
.
id
)
}
/**
* 是否显示时间
...
...
src/views/mall/promotion/kefu/components/KeFuConversationBox.vue
View file @
9ab367e4
...
...
@@ -8,7 +8,15 @@
@click="openRightMessage(item, index)"
>
<div
class=
"flex justify-center items-center w-100%"
>
<el-avatar
:src=
"item.userAvatar"
alt=
"avatar"
/>
<div
class=
"flex justify-center items-center"
style=
"width: 50px; height: 50px"
>
<el-badge
:hidden=
"item.adminUnreadMessageCount === 0"
:max=
"99"
:value=
"item.adminUnreadMessageCount"
>
<el-avatar
:src=
"item.userAvatar"
alt=
"avatar"
/>
</el-badge>
</div>
<div
class=
"ml-10px w-100%"
>
<div
class=
"flex justify-between items-center w-100%"
>
<span>
{{
item
.
userNickname
}}
</span>
...
...
@@ -24,8 +32,10 @@
></div>
</
template
>
<!-- 图片消息 -->
<
template
v-if=
"KeFuMessageContentTypeEnum.IMAGE === item.lastMessageContentType"
>
<div
class=
"last-message flex items-center color-[#989EA6]"
>
【图片消息】
</div>
<
template
v-else
>
<div
class=
"last-message flex items-center color-[#989EA6]"
>
{{
getContentType
(
item
.
lastMessageContentType
)
}}
</div>
</
template
>
</div>
</div>
...
...
@@ -55,6 +65,25 @@ const openRightMessage = (item: KeFuConversationRespVO, index: number) => {
activeConversationIndex
.
value
=
index
emits
(
'change'
,
item
)
}
// 获得消息类型
const
getContentType
=
computed
(()
=>
(
lastMessageContentType
:
number
)
=>
{
switch
(
lastMessageContentType
)
{
case
KeFuMessageContentTypeEnum
.
SYSTEM
:
return
'[系统消息]'
case
KeFuMessageContentTypeEnum
.
VIDEO
:
return
'[视频消息]'
case
KeFuMessageContentTypeEnum
.
IMAGE
:
return
'[图片消息]'
case
KeFuMessageContentTypeEnum
.
PRODUCT
:
return
'[商品消息]'
case
KeFuMessageContentTypeEnum
.
ORDER
:
return
'[订单消息]'
case
KeFuMessageContentTypeEnum
.
VOICE
:
return
'[语音消息]'
default
:
return
''
}
})
</
script
>
<
style
lang=
"scss"
scoped
>
...
...
src/views/mall/promotion/kefu/components/index.ts
View file @
9ab367e4
import
KeFuConversationBox
from
'./KeFuConversationBox.vue'
import
KeFuChatBox
from
'./KeFuChatBox.vue'
import
*
as
Constants
from
'./tools/constants'
export
{
KeFuConversationBox
,
KeFuChatBox
,
Constants
}
export
{
KeFuConversationBox
,
KeFuChatBox
}
src/views/mall/promotion/kefu/index.vue
View file @
9ab367e4
...
...
@@ -7,7 +7,7 @@
</el-col>
<el-col
:span=
"16"
>
<ContentWrap>
<KeFuChatBox
ref=
"keFuChatBoxRef"
/>
<KeFuChatBox
ref=
"keFuChatBoxRef"
@
change=
"getConversationList"
/>
</ContentWrap>
</el-col>
</el-row>
...
...
@@ -15,13 +15,14 @@
<
script
lang=
"ts"
setup
>
import
{
KeFuChatBox
,
KeFuConversationBox
}
from
'./components'
import
{
WebSocketMessageTypeConstants
}
from
'./components/tools/constants'
import
{
KeFuConversationRespVO
}
from
'@/api/mall/promotion/kefu/conversation'
import
{
getAccessToken
}
from
'@/utils/auth'
import
{
useWebSocket
}
from
'@vueuse/core'
import
{
WebSocketMessageTypeConstants
}
from
'@/views/mall/promotion/kefu/components/tools/constants'
defineOptions
({
name
:
'KeFu'
})
const
message
=
useMessage
()
// 加载消息
const
keFuChatBoxRef
=
ref
<
InstanceType
<
typeof
KeFuChatBox
>>
()
const
handleChange
=
(
conversation
:
KeFuConversationRespVO
)
=>
{
...
...
@@ -47,10 +48,6 @@ watchEffect(() => {
try
{
// 1. 收到心跳
if
(
data
.
value
===
'pong'
)
{
// state.recordList.push({
// text: '【心跳】',
// time: new Date().getTime()
// })
return
}
...
...
@@ -63,12 +60,17 @@ watchEffect(() => {
}
// 2.2 消息类型:KEFU_MESSAGE_TYPE
if
(
type
===
WebSocketMessageTypeConstants
.
KEFU_MESSAGE_TYPE
)
{
// 刷新列表
// 刷新
会话
列表
getConversationList
()
// 刷新消息列表
keFuChatBoxRef
.
value
?.
refreshMessageList
()
return
}
// 2.3 消息类型:KEFU_MESSAGE_ADMIN_READ
if
(
type
===
WebSocketMessageTypeConstants
.
KEFU_MESSAGE_ADMIN_READ
)
{
// 刷新会话列表
getConversationList
()
}
}
catch
(
error
)
{
console
.
error
(
error
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment