提交 a21e58e2 作者: 施汉文

feat: 客服样式

上级 869d9cf1
<!DOCTYPE html> <!DOCTYPE html>
<html lang=""> <html lang="">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<!-- HTTP 1.1 --> <!-- HTTP 1.1 -->
<meta http-equiv="pragma" content="no-cache"> <meta http-equiv="pragma" content="no-cache" />
<!-- HTTP 1.0 --> <!-- HTTP 1.0 -->
<meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="cache-control" content="no-cache" />
<!-- Prevent caching at the proxy server --> <!-- Prevent caching at the proxy server -->
<meta http-equiv="expires" content="0"> <meta http-equiv="expires" content="0" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" /> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9" />
<!-- <title><%= htmlWebpackPlugin.options.title %></title> --> <!-- <title><%= htmlWebpackPlugin.options.title %></title> -->
<title>企微侧边栏</title> <title>企微侧边栏</title>
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,shrink-to-fit=no,user-scalable=no"> --> <!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,shrink-to-fit=no,user-scalable=no"> -->
<script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script> <script src="https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js"></script>
<!-- iconpark CDN链接 -->
<script src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_27278_168.abab0e7be76224e5929cf4315f14d58c.es5.js"></script>
</head> </head>
<body> <body>
<noscript> <noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> <strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>
</noscript> </noscript>
<div id="app"></div> <div id="app"></div>
</body> </body>
......
<template> <template>
<div id="app" class="mobile-app-wrapper"> <div id="app" class="mobile-app-wrapper">
<Debug /> <Debug />
<div class="mobile-menu-bar" v-if="token && external_userid && showMemberId"> <div class="mobile-content">
<router-view></router-view>
</div>
<div
class="mobile-menu-bar w-[40px] overflow-hidden"
v-if="token && external_userid && showMemberId"
>
<!-- 临时调试信息 --> <!-- 临时调试信息 -->
<div class="menu-container"> <div class="menu-container">
<el-menu :default-active="selectedPath" mode="horizontal" class="mobile-el-menu" <el-menu
:class="{ 'collapsed': !isMenuExpanded && shouldShowToggle }" background-color="#fff" router :default-active="selectedPath"
@select="handleSelect" ref="menuRef"> class="mobile-el-menu"
<el-menu-item v-for="item in menuList" :key="item.path" :index="item.path" class="mobile-menu-item"> router
<!-- 任务列表菜单项显示红点 --> @select="handleSelect"
<div v-if="item.path === '/taskList' && hasTaskRedDot" class="menu-item-with-badge"> ref="menuRef"
<div class="task-badge"> active-text-color="#fff"
<el-badge is-dot> text-color="#B0B2B5"
<span>{{ item.label }}</span> >
</el-badge> <el-menu-item
v-for="item in menuList"
:key="item.path"
:index="item.path"
class="mobile-menu-item rounded-full"
style="padding: 0; margin: 8px 0; height: 24px; width: 24px"
>
<div
class="w-[24px] h-[24px] rounded-full bg-[#F2F3F5] flex items-center justify-center"
>
<!-- 任务列表菜单项显示红点 -->
<div
v-if="
(item.path === '/taskList' && hasTaskRedDot) ||
item.path === '/agentStatusManagement'
"
class="menu-item-with-badge"
>
<el-tooltip
class="item"
effect="dark"
:disabled="item.path !== '/agentStatusManagement'"
:content="'客服状态:' + csStatusInfo.text"
placement="left"
>
<div
class="task-badge"
:class="{
'agent-status-management':
item.path === '/agentStatusManagement',
}"
>
<el-badge is-dot :type="csStatusInfo.type">
<!-- <span>{{ item.label }}</span> -->
<iconpark-icon
class="w-[14px] h-[14px]"
:name="item.icon"
></iconpark-icon>
</el-badge>
</div>
</el-tooltip>
</div> </div>
<!-- 普通菜单项 -->
<!-- <span >{{ item.label }}</span> -->
<iconpark-icon
v-else
class="w-[14px] h-[14px]"
:name="item.icon"
></iconpark-icon>
</div> </div>
<!-- 普通菜单项 -->
<span v-else>{{ item.label }}</span>
</el-menu-item> </el-menu-item>
</el-menu> </el-menu>
<!-- 展开收起按钮 -->
<el-button type="text" size="mini" v-if="shouldShowToggle" class="menu-toggle-btn" @click="toggleMenu">
<i :class="isMenuExpanded ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
<span>{{ isMenuExpanded ? '收起' : '展开' }}</span>
</el-button>
</div> </div>
<!-- 绑定的 w 账号 --> <!-- 绑定的 w 账号 -->
<bindUserList /> <bindUserList />
</div> </div>
<div class="mobile-content">
<router-view></router-view>
</div>
</div> </div>
</template> </template>
<script> <script>
import bindUserList from '@/views/components/bindGameAccount/bindUserList.vue' import bindUserList from "@/views/components/bindGameAccount/bindUserList.vue";
import { getToken } from '@/utils/auth' import { getToken } from "@/utils/auth";
import { mapState, mapMutations, mapActions } from 'vuex' import { mapState, mapMutations, mapActions } from "vuex";
import Cookies from 'js-cookie' import Cookies from "js-cookie";
import { getParams } from '@/utils/index' import { getParams } from "@/utils/index";
import Debug from '@/components/debug.vue' import Debug from "@/components/debug.vue";
export default { export default {
name: 'App', name: "App",
components: { components: {
bindUserList, bindUserList,
Debug Debug,
}, },
data() { data() {
return { return {
menuList: [ menuList: [
{ {
label: '客户资料', label: "客服",
path: '/userInfo' path: "/agentStatusManagement",
icon: "gongnengicon-zaixiankefu",
},
{
label: "客户资料",
path: "/userInfo",
icon: "gongnengicon-kehuziliao",
}, },
// { // {
// label: '角色信息', // label: '角色信息',
...@@ -66,16 +114,18 @@ export default { ...@@ -66,16 +114,18 @@ export default {
// path: '/orderList' // path: '/orderList'
// }, // },
{ {
label: '快捷回复', label: "快捷回复",
path: '/quickReply' path: "/quickReply",
icon: "gongnengicon-kuaijiehuifu",
}, },
// { // {
// label: '违规记录', // label: '违规记录',
// path: '/violationRecord' // path: '/violationRecord'
// }, // },
{ {
label: '礼包记录', label: "礼包记录",
path: '/giftRecord' path: "/giftRecord",
icon: "gongnengicon-libaojilu",
}, },
// { // {
...@@ -83,188 +133,217 @@ export default { ...@@ -83,188 +133,217 @@ export default {
// path: '/taskRecord' // path: '/taskRecord'
// }, // },
{ {
label: '申请记录', label: "申请记录",
path: '/applyRecord' path: "/applyRecord",
icon: "gongnengicon-shenqingjilu",
}, },
{ {
label: '通讯录', label: "通讯录",
path: '/addressBook' path: "/addressBook",
icon: "gongnengicon-tongxunlu",
}, },
{ {
label: '快捷发送', label: "快捷发送",
path: '/quickSendGame' path: "/quickSendGame",
icon: "gongnengicon-kuaijiefasong",
}, },
{ {
label: '任务列表', label: "任务列表",
path: '/taskList', path: "/taskList",
hasRedDot: false // 红点状态 hasRedDot: false, // 红点状态
icon: "gongnengicon-renwuliebiao",
}, },
{ {
label: '微言助手', label: "微言助手",
path: '/aiChat' path: "/aiChat",
icon: "gongnengicon-weiyanzhushou",
}, },
// { // {
// label: '通讯录', // label: '通讯录',
// path: '/addressBook' // path: '/addressBook'
// }, // },
], ],
selectedPath: '/userInfo', selectedPath: "/userInfo",
showMemberId: false, showMemberId: false,
isMenuExpanded: false, // 菜单展开状态
shouldShowToggle: false, // 是否显示展开收起按钮 shouldShowToggle: false, // 是否显示展开收起按钮
} };
}, },
computed: { computed: {
...mapState('user', ['external_userid', 'token', 'userInfo']), ...mapState("user", [
...mapState('game', ['taskData']), "external_userid",
"token",
"userInfo",
"client_online_status",
]),
...mapState("game", ["taskData"]),
// 计算任务列表是否需要显示红点 // 计算任务列表是否需要显示红点
hasTaskRedDot() { hasTaskRedDot() {
return this.taskData.user_task > 0 || this.taskData.account_task > 0 return this.taskData.user_task > 0 || this.taskData.account_task > 0;
} },
//客服状态信息
csStatusInfo() {
const statusMap = {
online: {
text: "在线",
type: "success",
},
offline: {
text: "离线",
type: "danger",
},
rest: {
text: "休息中",
type: "warning",
},
};
return statusMap[this.client_online_status] || "未知";
},
}, },
watch: { watch: {
'$route.path'(val) { "$route.path"(val) {
// 处理各种可能的路径情况 // 处理各种可能的路径情况
if (val === '/' || val === '/index.html') { if (val === "/" || val === "/index.html") {
this.selectedPath = '/userInfo' this.selectedPath = "/userInfo";
} else { } else {
this.selectedPath = val this.selectedPath = val;
} }
console.log('路由变化:', val, '选中路径:', this.selectedPath) console.log("路由变化:", val, "选中路径:", this.selectedPath);
}, },
// 监听用户信息变化,只在初始化时获取一次任务数据 // 监听用户信息变化,只在初始化时获取一次任务数据
userInfo: { userInfo: {
handler(newVal, oldVal) { handler(newVal, oldVal) {
if (newVal && newVal.id && (!oldVal || !oldVal.id) && this.token) { if (newVal && newVal.id && (!oldVal || !oldVal.id) && this.token) {
console.log('用户信息初始化完成,获取任务数据:', newVal) console.log("用户信息初始化完成,获取任务数据:", newVal);
// 只在用户信息第一次设置时获取任务数据 // 只在用户信息第一次设置时获取任务数据
this.getTaskUnReadData() this.getTaskUnReadData();
} }
}, },
deep: true, deep: true,
immediate: true immediate: true,
}, },
// 监听 external_userid 的变化,确保界面及时更新 // 监听 external_userid 的变化,确保界面及时更新
external_userid: { external_userid: {
handler(newVal) { handler(newVal) {
if (newVal) { if (newVal) {
this.$nextTick(() => { this.$nextTick(() => {
this.showMemberId = true this.showMemberId = true;
console.log('external_userid 已设置:', newVal, window.location.href, this.token, Cookies.get('token')) console.log(
"external_userid 已设置:",
newVal,
window.location.href,
this.token,
Cookies.get("token")
);
// 强制更新组件 // 强制更新组件
this.$forceUpdate() this.$forceUpdate();
// 检查是否需要显示展开收起按钮 // 检查是否需要显示展开收起按钮
this.checkMenuOverflow() this.checkMenuOverflow();
}) });
} }
}, },
immediate: true immediate: true,
} },
}, },
created() { created() {
const urlParams = getParams(); const urlParams = getParams();
// 每次进入页面都缓存corp_id // 每次进入页面都缓存corp_id
if (urlParams.corp_id) { if (urlParams.corp_id) {
this.cacheCorp_id(urlParams.corp_id) // 缓存 corp_id this.cacheCorp_id(urlParams.corp_id); // 缓存 corp_id
} }
}, },
mounted() { mounted() {
// 页面刷新时从 Cookie 恢复 token 到 store // 页面刷新时从 Cookie 恢复 token 到 store
const cookieToken = Cookies.get('token') const cookieToken = Cookies.get("token");
if (cookieToken && !this.token) { if (cookieToken && !this.token) {
this.set_token(cookieToken) this.set_token(cookieToken);
console.log('从 Cookie 恢复 token:', cookieToken) console.log("从 Cookie 恢复 token:", cookieToken);
} }
// 初始化时处理路径 // 初始化时处理路径
const currentPath = this.$route.path const currentPath = this.$route.path;
if (currentPath === '/' || currentPath === '' || currentPath === '/index.html') { if (
this.selectedPath = '/userInfo' currentPath === "/" ||
currentPath === "" ||
currentPath === "/index.html"
) {
this.selectedPath = "/userInfo";
} else { } else {
this.selectedPath = currentPath this.selectedPath = currentPath;
} }
console.log('创建时路径:', currentPath, '选中路径:', this.selectedPath) console.log("创建时路径:", currentPath, "选中路径:", this.selectedPath);
// 监听窗口大小变化 // 监听窗口大小变化
window.addEventListener('resize', this.handleResize) window.addEventListener("resize", this.handleResize);
// 初始检查 // 初始检查
this.$nextTick(() => { this.$nextTick(() => {
this.checkMenuOverflow() this.checkMenuOverflow();
this.initVuexValue() this.initVuexValue();
}) });
}, },
beforeDestroy() { beforeDestroy() {
window.removeEventListener('resize', this.handleResize) window.removeEventListener("resize", this.handleResize);
}, },
methods: { methods: {
...mapMutations('user', ['set_userid', 'set_corp_id', 'set_token', 'set_cser_info', 'set_cser_id', 'set_cser_name', 'set_userInfo']), ...mapMutations("user", [
...mapMutations('game', ['set_accountSelect']), "set_userid",
...mapActions('game', ['getTaskUnReadData']), "set_corp_id",
"set_token",
"set_cser_info",
"set_cser_id",
"set_cser_name",
"set_userInfo",
]),
...mapMutations("game", ["set_accountSelect"]),
...mapActions("game", ["getTaskUnReadData"]),
// 设置缓存 // 设置缓存
cacheCorp_id(corp_id) { cacheCorp_id(corp_id) {
Cookies.set('corp_id', corp_id, { expires: 30 }) Cookies.set("corp_id", corp_id, { expires: 30 });
this.set_corp_id(corp_id) this.set_corp_id(corp_id);
}, },
initVuexValue() { initVuexValue() {
this.set_userid(Cookies.get('userid')) this.set_userid(Cookies.get("userid"));
this.set_corp_id(Cookies.get('corp_id')) this.set_corp_id(Cookies.get("corp_id"));
this.set_token(Cookies.get('token')) this.set_token(Cookies.get("token"));
this.set_cser_id(Cookies.get('cser_id')) this.set_cser_id(Cookies.get("cser_id"));
this.set_cser_name(Cookies.get('cser_name')) this.set_cser_name(Cookies.get("cser_name"));
const userinfo = { const userinfo = {
cser_id: Cookies.get('cser_id'), cser_id: Cookies.get("cser_id"),
cser_name: Cookies.get('cser_name'), cser_name: Cookies.get("cser_name"),
username: Cookies.get('cser_name'), username: Cookies.get("cser_name"),
id: Cookies.get('cser_id'), id: Cookies.get("cser_id"),
} };
this.set_userInfo(userinfo) this.set_userInfo(userinfo);
const cser_info = Cookies.get('cser_info') const cser_info = Cookies.get("cser_info");
cser_info ? this.set_cser_info(JSON.parse(cser_info)) : this.set_cser_info({}) cser_info
? this.set_cser_info(JSON.parse(cser_info))
: this.set_cser_info({});
}, },
handleSelect(key, keyPath) { handleSelect(key, keyPath) {
console.log('菜单选择:', key, keyPath, window.location.href) console.log("菜单选择:", key, keyPath, window.location.href);
},
// 切换菜单展开收起状态
toggleMenu() {
this.isMenuExpanded = !this.isMenuExpanded
}, },
// 检查菜单是否需要换行 // 检查菜单是否需要换行
checkMenuOverflow() { checkMenuOverflow() {
this.$nextTick(() => { this.$nextTick(() => {
const menuElement = this.$refs.menuRef?.$el const menuElement = this.$refs.menuRef?.$el;
if (!menuElement) return if (!menuElement) return;
// 临时展开菜单来检查实际高度 const menuHeight = menuElement.scrollHeight;
const wasCollapsed = !this.isMenuExpanded && this.shouldShowToggle const singleLineHeight = 50; // 单行高度
if (wasCollapsed) {
menuElement.classList.remove('collapsed')
}
const menuHeight = menuElement.scrollHeight
const singleLineHeight = 50 // 单行高度
// 如果菜单高度超过单行,说明需要换行 // 如果菜单高度超过单行,说明需要换行
this.shouldShowToggle = menuHeight > singleLineHeight + 10 // 加10px容错 this.shouldShowToggle = menuHeight > singleLineHeight + 10; // 加10px容错
});
// 如果不需要展开收起按钮,则直接展开
if (!this.shouldShowToggle) {
this.isMenuExpanded = true
} else if (wasCollapsed) {
// 恢复收起状态
menuElement.classList.add('collapsed')
}
})
}, },
// 窗口大小变化处理 // 窗口大小变化处理
handleResize() { handleResize() {
clearTimeout(this.resizeTimer) clearTimeout(this.resizeTimer);
this.resizeTimer = setTimeout(() => { this.resizeTimer = setTimeout(() => {
this.checkMenuOverflow() this.checkMenuOverflow();
}, 150) }, 150);
} },
}, },
} };
</script> </script>
<style scoped> <style scoped>
...@@ -280,7 +359,6 @@ export default { ...@@ -280,7 +359,6 @@ export default {
background: #f0f2f5; background: #f0f2f5;
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-direction: column;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.04); box-shadow: 0 0 12px rgba(0, 0, 0, 0.04);
} }
...@@ -293,37 +371,43 @@ export default { ...@@ -293,37 +371,43 @@ export default {
.menu-container { .menu-container {
position: relative; position: relative;
padding-right: 30px;
} }
.mobile-el-menu { .mobile-el-menu {
border: none; border: none;
background: #fff; background: #fff;
display: flex; display: flex;
justify-content: flex-start; justify-content: center;
padding-left: 16px; /* padding-left: 16px; */
flex-wrap: wrap; flex-wrap: wrap;
transition: all 0.3s ease; transition: all 0.3s ease;
overflow: hidden; overflow: hidden;
} }
/* 收起状态:只显示第一行 */ /* 收起状态:只显示第一行 */
.mobile-el-menu.collapsed { /* .mobile-el-menu.collapsed {
max-height: 35px; max-height: 35px;
overflow: hidden; overflow: hidden;
} } */
.mobile-menu-item { .mobile-menu-item {
display: flex;
align-items: center;
justify-content: center;
font-size: 14px; font-size: 14px;
padding: 0 16px !important; /* padding: 0 16px !important; */
min-width: 0; min-width: 0;
flex: none; flex: none;
width: auto; height: 40px;
max-width: 120px; max-width: 120px;
text-align: center; text-align: center;
margin-right: 8px; margin-right: 8px;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.el-menu-item,
.el-submenu__title {
line-height: auto;
}
.mobile-el-menu .el-menu-item.is-active { .mobile-el-menu .el-menu-item.is-active {
font-weight: bold; font-weight: bold;
...@@ -342,7 +426,10 @@ export default { ...@@ -342,7 +426,10 @@ export default {
transition: all 0.3s ease; transition: all 0.3s ease;
z-index: 20; z-index: 20;
} }
.el-dropdown-menu__item,
.el-menu-item {
padding: 0;
}
.menu-toggle-btn i { .menu-toggle-btn i {
font-size: 12px; font-size: 12px;
} }
...@@ -352,14 +439,14 @@ export default { ...@@ -352,14 +439,14 @@ export default {
overflow-y: auto; overflow-y: auto;
} }
.mobile-content>div { .mobile-content > div {
background: #fff; background: #fff;
border-radius: 8px; border-radius: 8px;
min-height: 60vh; min-height: 60vh;
padding: 10px; padding: 10px;
} }
.el-menu--horizontal>.el-menu-item { .el-menu--horizontal > .el-menu-item {
height: 35px; height: 35px;
line-height: 35px; line-height: 35px;
} }
...@@ -370,16 +457,27 @@ body { ...@@ -370,16 +457,27 @@ body {
/* 任务列表菜单项红点样式 */ /* 任务列表菜单项红点样式 */
.menu-item-with-badge { .menu-item-with-badge {
display: inline-block; /* display: inline-block; */
}
.mobile-el-menu .el-menu-item.is-active > div {
background: #267ef0;
} }
.task-badge { .task-badge {
::v-deep .el-badge__content.is-dot { ::v-deep .el-badge__content.is-dot {
top: 8px !important; top: 16px !important;
right: -5px !important; right: 3px !important;
} }
} }
.agent-status-management {
::v-deep .el-badge__content.is-dot {
top: 38px !important;
right: 2px !important;
}
}
.el-badge {
display: block;
}
/* 确保菜单项内容居中 */ /* 确保菜单项内容居中 */
.mobile-menu-item .menu-item-with-badge { .mobile-menu-item .menu-item-with-badge {
display: flex; display: flex;
......
import Vue from 'vue' import Vue from 'vue'
import VueRouter from 'vue-router' import VueRouter from 'vue-router'
import userInfo from '../views/userInfo/userInfo.vue' import userInfo from '../views/userInfo/userInfo.vue'
import agentStatusManagement from '../views/agentStatusManagement/index.vue'
import quickReply from '../views/quickReply.vue' import quickReply from '../views/quickReply.vue'
import giftRecord from '../views/giftRecord.vue' import giftRecord from '../views/giftRecord.vue'
import applyRecord from '../views/applyRecord.vue' import applyRecord from '../views/applyRecord.vue'
...@@ -26,6 +27,11 @@ const routes = [ ...@@ -26,6 +27,11 @@ const routes = [
path: '/index.html', path: '/index.html',
redirect: '/userInfo' redirect: '/userInfo'
}, },
{
path: '/agentStatusManagement',
name: 'agentStatusManagement',
component: agentStatusManagement
},
{ {
path: '/userInfo', path: '/userInfo',
name: 'userInfo', name: 'userInfo',
......
...@@ -11,8 +11,10 @@ const state = { ...@@ -11,8 +11,10 @@ const state = {
"agent_signature": "05a47ef848266c48ff28f52e7749ba8b70adcc14", "agent_signature": "05a47ef848266c48ff28f52e7749ba8b70adcc14",
"corp_signature": "29e61720786b3c6dac31f1041c70878b4819842e", "corp_signature": "29e61720786b3c6dac31f1041c70878b4819842e",
"time": 1747726636, "time": 1747726636,
external_userid:'' external_userid:'',
}, },
avatar:'',//客服头像
userid:Cookies.get('userid'), userid:Cookies.get('userid'),
corp_id:'', corp_id:'',
external_userid:'', external_userid:'',
...@@ -40,6 +42,9 @@ const mutations = { ...@@ -40,6 +42,9 @@ const mutations = {
set_userInfo(state,userInfo){ set_userInfo(state,userInfo){
state.userInfo = userInfo state.userInfo = userInfo
}, },
set_avatar(state,avatar){
state.avatar = avatar
},
set_userid(state,userid){ set_userid(state,userid){
state.userid = userid state.userid = userid
}, },
......
...@@ -14,6 +14,33 @@ body { ...@@ -14,6 +14,33 @@ body {
font-size: 14px; font-size: 14px;
margin: 0 ; margin: 0 ;
padding: 0; padding: 0;
// 设置全局滚动条不占位置
overflow: overlay;
}
// 全局滚动条样式
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background-color: rgba(144, 147, 153, 0.3);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background-color: rgba(144, 147, 153, 0.5);
}
// Firefox 滚动条样式
* {
scrollbar-width: thin;
scrollbar-color: rgba(144, 147, 153, 0.3) transparent;
} }
label { label {
...@@ -856,4 +883,4 @@ li { ...@@ -856,4 +883,4 @@ li {
.el-message-box__message { .el-message-box__message {
max-height: 500px !important; max-height: 500px !important;
overflow-y: auto !important; overflow-y: auto !important;
} }
\ No newline at end of file
<template>
<div class="p-3 h-full">
<div class="text-[13px] text-[#131920] font-medium">在线客服</div>
<div class="px-[9px] pt-[60px] flex flex-col items-center justify-center">
<div class="h-[80px] w-[80px]">
<img :src="avatar" alt="" class="h-full w-full rounded-[6px]" />
</div>
<div class="text-[14px] mt-[8px] text-black">
{{ userInfo.username }}
</div>
<div
v-if="clientStatus === 'rest'"
class="mt-[8px] text-[12px] flex items-center justify-center text-[#FA8F25] bg-[rgba(250,143,37,0.1)] px-[8px] rounded-full"
>
<div class="h-[6px] w-[6px] rounded-full bg-[#FA8F25] mr-[4px]"></div>
{{ clientStatusText }}
</div>
<div
v-else
class="mt-[8px] text-[12px] flex items-center justify-center text-[#26BF4C] bg-[rgba(38,191,76,0.1)] px-[8px] rounded-full"
>
<div class="h-[6px] w-[6px] rounded-full bg-[#26BF4C] mr-[4px]"></div>
{{ clientStatusText }}
</div>
<div class="mt-[32px] w-full space-y-[12px] space-x-0">
<el-button
plain
class="!w-full !h-[40px]"
@click="logout"
v-if="clientStatus !== 'offline'"
:loading="logoutLoading"
>
<div class="flex items-center justify-center">
<iconpark-icon
name="kefucaozuo-xiaxian"
class="mr-[8px] text-[14px]"
></iconpark-icon>
下线
</div>
</el-button>
<el-tooltip
effect="dark"
:content="'午休或者临时有事可点击休息'"
placement="top"
v-if="clientStatus === 'online'"
>
<el-button
plain
class="!w-full !h-[40px]"
@click="handleStartRest"
:loading="startRestLoading"
>
<div class="flex items-center justify-center">
<iconpark-icon
name="kefucaozuo-xiuxi"
class="mr-[8px] text-[14px]"
></iconpark-icon>
开始休息
</div>
</el-button>
</el-tooltip>
<el-button
type="primary"
class="!w-full !h-[40px]"
@click="handleFinishRest"
v-if="clientStatus === 'rest'"
:loading="finishRestLoading"
>
<div class="flex items-center justify-center">
<iconpark-icon
name="kefucaozuo-xiuxi"
class="mr-[8px] font-bold text-[14px]"
></iconpark-icon>
结束休息
</div>
</el-button>
<el-button
plain
class="!w-full !h-[40px]"
@click="handleSendComment"
:loading="sendCommentLoading"
>
<div class="flex items-center justify-center">
<iconpark-icon
name="kefucaozuo-pingjia"
class="mr-[8px] text-[14px]"
></iconpark-icon>
发送评价
</div>
</el-button>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from "vuex";
import {
getClientStatus,
finishRest,
client_session_rest,
sendComment,
logout,
} from "@/api/user.js";
import { sendChatMessage } from "@/utils/index.js";
import { getToken, removeToken } from "@/utils/auth";
import Cookies from "js-cookie";
export default {
name: "AgentStatusManagement",
data() {
return {
logoutLoading: false,
startRestLoading: false,
finishRestLoading: false,
sendCommentLoading: false,
};
},
computed: {
...mapState("user", [
"userInfo",
"avatar",
"client_online_status",
"corp_id",
"external_userid",
"userid",
"token",
]),
// 客服状态文本
clientStatusText() {
const statusMap = {
online: "在线",
offline: "离线",
rest: "休息中",
};
return statusMap[this.client_online_status] || "未知";
},
// 客服状态
clientStatus() {
console.log(this.client_online_status, 123131231);
return this.client_online_status;
},
},
mounted() {
// 获取客服状态和相关信息
this.$nextTick(() => {
if (this.userid && this.token) {
this.getInitialData();
}
});
},
methods: {
...mapMutations("user", ["set_client_online_status"]),
...mapActions("user", ["initWecom"]),
// 获取初始数据
async getInitialData() {
console.log(this.userInfo, 1111111);
// 如果userInfo.id存在,说明已经获取过客服状态,直接返回
if (this.userInfo.id) return;
try {
// 获取客服休息状态
const statusRes = await getClientStatus();
if (statusRes.status_code === 1) {
if (statusRes.data.client_online_status === "offline") {
removeToken();
window.location.href =
window.location.origin +
"/company_app/index.html?corp_id=" +
this.corp_id;
}
console.log(statusRes.data, 123131231);
this.set_client_online_status(statusRes.data.client_online_status);
}
} catch (error) {
console.error("获取初始数据失败:", error);
}
},
// 下线确认
logout() {
if (this.client_online_status === "rest") {
this.$message({
type: "error",
message: "当前客服号处于休息状态,不能下线",
});
return;
}
this.$confirm("确定下线吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.userLogout();
})
.catch(() => {
this.$message({
type: "info",
message: "已取消",
});
});
},
// 执行下线
async userLogout() {
this.logoutLoading = true;
try {
const data = {
userid: this.userid,
};
const res = await logout(data);
if (res.status_code === 1) {
this.$message({
type: "success",
message: "下线成功",
});
removeToken();
Cookies.remove("external_userid");
Cookies.remove("userid");
window.location.href =
window.location.origin +
"/company_app/index.html?corp_id=" +
this.corp_id;
} else {
this.$message({
type: "error",
message: "下线失败",
});
}
} finally {
this.logoutLoading = false;
}
},
// 开始休息
async handleStartRest() {
this.startRestLoading = true;
try {
const res = await client_session_rest();
if (res.status_code === 1) {
this.set_client_online_status("rest");
this.$message.success("已开始休息");
} else {
this.$message.error(res.msg || "开始休息失败");
}
} catch (error) {
console.error("开始休息失败:", error);
this.$message.error("开始休息失败");
} finally {
this.startRestLoading = false;
}
},
// 结束休息
async handleFinishRest() {
this.finishRestLoading = true;
try {
const res = await finishRest();
if (res.status_code === 1) {
this.set_client_online_status("online");
this.$message.success("已结束休息");
} else {
this.$message.error(res.msg || "结束休息失败");
}
} catch (error) {
console.error("结束休息失败:", error);
this.$message.error("结束休息失败");
} finally {
this.finishRestLoading = false;
}
},
// 发送评价
async handleSendComment() {
this.sendCommentLoading = true;
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("评价发送失败");
}
}
} catch (error) {
console.error("发送评价失败:", error);
this.$message.error("发送评价失败");
} finally {
this.sendCommentLoading = false;
}
},
},
};
</script>
<template> <template>
<div class="bindUserList rowFlex columnCenter"> <div class="bindUserList rowFlex columnCenter">
<div class="select"> <div class="select">
<el-select v-model="bindAccount" placeholder="请选择关联账号" :clearable="false" @change="handleChange"> <el-select
v-model="bindAccount"
placeholder="请选择关联账号"
:clearable="false"
@change="handleChange"
>
<el-option label="新增关联账号" value="add" @click="addNewUser"> <el-option label="新增关联账号" value="add" @click="addNewUser">
</el-option> </el-option>
<el-option v-for="(item, index) in bindGameUserList" :key="index" :label="item.username" <el-option
:value="item.member_id"> v-for="(item, index) in bindGameUserList"
:key="index"
:label="item.username"
:value="item.member_id"
>
<div class="rowFlex columnCenter"> <div class="rowFlex columnCenter">
<p class="text">{{ item.status_name <p class="text">
? `${item.username}/${item.status_name}` {{
: item.username}}</p> item.status_name
<span v-if="item.account_type==2" class="account_type" style="color: red;font-weight: bold;"> ()</span> ? `${item.username}/${item.status_name}`
: item.username
}}
</p>
<span
v-if="item.account_type == 2"
class="account_type"
style="color: red; font-weight: bold"
>
()</span
>
</div> </div>
</el-option> </el-option>
</el-select> </el-select>
</div> </div>
<p v-if="bindGameUserList.length > 0" class="num"> <p v-if="bindGameUserList.length > 0" class="num">
总共{{ bindGameUserList.length }}个账号 总共{{ bindGameUserList.length }}个账号
</p> </p>
<addUser <addUser
:show.sync="showLayer" :show.sync="showLayer"
title="选择玩家" title="选择玩家"
width="60%" width="60%"
@close="close" @close="close"
/> />
</div> </div>
</template> </template>
<script type="text/javascript"> <script type="text/javascript">
import { detailsInfoRequest } from '@/api/works' import { detailsInfoRequest } from "@/api/works";
import {memberView} from '@/api/game' import { memberView } from "@/api/game";
import { logout } from '@/api/user' import { logout } from "@/api/user";
import { mapState, mapMutations, mapActions } from 'vuex' import { mapState, mapMutations, mapActions } from "vuex";
import addUser from './addUser.vue' import addUser from "./addUser.vue";
import { getToken,removeToken } from '@/utils/auth' import { getToken, removeToken } from "@/utils/auth";
// 更新代码 // 更新代码
export default { export default {
name: 'bindUserList', name: "bindUserList",
components: { components: {
addUser addUser,
}, },
data() { data() {
return { return {
showLayer: false, showLayer: false,
accountValue: '', accountValue: "",
bindAccount:'', bindAccount: "",
memberCheckList:[], // 自定义列 memberCheckList: [], // 自定义列
} };
}, },
computed: { computed: {
...mapState('game', [ ...mapState("game", ["bindGameUserList", "accountSelect", "gameUserInfo"]),
'bindGameUserList', ...mapState("user", [
'accountSelect', "userid",
'gameUserInfo' "corp_id",
]), "external_userid",
...mapState('user', [ "client_online_status",
'userid',
'corp_id',
'external_userid',
'client_online_status'
]), ]),
}, },
watch: { watch: {
accountSelect(newVal,oldVal) { accountSelect(newVal, oldVal) {
if(newVal){ if (newVal) {
console.log(newVal,'hahhaha') console.log(newVal, "hahhaha");
this.gameMemberView() this.gameMemberView();
this.bindAccount = newVal this.bindAccount = newVal;
} }
} },
}, },
async mounted() { async mounted() {
this.bindUserList() this.bindUserList();
this.requestDetails() this.requestDetails();
this.gameMemberView() this.gameMemberView();
}, },
methods: { methods: {
...mapMutations('game', [ ...mapMutations("game", [
'set_accountSelect', "set_accountSelect",
'set_chatUserInfo', "set_chatUserInfo",
'set_gameUserInfo', "set_gameUserInfo",
'set_viewLoading' "set_viewLoading",
"set_avatar",
]), ]),
...mapActions('game', ['gameBindUser']), ...mapMutations("user", ["set_avatar"]),
...mapActions("game", ["gameBindUser"]),
handleChange(value) { handleChange(value) {
if (value == 'add') { if (value == "add") {
this.showLayer = true this.showLayer = true;
} else { } else {
this.set_accountSelect(value) this.set_accountSelect(value);
} }
}, },
close(){ close() {
this.bindAccount = this.accountSelect this.bindAccount = this.accountSelect;
}, },
async gameMemberView(item) { async gameMemberView(item) {
if (this.accountSelect && this.accountSelect !== '') { if (this.accountSelect && this.accountSelect !== "") {
this.set_viewLoading(true) this.set_viewLoading(true);
this.set_gameUserInfo({}) this.set_gameUserInfo({});
await this.$nextTick() await this.$nextTick();
const data = { member_id: this.accountSelect, need_channel: 1, need_roleInfo: 1, need_banned: 1 } const data = {
try { member_id: this.accountSelect,
const res = await memberView(data) need_channel: 1,
this.set_viewLoading(false) need_roleInfo: 1,
if (res.status_code === 1) { need_banned: 1,
this.set_gameUserInfo(res.data) };
} else { try {
this.set_gameUserInfo({}) const res = await memberView(data);
} this.set_viewLoading(false);
} catch (error) { if (res.status_code === 1) {
this.set_viewLoading(false) this.set_gameUserInfo(res.data);
this.set_gameUserInfo({}) } else {
this.set_gameUserInfo({});
} }
} } catch (error) {
this.set_viewLoading(false);
this.set_gameUserInfo({});
}
}
}, },
addNewUser() { addNewUser() {
console.log(11) console.log(11);
}, },
async requestDetails() { async requestDetails() {
const data = { const data = {
userid: this.userid, userid: this.userid,
external_userid: this.external_userid external_userid: this.external_userid,
} };
const res = await detailsInfoRequest(data) const res = await detailsInfoRequest(data);
if (res.data && res.data.userid) { if (res.data && res.data.userid) {
console.log(res.data,'1231') this.set_avatar(res.data.user.avatar);
this.chatUserDetails = res.data console.log(res.data, "1231");
this.set_chatUserInfo(this.chatUserDetails) // 设置云端信息 this.chatUserDetails = res.data;
console.log(this.chatUserDetails,'哈哈哈') this.set_chatUserInfo(this.chatUserDetails); // 设置云端信息
if (this.chatUserDetails.self_defined_columns && this.chatUserDetails.self_defined_columns.length > 0) { console.log(this.chatUserDetails, "哈哈哈");
this.memberCheckList = if (
this.chatUserDetails.self_defined_columns.map( this.chatUserDetails.self_defined_columns &&
(item) => item.name this.chatUserDetails.self_defined_columns.length > 0
) ) {
this.memberCheckList = this.chatUserDetails.self_defined_columns.map(
(item) => item.name
);
} else { } else {
this.memberCheckList = [] this.memberCheckList = [];
} }
} else { } else {
this.chatUserDetails = {} this.chatUserDetails = {};
} }
// 获取到用户的详情 储存在缓存里面 // 获取到用户的详情 储存在缓存里面
}, },
...@@ -146,20 +170,19 @@ export default { ...@@ -146,20 +170,19 @@ export default {
async bindUserList() { async bindUserList() {
const data = { const data = {
userid: this.userid, userid: this.userid,
external_userid: this.external_userid external_userid: this.external_userid,
} };
const res = await this.gameBindUser(data) const res = await this.gameBindUser(data);
if (res.length > 0) { if (res.length > 0) {
this.set_accountSelect(res[0].member_id) this.set_accountSelect(res[0].member_id);
this.bindAccount = res[0].member_id this.bindAccount = res[0].member_id;
} else { } else {
this.set_accountSelect('') this.set_accountSelect("");
this.bindAccount = '' this.bindAccount = "";
} }
},
} },
} };
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -173,21 +196,22 @@ export default { ...@@ -173,21 +196,22 @@ export default {
min-width: 200px; min-width: 200px;
height: 32px; height: 32px;
line-height: 32px; line-height: 32px;
background-color: #E8F7FF; background-color: #e8f7ff;
color: #3491FA; color: #3491fa;
font-size: 14px; font-size: 14px;
&:hover, &:focus { &:hover,
border-color: #3491FA; &:focus {
border-color: #3491fa;
} }
} }
::v-deep .el-input__suffix { ::v-deep .el-input__suffix {
color: #3491FA; color: #3491fa;
} }
::v-deep .el-select-dropdown__item.selected { ::v-deep .el-select-dropdown__item.selected {
color: #3491FA; color: #3491fa;
} }
} }
...@@ -197,17 +221,18 @@ export default { ...@@ -197,17 +221,18 @@ export default {
font-weight: 600; font-weight: 600;
margin-left: 10px; margin-left: 10px;
white-space: nowrap; white-space: nowrap;
color: #F53F3F; color: #f53f3f;
} }
::v-deep .el-button--danger { ::v-deep .el-button--danger {
background-color: #F56C6C; background-color: #f56c6c;
border-color: #F56C6C; border-color: #f56c6c;
&:hover, &:focus { &:hover,
&:focus {
background-color: #f78989; background-color: #f78989;
border-color: #f78989; border-color: #f78989;
} }
} }
} }
</style> </style>
\ No newline at end of file
...@@ -15,50 +15,7 @@ ...@@ -15,50 +15,7 @@
<div v-else-if="gameUserInfo.exp_ip" class="warnText"> <div v-else-if="gameUserInfo.exp_ip" class="warnText">
<p>高风险用户,禁止转端 !!!</p> <p>高风险用户,禁止转端 !!!</p>
</div> </div>
<div class="cser_info">
<div class="cser_name">
<span>当前客服:{{ `${cser_name}(${clientStatusText})` }}</span>
</div>
<!-- 添加客服状态显示及按钮 -->
<div class="cser_status">
<div class="status-actions">
<el-button
type="danger"
v-if="clientStatus !== 'offline'"
style="margin-left: 0px"
size="mini"
@click="logout"
>下线</el-button
>
<!-- 休息中状态显示结束休息按钮 -->
<el-button
v-if="clientStatus === 'rest'"
type="primary"
size="mini"
@click="handleFinishRest"
>结束休息</el-button
>
<!-- 在线状态显示开始休息按钮 -->
<el-tooltip
v-if="clientStatus === 'online'"
content="午休或者临时有事可点击休息"
placement="top"
>
<el-button type="warning" size="mini" @click="handleStartRest"
>开始休息</el-button
>
</el-tooltip>
<!-- 发送评价按钮 -->
<el-button
type="primary"
style="margin-left: 0px"
size="mini"
@click="handleSendComment"
>发送评价</el-button
>
</div>
</div>
</div>
<!-- 会话内容存档状态 --> <!-- 会话内容存档状态 -->
<div <div
class="archive-status" class="archive-status"
...@@ -118,7 +75,7 @@ ...@@ -118,7 +75,7 @@
<span class="label" style="min-width: 45px">备注:</span> <span class="label" style="min-width: 45px">备注:</span>
<p v-if="!showInputRemark" class="text" style="max-width: 170px"> <p v-if="!showInputRemark" class="text" style="max-width: 170px">
{{ {{
chatUserDetails.remark && chatUserDetails.remark != '' chatUserDetails.remark && chatUserDetails.remark != ""
? chatUserDetails.remark ? chatUserDetails.remark
: chatUserDetails.name : chatUserDetails.name
}} }}
...@@ -268,19 +225,19 @@ ...@@ -268,19 +225,19 @@
</div> </div>
</template> </template>
<script> <script>
import { mapState, mapMutations, mapActions } from 'vuex'; import { mapState, mapMutations, mapActions } from "vuex";
import gameDetails from './gameInfo/gameUserInfo.vue'; import gameDetails from "./gameInfo/gameUserInfo.vue";
import shareInfo from './shareInfo.vue'; import shareInfo from "./shareInfo.vue";
import changePhone from './changePhone.vue'; import changePhone from "./changePhone.vue";
import watchMember from '@/mixins/watchMember'; import watchMember from "@/mixins/watchMember";
import { autoResetPassword, bindUserSelfAdd } from '@/api/game'; import { autoResetPassword, bindUserSelfAdd } from "@/api/game";
import { import {
memberBindCser, memberBindCser,
editUser, editUser,
zyouUnBind, zyouUnBind,
getMemberInfoApi, getMemberInfoApi,
} from '@/api/works'; } from "@/api/works";
import selectTag from '@/components/selectTag.vue'; import selectTag from "@/components/selectTag.vue";
import { import {
getClientStatus, getClientStatus,
remarkSessionIntelTag, remarkSessionIntelTag,
...@@ -290,13 +247,13 @@ import { ...@@ -290,13 +247,13 @@ import {
checkUserPermit, checkUserPermit,
sendComment, sendComment,
logout, logout,
} from '@/api/user.js'; } from "@/api/user.js";
import { sendChatMessage } from '@/utils/index.js'; import { sendChatMessage } from "@/utils/index.js";
import { getToken, removeToken } from '@/utils/auth'; import { getToken, removeToken } from "@/utils/auth";
import vipLevel from './gameInfo/vipLevel.vue'; import vipLevel from "./gameInfo/vipLevel.vue";
import Cookies from 'js-cookie'; import Cookies from "js-cookie";
export default { export default {
name: 'info', name: "info",
components: { components: {
gameDetails, gameDetails,
changePhone, changePhone,
...@@ -315,50 +272,38 @@ export default { ...@@ -315,50 +272,38 @@ export default {
return { return {
// 备注相关 // 备注相关
showInputRemark: false, showInputRemark: false,
showInputRemarkValue: '', showInputRemarkValue: "",
change_appraisal: false, change_appraisal: false,
// 自定义列相关 // 自定义列相关
showInput: false, showInput: false,
showInputValue: '', showInputValue: "",
inputIndex: -1, inputIndex: -1,
changePhone: false, changePhone: false,
showTag: false, showTag: false,
// 新增状态数据 // 新增状态数据
agreeStatus: '', // 用户是否同意聊天内容存档:Agreen同意 Disagree不同意 agreeStatus: "", // 用户是否同意聊天内容存档:Agreen同意 Disagree不同意
hasPermit: false, // 客服号是否开启会话内容存档权限 hasPermit: false, // 客服号是否开启会话内容存档权限
lastTime: '', //上一次交互时间 lastTime: "", //上一次交互时间
}; };
}, },
computed: { computed: {
...mapState('game', [ ...mapState("game", [
'accountSelect', "accountSelect",
'gameUserInfo', "gameUserInfo",
'bindGameUserList', "bindGameUserList",
'viewLoading', "viewLoading",
]), ]),
...mapState('user', [ ...mapState("user", [
'cser_info', "cser_info",
'cser_id', "cser_id",
'cser_name', "cser_name",
'corp_id', "corp_id",
'external_userid', "external_userid",
'userid', "userid",
'client_online_status', "client_online_status",
'token', "token",
]), ]),
// 客服状态文本
clientStatusText() {
const statusMap = {
online: '在线',
offline: '离线',
rest: '休息中',
};
return statusMap[this.client_online_status] || '未知';
},
// 客服休息状态:online上线 offline下线 rest休息中
clientStatus() {
return this.client_online_status;
},
getDaysDifference() { getDaysDifference() {
// 解析目标日期字符串 // 解析目标日期字符串
const targetDate = new Date(this.lastTime); const targetDate = new Date(this.lastTime);
...@@ -389,64 +334,17 @@ export default { ...@@ -389,64 +334,17 @@ export default {
}, },
methods: { methods: {
...mapMutations('game', ['set_accountSelect', 'accountSelect']), ...mapMutations("game", ["set_accountSelect", "accountSelect"]),
...mapActions('user', ['initWecom']), ...mapActions("user", ["initWecom"]),
// 初始化企业微信SDK // 初始化企业微信SDK
async initializeWecom() { async initializeWecom() {
try { try {
console.log('🚀 开始初始化企业微信 SDK'); console.log("🚀 开始初始化企业微信 SDK");
const result = await this.initWecom(); const result = await this.initWecom();
console.log('✅ 企业微信 SDK 初始化成功', result); console.log("✅ 企业微信 SDK 初始化成功", result);
} catch (error) { } catch (error) {
console.error('❌ 企业微信 SDK 初始化失败:', error); console.error("❌ 企业微信 SDK 初始化失败:", error);
}
},
logout() {
if (this.client_online_status === 'rest') {
this.$message({
type: 'error',
message: '当前客服号处于休息状态,不能下线',
});
return;
}
this.$confirm('确定下线吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.userLogout();
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消',
});
});
},
async userLogout() {
const data = {
userid: this.userid,
};
const res = await logout(data);
if (res.status_code === 1) {
this.$message({
type: 'success',
message: '下线成功',
});
removeToken();
Cookies.remove('external_userid');
Cookies.remove('userid');
window.location.href =
window.location.origin +
'/company_app/index.html?corp_id=' +
this.corp_id;
} else {
this.$message({
type: 'error',
message: '下线失败',
});
} }
}, },
...@@ -456,15 +354,15 @@ export default { ...@@ -456,15 +354,15 @@ export default {
// 1. 获取客服休息状态 // 1. 获取客服休息状态
const statusRes = await getClientStatus(); const statusRes = await getClientStatus();
if (statusRes.status_code === 1) { if (statusRes.status_code === 1) {
if (statusRes.data.client_online_status === 'offline') { if (statusRes.data.client_online_status === "offline") {
removeToken(); removeToken();
window.location.href = window.location.href =
window.location.origin + window.location.origin +
'/company_app/index.html?corp_id=' + "/company_app/index.html?corp_id=" +
this.corp_id; this.corp_id;
} }
this.$store.commit( this.$store.commit(
'user/set_client_online_status', "user/set_client_online_status",
statusRes.data.client_online_status statusRes.data.client_online_status
); );
} }
...@@ -478,7 +376,7 @@ export default { ...@@ -478,7 +376,7 @@ export default {
// 4. 检查客服号是否开启会话内容存档 // 4. 检查客服号是否开启会话内容存档
this.checkPermitStatus(); this.checkPermitStatus();
} catch (error) { } catch (error) {
console.error('获取初始数据失败:', error); console.error("获取初始数据失败:", error);
} }
}, },
...@@ -490,9 +388,9 @@ export default { ...@@ -490,9 +388,9 @@ export default {
external_userid: this.external_userid, external_userid: this.external_userid,
userid: this.userid, userid: this.userid,
}); });
console.log('智能标签同步成功'); console.log("智能标签同步成功");
} catch (error) { } catch (error) {
console.error('智能标签同步失败:', error); console.error("智能标签同步失败:", error);
} }
}, },
...@@ -507,7 +405,7 @@ export default { ...@@ -507,7 +405,7 @@ export default {
this.agreeStatus = res.data.agree_status; this.agreeStatus = res.data.agree_status;
} }
} catch (error) { } catch (error) {
console.error('检查用户同意状态失败:', error); console.error("检查用户同意状态失败:", error);
} }
}, },
...@@ -521,65 +419,7 @@ export default { ...@@ -521,65 +419,7 @@ export default {
this.hasPermit = res.data.has_permit; this.hasPermit = res.data.has_permit;
} }
} catch (error) { } catch (error) {
console.error('检查客服权限失败:', 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('发送评价失败');
} }
}, },
...@@ -590,18 +430,18 @@ export default { ...@@ -590,18 +430,18 @@ export default {
}, },
// 解绑确认 // 解绑确认
zyouUnBindConfirm() { zyouUnBindConfirm() {
this.$confirm('确定要解绑当前账号么?', '确认提示', { this.$confirm("确定要解绑当前账号么?", "确认提示", {
confirmButtonText: '确定', confirmButtonText: "确定",
cancelButtonText: '取消', cancelButtonText: "取消",
type: 'warning', type: "warning",
}) })
.then(() => { .then(() => {
this.zyouUnBind(); this.zyouUnBind();
}) })
.catch(() => { .catch(() => {
this.$message({ this.$message({
type: 'info', type: "info",
message: '已取消', message: "已取消",
}); });
}); });
}, },
...@@ -610,11 +450,11 @@ export default { ...@@ -610,11 +450,11 @@ export default {
member_id: this.accountSelect, member_id: this.accountSelect,
}; };
memberBindCser(data).then((res) => { memberBindCser(data).then((res) => {
console.log(res.data.cser_name, 'cser_namecser_namecser_namecser_name'); console.log(res.data.cser_name, "cser_namecser_namecser_namecser_name");
if (res.data.cser_name) { if (res.data.cser_name) {
this.$set(this.chatUserDetails, 'bind_cser', res.data.cser_name); this.$set(this.chatUserDetails, "bind_cser", res.data.cser_name);
} else { } else {
this.$set(this.chatUserDetails, 'bind_cser', ''); this.$set(this.chatUserDetails, "bind_cser", "");
} }
}); });
}, },
...@@ -638,12 +478,12 @@ export default { ...@@ -638,12 +478,12 @@ export default {
// 修改密码 之前是客服手动设置密码 现在改成系统自动设置密码 // 修改密码 之前是客服手动设置密码 现在改成系统自动设置密码
autoResetPassword() { autoResetPassword() {
this.$confirm( this.$confirm(
'确认重置密码吗?密码重置后玩家将无法登录,请谨慎操作!', "确认重置密码吗?密码重置后玩家将无法登录,请谨慎操作!",
'重置密码', "重置密码",
{ {
confirmButtonText: '确定', confirmButtonText: "确定",
cancelButtonText: '取消', cancelButtonText: "取消",
type: 'warning', type: "warning",
} }
) )
.then((res) => { .then((res) => {
...@@ -653,14 +493,14 @@ export default { ...@@ -653,14 +493,14 @@ export default {
}; };
autoResetPassword(data).then((res) => { autoResetPassword(data).then((res) => {
if (res.status_code == 1) { if (res.status_code == 1) {
this.$message.success('密码重置成功'); this.$message.success("密码重置成功");
} }
}); });
}) })
.catch(() => { .catch(() => {
this.$message({ this.$message({
type: 'info', type: "info",
message: '已取消', message: "已取消",
}); });
}); });
}, },
...@@ -681,14 +521,14 @@ export default { ...@@ -681,14 +521,14 @@ export default {
}; };
bindUserSelfAdd(params).then((res) => { bindUserSelfAdd(params).then((res) => {
if (res.status_code == 1) { if (res.status_code == 1) {
this.$set(this.chatUserDetails, 'bind_cser', 1); this.$set(this.chatUserDetails, "bind_cser", 1);
this.$message.success(res.msg); this.$message.success(res.msg);
} }
}); });
}, },
// 误操作处理 // 误操作处理
errorHandle() { errorHandle() {
this.$emit('error-handle'); this.$emit("error-handle");
}, },
// 编辑备注 // 编辑备注
editRemark() { editRemark() {
...@@ -716,7 +556,7 @@ export default { ...@@ -716,7 +556,7 @@ export default {
editUser(data).then((res) => { editUser(data).then((res) => {
if (res.status_code == 1) { if (res.status_code == 1) {
this.$message({ this.$message({
type: 'success', type: "success",
message: res.msg, message: res.msg,
}); });
} }
...@@ -728,12 +568,12 @@ export default { ...@@ -728,12 +568,12 @@ export default {
this.inputIndex = index; this.inputIndex = index;
this.showInputValue = item.value; this.showInputValue = item.value;
this.$nextTick(() => { this.$nextTick(() => {
document.querySelectorAll('input')[0].focus(); document.querySelectorAll("input")[0].focus();
}); });
}, },
// 处理自定义列输入 // 处理自定义列输入
handleInput(item, index) { handleInput(item, index) {
this.$emit('update-custom-column', { this.$emit("update-custom-column", {
item, item,
index, index,
value: this.showInputValue, value: this.showInputValue,
...@@ -797,24 +637,6 @@ export default { ...@@ -797,24 +637,6 @@ export default {
} }
} }
.cser_name {
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 { .archive-status {
margin-bottom: 15px; margin-bottom: 15px;
padding: 8px; padding: 8px;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论