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
0ea51992
Commit
0ea51992
authored
Nov 09, 2023
by
yaya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 聊天页面介入聊天接口处理
parent
3b93e315
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
267 additions
and
18 deletions
+267
-18
src/api/business/chat.js
src/api/business/chat.js
+15
-0
src/views/customerService/chatDetail.vue
src/views/customerService/chatDetail.vue
+61
-15
src/views/customerService/chatList.vue
src/views/customerService/chatList.vue
+191
-3
No files found.
src/api/business/chat.js
View file @
0ea51992
...
@@ -38,3 +38,18 @@ export function setChatUserRemark(params) {
...
@@ -38,3 +38,18 @@ export function setChatUserRemark(params) {
})
})
}
}
export
function
setHumanIntervene
(
params
)
{
return
request
({
url
:
'
/sysIM/humanIntervene
'
,
method
:
'
post
'
,
data
:
params
})
}
export
function
stopHumanIntervene
(
params
)
{
return
request
({
url
:
'
/sysIM/stopHumanIntervene
'
,
method
:
'
post
'
,
data
:
params
})
}
src/views/customerService/chatDetail.vue
View file @
0ea51992
...
@@ -85,7 +85,7 @@
...
@@ -85,7 +85,7 @@
<
script
>
<
script
>
import
{
getUserSig
,
getUserList
,
sendChatMsg
,
findChatUserInfo
}
from
'
@/api/business/chat
'
import
{
getUserSig
,
getUserList
,
sendChatMsg
,
findChatUserInfo
,
setHumanIntervene
,
stopHumanIntervene
}
from
'
@/api/business/chat
'
import
chat
from
'
@/utils/chat
'
import
chat
from
'
@/utils/chat
'
import
{
formatTime
}
from
'
@/utils/index
'
import
{
formatTime
}
from
'
@/utils/index
'
import
TencentCloudChat
from
'
@tencentcloud/chat
'
import
TencentCloudChat
from
'
@tencentcloud/chat
'
...
@@ -108,7 +108,6 @@ export default {
...
@@ -108,7 +108,6 @@ export default {
conversationList
:
[],
// 会话列表
conversationList
:
[],
// 会话列表
currentConversationItem
:
{},
// 当前聊天
currentConversationItem
:
{},
// 当前聊天
messageList
:
[],
// 历史消息
messageList
:
[],
// 历史消息
isRealPersonal
:
false
,
// 是否人工介入
userId
:
''
,
userId
:
''
,
totalUnreadMessageCount
:
0
,
// 为读总数
totalUnreadMessageCount
:
0
,
// 为读总数
chatUserInfo
:
{}
chatUserInfo
:
{}
...
@@ -116,10 +115,13 @@ export default {
...
@@ -116,10 +115,13 @@ export default {
},
},
computed
:
{
computed
:
{
sendDisabled
()
{
sendDisabled
()
{
return
!
this
.
messageContent
||
this
.
messageContent
.
length
===
0
||
!
this
.
isRealPersonal
||
!
this
.
currentConversationItem
.
conversationID
return
!
this
.
messageContent
||
this
.
messageContent
.
length
===
0
||
!
this
.
chatUserInfo
.
intervened
||
!
this
.
currentConversationItem
.
conversationID
},
},
serviceTip
()
{
serviceTip
()
{
return
this
.
isRealPersonal
?
'
结束人工
'
:
'
人工介入
'
if
(
!
this
.
chatUserInfo
.
user
)
{
return
''
}
return
this
.
chatUserInfo
.
intervened
?
'
结束人工
'
:
'
人工介入
'
},
},
customerItem
()
{
customerItem
()
{
if
(
this
.
customerList
&&
this
.
customerList
.
length
>
0
&&
this
.
currentCustomerIndex
<=
this
.
customerList
.
length
-
1
)
{
if
(
this
.
customerList
&&
this
.
customerList
.
length
>
0
&&
this
.
currentCustomerIndex
<=
this
.
customerList
.
length
-
1
)
{
...
@@ -161,17 +163,60 @@ export default {
...
@@ -161,17 +163,60 @@ export default {
* 是否人工介入
* 是否人工介入
* */
* */
handleService
()
{
handleService
()
{
if
(
this
.
isRealPersonal
)
{
if
(
!
this
.
chatUserInfo
)
{
this
.
isRealPersonal
=
false
return
}
if
(
this
.
chatUserInfo
.
intervened
)
{
this
.
handleStopHumanIntervene
()
}
else
{
}
else
{
this
.
isRealPersonal
=
true
this
.
handleSetHumanIntervene
()
}
}
const
object
=
{
},
messageContent
:
this
.
isRealPersonal
?
'
人工接管聊天
'
:
'
退出人工聊天
'
,
/**
msgType
:
this
.
isRealPersonal
?
3
:
4
* 人工介入
*/
handleSetHumanIntervene
()
{
const
params
=
{
fromAccount
:
this
.
currentConversationItem
.
fromAccount
,
toAccount
:
this
.
customerItem
.
code
}
}
this
.
messageList
.
push
(
object
)
setHumanIntervene
(
params
).
then
(
response
=>
{
this
.
scrollToBottom
(
true
)
this
.
chatUserInfo
.
intervened
=
true
const
object
=
{
messageContent
:
'
人工接管聊天
'
,
msgType
:
3
}
this
.
messageList
.
push
(
object
)
this
.
scrollToBottom
(
true
)
}).
catch
(
response
=>
{
this
.
$notify
.
error
({
title
:
'
失败
'
,
message
:
response
.
data
.
errmsg
||
'
请求失败
'
})
})
},
/**
* 人工介入停止
*/
handleStopHumanIntervene
()
{
const
params
=
{
fromAccount
:
this
.
currentConversationItem
.
fromAccount
,
toAccount
:
this
.
customerItem
.
code
}
stopHumanIntervene
(
params
).
then
(
response
=>
{
this
.
chatUserInfo
.
intervened
=
false
const
object
=
{
messageContent
:
'
退出人工聊天
'
,
msgType
:
4
}
this
.
messageList
.
push
(
object
)
this
.
scrollToBottom
(
true
)
}).
catch
(
response
=>
{
this
.
$notify
.
error
({
title
:
'
失败
'
,
message
:
response
.
data
.
errmsg
||
'
请求失败
'
})
})
},
},
/**
/**
* 选择客服
* 选择客服
...
@@ -191,7 +236,7 @@ export default {
...
@@ -191,7 +236,7 @@ export default {
handleClear
()
{
handleClear
()
{
this
.
currentConversationItem
=
{}
this
.
currentConversationItem
=
{}
this
.
conversationList
=
[]
this
.
conversationList
=
[]
this
.
isRealPersonal
=
false
this
.
chatUserInfo
=
false
this
.
nextReqMessageID
=
''
this
.
nextReqMessageID
=
''
this
.
messageList
=
[]
this
.
messageList
=
[]
this
.
messageContent
=
''
this
.
messageContent
=
''
...
@@ -305,7 +350,7 @@ export default {
...
@@ -305,7 +350,7 @@ export default {
return
return
}
}
const
userID
=
this
.
customerList
[
this
.
currentCustomerIndex
].
code
const
userID
=
this
.
customerList
[
this
.
currentCustomerIndex
].
code
if
(
this
.
isRealPersonal
&&
message
.
from
===
this
.
envText
+
userID
)
{
if
(
this
.
chatUserInfo
.
intervened
&&
message
.
from
===
this
.
envText
+
userID
)
{
return
return
}
}
const
object
=
{
const
object
=
{
...
@@ -409,7 +454,7 @@ export default {
...
@@ -409,7 +454,7 @@ export default {
this
.
messageList
=
[]
this
.
messageList
=
[]
this
.
currentConversationItem
=
item
this
.
currentConversationItem
=
item
this
.
nextReqMessageID
=
''
this
.
nextReqMessageID
=
''
this
.
isRealPersonal
=
false
this
.
chatUserInfo
=
{}
this
.
handleGetHistory
()
this
.
handleGetHistory
()
this
.
handleFindChatUserInfo
()
this
.
handleFindChatUserInfo
()
}
}
...
@@ -660,6 +705,7 @@ export default {
...
@@ -660,6 +705,7 @@ export default {
height: 100%;
height: 100%;
.chat-message-top {
.chat-message-top {
height: 50px;
background: white;
background: white;
padding: 8px;
padding: 8px;
}
}
...
...
src/views/customerService/chatList.vue
View file @
0ea51992
<
template
>
<
template
>
<div>
<div
class=
"page_invite"
>
会话记录
<div
class=
"filter-container"
>
<el-input
v-model=
"listQuery.nickName"
clearable
size=
"mini"
class=
"filter-item"
style=
"width: 200px;"
placeholder=
"请输入用户昵称"
/>
<el-button
size=
"mini"
class=
"filter-item"
type=
"primary"
@
click=
"handleAdd"
>
生成邀请码
</el-button>
</div>
<!-- 查询结果 -->
<el-table
v-loading=
"listLoading"
:data=
"list"
size=
"small"
element-loading-text=
"正在查询中..."
border
fit
highlight-current-row
>
<el-table-column
align=
"center"
width=
"100px"
label=
"邀请码ID"
prop=
"id"
sortable
/>
<el-table-column
align=
"center"
label=
"邀请码"
prop=
"code"
/>
<el-table-column
align=
"center"
label=
"可邀请人数"
prop=
"enabledNum"
/>
<el-table-column
align=
"center"
label=
"使用人数"
prop=
"usedNum"
/>
<el-table-column
align=
"center"
label=
"状态"
prop=
"stateName"
/>
<el-table-column
align=
"center"
label=
"有效时间"
prop=
"effectiveStartTime"
width=
"300"
>
<template
slot-scope=
"scope"
>
{{
`${scope.row.effectiveStartTime
}
至${scope.row.effectiveEndTime
}
`
}}
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
align
=
"
center
"
label
=
"
创建时间
"
prop
=
"
createTime
"
/>
<
el
-
table
-
column
align
=
"
center
"
label
=
"
操作
"
width
=
"
250
"
class
-
name
=
"
small-padding fixed-width
"
>
<
template
slot
-
scope
=
"
scope
"
>
<
el
-
button
v
-
permission
=
"
['GET /admin/user/detailApprove']
"
type
=
"
text
"
size
=
"
mini
"
@
click
=
"
handleToDetail(scope.row)
"
>
详情
<
/el-button
>
<
el
-
button
v
-
permission
=
"
['POST /admin/user/approveAgency']
"
type
=
"
text
"
size
=
"
mini
"
@
click
=
"
handleCopyCode(scope.row)
"
>
复制邀请码
<
/el-button
>
<
el
-
button
v
-
permission
=
"
['GET /admin/user/detailApprove']
"
:
disabled
=
"
scope.row.state > 1
"
type
=
"
text
"
size
=
"
mini
"
@
click
=
"
handleSetEnable(scope.row)
"
>
失效
<
/el-button
>
<
/template
>
<
/el-table-column
>
<
/el-table
>
<
Pagination
v
-
show
=
"
total>0
"
:
total
=
"
total
"
:
page
.
sync
=
"
listQuery.page
"
:
limit
.
sync
=
"
listQuery.limit
"
@
pagination
=
"
getList
"
/>
<
/div
>
<
/div
>
<
/template
>
<
/template
>
<
script
>
<
script
>
import
{
fetchList
,
setInvalid
}
from
'
@/api/business/invite
'
import
Pagination
from
'
@/components/Pagination
'
export
default
{
export
default
{
name
:
'
ChatList
'
name
:
'
ChatList
'
,
components
:
{
Pagination
}
,
data
()
{
return
{
listLoading
:
true
,
listQuery
:
{
page
:
1
,
limit
:
20
}
,
list
:
[],
total
:
0
}
}
,
created
()
{
this
.
getList
()
}
,
methods
:
{
handleAdd
()
{
this
.
$router
.
push
({
path
:
'
/user/addInvite
'
}
)
}
,
handleToDetail
(
row
)
{
this
.
$router
.
push
({
path
:
'
/user/inviteInfo
'
,
query
:
{
id
:
row
.
code
}}
)
}
,
handleSetEnable
(
row
)
{
this
.
$confirm
(
'
你确定要把邀请码设置失效吗?
'
,
'
提示
'
,
{
confirmButtonText
:
'
确定
'
,
cancelButtonText
:
'
取消
'
,
type
:
'
warning
'
}
).
then
(()
=>
{
const
params
=
{
code
:
row
.
code
}
setInvalid
(
params
).
then
(
response
=>
{
this
.
list
=
this
.
list
.
filter
((
item
)
=>
{
if
(
item
.
code
===
row
.
code
)
{
item
.
state
=
6
item
.
stateName
=
'
已失效
'
return
item
}
return
item
}
)
this
.
$notify
.
success
({
message
:
'
设置失效成功
'
}
)
}
).
catch
((
e
)
=>
{
}
)
}
)
}
,
/**
* 复制
*/
handleCopyCode
(
row
)
{
// 复制结果
let
copyResult
=
true
// 设置想要复制的文本内容
if
(
!
row
.
code
)
{
return
}
const
text
=
`藏家相册注册邀请码${row.code
}
,最多可使用${row.enabledNum || 0
}
次,机会难得,快去体验吧~`
// 判断是否支持clipboard方式
if
(
window
.
navigator
.
clipboard
)
{
// 利用clipboard将文本写入剪贴板(这是一个异步promise)
window
.
navigator
.
clipboard
.
writeText
(
text
).
then
((
res
)
=>
{
console
.
log
(
'
复制成功
'
)
// 返回复制操作的最终结果
return
copyResult
}
).
catch
((
err
)
=>
{
copyResult
=
false
console
.
log
(
'
复制失败
'
,
err
)
// 返回复制操作的最终结果
return
copyResult
}
)
}
else
{
// 不支持clipboard方式 则采用document.execCommand()方式
// 创建一个input元素
const
inputDom
=
document
.
createElement
(
'
textarea
'
)
// 设置为只读 防止移动端手机上弹出软键盘
inputDom
.
setAttribute
(
'
readonly
'
,
'
readonly
'
)
// 给input元素赋值
inputDom
.
value
=
text
// 将创建的input添加到body
document
.
body
.
appendChild
(
inputDom
)
// 选中input元素的内容
inputDom
.
select
()
// 执行浏览器复制命令
// 复制命令会将当前选中的内容复制到剪切板中(这里就是创建的input标签中的内容)
// Input要在正常的编辑状态下原生复制方法才会生效
const
result
=
document
.
execCommand
(
'
copy
'
)
// 判断是否复制成功
if
(
result
)
{
console
.
log
(
'
复制成功
'
)
}
else
{
console
.
log
(
'
复制失败
'
)
copyResult
=
false
}
// 复制操作后再将构造的标签 移除
document
.
body
.
removeChild
(
inputDom
)
// 返回复制操作的最终结果
}
this
.
$notify
.
success
({
message
:
'
邀请码已复制,快去分享给好友吧~
'
}
)
}
,
getList
()
{
this
.
listLoading
=
true
fetchList
(
this
.
listQuery
).
then
(
response
=>
{
this
.
list
=
response
.
data
.
data
.
dataList
this
.
total
=
response
.
data
.
data
.
total
this
.
listLoading
=
false
}
).
catch
((
e
)
=>
{
this
.
list
=
[]
this
.
total
=
0
this
.
listLoading
=
false
}
)
}
}
}
}
<
/script
>
<
/script
>
<
style
scoped
>
<
style
scoped
>
.
page_invite
{
padding
:
20
px
;
}
.
filter
-
container
{
}
<
/style
>
<
/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