提交 527268d4 作者: 毛细亚

保存 1.2 版本的代码

上级 795fc408
# 客服休息状态功能文档
本文档描述了客服休息状态功能的实现方法和使用说明,该功能支持客服在忙碌或休息时暂时停止接收新消息。
## 功能概述
客服休息状态功能允许客服在午休或临时有事时设置自己为"休息中"状态,以便合理安排工作时间。同时,还提供了发送评价功能,方便客服向客户发送评价请求。
## 相关API
### 1. 获取客服休息状态
```javascript
import { getClientStatus } from '@/api/user.js'
// 获取客服休息状态
const response = await getClientStatus()
if (response.status_code === 1) {
const status = response.data.client_online_status
// status 可能的值:
// - online: 在线
// - offline: 离线
// - rest: 休息中
}
```
### 2. 开始休息
```javascript
import { client_session_rest } from '@/api/user.js'
// 开始休息
const response = await client_session_rest()
if (response.status_code === 1) {
// 休息开始成功
// 可以更新界面显示为"休息中"状态
}
```
### 3. 结束休息
```javascript
import { finishRest } from '@/api/user.js'
// 结束休息
const response = await finishRest()
if (response.status_code === 1) {
// 休息结束成功
// 可以更新界面显示为"在线"状态
}
```
### 4. 发送评价
```javascript
import { sendComment } from '@/api/user.js'
import { sendChatMessage } from '@/utils/index.js'
// 发送评价
const response = await sendComment({
corp_id: '企业ID',
external_userid: '外部联系人ID',
userid: '客服ID'
})
if (response.status_code === 1 && response.data.news) {
// 使用企业微信JSSDK发送评价
const result = await sendChatMessage(response.data.news, 'link')
if (result.success) {
// 评价发送成功
}
}
```
## 会话内容存档相关API
### 1. 检查客户是否同意聊天内容存档
```javascript
import { checkSingleAgree } from '@/api/user.js'
// 检查客户是否同意聊天内容存档
const response = await checkSingleAgree({
external_userid: '外部联系人ID',
userid: '客服ID'
})
if (response.status_code === 1) {
const agreeStatus = response.data.agree_status
// agreeStatus 可能的值:
// - Agreen: 已同意
// - Disagree: 未同意
}
```
### 2. 检查客服号是否开启会话内容存档
```javascript
import { checkUserPermit } from '@/api/user.js'
// 检查客服号是否开启会话内容存档
const response = await checkUserPermit({
userid: '客服ID'
})
if (response.status_code === 1) {
const hasPermit = response.data.has_permit
// hasPermit: true 已授权, false 未授权
}
```
### 3. 同步智能标签
```javascript
import { remarkSessionIntelTag } from '@/api/user.js'
// 同步智能标签
await remarkSessionIntelTag({
corp_id: '企业ID',
external_userid: '外部联系人ID',
userid: '客服ID'
})
```
## 使用示例
### 在Vue组件中整合所有功能
```javascript
import { mapState, mapMutations, mapActions } from 'vuex'
import {
getClientStatus,
remarkSessionIntelTag,
finishRest,
client_session_rest,
checkSingleAgree,
checkUserPermit,
sendComment
} from '@/api/user.js'
import { sendChatMessage } from '@/utils/index.js'
export default {
data() {
return {
// 相关状态
agreeStatus: '', // 用户是否同意聊天内容存档
hasPermit: false // 客服号是否开启会话内容存档权限
}
},
computed: {
...mapState('user', ['client_online_status', 'corp_id', 'external_userid', 'userid']),
// 状态文本转换
clientStatusText() {
const statusMap = {
'online': '在线',
'offline': '离线',
'rest': '休息中'
}
return statusMap[this.client_online_status] || '未知'
}
},
created() {
// 初始化企业微信SDK
this.initializeWecom()
// 获取各种状态
this.getInitialData()
},
methods: {
...mapActions('user', ['initWecom']),
// 获取初始数据
async getInitialData() {
// 实现获取状态逻辑
},
// 开始休息
async handleStartRest() {
// 实现开始休息逻辑
},
// 结束休息
async handleFinishRest() {
// 实现结束休息逻辑
},
// 发送评价
async handleSendComment() {
// 实现发送评价逻辑
}
}
}
```
## 界面展示
客服状态显示和按钮应该包含以下元素:
1. 当前状态显示:显示客服当前是"在线"、"离线"还是"休息中"
2. 休息相关按钮:
- 在线状态下显示"开始休息"按钮
- 休息中状态显示"结束休息"按钮
3. 发送评价按钮:用于向客户发送评价请求
4. 会话内容存档状态显示:
- 显示客户是否已开启会话内容存档
- 显示客服号是否已授权会话内容存档
## 注意事项
1. 客服在"休息中"状态时不能直接下线,必须先结束休息
2. 开始休息按钮悬停时应显示提示文字:"午休或者临时有事可点击休息"
3. 使用企业微信JSSDK前需确保已初始化成功
4. 所有状态变更应同步更新到Vuex store,以便在多个组件中共享
\ No newline at end of file
......@@ -120,7 +120,7 @@ export function remarkSessionIntelTag(data) {
// 获取客户号的休息状态
export function getClientStatus(data) {
return request({
url: '/sidebar/work_wei_xin/getClientStatus',
url: '/sidebar/work_wei_xin/info',
method: 'post',
data
})
......
......@@ -31,6 +31,7 @@ const state = {
},
weixin_blongs_id_list:[],
isWecomSDKReady: false, // 添加企业微信 SDK 就绪状态
client_online_status: '', // 客服休息状态: online上线 offline下线 rest休息中
// 六子的 用户id wm5rUgMgAAjqjOcqp8i3lEhFZDQieWug
// 我的 userid JinDuoXia cser_id 4090 corp_id wweaefe716636df3d1 cser_id 4090 token token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJpc3MiOjQwOTAsImlhdCI6MTc0NzgxMjMxMiwiZXhwIjoxNzQ4NDE3MTEyLCJuYmYiOjE3NDc4MTIzMTIsInN1YiI6InRva2Vu6K6k6K-BIiwianRpIjoiMjBkOTY3MDZiYzI1MDdmY2MxOWI2MjU1YTM0YWQ3M2YifQ.yX7E7QHV7x2ubpa8iK3Avy794EiHNCaW2CtB4A4UQWo
}
......@@ -73,6 +74,9 @@ const mutations = {
set_isWecomSDKReady(state, status) {
state.isWecomSDKReady = status
},
set_client_online_status(state, status) {
state.client_online_status = status
},
}
const actions = {
......
......@@ -79,8 +79,10 @@ service.interceptors.response.use(
if (res.status_code === -100) {
// 登录 过期 重新去登录
setTimeout(() => {
removeToken()
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+Cookies.get('corp_id')
if(process.env.NODE_ENV !== 'development'){
removeToken()
window.location.href = window.location.origin +'/company_app/index.html?corp_id='+Cookies.get('corp_id')
}
}, 2000);
return res
}
......
......@@ -22,7 +22,24 @@
<p>高风险用户,禁止转端 !!!</p>
</div>
<div class="cser_name">
<span>当前客服:{{ cser_name }}</span>
<span>当前客服:{{ `${cser_name}(${clientStatusText})` }}</span>
</div>
<!-- 添加客服状态显示及按钮 -->
<div class="cser_status">
<div class="status-actions">
<!-- 休息中状态显示结束休息按钮 -->
<el-button v-if="clientStatus === 'rest'" type="primary" size="mini" @click="handleFinishRest">结束休息</el-button>
<!-- 在线状态显示开始休息按钮 -->
<el-button v-if="clientStatus === 'online'" type="warning" size="mini" @click="handleStartRest"
title="午休或者临时有事可点击休息">开始休息</el-button>
<!-- 发送评价按钮 -->
<el-button type="primary" size="mini" @click="handleSendComment">发送评价</el-button>
</div>
</div>
<!-- 会话内容存档状态 -->
<div class="archive-status">
<p>当前微信用户{{ agreeStatusText }}开启会话内容存档</p>
<p>当前客服号{{ permitStatusText }}授权开启会话内容存档</p>
</div>
<div class="item rowFlex">
<!-- 公共的信息 -->
......@@ -176,7 +193,7 @@
</div>
</template>
<script>
import { mapState,mapMutations } from 'vuex'
import { mapState, mapMutations, mapActions } from 'vuex'
import gameDetails from './gameInfo/gameUserInfo.vue'
import shareInfo from './shareInfo.vue'
import changePhone from './changePhone.vue'
......@@ -184,6 +201,9 @@ import watchMember from '@/mixins/watchMember'
import { autoResetPassword,bindUserSelfAdd } from '@/api/game'
import { memberBindCser,editUser,zyouUnBind } from '@/api/works'
import selectTag from '@/components/selectTag.vue'
import { getClientStatus, remarkSessionIntelTag, finishRest, client_session_rest, checkSingleAgree, checkUserPermit, sendComment } from '@/api/user.js'
import { sendChatMessage } from '@/utils/index.js'
export default {
name: 'UserDetailsPanel',
components: {
......@@ -210,7 +230,11 @@ import watchMember from '@/mixins/watchMember'
showInputValue: '',
inputIndex: -1,
changePhone:false,
showTag:false
showTag:false,
// 新增状态数据
clientStatus: '', // 客服休息状态:online上线 offline下线 rest休息中
agreeStatus: '', // 用户是否同意聊天内容存档:Agreen同意 Disagree不同意
hasPermit: false, // 客服号是否开启会话内容存档权限
}
},
computed: {
......@@ -219,13 +243,172 @@ import watchMember from '@/mixins/watchMember'
'gameUserInfo',
'bindGameUserList'
]),
...mapState('user', ['cser_info','cser_id','cser_name'])
...mapState('user', ['cser_info', 'cser_id', 'cser_name', 'corp_id', 'external_userid', 'userid', 'client_online_status']),
// 客服状态文本
clientStatusText() {
const statusMap = {
'online': '在线',
'offline': '离线',
'rest': '休息中'
}
return statusMap[this.client_online_status] || '未知'
},
// 用户是否同意聊天内容存档文本
agreeStatusText() {
return this.agreeStatus === 'Agreen' ? '已' : '未'
},
// 客服是否有权限文本
permitStatusText() {
return this.hasPermit ? '已' : '未'
},
},
mixins: [watchMember],
created() {
// 初始化企业微信SDK
this.initializeWecom()
// 获取客服状态和相关信息
this.getInitialData()
},
mounted() {
},
methods: {
...mapMutations('game', ['set_accountSelect']),
...mapActions('user', ['initWecom']),
// 初始化企业微信SDK
async initializeWecom() {
try {
console.log('🚀 开始初始化企业微信 SDK')
const result = await this.initWecom()
console.log('✅ 企业微信 SDK 初始化成功', result)
} catch (error) {
console.error('❌ 企业微信 SDK 初始化失败:', error)
}
},
// 获取初始数据
async getInitialData() {
try {
// 1. 获取客服休息状态
const statusRes = await getClientStatus()
if (statusRes.status_code === 1) {
this.$store.commit('user/set_client_online_status', statusRes.data.client_online_status)
}
// 2. 同步智能标签
this.syncIntelligentTags()
// 3. 检查用户是否同意聊天内容存档
this.checkAgreeStatus()
// 4. 检查客服号是否开启会话内容存档
this.checkPermitStatus()
} catch (error) {
console.error('获取初始数据失败:', error)
}
},
// 同步智能标签
async syncIntelligentTags() {
try {
await remarkSessionIntelTag({
corp_id: this.corp_id,
external_userid: this.external_userid,
userid: this.userid
})
console.log('智能标签同步成功')
} catch (error) {
console.error('智能标签同步失败:', error)
}
},
// 检查用户是否同意聊天内容存档
async checkAgreeStatus() {
try {
const res = await checkSingleAgree({
external_userid: this.external_userid,
userid: this.userid
})
if (res.status_code === 1) {
this.agreeStatus = res.data.agree_status
}
} catch (error) {
console.error('检查用户同意状态失败:', error)
}
},
// 检查客服号是否开启会话内容存档
async checkPermitStatus() {
try {
const res = await checkUserPermit({
userid: this.userid
})
if (res.status_code === 1) {
this.hasPermit = res.data.has_permit
}
} catch (error) {
console.error('检查客服权限失败:', error)
}
},
// 开始休息
async handleStartRest() {
try {
const res = await client_session_rest()
if (res.status_code === 1) {
this.$store.commit('user/set_client_online_status', 'rest')
this.$message.success('已开始休息')
} else {
this.$message.error(res.msg || '开始休息失败')
}
} catch (error) {
console.error('开始休息失败:', error)
this.$message.error('开始休息失败')
}
},
// 结束休息
async handleFinishRest() {
try {
const res = await finishRest()
if (res.status_code === 1) {
this.$store.commit('user/set_client_online_status', 'online')
this.$message.success('已结束休息')
} else {
this.$message.error(res.msg || '结束休息失败')
}
} catch (error) {
console.error('结束休息失败:', error)
this.$message.error('结束休息失败')
}
},
// 发送评价
async handleSendComment() {
try {
const res = await sendComment({
corp_id: this.corp_id,
external_userid: this.external_userid,
userid: this.userid
})
if (res.status_code === 1 && res.data.news) {
// 使用企业微信JSSDK发送评价
const result = await sendChatMessage(res.data.news, 'link')
if (result.success) {
this.$message.success('评价已发送')
} else {
this.$message.error('评价发送失败')
}
} else {
this.$message.error(res.msg || '获取评价内容失败')
}
} catch (error) {
console.error('发送评价失败:', error)
this.$message.error('发送评价失败')
}
},
memberChange() {
this.requestBindUser()
},
......@@ -393,16 +576,6 @@ import watchMember from '@/mixins/watchMember'
}
this.editUserInfo(params)
},
editUserInfo(data) {
editUser(data).then((res) => {
if (res.status_code == 1) {
this.$message({
type: 'success',
message: res.msg
})
}
})
},
}
}
</script>
......@@ -432,6 +605,31 @@ import watchMember from '@/mixins/watchMember'
font-size: 14px;
margin-bottom: 10px;
}
.cser_status {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
font-size: 14px;
.status-actions {
display: flex;
gap: 10px;
}
}
.archive-status {
margin-bottom: 15px;
padding: 8px;
background-color: #f8f8f8;
border-radius: 4px;
font-size: 14px;
p {
margin: 5px 0;
color: #F56C6C;
font-weight: 600;
}
}
.detailsTitle {
height: 50px;
padding: 0 20px;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论