Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Q
qk_admin
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
quanku
qk_admin
Commits
a618a14c
Commit
a618a14c
authored
Nov 08, 2023
by
yaya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 添加用户信息
parent
3d8874f1
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
221 additions
and
31 deletions
+221
-31
src/api/business/chat.js
src/api/business/chat.js
+15
-0
src/views/customerService/chatDetail.vue
src/views/customerService/chatDetail.vue
+107
-31
src/views/customerService/components/chatUserInfo.vue
src/views/customerService/components/chatUserInfo.vue
+99
-0
No files found.
src/api/business/chat.js
View file @
a618a14c
...
...
@@ -22,4 +22,19 @@ export function sendChatMsg(params) {
data
:
params
})
}
export
function
findChatUserInfo
(
params
)
{
return
request
({
url
:
'
/sysIM/findChatUserInfo
'
,
method
:
'
post
'
,
data
:
params
})
}
export
function
setChatUserRemark
(
params
)
{
return
request
({
url
:
'
/sysIM/setChatUserRemark
'
,
method
:
'
post
'
,
data
:
params
})
}
src/views/customerService/chatDetail.vue
View file @
a618a14c
<
template
>
<div
class=
"page-chatDetail flex"
>
<!--
<el-menu
:default-active=
"
activeIndex
"
class=
"chat-list"
mode=
"horizontal"
@
select=
"handleSelect"
>
<el-menu-item
v-for=
"
item in chatList"
:key=
"item.userId"
:index=
"item.userId
"
>
<span
slot=
"title"
>
{{
item
.
titl
e
}}
</span>
<!--
<el-menu
:default-active=
"
0
"
class=
"chat-list"
mode=
"horizontal"
@
select=
"handleSelect"
>
<el-menu-item
v-for=
"
(item, index) in customerList"
:key=
"item.code"
:index=
"index
"
>
<span
slot=
"title"
>
{{
item
.
nam
e
}}
</span>
</el-menu-item>
</el-menu>
-->
<el-container
v-loading=
"loading"
style=
"width: 100%;height: 100%; border: 1px solid #eee"
>
<el-aside
style=
"width: 25%;background-color: white;padding: 0"
>
<el-tabs
style=
"width: 100%; padding: 10px 10px 0"
@
tab-click=
"handleClick"
>
<el-tab-pane
v-for=
"item in customerList"
:key=
"item.code"
:label=
"item.name"
/>
<el-tabs
style=
"padding: 10px 10px 0;"
@
tab-click=
"handleClick"
>
<el-tab-pane
v-for=
"(item, indexNum) in customerList"
:key=
"item.code"
>
<div
slot=
"label"
>
<div
class=
"span-box"
>
<span>
{{
item
.
name
}}
</span>
<div
v-if=
"indexNum === currentCustomerIndex && totalUnreadMessageCount > 0"
class=
"span-box__num"
/>
</div>
</div>
</el-tab-pane>
</el-tabs>
<div
class=
"conversation"
>
<div
v-for=
"item in conversationList"
...
...
@@ -19,10 +27,12 @@
@click="handleSelectChat(item)">
<div
class=
"conversation-item-image"
>
<img
:src=
"item.avatar"
class=
"conversation-item-image__avatar"
>
<div
class=
"conversation-item-image__num"
>
2
</div>
</div>
<div
class=
"conversation-item-info"
>
<div
class=
"flex f-jc-sb"
>
<div
class=
"conversation-item-info__nick"
>
{{
item
.
nick
}}
</div>
<div
v-if=
"item.unreadCount"
class=
"conversation-item-image__num"
>
{{
item
.
unreadCount
}}
</div>
</div>
<div
class=
"conversation-item-info__message flex f-jc-sb"
>
<div
class=
"conversation-item-info__message__profile"
>
{{
item
.
messageForShow
}}
</div>
<div
class=
"conversation-item-info__message__time"
>
{{
item
.
lastTime
}}
</div>
...
...
@@ -65,10 +75,8 @@
</div>
</div>
</el-main>
<el-aside
style=
"width: 20%;background-color: white;padding: 10px"
>
<div>
有边框
</div>
<el-aside
style=
"width: 25%;background-color: white;padding: 10px"
>
<ChatUserInfo
:chat-user-info=
"chatUserInfo"
/>
</el-aside>
</el-container>
...
...
@@ -77,16 +85,17 @@
<
script
>
import
{
getUserSig
,
getUserList
,
sendChatMsg
}
from
'
@/api/business/chat
'
import
{
getUserSig
,
getUserList
,
sendChatMsg
,
findChatUserInfo
}
from
'
@/api/business/chat
'
import
chat
from
'
@/utils/chat
'
import
{
formatTime
}
from
'
@/utils/index
'
import
TencentCloudChat
from
'
@tencentcloud/chat
'
import
ChatMessageItem
from
'
./components/chatMessageItem
'
import
store
from
'
../../store
'
import
ChatUserInfo
from
'
./components/chatUserInfo
'
export
default
{
name
:
'
ChatDetail
'
,
components
:
{
ChatMessageItem
},
components
:
{
Chat
UserInfo
,
Chat
MessageItem
},
data
()
{
return
{
customerList
:
[],
// 客服列表
...
...
@@ -100,7 +109,9 @@ export default {
currentConversationItem
:
{},
// 当前聊天
messageList
:
[],
// 历史消息
isRealPersonal
:
false
,
// 是否人工介入
userId
:
''
userId
:
''
,
totalUnreadMessageCount
:
0
,
// 为读总数
chatUserInfo
:
{}
}
},
computed
:
{
...
...
@@ -109,6 +120,14 @@ export default {
},
serviceTip
()
{
return
this
.
isRealPersonal
?
'
结束人工
'
:
'
人工介入
'
},
customerItem
()
{
if
(
this
.
customerList
&&
this
.
customerList
.
length
>
0
&&
this
.
currentCustomerIndex
<=
this
.
customerList
.
length
-
1
)
{
return
this
.
customerList
[
this
.
currentCustomerIndex
]
}
},
isShowTotalUnRead
(
index
)
{
return
index
===
this
.
currentCustomerIndex
&&
this
.
totalUnreadMessageCount
}
},
...
...
@@ -128,8 +147,19 @@ export default {
console
.
log
(
'
====userInfo=
'
,
err
)
})
},
handleSelect
(
key
,
keyPath
)
{
console
.
log
(
key
,
keyPath
)
handleFindChatUserInfo
()
{
const
params
=
{
fromAccount
:
this
.
currentConversationItem
.
fromAccount
,
toAccount
:
this
.
customerItem
.
code
}
findChatUserInfo
(
params
).
then
((
response
)
=>
{
console
.
log
(
'
=====获取聊天用户信息成功,
'
,
response
)
if
(
response
&&
response
.
data
&&
response
.
data
.
data
)
{
this
.
chatUserInfo
=
response
.
data
.
data
}
}).
catch
((
err
)
=>
{
console
.
log
(
'
=====获取聊天用户信息失败,
'
,
err
)
})
},
/**
* 是否人工介入
...
...
@@ -169,12 +199,14 @@ export default {
this
.
nextReqMessageID
=
''
this
.
messageList
=
[]
this
.
messageContent
=
''
this
.
totalUnreadMessageCount
=
0
},
/**
* 获取客服列表
**/
handleGetChatList
()
{
const
params
=
{}
this
.
totalUnreadMessageCount
=
0
// 为读总数
getUserList
(
params
).
then
(
response
=>
{
if
(
response
&&
response
.
data
&&
response
.
data
.
data
)
{
this
.
customerList
=
response
.
data
.
data
...
...
@@ -241,7 +273,9 @@ export default {
console
.
log
(
'
====登录成功===
'
,
imResponse
.
data
)
// 登录成功
chat
.
on
(
TencentCloudChat
.
EVENT
.
CONVERSATION_LIST_UPDATED
,
this
.
onConversationListUpdated
)
chat
.
on
(
TencentCloudChat
.
EVENT
.
MESSAGE_RECEIVED
,
this
.
onMessageReceived
)
chat
.
on
(
TencentCloudChat
.
EVENT
.
TOTAL_UNREAD_MESSAGE_COUNT_UPDATED
,
this
.
onTotalUnreadMessageCountUpdated
)
this
.
handleGetConversationList
()
if
(
imResponse
.
data
.
repeatLogin
===
true
)
{
// 标识账号已登录,本次登录操作为重复登录。
console
.
log
(
imResponse
.
data
.
errorInfo
)
...
...
@@ -278,7 +312,7 @@ export default {
fromUserId
:
message
.
from
,
toAccount
:
message
.
to
,
avatar
:
message
.
avatar
,
msgType
:
this
.
isRealPersonal
&&
message
.
from
===
this
.
envText
+
userID
?
1
:
2
msgType
:
message
.
from
===
this
.
envText
+
userID
?
1
:
2
}
this
.
messageList
.
push
(
object
)
...
...
@@ -306,6 +340,13 @@ export default {
})
},
/**
* 会话未读总数变更通知
* */
onTotalUnreadMessageCountUpdated
(
event
)
{
console
.
log
(
'
====会话未读总数
'
,
event
.
data
)
// 当前单聊和群聊会话的未读总数
this
.
totalUnreadMessageCount
=
event
.
data
},
/**
* 获取会话列表
* */
...
...
@@ -314,6 +355,7 @@ export default {
promise
.
then
((
imResponse
)
=>
{
// 全量的会话列表,用该列表覆盖原有的会话列表
const
conversationList
=
imResponse
.
data
.
conversationList
this
.
totalUnreadMessageCount
=
chat
.
getTotalUnreadMessageCount
()
this
.
setConversationList
(
conversationList
)
}).
catch
((
imError
)
=>
{
// 获取会话列表失败的相关信息
...
...
@@ -326,6 +368,9 @@ export default {
onConversationListUpdated
(
event
)
{
console
.
log
(
'
====会话列表更新--
'
,
event
.
data
)
// 包含 Conversation 实例的数组
this
.
setConversationList
(
event
.
data
)
if
(
this
.
currentConversationItem
&&
this
.
currentConversationItem
.
conversationID
)
{
this
.
handleSetMessageRead
(
this
.
currentConversationItem
.
conversationID
)
}
},
setConversationList
(
list
)
{
if
(
!
list
||
list
.
length
===
0
)
{
...
...
@@ -352,14 +397,29 @@ export default {
* 选择聊天
* */
handleSelectChat
(
item
)
{
this
.
messageList
=
[]
item
.
unreadCount
=
0
this
.
handleSetMessageRead
(
item
.
conversationID
)
if
(
this
.
currentConversationItem
&&
this
.
currentConversationItem
.
conversationID
!==
item
.
conversationID
)
{
this
.
messageList
=
[]
this
.
currentConversationItem
=
item
this
.
nextReqMessageID
=
''
this
.
isRealPersonal
=
false
this
.
handleGetHistory
()
this
.
handleFindChatUserInfo
()
}
},
/**
* 设置消息已读
* */
handleSetMessageRead
(
conversationID
)
{
const
promise
=
chat
.
setMessageRead
({
conversationID
:
conversationID
})
promise
.
then
(
function
(
imResponse
)
{
// 已读上报成功,指定 ID 的会话的 unreadCount 属性值被置为0
}).
catch
(
function
(
imError
)
{
// 已读上报失败
console
.
warn
(
'
setMessageRead error:
'
,
imError
)
})
},
/**
* 获取历史消息
...
...
@@ -486,6 +546,23 @@ export default {
.chat-list {
width: 30%;
}
.slot {
width: 100%;
}
.span-box {
position: relative;
width: 100%;
.span-box__num {
position: absolute;
top: 8px;
right: -4px;
background: #FA5151;
width: 8px;
height: 8px;
border-radius: 5px;
}
}
.conversation {
height: 100%;
...
...
@@ -508,19 +585,6 @@ export default {
border-radius: 15px;
}
.conversation-item-image__num {
position: absolute;
right: 0;
top: 0;
height: 12px;
background-color: red;
color: white;
font-size: 12px;
font-weight: bold;
padding: 3px 6px;
border-radius: 50%;
display: none;
}
}
.conversation-item-info {
...
...
@@ -534,6 +598,18 @@ export default {
color: #17191C;
line-height: 20px;
}
.conversation-item-image__num {
background: #FA5151;
border-radius: 14px;
font-size: 12px;
font-family: Brown-Regular, Brown;
font-weight: 400;
color: #FFFFFF;
line-height: 14px;
padding: 1px 4px;
min-width: 16px;
text-align: center;
}
.conversation-item-info__message {
width: 100%;
...
...
src/views/customerService/components/chatUserInfo.vue
0 → 100644
View file @
a618a14c
<
template
>
<div
class=
"component-chatUserInfo"
>
<div
class=
"info flex"
>
<div
class=
"info-title"
>
机器人昵称:
</div>
<div
class=
"info-content"
>
{{
chatUserInfo
.
aiAssistant
&&
chatUserInfo
.
aiAssistant
.
name
||
'
-
'
}}
</div>
</div>
<div
class=
"info flex"
>
<div
class=
"info-title"
>
简介:
</div>
<div
class=
"info-content"
>
{{
chatUserInfo
.
aiAssistant
&&
chatUserInfo
.
aiAssistant
.
profile
||
'
-
'
}}
</div>
</div>
<el-divider
/>
<div
class=
"info flex"
>
<div
class=
"info-title"
>
用户昵称:
</div>
<div
class=
"info-content"
>
{{
chatUserInfo
.
user
&&
chatUserInfo
.
user
.
nickname
||
'
-
'
}}
</div>
</div>
<div
class=
"info flex"
>
<div
class=
"info-title"
>
手机号:
</div>
<div
class=
"info-content"
>
{{
chatUserInfo
.
user
&&
chatUserInfo
.
user
.
mobile
||
'
-
'
}}
</div>
</div>
<div
class=
"info flex"
>
<div
class=
"info-title"
>
备注:
</div>
<el-input
v-model=
"chatUserInfo.user.remark"
:autosize=
"
{ minRows: 4, maxRows: 4}"
maxlength="30"
type="textarea"
show-word-limit
style="border: 1px solid #DCDFE6; border-radius: 4px;margin: 0;"
placeholder="请输入备注"
@blur="handleBlur"/>
</div>
</div>
</
template
>
<
script
>
import
{
setChatUserRemark
}
from
'
@/api/business/chat
'
export
default
{
name
:
'
ChatUserInfo
'
,
props
:
{
chatUserInfo
:
{
type
:
Object
,
required
:
true
}
},
data
()
{
return
{
preRemark
:
this
.
chatUserInfo
.
user
&&
this
.
chatUserInfo
.
user
.
remark
||
''
}
},
methods
:
{
handleBlur
()
{
if
(
this
.
chatUserInfo
.
user
.
remark
&&
this
.
chatUserInfo
.
user
.
remark
!==
this
.
preRemark
)
{
const
params
=
{
user
:
this
.
chatUserInfo
.
user
.
id
,
remark
:
this
.
chatUserInfo
.
user
.
remark
}
setChatUserRemark
(
params
).
then
(
response
=>
{
this
.
preRemark
=
this
.
chatUserInfo
.
user
.
remark
}).
catch
(
response
=>
{
this
.
closeLoading
()
this
.
$notify
.
error
({
title
:
'
失败
'
,
message
:
response
.
data
.
errmsg
||
'
请求失败
'
})
})
}
}
}
}
</
script
>
<
style
lang=
"less"
scoped
>
.component-chatUserInfo {
display: flex;
flex-direction: column;
.info {
font-size: 14px;
display: flex;
align-items: start;
line-height: 20px;
margin-top: 10px;
.info-title {
width: 90px;
text-align: end;
font-weight: bold;
}
.info-content {
flex: 1;
}
}
}
</
style
>
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