Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
company_app
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
毛细亚
company_app
Commits
c8006204
提交
c8006204
authored
11月 24, 2025
作者:
施汉文
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
🌈
style: 新增关联账号样式修改
上级
a21e58e2
隐藏空白字符变更
内嵌
并排
正在显示
15 个修改的文件
包含
1821 行增加
和
1106 行删除
+1821
-1106
index.html
public/index.html
+1
-1
App.vue
src/App.vue
+60
-13
Drawer.vue
src/components/common/Drawer.vue
+70
-0
pageNum.vue
src/components/page/pageNum.vue
+38
-41
user.js
src/store/modules/user.js
+2
-0
index.vue
src/views/agentStatusManagement/index.vue
+2
-36
addUser.vue
src/views/components/bindGameAccount/addUser.vue
+510
-273
bindUserList.vue
src/views/components/bindGameAccount/bindUserList.vue
+32
-56
crossLibrary.vue
src/views/components/skill/crossLibrary.vue
+225
-141
skillCompany.vue
src/views/components/skill/skillCompany.vue
+239
-164
skillLibrary.vue
src/views/components/skill/skillLibrary.vue
+220
-137
skillPersonal.vue
src/views/components/skill/skillPersonal.vue
+243
-170
newLogin.vue
src/views/newLogin.vue
+175
-72
Info.vue
src/views/userInfo/components/Info.vue
+1
-1
tailwind.config.js
tailwind.config.js
+3
-1
没有找到文件。
public/index.html
浏览文件 @
c8006204
...
...
@@ -17,7 +17,7 @@
<!-- <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>
<!-- iconpark CDN链接 -->
<script
src=
"https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_27278_16
8.abab0e7be76224e5929cf4315f14d58c
.es5.js"
></script>
<script
src=
"https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/icons_27278_16
9.71fe6b5f95ef2c1f5cb5bd7e2398c9dd
.es5.js"
></script>
</head>
<body>
<noscript>
...
...
src/App.vue
浏览文件 @
c8006204
<
template
>
<div
id=
"app"
class=
"mobile-app-wrapper"
>
<Debug
/>
<div
class=
"mobile-content"
>
<router-view></router-view>
<div
class=
"mobile-content flex flex-col"
>
<div
class=
"!p-[10px] !min-h-auto text-[13px] text-[#131920] font-medium"
>
{{
title
}}
</div>
<!-- 绑定的 w 账号 -->
<bindUserList
class=
"!min-h-auto"
/>
<div
class=
"flex-1 w-full h-full overflow-hidden"
>
<router-view></router-view>
</div>
</div>
<div
class=
"mobile-menu-bar w-[40px] overflow-hidden"
...
...
@@ -40,8 +47,11 @@
<el-tooltip
class=
"item"
effect=
"dark"
:disabled=
"item.path !== '/agentStatusManagement'"
:content=
"'客服状态:' + csStatusInfo.text"
:content=
"
item.path === '/agentStatusManagement'
? '客服状态:' + csStatusInfo.text
: item.label
"
placement=
"left"
>
<div
...
...
@@ -63,18 +73,22 @@
</div>
<!-- 普通菜单项 -->
<!--
<span
>
{{
item
.
label
}}
</span>
-->
<
iconpark-icon
<
el-tooltip
v-else
class=
"w-[14px] h-[14px]"
:name=
"item.icon"
></iconpark-icon>
class=
"item"
effect=
"dark"
:content=
"item.label"
placement=
"left"
>
<iconpark-icon
class=
"w-[14px] h-[14px]"
:name=
"item.icon"
></iconpark-icon>
</el-tooltip>
</div>
</el-menu-item>
</el-menu>
</div>
<!-- 绑定的 w 账号 -->
<bindUserList
/>
</div>
</div>
</
template
>
...
...
@@ -85,6 +99,7 @@ import { mapState, mapMutations, mapActions } from "vuex";
import
Cookies
from
"js-cookie"
;
import
{
getParams
}
from
"@/utils/index"
;
import
Debug
from
"@/components/debug.vue"
;
import
{
getClientStatus
}
from
"@/api/user"
;
export
default
{
name
:
"App"
,
...
...
@@ -174,6 +189,7 @@ export default {
"token"
,
"userInfo"
,
"client_online_status"
,
"userid"
,
]),
...
mapState
(
"game"
,
[
"taskData"
]),
// 计算任务列表是否需要显示红点
...
...
@@ -198,6 +214,10 @@ export default {
};
return
statusMap
[
this
.
client_online_status
]
||
"未知"
;
},
title
()
{
return
this
.
menuList
.
find
((
item
)
=>
item
.
path
===
this
.
$route
.
path
)
?.
label
;
},
},
watch
:
{
"$route.path"
(
val
)
{
...
...
@@ -258,6 +278,7 @@ export default {
this
.
set_token
(
cookieToken
);
console
.
log
(
"从 Cookie 恢复 token:"
,
cookieToken
);
}
// 初始化时处理路径
const
currentPath
=
this
.
$route
.
path
;
if
(
...
...
@@ -277,6 +298,10 @@ export default {
this
.
$nextTick
(()
=>
{
this
.
checkMenuOverflow
();
this
.
initVuexValue
();
// 获取客服状态和相关信息
if
(
this
.
userid
&&
this
.
token
)
{
this
.
getInitialData
();
}
});
},
beforeDestroy
()
{
...
...
@@ -291,6 +316,7 @@ export default {
"set_cser_id"
,
"set_cser_name"
,
"set_userInfo"
,
"set_client_online_status"
,
]),
...
mapMutations
(
"game"
,
[
"set_accountSelect"
]),
...
mapActions
(
"game"
,
[
"getTaskUnReadData"
]),
...
...
@@ -320,6 +346,25 @@ export default {
handleSelect
(
key
,
keyPath
)
{
console
.
log
(
"菜单选择:"
,
key
,
keyPath
,
window
.
location
.
href
);
},
// 获取初始数据
async
getInitialData
()
{
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
;
}
this
.
set_client_online_status
(
statusRes
.
data
.
client_online_status
);
}
}
catch
(
error
)
{
console
.
error
(
"获取初始数据失败:"
,
error
);
}
},
// 检查菜单是否需要换行
checkMenuOverflow
()
{
...
...
@@ -442,8 +487,7 @@ export default {
.mobile-content
>
div
{
background
:
#fff
;
border-radius
:
8px
;
min-height
:
60vh
;
padding
:
10px
;
padding
:
10px
0px
;
}
.el-menu--horizontal
>
.el-menu-item
{
...
...
@@ -484,4 +528,7 @@ body {
align-items
:
center
;
justify-content
:
center
;
}
.p-common
{
padding
:
0
10px
;
}
</
style
>
src/components/common/Drawer.vue
0 → 100644
浏览文件 @
c8006204
<
template
>
<el-drawer
:visible=
"visible"
:title=
"title"
:size=
"size"
:append-to-body=
"true"
@
close=
"$emit('close')"
:show-close=
"false"
>
<template
#
title
>
<div
class=
"flex items-center"
>
<iconpark-icon
@
click=
"$emit('close')"
name=
"icon-fanhui"
class=
"mr-[8px] w-[20px] text-[20px] cursor-pointer"
></iconpark-icon>
<span
class=
"text-[13px] text-[#131920] leading-[13px]"
>
{{
title
}}
</span>
</div>
</
template
>
<slot></slot>
<span
class=
"dialog-footer rowFlex"
>
<slot
name=
"footer"
>
<el-button
class=
"btn"
size=
"small"
@
click=
"$emit('close')"
>
取 消
</el-button>
<el-button
class=
"btn"
type=
"primary"
size=
"small"
:disabled=
"okDisabled"
@
click=
"this.$emit('ok')"
>
确 定
</el-button>
</slot>
</span>
</el-drawer>
</template>
<
script
>
export
default
{
name
:
"Ui-Drawer"
,
props
:
[
"visible"
,
"size"
,
"title"
,
"okDisabled"
],
};
</
script
>
<
style
scoped
>
::v-deep
.el-drawer__header
{
padding
:
12px
0px
;
margin
:
0
12px
;
}
.dialog-footer
{
width
:
100%
;
position
:
absolute
;
bottom
:
0
;
padding-top
:
20px
;
padding-bottom
:
20px
;
border-top
:
0
;
justify-content
:
flex-end
;
background
:
#fff
;
z-index
:
10
;
.btn
{
width
:
60px
;
height
:
32px
;
border-radius
:
6px
;
}
}
</
style
>
src/components/page/pageNum.vue
浏览文件 @
c8006204
<
template
>
<div
class=
"newPage rowFlex allCenter"
>
<el-pagination
:total=
"Number(pageInfo.total)"
:current-page
.
sync=
"pageInfo.page"
:page-size=
"Number(pageInfo.page_size)"
background
layout=
"total,prev, pager, next, jumper"
@
current-change=
"handleCurrentChange"
>
</el-pagination>
</div>
</
template
>
<
script
type=
"text/javascript"
>
export
default
{
name
:
'pageNum'
,
props
:
[
'pageInfo'
],
data
()
{
return
{}
<div
class=
"newPage rowFlex allCenter"
>
<el-pagination
:total=
"Number(pageInfo.total)"
:current-page
.
sync=
"pageInfo.page"
:page-size=
"Number(pageInfo.page_size)"
background
layout=
"prev, pager, next"
@
current-change=
"handleCurrentChange"
>
</el-pagination>
</div>
</
template
>
<
script
type=
"text/javascript"
>
export
default
{
name
:
"pageNum"
,
props
:
[
"pageInfo"
],
data
()
{
return
{};
},
mounted
()
{},
methods
:
{
handleCurrentChange
(
newPage
)
{
this
.
pageInfo
.
page
=
newPage
;
this
.
$emit
(
"requestNextPage"
,
this
.
pageInfo
);
},
mounted
()
{
},
methods
:
{
handleCurrentChange
(
newPage
)
{
this
.
pageInfo
.
page
=
newPage
this
.
$emit
(
'requestNextPage'
,
this
.
pageInfo
)
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.newPage
{
width
:
100%
;
height
:
60px
;
background
:
#fff
;
border-radius
:
0
0
5px
5px
;
padding-bottom
:
20px
;
}
</
style
>
\ No newline at end of file
},
};
</
script
>
<
style
lang=
"scss"
scoped
>
.newPage
{
width
:
100%
;
height
:
60px
;
background
:
#fff
;
border-radius
:
0
0
5px
5px
;
padding-bottom
:
20px
;
}
</
style
>
src/store/modules/user.js
浏览文件 @
c8006204
...
...
@@ -80,6 +80,8 @@ const mutations = {
state
.
isWecomSDKReady
=
status
},
set_client_online_status
(
state
,
status
)
{
console
.
log
(
'设置客服休息状态'
,
status
);
state
.
client_online_status
=
status
}
}
...
...
src/views/agentStatusManagement/index.vue
浏览文件 @
c8006204
<
template
>
<div
class=
"p-3 h-full"
>
<div
class=
"text-[13px] text-[#131920] font-medium"
>
在线客服
</div>
<div
class=
"!p-[12px] h-full"
>
<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]"
/>
...
...
@@ -141,44 +140,11 @@ export default {
return
this
.
client_online_status
;
},
},
mounted
()
{
// 获取客服状态和相关信息
this
.
$nextTick
(()
=>
{
if
(
this
.
userid
&&
this
.
token
)
{
this
.
getInitialData
();
}
});
},
mounted
()
{},
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"
)
{
...
...
src/views/components/bindGameAccount/addUser.vue
浏览文件 @
c8006204
<
template
>
<el-drawer
title=
"新增关联账号"
:visible=
"show"
size=
"360px"
:append-to-body=
"true"
@
close=
"close"
>
<Drawer
title=
"新增关联账号"
:visible=
"show"
size=
"360px"
@
close=
"close"
:okDisabled=
"!userDetails.id"
@
ok=
"confirmSubmit"
>
<div
class=
"w-full h-full py-[10px]"
>
<div
class=
"flex items-center px-[12px]"
>
<el-input
v-model
.
trim=
"inputValue"
@
input=
"handleChange"
class=
"custom-input"
placeholder=
"请输入W账号/角色名"
>
<i
slot=
"prepend"
class=
"el-icon-search"
></i>
</el-input>
<el-popover
placement=
"bottom"
width=
"180"
trigger=
"click"
>
<div>
<div>
注游戏
</div>
<el-select
v-model=
"form.main_game_id"
filterable
remote
clearable
reserve-keyword
placeholder=
"请输入"
style=
"width: 100%"
:remote-method=
"remoteMethod"
:loading=
"loading"
@
focus=
"gameNameList = optionsList"
>
<el-option
v-for=
"item in gameNameList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
<div>
区服
</div>
<el-select
v-model
.
trim=
"form.server_info"
filterable
remote
:disabled=
"form.main_game_id == ''"
clearable
style=
"width: 100%"
reserve-keyword
placeholder=
"请先选择主游戏"
:remote-method=
"remoteMethodServer"
:loading=
"loading"
>
<el-option
v-for=
"item in serverNameList"
:key=
"item.id"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
<div
class=
"flex items-center justify-end"
>
<el-button
type=
"text"
@
click=
""
class=
"text-[#323335]"
>
重置
</el-button>
<el-button
type=
"primary"
size=
"small"
class=
"rounded-[4px] h-[24px] py-[5px] px-[12px]"
@
click=
"onSubmit"
>
查询
</el-button>
</div>
</div>
<el-button
slot=
"reference"
class=
"shrink-0 !h-[32px] !w-[32px] ml-[8px] !p-[7px]"
>
<iconpark-icon
name=
"icon-shaixuan"
class=
"text-[16px] text-[#D6D9E0]"
></iconpark-icon>
</el-button>
</el-popover>
</div>
<div
class=
"mt-[12px]"
>
<div
class=
"flex items-center p-[12px] cursor-pointer hover:bg-[#F5F6F7]"
v-for=
"item in tableList"
:key=
"item.role_id"
@
click
.
prevent=
"checkedTag(item)"
>
<el-radio
class=
"w-[15px] mr-0"
:value=
"checkoutUser.role_id"
:label=
"item.role_id"
>
{{
""
}}
</el-radio
>
<div
class=
"mx-[12px]"
>
<iconpark-icon
name=
"icon-shouqi"
class=
"text-[18px] text-[#B0B2B5]"
@
click
.
stop=
"expandTag(item)"
></iconpark-icon>
</div>
<div
class=
"flex-1"
>
<div
class=
"text-[#323335] text-[16px] font-medium"
>
{{
item
.
username
}}
</div>
<div
class=
"text-[#6D7176] text-[12px] mt-[2px]"
>
区服/角色:
{{
item
.
server_name
}}
-
{{
item
.
role_name
}}
</div>
</div>
<div>
<div
class=
"text-[#B0B2B5] text-[12px]"
>
充值金额
</div>
<div
class=
"text-[#6D7176] text-[13px] mt-[2px]"
>
{{
item
.
recharge_total
}}
</div>
</div>
</div>
</div>
</div>
<div
class=
"content"
>
<el-form
ref=
"form"
:model=
"form"
label-position=
"top"
:rules=
"rules"
label-width=
"120px"
>
<el-form
ref=
"form"
:model=
"form"
label-position=
"top"
:rules=
"rules"
label-width=
"120px"
>
<div
class=
"inputContent"
>
<el-form-item
label=
"请输入w账号"
prop=
"username"
>
<el-input
v-model
.
trim=
"form.username"
placeholder=
"请输入w账号"
class=
"input-with-select"
>
<el-input
v-model
.
trim=
"form.username"
placeholder=
"请输入w账号"
class=
"input-with-select"
>
</el-input>
</el-form-item>
<el-form-item
label=
"请输入主游戏名"
prop=
"main_game_id"
>
<el-select
v-model=
"form.main_game_id"
filterable
remote
clearable
reserve-keyword
placeholder=
"请输入主游戏名"
style=
"width: 100%;"
:remote-method=
"remoteMethod"
:loading=
"loading"
@
focus=
"gameNameList = optionsList"
>
<el-option
v-for=
"item in gameNameList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
<el-select
v-model=
"form.main_game_id"
filterable
remote
clearable
reserve-keyword
placeholder=
"请输入主游戏名"
style=
"width: 100%"
:remote-method=
"remoteMethod"
:loading=
"loading"
@
focus=
"gameNameList = optionsList"
>
<el-option
v-for=
"item in gameNameList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"请输入区服"
prop=
"server_info"
>
<el-select
v-model
.
trim=
"form.server_info"
filterable
remote
:disabled=
"form.main_game_id == ''"
clearable
style=
"width: 100%;"
reserve-keyword
placeholder=
"请先选择主游戏"
:remote-method=
"remoteMethodServer"
:loading=
"loading"
>
<el-option
v-for=
"item in serverNameList"
:key=
"item.id"
:label=
"item.label"
:value=
"item.value"
>
<el-select
v-model
.
trim=
"form.server_info"
filterable
remote
:disabled=
"form.main_game_id == ''"
clearable
style=
"width: 100%"
reserve-keyword
placeholder=
"请先选择主游戏"
:remote-method=
"remoteMethodServer"
:loading=
"loading"
>
<el-option
v-for=
"item in serverNameList"
:key=
"item.id"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"请输入角色名"
prop=
"role_name"
>
<el-input
v-model
.
trim=
"form.role_name"
placeholder=
"请输入角色"
class=
"input-with-select"
>
<el-input
v-model
.
trim=
"form.role_name"
placeholder=
"请输入角色"
class=
"input-with-select"
>
</el-input>
</el-form-item>
<el-form-item>
<el-button
type=
"primary"
size=
"small"
@
click=
"onSubmit"
>
搜索
</el-button>
<el-button
type=
"primary"
size=
"small"
@
click=
"onSubmit"
>
搜索
</el-button
>
</el-form-item>
</div>
</el-form>
<div
class=
"table account_table"
>
<div
class=
"bind-account-title"
>
账号列表
</div>
<!--
<div
class=
"table account_table"
>
<div
class=
"bind-account-title"
>
账号列表
</div>
<userTable
:list=
"tableList"
@
checkedTag=
"checkedTag"
/>
</div>
</div>
-->
<!--
<div
class=
"line"
></div>
w92865226508-->
<div
v-if=
"userDetails.username"
class=
"account_select_userInfo"
>
<div
class=
"bind-account-title"
style=
"margin-top: 20px;"
>
账号详情
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
账号
</span>
<p
class=
"text"
>
{{
userDetails
.
username
}}
</p>
<span
v-if=
"userDetails.account_type == 2"
class=
"account_type"
>
内
</span>
<div
class=
"bind-account-title"
style=
"margin-top: 20px"
>
账号详情
</div>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
账号
</span>
<p
class=
"text"
>
{{
userDetails
.
username
}}
</p>
<span
v-if=
"userDetails.account_type == 2"
class=
"account_type"
>
内
</span
>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
获客渠道
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
获客渠道
</span>
<p
class=
"text"
>
{{
userDetails
.
channel_name
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
注册渠道
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
注册渠道
</span>
<p
class=
"text"
>
{{
userDetails
.
register_channel_name
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
运营渠道
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
运营渠道
</span>
<p
class=
"text"
>
{{
userDetails
.
operator_channel_name
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
注册游戏
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
注册游戏
</span>
<p
class=
"text"
>
{{
userDetails
.
reg_game_name
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
主游戏
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
主游戏
</span>
<p
class=
"text"
>
{{
userDetails
.
main_game_name
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
真实姓名
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
真实姓名
</span>
<p
class=
"text"
>
{{
userDetails
.
real_name
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
手机号
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
手机号
</span>
<p
class=
"text"
>
{{
userDetails
.
mobile
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
染色时间
</span>
<p
class=
"text"
>
{{
moment
(
userDetails
.
seq_time
*
1000
).
format
(
'YYYY-MM-DD'
)
}}
</p>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
染色时间
</span>
<p
class=
"text"
>
{{
moment
(
userDetails
.
seq_time
*
1000
).
format
(
"YYYY-MM-DD"
)
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
注册时间
</span>
<p
class=
"text"
>
{{
moment
(
userDetails
.
reg_time
*
1000
).
format
(
'YYYY-MM-DD'
)
}}
</p>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
注册时间
</span>
<p
class=
"text"
>
{{
moment
(
userDetails
.
reg_time
*
1000
).
format
(
"YYYY-MM-DD"
)
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
登录系统
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
登录系统
</span>
<p
class=
"text"
>
{{
userDetails
.
last_login_os
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
充值金额
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
充值金额
</span>
<p
class=
"text"
>
{{
userDetails
.
recharge_total
}}
</p>
</div>
<div
class=
"item rowFlex columnCenter"
><span
class=
"label"
>
是否添加微信
</span>
<div
class=
"item rowFlex columnCenter"
>
<span
class=
"label"
>
是否添加微信
</span>
<p
class=
"text"
>
{{
userDetails
.
wechat_add_status_text
}}
</p>
</div>
</div>
</div>
<page
class=
"pageInfo"
:page-info=
"pageInfo"
@
requestNextPage=
"requestNextPage"
/>
<span
class=
"dialog-footer rowFlex"
>
<el-button
class=
"btn"
type=
"primary"
size=
"small"
:disabled=
"!userDetails.id"
@
click=
"confirmSubmit"
>
确
定
</el-button>
<page
class=
"pageInfo"
:page-info=
"pageInfo"
@
requestNextPage=
"requestNextPage"
/>
<!--
<span
class=
"dialog-footer rowFlex"
>
<el-button
class=
"btn"
type=
"primary"
size=
"small"
:disabled=
"!userDetails.id"
@
click=
"confirmSubmit"
>
确 定
</el-button
>
<el-button
class=
"btn"
size=
"small"
@
click=
"close"
>
取 消
</el-button>
</span>
</
el-d
rawer>
</span>
-->
</
D
rawer>
</
template
>
<
script
type=
"text/javascript"
>
import
moment
from
'moment'
import
userTable
from
'./userTable.vue'
import
{
getRoleHoLo
,
memberView
,
selectSearch
}
from
'@/api/game'
import
{
checkZyouBind
,
zyouBind
}
from
'@/api/works'
import
{
mapMutations
,
mapActions
,
mapState
}
from
'vuex'
import
page
from
'@/components/page/pageNum.vue'
export
default
{
name
:
'addUser'
,
components
:
{
userTable
,
page
},
props
:
[
'show'
],
data
()
{
return
{
moment
,
tableList
:
[],
checkoutUser
:
{},
userDetails
:
{},
loading
:
false
,
pageInfo
:
{
page
:
1
,
page_size
:
20
,
total
:
0
},
form
:
{
member_id
:
''
,
username
:
''
,
role_name
:
''
,
main_game_id
:
''
,
server_info
:
''
},
gameNameList
:
[],
optionsList
:
[],
serverNameList
:
[],
rules
:
{
}
import
moment
from
"moment"
;
import
userTable
from
"./userTable.vue"
;
import
{
getRoleHoLo
,
memberView
,
selectSearch
}
from
"@/api/game"
;
import
{
checkZyouBind
,
zyouBind
}
from
"@/api/works"
;
import
{
mapMutations
,
mapActions
,
mapState
}
from
"vuex"
;
import
page
from
"@/components/page/pageNum.vue"
;
import
Drawer
from
"@/components/common/Drawer.vue"
;
import
{
debounce
}
from
"@/utils/index"
;
export
default
{
name
:
"addUser"
,
components
:
{
userTable
,
page
,
Drawer
,
},
props
:
[
"show"
],
data
()
{
return
{
moment
,
inputValue
:
""
,
tableList
:
[],
checkoutUser
:
{},
userDetails
:
{},
loading
:
false
,
pageInfo
:
{
page
:
1
,
page_size
:
20
,
total
:
0
,
},
form
:
{
member_id
:
""
,
username
:
""
,
role_name
:
""
,
main_game_id
:
""
,
server_info
:
""
,
},
gameNameList
:
[],
optionsList
:
[],
serverNameList
:
[],
rules
:
{},
};
},
computed
:
{
...
mapState
(
"game"
,
[
"chatUserInfo"
,
"userid"
,
"external_userid"
]),
},
watch
:
{
show
(
newVal
,
oldVal
)
{
if
(
newVal
)
{
// this.requestRoleList()
this
.
requestGameList
();
}
},
computed
:
{
...
mapState
(
'game'
,
[
'chatUserInfo'
,
'userid'
,
'external_userid'
]),
},
watch
:
{
show
(
newVal
,
oldVal
)
{
if
(
newVal
)
{
// this.requestRoleList()
this
.
requestGameList
()
},
mounted
()
{},
methods
:
{
...
mapActions
(
"game"
,
[
"gameBindUser"
]),
...
mapMutations
(
"game"
,
[
"set_accountSelect"
]),
requestRoleList
()
{
const
data
=
{
member_id
:
this
.
form
.
member_id
,
username
:
this
.
form
.
username
.
trim
(),
role_name
:
this
.
form
.
role_name
.
trim
(),
main_game_id
:
this
.
form
.
main_game_id
!==
""
?
[
this
.
form
.
main_game_id
]
:
[],
server_info
:
this
.
form
.
server_info
!==
""
?
[
this
.
form
.
server_info
]
:
[],
search_type
:
"bind"
,
...
this
.
pageInfo
,
};
getRoleHoLo
(
data
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
if
(
res
.
data
.
data
.
length
==
0
)
{
this
.
tableList
=
[];
this
.
$message
.
warning
(
"暂无数据"
);
}
else
{
this
.
tableList
=
res
.
data
.
data
;
this
.
pageInfo
=
res
.
data
.
page_info
;
}
}
}
}
);
},
mounted
()
{
// S181.啊呸¤可瑞 八荒181服
// 分页
requestNextPage
(
pageInfo
)
{
this
.
pageInfo
.
page
=
pageInfo
.
page
;
this
.
requestRoleList
();
},
methods
:
{
...
mapActions
(
'game'
,
[
'gameBindUser'
]),
...
mapMutations
(
'game'
,
[
'set_accountSelect'
]),
requestRoleList
()
{
remoteMethodServer
(
query
)
{
if
(
query
!==
""
)
{
this
.
loading
=
true
;
const
data
=
{
member_id
:
this
.
form
.
member_id
,
username
:
this
.
form
.
username
.
trim
(),
role_name
:
this
.
form
.
role_name
.
trim
(),
main_game_id
:
this
.
form
.
main_game_id
!==
''
?
[
this
.
form
.
main_game_id
]
:
[],
server_info
:
this
.
form
.
server_info
!==
''
?
[
this
.
form
.
server_info
]
:
[],
search_type
:
'bind'
,
...
this
.
pageInfo
}
getRoleHoLo
(
data
).
then
(
res
=>
{
type
:
"server_info"
,
value
:
query
,
main_game_ids
:
this
.
form
.
main_game_id
,
};
selectSearch
(
data
).
then
((
res
)
=>
{
this
.
loading
=
false
;
if
(
res
.
status_code
==
1
)
{
if
(
res
.
data
.
data
.
length
==
0
)
{
this
.
tableList
=
[]
this
.
$message
.
warning
(
'暂无数据'
)
}
else
{
this
.
tableList
=
res
.
data
.
data
this
.
pageInfo
=
res
.
data
.
page_info
}
this
.
serverNameList
=
res
.
data
.
data
;
}
})
},
// S181.啊呸¤可瑞 八荒181服
// 分页
requestNextPage
(
pageInfo
)
{
this
.
pageInfo
.
page
=
pageInfo
.
page
this
.
requestRoleList
()
},
remoteMethodServer
(
query
)
{
if
(
query
!==
''
)
{
this
.
loading
=
true
const
data
=
{
type
:
'server_info'
,
value
:
query
,
main_game_ids
:
this
.
form
.
main_game_id
}
selectSearch
(
data
).
then
(
res
=>
{
this
.
loading
=
false
if
(
res
.
status_code
==
1
)
{
this
.
serverNameList
=
res
.
data
.
data
}
})
}
},
remoteMethod
(
query
)
{
if
(
query
!==
''
)
{
this
.
gameNameList
=
this
.
optionsList
.
filter
(
item
=>
{
return
item
.
label
.
toLowerCase
()
.
indexOf
(
query
.
toLowerCase
())
>
-
1
})
}
else
{
this
.
gameNameList
=
[]
}
},
requestGameList
()
{
const
data
=
{
type
:
'mainGameList'
,
value
:
''
,
weixin_blong_id
:
''
});
}
},
remoteMethod
(
query
)
{
if
(
query
!==
""
)
{
this
.
gameNameList
=
this
.
optionsList
.
filter
((
item
)
=>
{
return
item
.
label
.
toLowerCase
().
indexOf
(
query
.
toLowerCase
())
>
-
1
;
});
}
else
{
this
.
gameNameList
=
[];
}
},
requestGameList
()
{
const
data
=
{
type
:
"mainGameList"
,
value
:
""
,
weixin_blong_id
:
""
,
};
selectSearch
(
data
).
then
((
res
)
=>
{
this
.
loading
=
false
;
if
(
res
.
status_code
==
1
)
{
this
.
gameNameList
=
this
.
optionsList
=
res
.
data
.
data
;
}
selectSearch
(
data
).
then
(
res
=>
{
this
.
loading
=
false
if
(
res
.
status_code
==
1
)
{
this
.
gameNameList
=
this
.
optionsList
=
res
.
data
.
data
}
})
},
close
()
{
this
.
$emit
(
'update:show'
,
false
)
this
.
resizeData
()
this
.
$emit
(
'close'
)
},
onSubmit
()
{
this
.
$refs
.
form
.
validate
((
valid
)
=>
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
20
,
total
:
0
});
},
close
()
{
this
.
$emit
(
"update:show"
,
false
);
this
.
resizeData
();
this
.
$emit
(
"close"
);
},
// 防抖处理输入变化,300毫秒延迟
handleChange
:
debounce
(
function
()
{
if
(
this
.
inputValue
==
""
)
{
return
;
}
this
.
onSubmit
();
},
300
),
onSubmit
()
{
this
.
$refs
.
form
.
validate
((
valid
)
=>
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
20
,
total
:
0
,
};
if
(
valid
)
{
if
(
this
.
inputValue
==
""
)
{
this
.
$message
.
warning
(
"请输入角色名或者w账号"
);
return
;
}
if
(
valid
)
{
if
(
this
.
form
.
role_name
==
''
&&
this
.
form
.
username
==
''
)
{
this
.
$message
.
warning
(
'请输入角色名或者w账号'
)
return
}
this
.
requestRoleList
()
// 正则表达式:以w开头,后面全是数字为username,否则为role_name
if
(
/^w
\d
+$/
.
test
(
this
.
inputValue
))
{
this
.
form
.
username
=
this
.
inputValue
;
this
.
form
.
role_name
=
""
;
}
else
{
console
.
log
(
'error submit!!'
)
return
false
this
.
form
.
role_name
=
this
.
inputValue
;
this
.
form
.
username
=
""
;
}
})
},
resizeData
()
{
this
.
form
=
{
member_id
:
''
,
username
:
''
,
role_name
:
''
,
main_game_id
:
''
,
server_info
:
''
}
this
.
tableList
=
[]
this
.
checkoutUser
=
{}
this
.
userDetails
=
{}
},
confirmSubmit
()
{
const
data
=
{
member_id
:
this
.
userDetails
.
id
&&
this
.
userDetails
.
id
!=
''
?
this
.
userDetails
.
id
:
this
.
checkoutUser
.
member_id
,
username
:
this
.
userDetails
.
username
this
.
requestRoleList
();
}
else
{
console
.
log
(
"error submit!!"
);
return
false
;
}
checkZyouBind
(
data
).
then
(
res
=>
{
console
.
log
(
data
)
if
(
!
res
.
data
.
has_bind
)
{
this
.
submit
()
}
else
{
this
.
$confirm
(
res
.
data
.
tip
||
''
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
});
},
expandTag
(
item
)
{
console
.
log
(
item
);
},
resizeData
()
{
this
.
form
=
{
member_id
:
""
,
username
:
""
,
role_name
:
""
,
main_game_id
:
""
,
server_info
:
""
,
};
this
.
inputValue
=
""
;
this
.
tableList
=
[];
this
.
checkoutUser
=
{};
this
.
userDetails
=
{};
},
confirmSubmit
()
{
const
data
=
{
member_id
:
this
.
userDetails
.
id
&&
this
.
userDetails
.
id
!=
""
?
this
.
userDetails
.
id
:
this
.
checkoutUser
.
member_id
,
username
:
this
.
userDetails
.
username
,
};
checkZyouBind
(
data
).
then
((
res
)
=>
{
console
.
log
(
data
);
if
(
!
res
.
data
.
has_bind
)
{
this
.
submit
();
}
else
{
this
.
$confirm
(
res
.
data
.
tip
||
""
,
{
confirmButtonText
:
"确定"
,
cancelButtonText
:
"取消"
,
type
:
"warning"
,
})
.
then
(()
=>
{
this
.
submit
();
})
.
then
(()
=>
{
this
.
submit
()
})
.
catch
((
err
)
=>
{
console
.
log
(
err
)
this
.
$message
({
type
:
'info'
,
message
:
'已取消删除'
})
})
}
})
},
submit
()
{
const
data
=
{
userid
:
this
.
chatUserInfo
.
userid
||
this
.
userid
,
external_userid
:
this
.
chatUserInfo
.
external_userid
||
this
.
external_userid
,
member_id
:
this
.
userDetails
.
id
&&
this
.
userDetails
.
id
!=
''
?
this
.
userDetails
.
id
:
this
.
checkoutUser
.
member_id
,
username
:
this
.
userDetails
.
username
,
reg_game_id
:
this
.
userDetails
.
reg_game_id
,
main_game_id
:
this
.
userDetails
.
main_game_id
,
recharge_total
:
this
.
userDetails
.
recharge_total
,
.
catch
((
err
)
=>
{
console
.
log
(
err
);
this
.
$message
({
type
:
"info"
,
message
:
"已取消删除"
,
});
});
}
// 绑定掌游账号
zyouBind
(
data
).
then
(
res
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
updateData
()
}
})
},
// 更新列表数据
updateData
()
{
const
data
=
{
userid
:
this
.
chatUserInfo
.
userid
,
external_userid
:
this
.
chatUserInfo
.
external_userid
});
},
submit
()
{
const
data
=
{
userid
:
this
.
chatUserInfo
.
userid
||
this
.
userid
,
external_userid
:
this
.
chatUserInfo
.
external_userid
||
this
.
external_userid
,
member_id
:
this
.
userDetails
.
id
&&
this
.
userDetails
.
id
!=
""
?
this
.
userDetails
.
id
:
this
.
checkoutUser
.
member_id
,
username
:
this
.
userDetails
.
username
,
reg_game_id
:
this
.
userDetails
.
reg_game_id
,
main_game_id
:
this
.
userDetails
.
main_game_id
,
recharge_total
:
this
.
userDetails
.
recharge_total
,
};
// 绑定掌游账号
zyouBind
(
data
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
);
this
.
updateData
();
}
this
.
gameBindUser
(
data
).
then
(
res
=>
{
this
.
set_accountSelect
(
this
.
userDetails
.
id
)
this
.
close
()
})
},
// 勾选活码
checkedTag
(
value
)
{
this
.
checkoutUser
=
value
const
data
=
{
member_id
:
value
.
member_id
,
need_channel
:
1
,
need_roleInfo
:
1
});
},
// 更新列表数据
updateData
()
{
const
data
=
{
userid
:
this
.
chatUserInfo
.
userid
,
external_userid
:
this
.
chatUserInfo
.
external_userid
,
};
this
.
gameBindUser
(
data
).
then
((
res
)
=>
{
this
.
set_accountSelect
(
this
.
userDetails
.
id
);
this
.
close
();
});
},
// 勾选活码
checkedTag
(
value
)
{
console
.
log
(
1
);
this
.
checkoutUser
=
value
;
const
data
=
{
member_id
:
value
.
member_id
,
need_channel
:
1
,
need_roleInfo
:
1
,
};
this
.
rquestUserInfo
(
data
);
},
rquestUserInfo
(
data
)
{
memberView
(
data
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
userDetails
=
res
.
data
;
}
this
.
rquestUserInfo
(
data
)
},
rquestUserInfo
(
data
)
{
memberView
(
data
).
then
(
res
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
userDetails
=
res
.
data
}
})
}
}
}
</
script
>
});
},
},
};
</
script
>
<
style
lang=
"scss"
scoped
>
::v-deep
.el-drawer
{
...
...
@@ -410,7 +632,6 @@
}
}
}
}
.account_table
{
...
...
@@ -429,7 +650,7 @@
}
.pageInfo
{
width
:
calc
(
100%
-
20px
)
;
width
:
100%
;
height
:
82px
;
position
:
absolute
;
right
:
20px
;
...
...
@@ -438,7 +659,7 @@
}
.dialog-footer
{
width
:
calc
(
100%
-
20px
)
;
width
:
100%
;
position
:
absolute
;
right
:
20px
;
bottom
:
0
;
...
...
@@ -454,9 +675,26 @@
height
:
32px
;
}
}
</
style
>
<
style
>
::v-deep
.el-select-dropdown
{
min-width
:
210px
!important
;
::v-deep
.el-input-group--prepend
.el-input__inner
{
border-top-left-radius
:
4px
;
border-bottom-left-radius
:
4px
;
}
</
style
>
\ No newline at end of file
.custom-input
{
::v-deep
.el-input
{
position
:
relative
;
}
::v-deep
.el-input__inner
{
padding-left
:
34px
;
}
::v-deep
.el-input-group__prepend
{
background-color
:
transparent
;
padding
:
0
;
border
:
none
;
position
:
absolute
;
left
:
12px
;
top
:
50%
;
transform
:
translate
(
0
,
-50%
);
}
}
</
style
>
src/views/components/bindGameAccount/bindUserList.vue
浏览文件 @
c8006204
<
template
>
<div
class=
"bindUserList rowFlex columnCenter"
>
<div
class=
"bindUserList rowFlex columnCenter
!pt-0 !px-[10px]
"
>
<div
class=
"select"
>
<el-select
v-model=
"bindAccount"
placeholder=
"请选择关联账号"
:clearable=
"false"
class=
"w-[258px]"
:class=
"
{ 'show-number': bindGameUserList.length > 0 }"
:style="{ '--number': `'${bindGameUserList.length}'` }"
@change="handleChange"
>
<el-option
label=
"新增关联账号"
value=
"add"
@
click=
"addNewUser"
>
</el-option>
<
!--
<
el-option
label=
"新增关联账号"
value=
"add"
@
click=
"addNewUser"
>
</el-option>
-->
<el-option
v-for=
"(item, index) in bindGameUserList"
:key=
"index"
...
...
@@ -34,9 +37,15 @@
<
/el-option
>
<
/el-select
>
<
/div
>
<
p
v
-
if
=
"bindGameUserList.length > 0"
class
=
"num"
>
<
!--
<
p
v
-
if
=
"bindGameUserList.length > 0"
class
=
"num"
>
总共
{{
bindGameUserList
.
length
}}
个账号
<
/p
>
<
/p> --
>
<
el
-
button
icon
=
"el-icon-plus "
size
=
"small"
class
=
"!h-[32px] ml-[8px] !w-[32px] text-[16px] flex items-center justify-center"
@
click
=
"addNewUser"
><
/el-button
>
<
addUser
:
show
.
sync
=
"showLayer"
title
=
"选择玩家"
...
...
@@ -102,11 +111,7 @@ export default {
...
mapMutations
(
"user"
,
[
"set_avatar"
]),
...
mapActions
(
"game"
,
[
"gameBindUser"
]),
handleChange
(
value
)
{
if
(
value
==
"add"
)
{
this
.
showLayer
=
true
;
}
else
{
this
.
set_accountSelect
(
value
);
}
this
.
set_accountSelect
(
value
);
}
,
close
()
{
this
.
bindAccount
=
this
.
accountSelect
;
...
...
@@ -137,7 +142,7 @@ export default {
}
}
,
addNewUser
()
{
console
.
log
(
11
)
;
this
.
showLayer
=
true
;
}
,
async
requestDetails
()
{
const
data
=
{
...
...
@@ -186,53 +191,24 @@ export default {
<
/script
>
<
style
lang
=
"scss"
scoped
>
.
bindUserList
{
margin
:
10
px
;
.
select
{
::
v
-
deep
.
el
-
input
--
small
.
el
-
input__inner
{
border
-
radius
:
4
px
;
border
:
1
px
solid
#
e4e7ed
;
min
-
width
:
200
px
;
height
:
32
px
;
line
-
height
:
32
px
;
background
-
color
:
#
e8f7ff
;
color
:
#
3491
fa
;
font
-
size
:
14
px
;
&
:
hover
,
&
:
focus
{
border
-
color
:
#
3491
fa
;
}
}
::
v
-
deep
.
el
-
input__suffix
{
color
:
#
3491
fa
;
}
::
v
-
deep
.
el
-
select
-
dropdown__item
.
selected
{
color
:
#
3491
fa
;
}
}
.
num
{
.
show
-
number
::
v
-
deep
.
el
-
input
{
position
:
relative
;
&
:
after
{
display
:
flex
;
justify
-
content
:
center
;
align
-
items
:
center
;
content
:
var
(
--
number
);
height
:
20
px
;
width
:
20
px
;
font
-
size
:
12
px
;
font
-
family
:
PingFangSC
-
Regular
,
PingFang
SC
;
font
-
weight
:
600
;
margin
-
left
:
10
px
;
white
-
space
:
nowrap
;
color
:
#
f53f3f
;
}
::
v
-
deep
.
el
-
button
--
danger
{
background
-
color
:
#
f56c6c
;
border
-
color
:
#
f56c6c
;
color
:
#
267
ef0
;
background
:
#
e7f1fd
;
border
-
radius
:
50
%
;
&
:
hover
,
&
:
focus
{
background
-
color
:
#
f78989
;
border
-
color
:
#
f78989
;
}
position
:
absolute
;
top
:
50
%
;
transform
:
translateY
(
-
50
%
);
right
:
30
px
;
}
}
<
/style
>
src/views/components/skill/crossLibrary.vue
浏览文件 @
c8006204
<
template
>
<div
class=
"skillLibrary"
>
<div
v-loading=
"loading"
class=
"rowFlex skillBox"
>
<div
v-loading=
"loading"
class=
"rowFlex skillBox
pl-[10px]
"
>
<!-- 标签 -->
<el-collapse-transition>
<div
v-if=
"groupList.length > 0"
class=
"tagList columnFlex"
>
<div
v-for=
"(item, index) in groupList"
:key=
"index"
class=
"tagItem columnCenter"
:draggable=
"false"
<div
v-if=
"groupList.length > 0"
class=
"tagList columnFlex overflow-y-auto"
>
<div
v-for=
"(item, index) in groupList"
:key=
"index"
class=
"tagItem columnCenter"
:draggable=
"false"
:class=
"groupActive == item.value ? 'tagItemActiveText' : ''"
@
dragstart=
"handleDragStart($event, item, index)"
@
dragover
.
prevent=
"handleDragOver($event, item)"
@
dragenter=
"handleDragEnter($event, item, 'group')"
@
dragend=
"handleDragEnd($event, item, 'group')"
>
<div
class=
"rowFlex columnCenter spaceBetween tagItemGroup"
@
click=
"groupFilter(item, index)"
>
@
dragstart=
"handleDragStart($event, item, index)"
@
dragover
.
prevent=
"handleDragOver($event, item)"
@
dragenter=
"handleDragEnter($event, item, 'group')"
@
dragend=
"handleDragEnd($event, item, 'group')"
>
<div
class=
"rowFlex columnCenter spaceBetween tagItemGroup"
@
click=
"groupFilter(item, index)"
>
<div
class=
"rowFlex columnCenter"
>
<el-tooltip
effect=
"dark"
placement=
"top"
:content=
"item.name"
v-if=
"item.name.length >= 6"
>
<el-tooltip
effect=
"dark"
placement=
"top"
:content=
"item.name"
v-if=
"item.name.length >= 6"
>
<p
class=
"text hidden"
>
{{
item
.
name
}}
</p>
</el-tooltip>
<p
v-else
class=
"text hidden"
>
{{
item
.
name
}}
</p>
</div>
<i
class=
"el-icon-caret-right rotageIcon"
:class=
"groupActive == item.value ? 'rotage' : ''"
></i>
<i
class=
"el-icon-caret-right rotageIcon"
:class=
"groupActive == item.value ? 'rotage' : ''"
></i>
</div>
<!-- 二级分组 -->
<div
v-if=
"item.child.length > 0 && groupActive == item.value"
class=
"childGroup"
>
<div
v-for=
"child in item.child"
:key=
"child._id"
class=
"childGroupText"
:class=
"[groupActiveChild == child._id ? 'tagItemActive' : '']"
@
click
.
stop=
"groupFilterChild(child)"
>
<div
v-if=
"item.child.length > 0 && groupActive == item.value"
class=
"childGroup"
>
<div
v-for=
"child in item.child"
:key=
"child._id"
class=
"childGroupText"
:class=
"[groupActiveChild == child._id ? 'tagItemActive' : '']"
@
click
.
stop=
"groupFilterChild(child)"
>
<p
class=
"text hidden"
>
{{
child
.
name
}}
</p>
</div>
</div>
...
...
@@ -33,27 +62,67 @@
<!-- 话术 -->
<div
class=
"libraryListContent"
>
<div
class=
"inputContent"
>
<el-input
v-model=
"requestData.title"
placeholder=
"请输入话术内容"
class=
"input-with-select"
>
<el-button
slot=
"append"
icon=
"el-icon-search"
@
click=
"contentSearch"
></el-button>
<el-input
v-model=
"requestData.title"
placeholder=
"请输入话术内容"
class=
"input-with-select"
>
<el-button
slot=
"append"
icon=
"el-icon-search"
@
click=
"contentSearch"
></el-button>
</el-input>
</div>
<div
ref=
"skillLibrary"
v-loading=
"skillLoading"
@
scroll=
"paperScroll"
class=
"scrollList"
>
<div
v-for=
"(items, indexs) in groupDataList"
:key=
"indexs"
class=
"answerContent"
>
<div
class=
"question"
><span
class=
"title"
>
Q:
</span>
{{
items
.
question
}}
</div>
<div
v-for=
"(answer, answerIndex) in items.answer"
:key=
"answerIndex"
class=
"answerItem"
style=
"width: 100%"
>
<div
ref=
"skillLibrary"
v-loading=
"skillLoading"
@
scroll=
"paperScroll"
class=
"scrollList"
>
<div
v-for=
"(items, indexs) in groupDataList"
:key=
"indexs"
class=
"answerContent"
>
<div
class=
"question"
>
<span
class=
"title"
>
Q:
</span>
{{
items
.
question
}}
</div>
<div
v-for=
"(answer, answerIndex) in items.answer"
:key=
"answerIndex"
class=
"answerItem"
style=
"width: 100%"
>
<!--
<span
class=
"question"
>
{{
answerIndex
+
1
}}
:
{{
answer
}}
</span>
-->
<div
v-if=
"answer.msgtype == 'text'"
class=
"answerText rowFlex spaceBetween"
>
<div
v-if=
"answer.msgtype == 'text'"
class=
"answerText rowFlex spaceBetween"
>
<span
class=
"title rowFlex"
>
A
{{
answerIndex
+
1
}}
:
</span>
<p
v-if=
"answer.msgtype == 'text'"
class=
"rowFlex textAnswer flex1"
>
{{
answer
.
text
.
content
||
''
}}
<p
v-if=
"answer.msgtype == 'text'"
class=
"rowFlex textAnswer flex1 break-all"
>
{{
answer
.
text
.
content
||
""
}}
</p>
<i
class=
"el-icon-document-copy copyIcon rowFlex"
@
click=
"sendMessageEdit(answer, items._id)"
></i>
<i
class=
"el-icon-document-copy copyIcon rowFlex"
@
click=
"sendMessageEdit(answer, items._id)"
></i>
</div>
<div
v-else-if=
"answer.msgtype == 'image'"
class=
"answerText rowFlex"
>
<div
v-else-if=
"answer.msgtype == 'image'"
class=
"answerText rowFlex"
>
<span
class=
"title rowFlex"
>
A
{{
answerIndex
+
1
}}
:
</span>
<el-image
style=
"max-width: 200px"
:src=
"answer.image.picurl"
@
click=
"sendMessageImage(answer, items._id)"
:preview-src-list=
"[answer.image.picurl]"
>
</el-image>
<el-image
style=
"max-width: 200px"
:src=
"answer.image.picurl"
@
click=
"sendMessageImage(answer, items._id)"
:preview-src-list=
"[answer.image.picurl]"
>
</el-image>
</div>
</div>
</div>
...
...
@@ -65,26 +134,34 @@
<
script
>
// procedure_group, procedureList, procedureSort, procedureGroupSort, skillQuote,
import
{
cross_corp_robot_knowledge_group_index
,
cross_corp_robot_knowledge_group_getList
}
from
'@/api/skill'
import
{
mapState
,
mapMutations
,
mapActions
}
from
'vuex'
import
{
throttle
,
debounce
,
copyToClipboard
,
sendChatMessage
}
from
'@/utils/index'
import
noContent
from
'@/components/noContent.vue'
import
{
cross_corp_robot_knowledge_group_index
,
cross_corp_robot_knowledge_group_getList
,
}
from
"@/api/skill"
;
import
{
mapState
,
mapMutations
,
mapActions
}
from
"vuex"
;
import
{
throttle
,
debounce
,
copyToClipboard
,
sendChatMessage
,
}
from
"@/utils/index"
;
import
noContent
from
"@/components/noContent.vue"
;
export
default
{
name
:
'skillLibrary'
,
name
:
"skillLibrary"
,
components
:
{
noContent
noContent
,
},
props
:
{
activeName
:
{
default
:
''
,
type
:
String
}
default
:
""
,
type
:
String
,
}
,
},
data
()
{
return
{
collapseActive
:
''
,
groupActive
:
'0'
,
groupActiveChild
:
'0'
,
collapseActive
:
""
,
groupActive
:
"0"
,
groupActiveChild
:
"0"
,
activeGroup
:
{},
groupList
:
[],
groupLastList
:
[],
...
...
@@ -93,93 +170,93 @@ export default {
pageInfo
:
{
page
:
1
,
page_size
:
20
,
total
:
0
total
:
0
,
},
skillLoading
:
false
,
loading
:
false
,
requestData
:
{
title
:
''
,
first_group_id
:
''
,
second_group_id
:
''
title
:
""
,
first_group_id
:
""
,
second_group_id
:
""
,
},
sortType
:
''
,
sortType
:
""
,
sortID
:
{
_id
:
''
,
before_id
:
''
,
after_id
:
''
_id
:
""
,
before_id
:
""
,
after_id
:
""
,
},
filterText
:
{},
dragging
:
null
,
orderList
:
[
{
label
:
'知识库'
,
type
:
'library'
},
{
label
:
'个人话术'
,
type
:
'personal'
},
{
label
:
'企业话术'
,
type
:
'company'
}
]
}
{
label
:
"知识库"
,
type
:
"library"
},
{
label
:
"个人话术"
,
type
:
"personal"
},
{
label
:
"企业话术"
,
type
:
"company"
},
]
,
}
;
},
computed
:
{
...
mapState
(
'game'
,
[
'accountSelect'
,
'chatUserInfo'
]),
...
mapState
(
"game"
,
[
"accountSelect"
,
"chatUserInfo"
]),
},
watch
:
{
accountSelect
(
newVal
,
oldVal
)
{
if
(
newVal
&&
newVal
!==
''
)
{
if
(
newVal
&&
newVal
!==
""
)
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
20
,
total
:
0
}
total
:
0
,
}
;
}
},
activeName
(
newVal
,
oldVal
)
{
if
(
newVal
==
'library'
&&
newVal
!=
oldVal
)
{
this
.
resizeSelect
()
this
.
requestLibraryData
()
if
(
newVal
==
"library"
&&
newVal
!=
oldVal
)
{
this
.
resizeSelect
()
;
this
.
requestLibraryData
()
;
}
}
}
,
},
mounted
()
{
this
.
requestLibraryData
()
this
.
requestLibraryData
()
;
},
methods
:
{
sendMessage
:
throttle
(
function
(
item
,
id
)
{
console
.
log
(
item
,
id
)
console
.
log
(
item
,
id
)
;
// this.skillQuote(id, item.length)
},
500
),
handleDragStart
(
e
,
item
,
index
)
{
this
.
sortID
.
_id
=
item
.
_id
this
.
dragging
=
item
this
.
sortID
.
_id
=
item
.
_id
;
this
.
dragging
=
item
;
},
paperScroll
:
debounce
(
function
()
{
const
el
=
this
.
$refs
.
skillLibrary
const
el
=
this
.
$refs
.
skillLibrary
;
if
(
el
.
offsetHeight
+
el
.
scrollTop
+
10
>=
el
.
scrollHeight
)
{
console
.
log
(
'下一页'
)
this
.
pageInfo
.
page
++
this
.
searchTable
()
console
.
log
(
"下一页"
);
this
.
pageInfo
.
page
++
;
this
.
searchTable
()
;
}
},
500
),
skillQuote
(
id
,
num
)
{
const
data
=
{
type
:
this
.
activeName
,
procedure_id
:
id
,
quote_count
:
num
||
1
}
quote_count
:
num
||
1
,
}
;
skillQuote
(
data
).
then
((
res
)
=>
{
console
.
log
(
res
)
})
console
.
log
(
res
)
;
})
;
},
sortSkill
()
{
procedureSort
(
this
.
sortID
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
$message
.
success
(
res
.
msg
)
;
}
})
})
;
},
sortSkillGroup
()
{
procedureGroupSort
(
this
.
sortID
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
$message
.
success
(
res
.
msg
)
;
}
})
})
;
},
// 发送语音的时候 先编辑再发送
sendMessageEdit
(
item
,
id
)
{
...
...
@@ -189,98 +266,107 @@ export default {
item
.
text
.
content
,
(
message
)
=>
this
.
$message
.
success
(
message
),
(
message
)
=>
this
.
$message
.
error
(
message
)
)
)
;
}
this
.
sendChatMessage
(
item
.
text
.
content
||
''
,
'text'
)
this
.
sendChatMessage
(
item
.
text
.
content
||
""
,
"text"
);
},
sendMessageImage
(
item
)
{
console
.
log
(
item
,
'item'
)
this
.
sendChatMessage
(
item
.
image
.
picurl
||
''
,
'image'
)
console
.
log
(
item
,
"item"
);
this
.
sendChatMessage
(
item
.
image
.
picurl
||
""
,
"image"
);
},
contentSearch
()
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
20
,
total
:
0
}
this
.
searchTable
(
'msg'
)
total
:
0
,
}
;
this
.
searchTable
(
"msg"
);
},
// 知识库话术
requestLibraryData
()
{
console
.
log
(
this
.
chatUserInfo
,
'chatUserInfo'
)
this
.
loading
=
true
console
.
log
(
this
.
chatUserInfo
,
"chatUserInfo"
);
this
.
loading
=
true
;
const
data
=
{
page
:
1
,
page_size
:
100
,
userid
:
this
.
chatUserInfo
.
userid
}
userid
:
this
.
chatUserInfo
.
userid
,
}
;
cross_corp_robot_knowledge_group_index
(
data
).
then
((
res
)
=>
{
this
.
loading
=
false
this
.
loading
=
false
;
if
(
res
.
data
.
data
)
{
res
.
data
.
data
.
unshift
({
name
:
'全部分组'
,
value
:
''
,
child
:
[]
})
name
:
"全部分组"
,
value
:
""
,
child
:
[]
,
})
;
this
.
groupList
=
res
.
data
.
data
.
map
((
item
,
index
)
=>
{
item
.
label
=
item
.
name
item
.
value
=
item
.
_id
return
item
})
this
.
groupLastList
=
this
.
groupList
this
.
groupFilter
(
this
.
groupList
[
0
])
item
.
label
=
item
.
name
;
item
.
value
=
item
.
_id
;
return
item
;
})
;
this
.
groupLastList
=
this
.
groupList
;
this
.
groupFilter
(
this
.
groupList
[
0
])
;
}
else
{
this
.
groupList
=
[]
this
.
groupLastList
=
[]
this
.
groupList
=
[]
;
this
.
groupLastList
=
[]
;
}
})
})
;
},
groupFilter
(
item
,
index
)
{
if
(
!
item
.
_id
)
{
this
.
requestData
.
second_group_id
=
''
this
.
activeGroup
=
{}
this
.
requestData
.
second_group_id
=
""
;
this
.
activeGroup
=
{}
;
}
this
.
groupActive
=
item
.
value
item
.
child
&&
item
.
child
[
0
]
?
((
this
.
activeGroup
=
item
.
child
[
0
]),
(
this
.
groupActiveChild
=
item
.
child
[
0
].
_id
))
:
''
this
.
searchTable
()
this
.
groupActive
=
item
.
value
;
item
.
child
&&
item
.
child
[
0
]
?
((
this
.
activeGroup
=
item
.
child
[
0
]),
(
this
.
groupActiveChild
=
item
.
child
[
0
].
_id
))
:
""
;
this
.
searchTable
();
},
groupFilterChild
(
child
)
{
this
.
groupActiveChild
=
0
this
.
activeGroup
=
child
this
.
groupActiveChild
=
child
.
_id
this
.
searchTable
()
this
.
$forceUpdate
()
this
.
groupActiveChild
=
0
;
this
.
activeGroup
=
child
;
this
.
groupActiveChild
=
child
.
_id
;
this
.
searchTable
()
;
this
.
$forceUpdate
()
;
},
// 搜索结果
async
searchTable
(
msg
)
{
this
.
skillLoading
=
true
this
.
requestData
.
second_group_id
=
this
.
activeGroup
.
_id
||
''
this
.
requestData
.
title
=
this
.
requestData
.
title
.
trim
()
const
data
=
{
...
this
.
requestData
,
...
this
.
pageInfo
,
log_scan
:
msg
?
1
:
0
,
userid
:
this
.
chatUserInfo
.
userid
}
this
.
skillLoading
=
true
;
this
.
requestData
.
second_group_id
=
this
.
activeGroup
.
_id
||
""
;
this
.
requestData
.
title
=
this
.
requestData
.
title
.
trim
();
const
data
=
{
...
this
.
requestData
,
...
this
.
pageInfo
,
log_scan
:
msg
?
1
:
0
,
userid
:
this
.
chatUserInfo
.
userid
,
};
cross_corp_robot_knowledge_group_getList
(
data
).
then
((
res
)
=>
{
this
.
skillLoading
=
false
this
.
pageInfo
.
page
===
1
?
this
.
groupDataList
=
res
.
data
.
data
:
this
.
groupDataList
=
this
.
groupDataList
.
concat
(
res
.
data
.
data
)
this
.
groupLastDataList
=
this
.
groupDataList
})
this
.
skillLoading
=
false
;
this
.
pageInfo
.
page
===
1
?
(
this
.
groupDataList
=
res
.
data
.
data
)
:
(
this
.
groupDataList
=
this
.
groupDataList
.
concat
(
res
.
data
.
data
));
this
.
groupLastDataList
=
this
.
groupDataList
;
});
},
handleChange
()
{
},
handleChange
()
{},
// 重置select
resizeSelect
()
{
this
.
groupActive
=
'0'
this
.
isResize
=
true
this
.
groupDataList
=
[]
this
.
requestData
.
content
=
''
this
.
pageInfo
.
page
=
1
this
.
groupActive
=
"0"
;
this
.
isResize
=
true
;
this
.
groupDataList
=
[]
;
this
.
requestData
.
content
=
""
;
this
.
pageInfo
.
page
=
1
;
setTimeout
(()
=>
{
this
.
isResize
=
false
},
2000
)
this
.
isResize
=
false
;
},
2000
)
;
},
sendChatMessage
(
content
,
type
)
{
sendChatMessage
(
content
,
type
)
sendChatMessage
(
content
,
type
)
;
},
}
}
}
,
}
;
</
script
>
<
style
lang=
"scss"
scoped
>
.skillLibrary
{
...
...
@@ -321,7 +407,7 @@ export default {
font-size
:
14px
;
font-family
:
PingFangSC-Regular
,
PingFang
SC
;
font-weight
:
400
;
color
:
#409
EFF
;
color
:
#409
eff
;
margin-right
:
10px
;
}
...
...
@@ -457,8 +543,8 @@ export default {
.inputContent
{
width
:
100%
;
margin-bottom
:
20px
;
margin-left
:
2
0px
;
margin-left
:
1
0px
;
margin-right
:
10px
;
::v-deep
.el-input
{
width
:
90%
;
}
...
...
@@ -467,7 +553,6 @@ export default {
.skillBox
{
width
:
100%
;
height
:
calc
(
100%
-
20px
);
}
.tagList
{
...
...
@@ -513,14 +598,14 @@ export default {
}
.tagItemActive
{
color
:
#409
EFF
!important
;
color
:
#409
eff
!important
;
font-family
:
PingFangSC-Regular
,
PingFang
SC
;
font-weight
:
400
;
background
:
#e4fff1
;
}
.tagItemActiveText
{
color
:
#409
EFF
;
color
:
#409
eff
;
}
}
...
...
@@ -555,7 +640,7 @@ export default {
.scrollList
{
width
:
100%
;
height
:
100%
;
padding-left
:
2
0px
;
padding-left
:
1
0px
;
.answerContent
{
width
:
100%
;
...
...
@@ -607,7 +692,7 @@ export default {
.copyIcon
{
width
:
20px
;
color
:
#409
EFF
;
color
:
#409
eff
;
font-size
:
16px
;
position
:
relative
;
top
:
2px
;
...
...
@@ -619,7 +704,7 @@ export default {
}
.scrollList
::-webkit-scrollbar
{
display
:
none
display
:
none
;
}
.container
{
...
...
@@ -676,10 +761,10 @@ export default {
}
.skillLibrary
::-webkit-scrollbar
{
display
:
none
display
:
none
;
}
::v-deep
.el-icon-circle-close
{
color
:
#fff
;
}
</
style
>
\ No newline at end of file
</
style
>
src/views/components/skill/skillCompany.vue
浏览文件 @
c8006204
<
template
>
<div
class=
"skillTab"
>
<div
class=
"inputContent"
>
<el-input
v-model=
"requestData.content"
placeholder=
"请输入话术内容"
class=
"input-with-select"
@
change=
"contentSearch"
>
<el-input
v-model=
"requestData.content"
placeholder=
"请输入话术内容"
class=
"input-with-select"
@
change=
"contentSearch"
>
<el-button
slot=
"append"
icon=
"el-icon-search"
></el-button>
</el-input>
</div>
<div
v-loading=
"loading"
class=
"rowFlex skillBox"
>
<div
v-loading=
"loading"
class=
"rowFlex skillBox
pl-[10px]
"
>
<!-- 标签 -->
<el-collapse-transition>
<div
v-if=
"groupList.length > 0"
class=
"tagList columnFlex"
>
<div
v-for=
"(item, index) in groupList"
:key=
"index"
class=
"tagItem rowFlex columnCenter"
<div
v-for=
"(item, index) in groupList"
:key=
"index"
class=
"tagItem rowFlex columnCenter"
:draggable=
"activeName == 'personal' ? true : false"
:class=
"groupActive == item.value ? 'tagItemActive' : ''"
@
dragstart=
"handleDragStart($event, item, index)"
@
dragover
.
prevent=
"handleDragOver($event, item)"
@
dragenter=
"handleDragEnter($event, item, 'group')"
@
dragend=
"handleDragEnd($event, item, 'group')"
>
<el-tooltip
effect=
"dark"
placement=
"top"
:content=
"item.group_name"
v-if=
"item.group_name.length >= 6"
>
<p
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
group_name
}}
</p>
:class=
"groupActive == item.value ? 'tagItemActive' : ''"
@
dragstart=
"handleDragStart($event, item, index)"
@
dragover
.
prevent=
"handleDragOver($event, item)"
@
dragenter=
"handleDragEnter($event, item, 'group')"
@
dragend=
"handleDragEnd($event, item, 'group')"
>
<el-tooltip
effect=
"dark"
placement=
"top"
:content=
"item.group_name"
v-if=
"item.group_name.length >= 6"
>
<p
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
group_name
}}
</p>
</el-tooltip>
<p
v-else
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
group_name
}}
</p>
<p
v-else
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
group_name
}}
</p>
</div>
</div>
<div
v-else
>
暂无话术内容
</div>
</el-collapse-transition>
<!-- 话术 -->
<div
v-loading=
"skillLoading"
class=
"scrollList"
>
<div
v-loading=
"skillLoading"
class=
"scrollList
px-[10px]
"
>
<el-collapse
v-model=
"collapseActive"
@
change=
"handleChange"
>
<transition-group
v-if=
"groupDataList.length > 0"
tag=
"div"
class=
"container"
>
<div
v-for=
"(items, indexs) in groupDataList"
:key=
"indexs"
:draggable=
"activeName == 'personal' ? true : false"
class=
"draggable"
@
dragstart=
"handleDragStart($event, items, indexs)"
@
dragover
.
prevent=
"handleDragOver($event, items)"
@
dragenter=
"handleDragEnter($event, items, 'item')"
@
dragend=
"handleDragEnd($event, items, 'item')"
>
<transition-group
v-if=
"groupDataList.length > 0"
tag=
"div"
class=
"container"
>
<div
v-for=
"(items, indexs) in groupDataList"
:key=
"indexs"
:draggable=
"activeName == 'personal' ? true : false"
class=
"draggable"
@
dragstart=
"handleDragStart($event, items, indexs)"
@
dragover
.
prevent=
"handleDragOver($event, items)"
@
dragenter=
"handleDragEnter($event, items, 'item')"
@
dragend=
"handleDragEnd($event, items, 'item')"
>
<el-popover
placement=
"top"
width=
"300"
trigger=
"hover"
>
<p>
{{
items
.
title
}}
</p>
<div
slot=
"reference"
class=
"contentItemTitle allCenter"
:style=
"
{ top: items.title.length > 8 ? '5px' : '13px' }">
{{
items
.
title
}}
</div>
<div
slot=
"reference"
class=
"contentItemTitle allCenter"
:style=
"
{ top: items.title.length > 8 ? '5px' : '13px' }"
>
{{
items
.
title
}}
</div>
</el-popover>
<div
class=
"rowFlex titleFixed columnCenter"
>
<div
class=
"num"
>
{{
items
.
message
&&
items
.
message
.
attachments
&&
items
.
message
.
attachments
.
length
>
1
?
`+${items.message.attachments.length - 1
}
条`
:
''
}}
<
/div
>
<div
class=
"num"
>
{{
items
.
message
&&
items
.
message
.
attachments
&&
items
.
message
.
attachments
.
length
>
1
?
`+${items.message.attachments.length - 1
}
条`
:
""
}}
<
/div
>
<
/div
>
<
el
-
collapse
-
item
title
=
""
:
name
=
"items._id"
class
=
"contentItem"
>
<
div
v
-
for
=
"(i, j) in items.message.attachments"
:
key
=
"j"
>
<
div
>
<
div
v
-
if
=
"i.msgtype == 'text'"
class
=
"contentItemDetails rowFlex spaceBetween columnCenter"
>
<
div
v
-
if
=
"i.msgtype == 'text'"
class
=
"contentItemDetails rowFlex spaceBetween columnCenter"
>
<
div
class
=
"text"
>
{{
i
.
text
.
content
}}
<
/div
>
<
el
-
button
class
=
"sendButton rowFlex allCenter"
@
click
.
stop
=
"sendMessageEdit(i, items._id)"
>
发送
<
/el-button
>
<
el
-
button
class
=
"sendButton rowFlex allCenter"
@
click
.
stop
=
"sendMessageEdit(i, items._id)"
>
发送
<
/el-butto
n
>
<
/div
>
<
div
v
-
if
=
"i.msgtype == 'image'"
class
=
"contentItemDetails rowFlex spaceBetween columnCenter"
>
<
el
-
image
class
=
"image"
:
src
=
"i.image.picurl"
:
preview
-
src
-
list
=
"[i.image.picurl]"
fit
=
"contain"
><
/el-image
>
<
el
-
button
class
=
"sendButton rowFlex allCenter"
@
click
.
stop
=
"sendMessageEdit(i, items._id)"
>
发送
<
/el-button
>
<
div
v
-
if
=
"i.msgtype == 'image'"
class
=
"contentItemDetails rowFlex spaceBetween columnCenter"
>
<
el
-
image
class
=
"image"
:
src
=
"i.image.picurl"
:
preview
-
src
-
list
=
"[i.image.picurl]"
fit
=
"contain"
><
/el-image
>
<
el
-
button
class
=
"sendButton rowFlex allCenter"
@
click
.
stop
=
"sendMessageEdit(i, items._id)"
>
发送
<
/el-butto
n
>
<
/div
>
<
/div
>
<
/div
>
...
...
@@ -67,23 +124,29 @@
<
/div
>
<
/template
>
<
script
>
import
{
procedure_group
,
procedureList
,
procedureSort
,
procedureGroupSort
,
skillQuote
}
from
'@/api/skill'
import
{
mapState
,
mapMutations
,
mapActions
}
from
'vuex'
import
{
throttle
,
copyToClipboard
}
from
'@/utils/index'
import
{
getMediaId
}
from
'@/api/works'
import
{
procedure_group
,
procedureList
,
procedureSort
,
procedureGroupSort
,
skillQuote
,
}
from
"@/api/skill"
;
import
{
mapState
,
mapMutations
,
mapActions
}
from
"vuex"
;
import
{
throttle
,
copyToClipboard
}
from
"@/utils/index"
;
import
{
getMediaId
}
from
"@/api/works"
;
export
default
{
name
:
'skillCompany'
,
name
:
"skillCompany"
,
components
:
{
}
,
props
:
{
activeName
:
{
default
:
''
,
type
:
String
}
default
:
""
,
type
:
String
,
}
,
}
,
data
()
{
return
{
collapseActive
:
''
,
groupActive
:
'0'
,
collapseActive
:
""
,
groupActive
:
"0"
,
activeGroup
:
{
}
,
groupList
:
[],
groupLastList
:
[],
...
...
@@ -92,282 +155,294 @@ export default {
pageInfo
:
{
page
:
1
,
page_size
:
100
,
total
:
0
total
:
0
,
}
,
skillLoading
:
false
,
loading
:
false
,
requestData
:
{
content
:
''
,
type
:
''
,
procedure_group_id
:
''
content
:
""
,
type
:
""
,
procedure_group_id
:
""
,
}
,
sortType
:
''
,
sortType
:
""
,
sortID
:
{
_id
:
''
,
before_id
:
''
,
after_id
:
''
_id
:
""
,
before_id
:
""
,
after_id
:
""
,
}
,
filterText
:
{
}
,
dragging
:
null
,
orderList
:
[
{
label
:
'个人话术'
,
type
:
'personal'
}
,
{
label
:
'企业话术'
,
type
:
'company'
}
]
}
{
label
:
"个人话术"
,
type
:
"personal"
}
,
{
label
:
"企业话术"
,
type
:
"company"
}
,
]
,
}
;
}
,
computed
:
{
...
mapState
(
'game'
,
[
'accountSelect'
]),
...
mapState
(
"game"
,
[
"accountSelect"
]),
}
,
watch
:
{
accountSelect
(
newVal
,
oldVal
)
{
if
(
newVal
&&
newVal
!==
''
)
{
if
(
newVal
&&
newVal
!==
""
)
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
100
,
total
:
0
}
total
:
0
,
}
;
}
}
,
activeName
(
newVal
,
oldVal
)
{
if
(
newVal
==
'company'
&&
newVal
!=
oldVal
)
{
this
.
resizeSelect
()
this
.
requestGroup
()
if
(
newVal
==
"company"
&&
newVal
!=
oldVal
)
{
this
.
resizeSelect
()
;
this
.
requestGroup
()
;
}
}
}
,
}
,
mounted
()
{
// this.requestGroup()
}
,
methods
:
{
handleDragStart
(
e
,
item
,
index
)
{
this
.
sortID
.
_id
=
item
.
_id
this
.
dragging
=
item
this
.
sortID
.
_id
=
item
.
_id
;
this
.
dragging
=
item
;
}
,
skillQuote
(
id
,
num
)
{
const
data
=
{
type
:
this
.
activeName
,
procedure_id
:
id
,
quote_count
:
num
||
1
}
quote_count
:
num
||
1
,
}
;
skillQuote
(
data
).
then
((
res
)
=>
{
console
.
log
(
res
)
}
)
console
.
log
(
res
)
;
}
)
;
}
,
sortSkill
()
{
procedureSort
(
this
.
sortID
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
$message
.
success
(
res
.
msg
)
;
}
}
)
}
)
;
}
,
sortSkillGroup
()
{
procedureGroupSort
(
this
.
sortID
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
$message
.
success
(
res
.
msg
)
;
}
}
)
}
)
;
}
,
handleDragEnd
(
e
,
item
,
type
)
{
// type group 话术库排序 item 话术排序
console
.
log
(
type
,
'type'
,
this
.
sortID
)
this
.
dragging
=
null
this
.
groupLastDataList
=
this
.
groupDataList
this
.
groupLastList
=
this
.
groupList
type
===
'group'
?
this
.
sortSkillGroup
()
:
this
.
sortSkill
()
console
.
log
(
type
,
"type"
,
this
.
sortID
);
this
.
dragging
=
null
;
this
.
groupLastDataList
=
this
.
groupDataList
;
this
.
groupLastList
=
this
.
groupList
;
type
===
"group"
?
this
.
sortSkillGroup
()
:
this
.
sortSkill
();
}
,
// 首先把div变成可以放置的元素,即重写dragenter/dragover
// DataTransfer 对象用来保存,通过拖放动作,拖动到浏览器的数据。
// 如果dropEffect 属性设定为none,则不允许被拖放到目标元素中。
handleDragOver
(
e
)
{
e
.
dataTransfer
.
dropEffect
=
'move'
// e.dataTransfer.dropEffect="move";//在dragenter中针对放置目标来设置!
e
.
dataTransfer
.
dropEffect
=
"move"
;
// e.dataTransfer.dropEffect="move";//在dragenter中针对放置目标来设置!
}
,
handleDragEnter
(
e
,
item
,
type
)
{
e
.
dataTransfer
.
effectAllowed
=
'move'
// 为需要移动的元素设置dragstart事件
e
.
dataTransfer
.
effectAllowed
=
"move"
;
// 为需要移动的元素设置dragstart事件
if
(
item
===
this
.
dragging
)
{
return
return
;
}
if
(
type
===
'group'
)
{
if
(
type
===
"group"
)
{
// 话术租排序
const
newItems
=
[...
this
.
groupList
]
const
src
=
newItems
.
indexOf
(
this
.
dragging
)
const
dst
=
newItems
.
indexOf
(
item
)
const
newItems
=
[...
this
.
groupList
]
;
const
src
=
newItems
.
indexOf
(
this
.
dragging
)
;
const
dst
=
newItems
.
indexOf
(
item
)
;
if
(
src
>
dst
)
{
// 往上拖动
this
.
sortID
.
after_id
=
this
.
groupLastList
[
dst
].
_id
this
.
groupLastList
[
dst
-
1
]
?
(
this
.
sortID
.
before_id
=
this
.
groupLastList
[
dst
-
1
].
_id
)
:
(
this
.
sortID
.
before_id
=
''
)
this
.
sortID
.
after_id
=
this
.
groupLastList
[
dst
].
_id
;
this
.
groupLastList
[
dst
-
1
]
?
(
this
.
sortID
.
before_id
=
this
.
groupLastList
[
dst
-
1
].
_id
)
:
(
this
.
sortID
.
before_id
=
""
);
// 替换
}
else
{
// 往下拖动
this
.
sortID
.
before_id
=
this
.
groupLastList
[
dst
].
_id
this
.
groupLastList
[
dst
+
1
]
?
(
this
.
sortID
.
after_id
=
this
.
groupLastList
[
dst
+
1
].
_id
)
:
(
this
.
sortID
.
after_id
=
''
)
this
.
sortID
.
before_id
=
this
.
groupLastList
[
dst
].
_id
;
this
.
groupLastList
[
dst
+
1
]
?
(
this
.
sortID
.
after_id
=
this
.
groupLastList
[
dst
+
1
].
_id
)
:
(
this
.
sortID
.
after_id
=
""
);
}
// 替换
newItems
.
splice
(
dst
,
0
,
...
newItems
.
splice
(
src
,
1
))
newItems
.
splice
(
dst
,
0
,
...
newItems
.
splice
(
src
,
1
))
;
// 让item的颜色等于新交换的颜色
this
.
groupList
=
newItems
this
.
groupList
=
newItems
;
}
else
{
// 话术排序
const
newItems
=
[...
this
.
groupDataList
]
const
src
=
newItems
.
indexOf
(
this
.
dragging
)
const
dst
=
newItems
.
indexOf
(
item
)
const
newItems
=
[...
this
.
groupDataList
]
;
const
src
=
newItems
.
indexOf
(
this
.
dragging
)
;
const
dst
=
newItems
.
indexOf
(
item
)
;
if
(
src
>
dst
)
{
// 往上拖动
this
.
sortID
.
after_id
=
this
.
groupLastDataList
[
dst
].
_id
this
.
groupLastDataList
[
dst
-
1
]
?
(
this
.
sortID
.
before_id
=
this
.
groupLastDataList
[
dst
-
1
].
_id
)
:
(
this
.
sortID
.
before_id
=
''
)
this
.
sortID
.
after_id
=
this
.
groupLastDataList
[
dst
].
_id
;
this
.
groupLastDataList
[
dst
-
1
]
?
(
this
.
sortID
.
before_id
=
this
.
groupLastDataList
[
dst
-
1
].
_id
)
:
(
this
.
sortID
.
before_id
=
""
);
// 替换
}
else
{
// 往下拖动
this
.
sortID
.
before_id
=
this
.
groupLastDataList
[
dst
].
_id
this
.
groupLastDataList
[
dst
+
1
]
?
(
this
.
sortID
.
after_id
=
this
.
groupLastDataList
[
dst
+
1
].
_id
)
:
(
this
.
sortID
.
after_id
=
''
)
this
.
sortID
.
before_id
=
this
.
groupLastDataList
[
dst
].
_id
;
this
.
groupLastDataList
[
dst
+
1
]
?
(
this
.
sortID
.
after_id
=
this
.
groupLastDataList
[
dst
+
1
].
_id
)
:
(
this
.
sortID
.
after_id
=
""
);
}
newItems
.
splice
(
dst
,
0
,
...
newItems
.
splice
(
src
,
1
))
newItems
.
splice
(
dst
,
0
,
...
newItems
.
splice
(
src
,
1
))
;
// 让item的颜色等于新交换的颜色
this
.
groupDataList
=
newItems
this
.
groupDataList
=
newItems
;
}
}
,
// 发送语音的时候 先编辑再发送
// 发送语音的时候 先编辑再发送
sendMessageEdit
(
item
,
id
)
{
// 复制内容到粘贴板
if
(
item
.
msgtype
==
'text'
)
{
if
(
item
.
msgtype
==
"text"
)
{
if
(
item
&&
item
.
text
&&
item
.
text
.
content
)
{
// copyToClipboard(
// item.text.content,
// (message) => this.$message.success(message),
// (message) => this.$message.error(message)
// )
this
.
sendChatMessage
(
item
.
text
.
content
)
this
.
sendChatMessage
(
item
.
text
.
content
)
;
}
}
else
if
(
item
.
msgtype
==
'image'
&&
item
.
image
.
picurl
)
{
this
.
sendMessageImage
(
item
)
}
else
if
(
item
.
msgtype
==
"image"
&&
item
.
image
.
picurl
)
{
this
.
sendMessageImage
(
item
)
;
}
}
,
async
sendMessageImage
(
item
,
id
)
{
// 发送图片作为链接消息
if
(
item
.
image
&&
item
.
image
.
picurl
)
{
const
res
=
await
getMediaId
({
url
:
item
.
image
.
picurl
}
)
const
res
=
await
getMediaId
({
url
:
item
.
image
.
picurl
}
)
;
if
(
res
.
status_code
==
1
)
{
this
.
sendImageAsMedia
(
res
.
data
.
media_id
)
this
.
sendImageAsMedia
(
res
.
data
.
media_id
)
;
}
}
else
{
// 如果没有图片URL,提示用户
this
.
$message
.
error
(
'图片链接不存在,无法发送'
)
this
.
$message
.
error
(
"图片链接不存在,无法发送"
);
}
}
,
// 发送图片作为链接消息
sendImageAsMedia
(
media_id
)
{
this
.
$ww
.
sendChatMessage
({
msgtype
:
'image'
,
msgtype
:
"image"
,
image
:
{
mediaid
:
media_id
mediaid
:
media_id
,
}
,
success
:
(
res
)
=>
{
console
.
log
(
res
,
'发送图片链接成功'
)
this
.
$message
.
success
(
'图片发送成功'
)
console
.
log
(
res
,
"发送图片链接成功"
);
this
.
$message
.
success
(
"图片发送成功"
);
}
,
fail
:
(
err
)
=>
{
console
.
log
(
err
,
'发送图片链接失败'
)
this
.
$message
.
error
(
'图片发送失败:'
+
(
err
.
errMsg
||
err
.
message
||
'未知错误'
))
}
}
)
console
.
log
(
err
,
"发送图片链接失败"
);
this
.
$message
.
error
(
"图片发送失败:"
+
(
err
.
errMsg
||
err
.
message
||
"未知错误"
)
);
}
,
}
);
}
,
// 发送文本消息
sendChatMessage
(
text
)
{
this
.
$ww
.
sendChatMessage
({
msgtype
:
'text'
,
msgtype
:
"text"
,
text
:
{
content
:
text
content
:
text
,
}
,
success
:
(
res
)
=>
{
console
.
log
(
res
,
'发送文本成功'
)
console
.
log
(
res
,
"发送文本成功"
);
}
,
fail
:
(
err
)
=>
{
console
.
log
(
err
,
'发送文本失败'
)
}
}
)
console
.
log
(
err
,
"发送文本失败"
);
}
,
}
)
;
}
,
contentSearch
()
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
100
,
total
:
0
}
this
.
searchTable
()
total
:
0
,
}
;
this
.
searchTable
()
;
}
,
requestGroup
()
{
this
.
loading
=
true
this
.
loading
=
true
;
const
data
=
{
page
:
1
,
pageSize
:
100
,
type
:
this
.
activeName
}
type
:
this
.
activeName
,
}
;
procedure_group
(
data
).
then
((
res
)
=>
{
this
.
loading
=
false
this
.
loading
=
false
;
if
(
res
.
data
&&
res
.
data
.
data
&&
res
.
data
.
data
.
length
>
0
)
{
this
.
groupList
=
res
.
data
.
data
.
map
((
item
,
index
)
=>
{
item
.
label
=
item
.
group_name
item
.
value
=
item
.
_id
return
item
}
)
this
.
groupLastList
=
this
.
groupList
this
.
groupFilter
(
this
.
groupList
[
0
])
item
.
label
=
item
.
group_name
;
item
.
value
=
item
.
_id
;
return
item
;
}
)
;
this
.
groupLastList
=
this
.
groupList
;
this
.
groupFilter
(
this
.
groupList
[
0
])
;
}
else
{
this
.
groupList
=
[]
this
.
groupLastList
=
[]
this
.
groupList
=
[]
;
this
.
groupLastList
=
[]
;
}
}
)
}
)
;
}
,
// 62bd394d3747fe7c600a04f1
groupFilter
(
item
,
index
)
{
if
(
!
item
.
_id
)
{
this
.
requestData
.
second_group_id
=
''
this
.
activeGroup
=
{
}
this
.
requestData
.
second_group_id
=
""
;
this
.
activeGroup
=
{
}
;
}
this
.
groupActive
=
item
.
value
this
.
activeGroup
=
item
this
.
searchTable
()
this
.
groupActive
=
item
.
value
;
this
.
activeGroup
=
item
;
this
.
searchTable
()
;
}
,
// 搜索结果
async
searchTable
(
msg
)
{
this
.
skillLoading
=
true
this
.
requestData
.
type
=
this
.
activeName
this
.
requestData
.
procedure_group_id
=
this
.
activeGroup
.
_id
||
''
const
data
=
{
...
this
.
requestData
,
...
this
.
pageInfo
}
this
.
skillLoading
=
true
;
this
.
requestData
.
type
=
this
.
activeName
;
this
.
requestData
.
procedure_group_id
=
this
.
activeGroup
.
_id
||
""
;
const
data
=
{
...
this
.
requestData
,
...
this
.
pageInfo
}
;
procedureList
(
data
).
then
((
res
)
=>
{
this
.
skillLoading
=
false
this
.
groupDataList
=
res
.
data
.
data
this
.
skillLoading
=
false
;
this
.
groupDataList
=
res
.
data
.
data
;
this
.
groupDataList
.
map
((
item
,
index
)
=>
{
const
text
=
item
.
message
.
attachments
.
find
((
item
)
=>
item
.
msgtype
===
'text'
)
const
text
=
item
.
message
.
attachments
.
find
(
(
item
)
=>
item
.
msgtype
===
"text"
);
if
(
text
)
{
item
.
title
=
text
.
text
.
content
item
.
title
=
text
.
text
.
content
;
}
else
{
item
.
title
=
''
item
.
title
=
""
;
}
}
)
this
.
groupLastDataList
=
this
.
groupDataList
}
)
}
)
;
this
.
groupLastDataList
=
this
.
groupDataList
;
}
)
;
}
,
handleChange
()
{
}
,
handleChange
()
{
}
,
// 重置select
resizeSelect
()
{
this
.
groupActive
=
'0'
this
.
isResize
=
true
this
.
groupDataList
=
[]
this
.
requestData
.
content
=
''
this
.
pageInfo
.
page
=
1
this
.
groupActive
=
"0"
;
this
.
isResize
=
true
;
this
.
groupDataList
=
[]
;
this
.
requestData
.
content
=
""
;
this
.
pageInfo
.
page
=
1
;
setTimeout
(()
=>
{
this
.
isResize
=
false
}
,
2000
)
this
.
isResize
=
false
;
}
,
2000
)
;
}
,
handleClick
(
tab
,
event
)
{
// 切换table
this
.
resizeSelect
()
this
.
requestGroup
()
}
}
}
this
.
resizeSelect
()
;
this
.
requestGroup
()
;
}
,
}
,
}
;
<
/script
>
<
style
lang
=
"scss"
scoped
>
.
details
{
...
...
@@ -425,7 +500,7 @@ export default {
font
-
size
:
14
px
;
font
-
family
:
PingFangSC
-
Regular
,
PingFang
SC
;
font
-
weight
:
400
;
color
:
#
409
EFF
;
color
:
#
409
eff
;
margin
-
right
:
10
px
;
}
...
...
@@ -611,7 +686,7 @@ export default {
}
.
tagItemActive
{
color
:
#
409
EFF
;
color
:
#
409
eff
;
font
-
family
:
PingFangSC
-
Regular
,
PingFang
SC
;
font
-
weight
:
400
;
background
:
#
e4fff1
;
...
...
src/views/components/skill/skillLibrary.vue
浏览文件 @
c8006204
<
template
>
<div
class=
"skillLibrary"
>
<div
v-loading=
"loading"
class=
"rowFlex skillBox"
>
<div
v-loading=
"loading"
class=
"rowFlex skillBox
pl-[10px]
"
>
<!-- 标签 -->
<el-collapse-transition>
<div
v-if=
"groupList.length > 0"
class=
"tagList columnFlex"
>
<div
v-for=
"(item, index) in groupList"
:key=
"index"
class=
"tagItem columnCenter"
:draggable=
"false"
<div
v-for=
"(item, index) in groupList"
:key=
"index"
class=
"tagItem columnCenter"
:draggable=
"false"
:class=
"groupActive == item.value ? 'tagItemActiveText' : ''"
@
dragstart=
"handleDragStart($event, item, index)"
@
dragover
.
prevent=
"handleDragOver($event, item)"
@
dragenter=
"handleDragEnter($event, item, 'group')"
@
dragend=
"handleDragEnd($event, item, 'group')"
>
<div
class=
"rowFlex columnCenter spaceBetween tagItemGroup"
@
click=
"groupFilter(item, index)"
>
@
dragstart=
"handleDragStart($event, item, index)"
@
dragover
.
prevent=
"handleDragOver($event, item)"
@
dragenter=
"handleDragEnter($event, item, 'group')"
@
dragend=
"handleDragEnd($event, item, 'group')"
>
<div
class=
"rowFlex columnCenter spaceBetween tagItemGroup"
@
click=
"groupFilter(item, index)"
>
<div
class=
"rowFlex columnCenter"
>
<el-tooltip
effect=
"dark"
placement=
"top"
:content=
"item.name"
v-if=
"item.name.length >= 6"
>
<p
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
name
}}
</p>
<el-tooltip
effect=
"dark"
placement=
"top"
:content=
"item.name"
v-if=
"item.name.length >= 6"
>
<p
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
name
}}
</p>
</el-tooltip>
<p
v-else
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
name
}}
</p>
<p
v-else
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
name
}}
</p>
</div>
<i
class=
"el-icon-caret-right rotageIcon"
:class=
"groupActive == item.value ? 'rotage' : ''"
></i>
<i
class=
"el-icon-caret-right rotageIcon"
:class=
"groupActive == item.value ? 'rotage' : ''"
></i>
</div>
<!-- 二级分组 -->
<div
v-if=
"item.child.length > 0 && groupActive == item.value"
class=
"childGroup"
>
<div
v-for=
"child in item.child"
:key=
"child._id"
class=
"childGroupText"
:class=
"[groupActiveChild == child._id ? 'tagItemActive' : '']"
@
click
.
stop=
"groupFilterChild(child)"
>
<div
v-if=
"item.child.length > 0 && groupActive == item.value"
class=
"childGroup"
>
<div
v-for=
"child in item.child"
:key=
"child._id"
class=
"childGroupText"
:class=
"[groupActiveChild == child._id ? 'tagItemActive' : '']"
@
click
.
stop=
"groupFilterChild(child)"
>
<p
class=
"text hidden"
>
{{
child
.
name
}}
</p>
</div>
</div>
...
...
@@ -33,27 +63,67 @@
<!-- 话术 -->
<div
class=
"libraryListContent"
>
<div
class=
"inputContent"
>
<el-input
v-model=
"requestData.title"
placeholder=
"请输入话术内容"
class=
"input-with-select"
>
<el-button
slot=
"append"
icon=
"el-icon-search"
@
click=
"contentSearch"
></el-button>
<el-input
v-model=
"requestData.title"
placeholder=
"请输入话术内容"
class=
"input-with-select"
>
<el-button
slot=
"append"
icon=
"el-icon-search"
@
click=
"contentSearch"
></el-button>
</el-input>
</div>
<div
ref=
"skillLibrary"
v-loading=
"skillLoading"
@
scroll=
"paperScroll"
class=
"scrollList"
>
<div
v-for=
"(items, indexs) in groupDataList"
:key=
"indexs"
class=
"answerContent"
>
<div
class=
"question"
><span
class=
"title"
>
Q:
</span>
{{
items
.
name
}}
</div>
<div
v-for=
"(answer, answerIndex) in items.answer"
:key=
"answerIndex"
class=
"answerItem"
style=
"width: 100%"
>
<div
ref=
"skillLibrary"
v-loading=
"skillLoading"
@
scroll=
"paperScroll"
class=
"scrollList px-[10px]"
>
<div
v-for=
"(items, indexs) in groupDataList"
:key=
"indexs"
class=
"answerContent"
>
<div
class=
"question"
>
<span
class=
"title"
>
Q:
</span>
{{
items
.
name
}}
</div>
<div
v-for=
"(answer, answerIndex) in items.answer"
:key=
"answerIndex"
class=
"answerItem"
style=
"width: 100%"
>
<!--
<span
class=
"question"
>
{{
answerIndex
+
1
}}
:
{{
answer
}}
</span>
-->
<div
v-if=
"answer.msgtype == 'text'"
class=
"answerText rowFlex spaceBetween"
>
<div
v-if=
"answer.msgtype == 'text'"
class=
"answerText rowFlex spaceBetween"
>
<span
class=
"title rowFlex"
>
A
{{
answerIndex
+
1
}}
:
</span>
<p
v-if=
"answer.msgtype == 'text'"
class=
"rowFlex textAnswer flex1"
>
{{
answer
.
text
.
content
||
''
}}
<p
v-if=
"answer.msgtype == 'text'"
class=
"rowFlex textAnswer flex1"
>
{{
answer
.
text
.
content
||
""
}}
</p>
<i
class=
"el-icon-document-copy copyIcon rowFlex"
@
click=
"sendMessageEdit(answer, items._id)"
></i>
<i
class=
"el-icon-document-copy copyIcon rowFlex"
@
click=
"sendMessageEdit(answer, items._id)"
></i>
</div>
<div
v-else-if=
"answer.msgtype == 'image'"
class=
"answerText rowFlex"
>
<div
v-else-if=
"answer.msgtype == 'image'"
class=
"answerText rowFlex"
>
<span
class=
"title rowFlex"
>
A
{{
answerIndex
+
1
}}
:
</span>
<el-image
style=
"max-width: 200px"
:src=
"answer.image.picurl"
@
click=
"sendMessageImage(answer, items._id)"
:preview-src-list=
"[answer.image.picurl]"
>
</el-image>
<el-image
style=
"max-width: 200px"
:src=
"answer.image.picurl"
@
click=
"sendMessageImage(answer, items._id)"
:preview-src-list=
"[answer.image.picurl]"
>
</el-image>
</div>
</div>
</div>
...
...
@@ -65,26 +135,31 @@
<
script
>
// procedure_group, procedureList, procedureSort, procedureGroupSort, skillQuote,
import
{
groupList
,
libraryIndex
,
logClickTime
}
from
'@/api/skill'
import
{
mapState
,
mapMutations
,
mapActions
}
from
'vuex'
import
{
throttle
,
debounce
,
copyToClipboard
,
sendChatMessage
}
from
'@/utils/index'
import
noContent
from
'@/components/noContent.vue'
import
{
groupList
,
libraryIndex
,
logClickTime
}
from
"@/api/skill"
;
import
{
mapState
,
mapMutations
,
mapActions
}
from
"vuex"
;
import
{
throttle
,
debounce
,
copyToClipboard
,
sendChatMessage
,
}
from
"@/utils/index"
;
import
noContent
from
"@/components/noContent.vue"
;
export
default
{
name
:
'skillLibrary'
,
name
:
"skillLibrary"
,
components
:
{
noContent
noContent
,
},
props
:
{
activeName
:
{
default
:
''
,
type
:
String
}
default
:
""
,
type
:
String
,
}
,
},
data
()
{
return
{
collapseActive
:
''
,
groupActive
:
'0'
,
groupActiveChild
:
'0'
,
collapseActive
:
""
,
groupActive
:
"0"
,
groupActiveChild
:
"0"
,
activeGroup
:
{},
groupList
:
[],
groupLastList
:
[],
...
...
@@ -93,93 +168,93 @@ export default {
pageInfo
:
{
page
:
1
,
page_size
:
20
,
total
:
0
total
:
0
,
},
skillLoading
:
false
,
loading
:
false
,
requestData
:
{
title
:
''
,
first_group_id
:
''
,
second_group_id
:
''
title
:
""
,
first_group_id
:
""
,
second_group_id
:
""
,
},
sortType
:
''
,
sortType
:
""
,
sortID
:
{
_id
:
''
,
before_id
:
''
,
after_id
:
''
_id
:
""
,
before_id
:
""
,
after_id
:
""
,
},
filterText
:
{},
dragging
:
null
,
orderList
:
[
{
label
:
'知识库'
,
type
:
'library'
},
{
label
:
'个人话术'
,
type
:
'personal'
},
{
label
:
'企业话术'
,
type
:
'company'
}
]
}
{
label
:
"知识库"
,
type
:
"library"
},
{
label
:
"个人话术"
,
type
:
"personal"
},
{
label
:
"企业话术"
,
type
:
"company"
},
]
,
}
;
},
computed
:
{
...
mapState
(
'game'
,
[
'accountSelect'
,
'chatUserInfo'
]),
...
mapState
(
"game"
,
[
"accountSelect"
,
"chatUserInfo"
]),
},
watch
:
{
accountSelect
(
newVal
,
oldVal
)
{
if
(
newVal
&&
newVal
!==
''
)
{
if
(
newVal
&&
newVal
!==
""
)
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
20
,
total
:
0
}
total
:
0
,
}
;
}
},
activeName
(
newVal
,
oldVal
)
{
if
(
newVal
==
'library'
&&
newVal
!=
oldVal
)
{
this
.
resizeSelect
()
this
.
requestLibraryData
()
if
(
newVal
==
"library"
&&
newVal
!=
oldVal
)
{
this
.
resizeSelect
()
;
this
.
requestLibraryData
()
;
}
}
}
,
},
mounted
()
{
this
.
requestLibraryData
()
this
.
requestLibraryData
()
;
},
methods
:
{
sendMessage
:
throttle
(
function
(
item
,
id
)
{
console
.
log
(
item
,
id
)
console
.
log
(
item
,
id
)
;
// this.skillQuote(id, item.length)
},
500
),
handleDragStart
(
e
,
item
,
index
)
{
this
.
sortID
.
_id
=
item
.
_id
this
.
dragging
=
item
this
.
sortID
.
_id
=
item
.
_id
;
this
.
dragging
=
item
;
},
paperScroll
:
debounce
(
function
()
{
const
el
=
this
.
$refs
.
skillLibrary
const
el
=
this
.
$refs
.
skillLibrary
;
if
(
el
.
offsetHeight
+
el
.
scrollTop
+
10
>=
el
.
scrollHeight
)
{
console
.
log
(
'下一页'
)
this
.
pageInfo
.
page
++
this
.
searchTable
()
console
.
log
(
"下一页"
);
this
.
pageInfo
.
page
++
;
this
.
searchTable
()
;
}
},
500
),
skillQuote
(
id
,
num
)
{
const
data
=
{
type
:
this
.
activeName
,
procedure_id
:
id
,
quote_count
:
num
||
1
}
quote_count
:
num
||
1
,
}
;
skillQuote
(
data
).
then
((
res
)
=>
{
console
.
log
(
res
)
})
console
.
log
(
res
)
;
})
;
},
sortSkill
()
{
procedureSort
(
this
.
sortID
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
$message
.
success
(
res
.
msg
)
;
}
})
})
;
},
sortSkillGroup
()
{
procedureGroupSort
(
this
.
sortID
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
$message
.
success
(
res
.
msg
)
;
}
})
})
;
},
// 发送语音的时候 先编辑再发送
sendMessageEdit
(
item
,
id
)
{
...
...
@@ -189,98 +264,107 @@ export default {
item
.
text
.
content
,
(
message
)
=>
this
.
$message
.
success
(
message
),
(
message
)
=>
this
.
$message
.
error
(
message
)
)
)
;
}
this
.
sendChatMessage
(
item
.
text
.
content
||
''
,
'text'
)
this
.
sendChatMessage
(
item
.
text
.
content
||
""
,
"text"
);
},
sendMessageImage
(
item
)
{
console
.
log
(
item
,
'item'
)
this
.
sendChatMessage
(
item
.
image
.
picurl
||
''
,
'image'
)
console
.
log
(
item
,
"item"
);
this
.
sendChatMessage
(
item
.
image
.
picurl
||
""
,
"image"
);
},
contentSearch
()
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
20
,
total
:
0
}
this
.
searchTable
(
'msg'
)
total
:
0
,
}
;
this
.
searchTable
(
"msg"
);
},
// 知识库话术
requestLibraryData
()
{
console
.
log
(
this
.
chatUserInfo
,
'chatUserInfo'
)
this
.
loading
=
true
console
.
log
(
this
.
chatUserInfo
,
"chatUserInfo"
);
this
.
loading
=
true
;
const
data
=
{
page
:
1
,
page_size
:
100
,
userid
:
this
.
chatUserInfo
.
userid
}
userid
:
this
.
chatUserInfo
.
userid
,
}
;
groupList
(
data
).
then
((
res
)
=>
{
this
.
loading
=
false
this
.
loading
=
false
;
if
(
res
.
data
.
data
)
{
res
.
data
.
data
.
unshift
({
name
:
'全部分组'
,
value
:
''
,
child
:
[]
})
name
:
"全部分组"
,
value
:
""
,
child
:
[]
,
})
;
this
.
groupList
=
res
.
data
.
data
.
map
((
item
,
index
)
=>
{
item
.
label
=
item
.
name
item
.
value
=
item
.
_id
return
item
})
this
.
groupLastList
=
this
.
groupList
this
.
groupFilter
(
this
.
groupList
[
0
])
item
.
label
=
item
.
name
;
item
.
value
=
item
.
_id
;
return
item
;
})
;
this
.
groupLastList
=
this
.
groupList
;
this
.
groupFilter
(
this
.
groupList
[
0
])
;
}
else
{
this
.
groupList
=
[]
this
.
groupLastList
=
[]
this
.
groupList
=
[]
;
this
.
groupLastList
=
[]
;
}
})
})
;
},
groupFilter
(
item
,
index
)
{
if
(
!
item
.
_id
)
{
this
.
requestData
.
second_group_id
=
''
this
.
activeGroup
=
{}
this
.
requestData
.
second_group_id
=
""
;
this
.
activeGroup
=
{}
;
}
this
.
groupActive
=
item
.
value
item
.
child
&&
item
.
child
[
0
]
?
((
this
.
activeGroup
=
item
.
child
[
0
]),
(
this
.
groupActiveChild
=
item
.
child
[
0
].
_id
))
:
''
this
.
searchTable
()
this
.
groupActive
=
item
.
value
;
item
.
child
&&
item
.
child
[
0
]
?
((
this
.
activeGroup
=
item
.
child
[
0
]),
(
this
.
groupActiveChild
=
item
.
child
[
0
].
_id
))
:
""
;
this
.
searchTable
();
},
groupFilterChild
(
child
)
{
this
.
groupActiveChild
=
0
this
.
activeGroup
=
child
this
.
groupActiveChild
=
child
.
_id
this
.
searchTable
()
this
.
$forceUpdate
()
this
.
groupActiveChild
=
0
;
this
.
activeGroup
=
child
;
this
.
groupActiveChild
=
child
.
_id
;
this
.
searchTable
()
;
this
.
$forceUpdate
()
;
},
// 搜索结果
async
searchTable
(
msg
)
{
this
.
skillLoading
=
true
this
.
requestData
.
second_group_id
=
this
.
activeGroup
.
_id
||
''
this
.
requestData
.
title
=
this
.
requestData
.
title
.
trim
()
const
data
=
{
...
this
.
requestData
,
...
this
.
pageInfo
,
log_scan
:
msg
?
1
:
0
,
userid
:
this
.
chatUserInfo
.
userid
}
this
.
skillLoading
=
true
;
this
.
requestData
.
second_group_id
=
this
.
activeGroup
.
_id
||
""
;
this
.
requestData
.
title
=
this
.
requestData
.
title
.
trim
();
const
data
=
{
...
this
.
requestData
,
...
this
.
pageInfo
,
log_scan
:
msg
?
1
:
0
,
userid
:
this
.
chatUserInfo
.
userid
,
};
libraryIndex
(
data
).
then
((
res
)
=>
{
this
.
skillLoading
=
false
this
.
pageInfo
.
page
===
1
?
this
.
groupDataList
=
res
.
data
.
data
:
this
.
groupDataList
=
this
.
groupDataList
.
concat
(
res
.
data
.
data
)
this
.
groupLastDataList
=
this
.
groupDataList
})
this
.
skillLoading
=
false
;
this
.
pageInfo
.
page
===
1
?
(
this
.
groupDataList
=
res
.
data
.
data
)
:
(
this
.
groupDataList
=
this
.
groupDataList
.
concat
(
res
.
data
.
data
));
this
.
groupLastDataList
=
this
.
groupDataList
;
});
},
handleChange
()
{
},
handleChange
()
{},
// 重置select
resizeSelect
()
{
this
.
groupActive
=
'0'
this
.
isResize
=
true
this
.
groupDataList
=
[]
this
.
requestData
.
content
=
''
this
.
pageInfo
.
page
=
1
this
.
groupActive
=
"0"
;
this
.
isResize
=
true
;
this
.
groupDataList
=
[]
;
this
.
requestData
.
content
=
""
;
this
.
pageInfo
.
page
=
1
;
setTimeout
(()
=>
{
this
.
isResize
=
false
},
2000
)
this
.
isResize
=
false
;
},
2000
)
;
},
sendChatMessage
(
content
,
type
)
{
sendChatMessage
(
content
,
type
)
sendChatMessage
(
content
,
type
)
;
},
}
}
}
,
}
;
</
script
>
<
style
lang=
"scss"
scoped
>
.skillLibrary
{
...
...
@@ -321,7 +405,7 @@ export default {
font-size
:
14px
;
font-family
:
PingFangSC-Regular
,
PingFang
SC
;
font-weight
:
400
;
color
:
#409
EFF
;
color
:
#409
eff
;
margin-right
:
10px
;
}
...
...
@@ -467,7 +551,6 @@ export default {
.skillBox
{
width
:
100%
;
height
:
calc
(
100%
-
20px
);
}
.tagList
{
...
...
@@ -513,14 +596,14 @@ export default {
}
.tagItemActive
{
color
:
#409
EFF
!important
;
color
:
#409
eff
!important
;
font-family
:
PingFangSC-Regular
,
PingFang
SC
;
font-weight
:
400
;
background
:
#e4fff1
;
}
.tagItemActiveText
{
color
:
#409
EFF
;
color
:
#409
eff
;
}
}
...
...
@@ -607,7 +690,7 @@ export default {
.copyIcon
{
width
:
20px
;
color
:
#409
EFF
;
color
:
#409
eff
;
font-size
:
16px
;
position
:
relative
;
top
:
2px
;
...
...
@@ -619,7 +702,7 @@ export default {
}
.scrollList
::-webkit-scrollbar
{
display
:
none
display
:
none
;
}
.container
{
...
...
@@ -676,7 +759,7 @@ export default {
}
.skillLibrary
::-webkit-scrollbar
{
display
:
none
display
:
none
;
}
::v-deep
.el-icon-circle-close
{
...
...
src/views/components/skill/skillPersonal.vue
浏览文件 @
c8006204
<
template
>
<div
class=
"skillTab"
>
<div
class=
"inputContent"
>
<el-input
v-model=
"requestData.content"
placeholder=
"请输入话术内容"
class=
"input-with-select"
@
change=
"contentSearch"
>
<el-input
v-model=
"requestData.content"
placeholder=
"请输入话术内容"
class=
"input-with-select"
@
change=
"contentSearch"
>
<el-button
slot=
"append"
icon=
"el-icon-search"
></el-button>
</el-input>
</div>
<div
v-loading=
"loading"
class=
"rowFlex skillBox"
>
<div
v-loading=
"loading"
class=
"rowFlex skillBox
pl-[10px]
"
>
<!-- 标签 -->
<el-collapse-transition>
<div
v-if=
"groupList.length > 0"
class=
"tagList columnFlex"
>
<div
v-for=
"(item, index) in groupList"
:key=
"index"
class=
"tagItem rowFlex columnCenter"
<div
v-for=
"(item, index) in groupList"
:key=
"index"
class=
"tagItem rowFlex columnCenter"
:draggable=
"activeName == 'personal' ? true : false"
:class=
"groupActive == item.value ? 'tagItemActive' : ''"
@
dragstart=
"handleDragStart($event, item, index)"
@
dragover
.
prevent=
"handleDragOver($event, item)"
@
dragenter=
"handleDragEnter($event, item, 'group')"
@
dragend=
"handleDragEnd($event, item, 'group')"
>
<el-tooltip
effect=
"dark"
placement=
"top"
:content=
"item.group_name"
v-if=
"item.group_name.length >= 6"
>
<p
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
group_name
}}
</p>
:class=
"groupActive == item.value ? 'tagItemActive' : ''"
@
dragstart=
"handleDragStart($event, item, index)"
@
dragover
.
prevent=
"handleDragOver($event, item)"
@
dragenter=
"handleDragEnter($event, item, 'group')"
@
dragend=
"handleDragEnd($event, item, 'group')"
>
<el-tooltip
effect=
"dark"
placement=
"top"
:content=
"item.group_name"
v-if=
"item.group_name.length >= 6"
>
<p
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
group_name
}}
</p>
</el-tooltip>
<p
v-else
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
group_name
}}
</p>
<p
v-else
class=
"text hidden"
@
click=
"groupFilter(item, index)"
>
{{
item
.
group_name
}}
</p>
</div>
</div>
<div
v-else
>
暂无话术内容
</div>
</el-collapse-transition>
<!-- 话术 -->
<div
v-loading=
"skillLoading"
class=
"scrollList"
>
<div
v-loading=
"skillLoading"
class=
"scrollList
px-[10px]
"
>
<el-collapse
v-model=
"collapseActive"
@
change=
"handleChange"
>
<transition-group
v-if=
"groupDataList.length > 0"
tag=
"div"
class=
"container"
>
<div
v-for=
"(items, indexs) in groupDataList"
:key=
"indexs"
:draggable=
"activeName == 'personal' ? true : false"
class=
"draggable"
@
dragstart=
"handleDragStart($event, items, indexs)"
@
dragover
.
prevent=
"handleDragOver($event, items)"
@
dragenter=
"handleDragEnter($event, items, 'item')"
@
dragend=
"handleDragEnd($event, items, 'item')"
>
<transition-group
v-if=
"groupDataList.length > 0"
tag=
"div"
class=
"container"
>
<div
v-for=
"(items, indexs) in groupDataList"
:key=
"indexs"
:draggable=
"activeName == 'personal' ? true : false"
class=
"draggable"
@
dragstart=
"handleDragStart($event, items, indexs)"
@
dragover
.
prevent=
"handleDragOver($event, items)"
@
dragenter=
"handleDragEnter($event, items, 'item')"
@
dragend=
"handleDragEnd($event, items, 'item')"
>
<el-popover
placement=
"top"
width=
"300"
trigger=
"hover"
>
<p>
{{
items
.
title
}}
</p>
<div
slot=
"reference"
class=
"contentItemTitle allCenter"
:style=
"
{ top: items.title.length > 8 ? '5px' : '13px' }">
{{
items
.
title
}}
</div>
<div
slot=
"reference"
class=
"contentItemTitle allCenter"
:style=
"
{ top: items.title.length > 8 ? '5px' : '13px' }"
>
{{
items
.
title
}}
</div>
</el-popover>
<div
class=
"rowFlex titleFixed columnCenter"
>
<div
class=
"num"
>
{{
items
.
message
.
attachments
.
length
>
1
?
`+${items.message.attachments.length - 1
}
条`
:
''
}}
<
/div
>
<div
class=
"num"
>
{{
items
.
message
.
attachments
.
length
>
1
?
`+${items.message.attachments.length - 1
}
条`
:
""
}}
<
/div
>
<!--
<
el
-
button
class
=
"button rowFlex allCenter"
@
click
.
stop
=
"sendMessage(items.message.attachments, items._id)"
>
发送
<
/el-button> --
>
<
/div
>
<
el
-
collapse
-
item
title
=
""
:
name
=
"items._id"
class
=
"contentItem"
>
<
div
v
-
for
=
"(i, j) in items.message.attachments"
:
key
=
"j"
>
<
div
>
<
div
v
-
if
=
"i.msgtype == 'text'"
class
=
"contentItemDetails rowFlex spaceBetween columnCenter"
>
<
div
v
-
if
=
"i.msgtype == 'text'"
class
=
"contentItemDetails rowFlex spaceBetween columnCenter"
>
<
div
class
=
"text"
>
{{
i
.
text
.
content
}}
<
/div
>
<
el
-
button
class
=
"sendButton rowFlex allCenter"
@
click
.
stop
=
"sendMessageEdit(i, items._id)"
>
发送
<
/el-button
>
<
el
-
button
class
=
"sendButton rowFlex allCenter"
@
click
.
stop
=
"sendMessageEdit(i, items._id)"
>
发送
<
/el-butto
n
>
<
/div
>
<
div
v
-
if
=
"i.msgtype == 'image'"
class
=
"contentItemDetails rowFlex spaceBetween columnCenter"
>
<
el
-
image
class
=
"image"
:
src
=
"i.image.picurl"
:
preview
-
src
-
list
=
"[i.image.picurl]"
fit
=
"contain"
><
/el-image
>
<
el
-
button
class
=
"sendButton rowFlex allCenter"
@
click
.
stop
=
"sendMessageEdit(i, items._id)"
>
发送
<
/el-button
>
<
div
v
-
if
=
"i.msgtype == 'image'"
class
=
"contentItemDetails rowFlex spaceBetween columnCenter"
>
<
el
-
image
class
=
"image"
:
src
=
"i.image.picurl"
:
preview
-
src
-
list
=
"[i.image.picurl]"
fit
=
"contain"
><
/el-image
>
<
el
-
button
class
=
"sendButton rowFlex allCenter"
@
click
.
stop
=
"sendMessageEdit(i, items._id)"
>
发送
<
/el-butto
n
>
<
/div
>
<
/div
>
<
/div
>
...
...
@@ -67,23 +123,28 @@
<
/div
>
<
/template
>
<
script
>
import
{
procedure_group
,
procedureList
,
procedureSort
,
procedureGroupSort
}
from
'@/api/skill'
import
{
getMediaId
}
from
'@/api/works'
import
{
mapState
,
mapMutations
,
mapActions
}
from
'vuex'
import
{
debounce
,
copyToClipboard
}
from
'@/utils/index'
import
{
procedure_group
,
procedureList
,
procedureSort
,
procedureGroupSort
,
}
from
"@/api/skill"
;
import
{
getMediaId
}
from
"@/api/works"
;
import
{
mapState
,
mapMutations
,
mapActions
}
from
"vuex"
;
import
{
debounce
,
copyToClipboard
}
from
"@/utils/index"
;
export
default
{
name
:
'skillPersonal'
,
name
:
"skillPersonal"
,
components
:
{
}
,
props
:
{
activeName
:
{
default
:
''
,
type
:
String
}
default
:
""
,
type
:
String
,
}
,
}
,
data
()
{
return
{
collapseActive
:
''
,
groupActive
:
'0'
,
collapseActive
:
""
,
groupActive
:
"0"
,
activeGroup
:
{
}
,
groupList
:
[],
groupLastList
:
[],
...
...
@@ -92,196 +153,206 @@ export default {
pageInfo
:
{
page
:
1
,
page_size
:
100
,
total
:
0
total
:
0
,
}
,
skillLoading
:
false
,
loading
:
false
,
requestData
:
{
content
:
''
,
type
:
''
,
procedure_group_id
:
''
content
:
""
,
type
:
""
,
procedure_group_id
:
""
,
}
,
sortType
:
''
,
sortType
:
""
,
sortID
:
{
_id
:
''
,
before_id
:
''
,
after_id
:
''
_id
:
""
,
before_id
:
""
,
after_id
:
""
,
}
,
filterText
:
{
}
,
dragging
:
null
,
orderList
:
[
{
label
:
'个人话术'
,
type
:
'personal'
}
,
{
label
:
'企业话术'
,
type
:
'company'
}
]
}
{
label
:
"个人话术"
,
type
:
"personal"
}
,
{
label
:
"企业话术"
,
type
:
"company"
}
,
]
,
}
;
}
,
computed
:
{
...
mapState
(
'game'
,
[
'accountSelect'
]),
...
mapState
(
'user'
,
[
'userid'
,
'external_userid'
]),
...
mapState
(
"game"
,
[
"accountSelect"
]),
...
mapState
(
"user"
,
[
"userid"
,
"external_userid"
]),
}
,
watch
:
{
accountSelect
(
newVal
,
oldVal
)
{
if
(
newVal
&&
newVal
!==
''
)
{
if
(
newVal
&&
newVal
!==
""
)
{
this
.
pageInfo
=
{
page
:
1
,
page_size
:
100
,
total
:
0
}
total
:
0
,
}
;
}
}
,
activeName
(
newVal
,
oldVal
)
{
if
(
newVal
==
'personal'
&&
newVal
!=
oldVal
)
{
this
.
resizeSelect
()
this
.
requestGroup
()
if
(
newVal
==
"personal"
&&
newVal
!=
oldVal
)
{
this
.
resizeSelect
()
;
this
.
requestGroup
()
;
}
}
}
,
}
,
mounted
()
{
this
.
requestGroup
()
this
.
requestGroup
()
;
}
,
methods
:
{
// ...mapMutations('common', ['set_sendSkillMessage', 'set_isEditSkill']),
sendMessage
:
debounce
(
function
(
item
,
id
)
{
console
.
log
(
item
,
id
,
'sendMessage'
)
console
.
log
(
item
,
id
,
"sendMessage"
);
}
,
500
),
// 发送语音的时候 先编辑再发送
sendMessageEdit
(
item
,
id
)
{
console
.
log
(
item
)
console
.
log
(
item
)
;
// 复制内容到粘贴板
if
(
item
.
msgtype
==
'text'
)
{
if
(
item
.
msgtype
==
"text"
)
{
if
(
item
&&
item
.
text
&&
item
.
text
.
content
)
{
// copyToClipboard(
// item.text.content,
// (message) => this.$message.success(message),
// (message) => this.$message.error(message)
// )
this
.
sendChatMessage
(
item
.
text
.
content
)
this
.
sendChatMessage
(
item
.
text
.
content
)
;
}
}
else
if
(
item
.
msgtype
==
'image'
&&
item
.
image
.
picurl
)
{
this
.
sendMessageImage
(
item
)
}
else
if
(
item
.
msgtype
==
"image"
&&
item
.
image
.
picurl
)
{
this
.
sendMessageImage
(
item
)
;
}
}
,
async
sendMessageImage
(
item
,
id
)
{
// 发送图片作为链接消息
if
(
item
.
image
&&
item
.
image
.
picurl
)
{
const
res
=
await
getMediaId
({
url
:
item
.
image
.
picurl
}
)
const
res
=
await
getMediaId
({
url
:
item
.
image
.
picurl
}
)
;
if
(
res
.
status_code
==
1
)
{
this
.
sendImageAsMedia
(
res
.
data
.
media_id
)
this
.
sendImageAsMedia
(
res
.
data
.
media_id
)
;
}
}
else
{
// 如果没有图片URL,提示用户
this
.
$message
.
error
(
'图片链接不存在,无法发送'
)
this
.
$message
.
error
(
"图片链接不存在,无法发送"
);
}
}
,
// 发送图片作为链接消息
sendImageAsMedia
(
media_id
)
{
this
.
$ww
.
sendChatMessage
({
msgtype
:
'image'
,
msgtype
:
"image"
,
image
:
{
mediaid
:
media_id
mediaid
:
media_id
,
}
,
success
:
(
res
)
=>
{
console
.
log
(
res
,
'发送图片链接成功'
)
this
.
$message
.
success
(
'图片发送成功'
)
console
.
log
(
res
,
"发送图片链接成功"
);
this
.
$message
.
success
(
"图片发送成功"
);
}
,
fail
:
(
err
)
=>
{
console
.
log
(
err
,
'发送图片链接失败'
)
this
.
$message
.
error
(
'图片发送失败:'
+
(
err
.
errMsg
||
err
.
message
||
'未知错误'
))
}
}
)
console
.
log
(
err
,
"发送图片链接失败"
);
this
.
$message
.
error
(
"图片发送失败:"
+
(
err
.
errMsg
||
err
.
message
||
"未知错误"
)
);
}
,
}
);
}
,
// 发送文本消息
sendChatMessage
(
text
)
{
this
.
$ww
.
sendChatMessage
({
msgtype
:
'text'
,
msgtype
:
"text"
,
text
:
{
content
:
text
content
:
text
,
}
,
success
:
(
res
)
=>
{
console
.
log
(
res
,
'发送文本成功'
)
console
.
log
(
res
,
"发送文本成功"
);
}
,
fail
:
(
err
)
=>
{
console
.
log
(
err
,
'发送文本失败'
)
}
}
)
console
.
log
(
err
,
"发送文本失败"
);
}
,
}
)
;
}
,
handleDragStart
(
e
,
item
,
index
)
{
this
.
sortID
.
_id
=
item
.
_id
this
.
dragging
=
item
this
.
sortID
.
_id
=
item
.
_id
;
this
.
dragging
=
item
;
}
,
sortSkill
()
{
procedureSort
(
this
.
sortID
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
$message
.
success
(
res
.
msg
)
;
}
}
)
}
)
;
}
,
sortSkillGroup
()
{
if
(
this
.
sortID
.
before_id
!==
''
||
this
.
sortID
.
after_id
!==
''
)
{
if
(
this
.
sortID
.
before_id
!==
""
||
this
.
sortID
.
after_id
!==
""
)
{
procedureGroupSort
(
this
.
sortID
).
then
((
res
)
=>
{
if
(
res
.
status_code
==
1
)
{
this
.
$message
.
success
(
res
.
msg
)
this
.
$message
.
success
(
res
.
msg
)
;
}
}
)
}
)
;
}
}
,
handleDragEnd
(
e
,
item
,
type
)
{
// type group 话术库排序 item 话术排序
console
.
log
(
type
,
'type'
,
this
.
sortID
)
this
.
dragging
=
null
this
.
groupLastDataList
=
this
.
groupDataList
this
.
groupLastList
=
this
.
groupList
type
===
'group'
?
this
.
sortSkillGroup
()
:
this
.
sortSkill
()
console
.
log
(
type
,
"type"
,
this
.
sortID
);
this
.
dragging
=
null
;
this
.
groupLastDataList
=
this
.
groupDataList
;
this
.
groupLastList
=
this
.
groupList
;
type
===
"group"
?
this
.
sortSkillGroup
()
:
this
.
sortSkill
();
}
,
// 首先把div变成可以放置的元素,即重写dragenter/dragover
// DataTransfer 对象用来保存,通过拖放动作,拖动到浏览器的数据。
// 如果dropEffect 属性设定为none,则不允许被拖放到目标元素中。
handleDragOver
(
e
)
{
e
.
dataTransfer
.
dropEffect
=
'move'
// e.dataTransfer.dropEffect="move";//在dragenter中针对放置目标来设置!
e
.
dataTransfer
.
dropEffect
=
"move"
;
// e.dataTransfer.dropEffect="move";//在dragenter中针对放置目标来设置!
}
,
handleDragEnter
(
e
,
item
,
type
)
{
e
.
dataTransfer
.
effectAllowed
=
'move'
// 为需要移动的元素设置dragstart事件
e
.
dataTransfer
.
effectAllowed
=
"move"
;
// 为需要移动的元素设置dragstart事件
if
(
item
===
this
.
dragging
)
{
return
return
;
}
if
(
type
===
'group'
)
{
if
(
type
===
"group"
)
{
// 话术租排序
const
newItems
=
[...
this
.
groupList
]
const
src
=
newItems
.
indexOf
(
this
.
dragging
)
const
dst
=
newItems
.
indexOf
(
item
)
const
newItems
=
[...
this
.
groupList
]
;
const
src
=
newItems
.
indexOf
(
this
.
dragging
)
;
const
dst
=
newItems
.
indexOf
(
item
)
;
if
(
src
>
dst
)
{
// 往上拖动
this
.
sortID
.
after_id
=
this
.
groupLastList
[
dst
].
_id
this
.
groupLastList
[
dst
-
1
]
?
(
this
.
sortID
.
before_id
=
this
.
groupLastList
[
dst
-
1
].
_id
)
:
(
this
.
sortID
.
before_id
=
''
)
this
.
sortID
.
after_id
=
this
.
groupLastList
[
dst
].
_id
;
this
.
groupLastList
[
dst
-
1
]
?
(
this
.
sortID
.
before_id
=
this
.
groupLastList
[
dst
-
1
].
_id
)
:
(
this
.
sortID
.
before_id
=
""
);
// 替换
}
else
{
// 往下拖动
this
.
sortID
.
before_id
=
this
.
groupLastList
[
dst
].
_id
this
.
groupLastList
[
dst
+
1
]
?
(
this
.
sortID
.
after_id
=
this
.
groupLastList
[
dst
+
1
].
_id
)
:
(
this
.
sortID
.
after_id
=
''
)
this
.
sortID
.
before_id
=
this
.
groupLastList
[
dst
].
_id
;
this
.
groupLastList
[
dst
+
1
]
?
(
this
.
sortID
.
after_id
=
this
.
groupLastList
[
dst
+
1
].
_id
)
:
(
this
.
sortID
.
after_id
=
""
);
}
// 替换
newItems
.
splice
(
dst
,
0
,
...
newItems
.
splice
(
src
,
1
))
newItems
.
splice
(
dst
,
0
,
...
newItems
.
splice
(
src
,
1
))
;
// 让item的颜色等于新交换的颜色
this
.
groupList
=
newItems
this
.
groupList
=
newItems
;
}
else
{
// 话术排序
const
newItems
=
[...
this
.
groupDataList
]
const
src
=
newItems
.
indexOf
(
this
.
dragging
)
const
dst
=
newItems
.
indexOf
(
item
)
const
newItems
=
[...
this
.
groupDataList
]
;
const
src
=
newItems
.
indexOf
(
this
.
dragging
)
;
const
dst
=
newItems
.
indexOf
(
item
)
;
if
(
src
>
dst
)
{
// 往上拖动
this
.
sortID
.
after_id
=
this
.
groupLastDataList
[
dst
].
_id
this
.
groupLastDataList
[
dst
-
1
]
?
(
this
.
sortID
.
before_id
=
this
.
groupLastDataList
[
dst
-
1
].
_id
)
:
(
this
.
sortID
.
before_id
=
''
)
this
.
sortID
.
after_id
=
this
.
groupLastDataList
[
dst
].
_id
;
this
.
groupLastDataList
[
dst
-
1
]
?
(
this
.
sortID
.
before_id
=
this
.
groupLastDataList
[
dst
-
1
].
_id
)
:
(
this
.
sortID
.
before_id
=
""
);
// 替换
}
else
{
// 往下拖动
this
.
sortID
.
before_id
=
this
.
groupLastDataList
[
dst
].
_id
this
.
groupLastDataList
[
dst
+
1
]
?
(
this
.
sortID
.
after_id
=
this
.
groupLastDataList
[
dst
+
1
].
_id
)
:
(
this
.
sortID
.
after_id
=
''
)
this
.
sortID
.
before_id
=
this
.
groupLastDataList
[
dst
].
_id
;
this
.
groupLastDataList
[
dst
+
1
]
?
(
this
.
sortID
.
after_id
=
this
.
groupLastDataList
[
dst
+
1
].
_id
)
:
(
this
.
sortID
.
after_id
=
""
);
}
newItems
.
splice
(
dst
,
0
,
...
newItems
.
splice
(
src
,
1
))
newItems
.
splice
(
dst
,
0
,
...
newItems
.
splice
(
src
,
1
))
;
// 让item的颜色等于新交换的颜色
this
.
groupDataList
=
newItems
this
.
groupDataList
=
newItems
;
}
}
,
...
...
@@ -289,82 +360,84 @@ export default {
this
.
pageInfo
=
{
page
:
1
,
page_size
:
100
,
total
:
0
}
this
.
searchTable
()
total
:
0
,
}
;
this
.
searchTable
()
;
}
,
requestGroup
()
{
this
.
loading
=
true
this
.
loading
=
true
;
const
data
=
{
page
:
1
,
pageSize
:
100
,
type
:
this
.
activeName
}
type
:
this
.
activeName
,
}
;
procedure_group
(
data
).
then
((
res
)
=>
{
this
.
loading
=
false
this
.
loading
=
false
;
if
(
res
.
data
.
data
&&
res
.
data
.
data
.
length
>
0
)
{
this
.
groupList
=
res
.
data
.
data
.
map
((
item
,
index
)
=>
{
item
.
label
=
item
.
group_name
item
.
value
=
item
.
_id
return
item
}
)
this
.
groupLastList
=
this
.
groupList
this
.
groupFilter
(
this
.
groupList
[
0
])
item
.
label
=
item
.
group_name
;
item
.
value
=
item
.
_id
;
return
item
;
}
)
;
this
.
groupLastList
=
this
.
groupList
;
this
.
groupFilter
(
this
.
groupList
[
0
])
;
}
else
{
this
.
groupList
=
[]
this
.
groupLastList
=
[]
this
.
groupList
=
[]
;
this
.
groupLastList
=
[]
;
}
}
)
}
)
;
}
,
// 62bd394d3747fe7c600a04f1
groupFilter
(
item
,
index
)
{
if
(
!
item
.
_id
)
{
this
.
requestData
.
second_group_id
=
''
this
.
activeGroup
=
{
}
this
.
requestData
.
second_group_id
=
""
;
this
.
activeGroup
=
{
}
;
}
this
.
groupActive
=
item
.
value
this
.
activeGroup
=
item
this
.
searchTable
()
this
.
groupActive
=
item
.
value
;
this
.
activeGroup
=
item
;
this
.
searchTable
()
;
}
,
// 搜索结果
async
searchTable
(
msg
)
{
this
.
skillLoading
=
true
this
.
requestData
.
type
=
this
.
activeName
this
.
requestData
.
procedure_group_id
=
this
.
activeGroup
.
_id
||
''
const
data
=
{
...
this
.
requestData
,
...
this
.
pageInfo
}
this
.
skillLoading
=
true
;
this
.
requestData
.
type
=
this
.
activeName
;
this
.
requestData
.
procedure_group_id
=
this
.
activeGroup
.
_id
||
""
;
const
data
=
{
...
this
.
requestData
,
...
this
.
pageInfo
}
;
procedureList
(
data
).
then
((
res
)
=>
{
this
.
skillLoading
=
false
this
.
groupDataList
=
res
.
data
.
data
this
.
skillLoading
=
false
;
this
.
groupDataList
=
res
.
data
.
data
;
this
.
groupDataList
.
map
((
item
,
index
)
=>
{
const
text
=
item
.
message
.
attachments
.
find
((
item
)
=>
item
.
msgtype
===
'text'
)
const
text
=
item
.
message
.
attachments
.
find
(
(
item
)
=>
item
.
msgtype
===
"text"
);
if
(
text
)
{
item
.
title
=
text
.
text
.
content
item
.
title
=
text
.
text
.
content
;
}
else
{
item
.
title
=
''
item
.
title
=
""
;
}
}
)
this
.
groupLastDataList
=
this
.
groupDataList
}
)
}
)
;
this
.
groupLastDataList
=
this
.
groupDataList
;
}
)
;
}
,
handleChange
()
{
}
,
handleChange
()
{
}
,
// 重置select
resizeSelect
()
{
this
.
groupActive
=
'0'
this
.
isResize
=
true
this
.
groupDataList
=
[]
this
.
requestData
.
content
=
''
this
.
pageInfo
.
page
=
1
this
.
groupActive
=
"0"
;
this
.
isResize
=
true
;
this
.
groupDataList
=
[]
;
this
.
requestData
.
content
=
""
;
this
.
pageInfo
.
page
=
1
;
setTimeout
(()
=>
{
this
.
isResize
=
false
}
,
2000
)
this
.
isResize
=
false
;
}
,
2000
)
;
}
,
handleClick
(
tab
,
event
)
{
// 切换table
this
.
resizeSelect
()
this
.
requestGroup
()
}
}
}
this
.
resizeSelect
()
;
this
.
requestGroup
()
;
}
,
}
,
}
;
<
/script
>
<
style
lang
=
"scss"
scoped
>
.
details
{
...
...
@@ -422,7 +495,7 @@ export default {
font
-
size
:
14
px
;
font
-
family
:
PingFangSC
-
Regular
,
PingFang
SC
;
font
-
weight
:
400
;
color
:
#
409
EFF
;
color
:
#
409
eff
;
margin
-
right
:
10
px
;
}
...
...
@@ -608,7 +681,7 @@ export default {
}
.
tagItemActive
{
color
:
#
409
EFF
;
color
:
#
409
eff
;
font
-
family
:
PingFangSC
-
Regular
,
PingFang
SC
;
font
-
weight
:
400
;
background
:
#
e4fff1
;
...
...
@@ -682,8 +755,8 @@ export default {
}
.
el
-
input
-
group__append
{
background
-
color
:
#
3491
FA
;
border
-
color
:
#
3491
FA
;
background
-
color
:
#
3491
fa
;
border
-
color
:
#
3491
fa
;
color
:
#
fff
;
}
}
...
...
@@ -701,16 +774,16 @@ export default {
}
.
tagItemActive
{
color
:
#
3491
FA
!
important
;
background
:
#
E8F7FF
!
important
;
color
:
#
3491
fa
!
important
;
background
:
#
e8f7ff
!
important
;
font
-
weight
:
500
!
important
;
}
}
// 发送按钮样式
.
sendButton
{
background
-
color
:
#
3491
FA
!
important
;
background
-
color
:
#
3491
fa
!
important
;
color
:
white
!
important
;
border
-
color
:
#
3491
FA
!
important
;
border
-
color
:
#
3491
fa
!
important
;
}
<
/style
>
src/views/newLogin.vue
浏览文件 @
c8006204
// UnifiedLogin.vue
<
template
>
<div
class=
"loginContent"
>
<div
class=
"p-[12px] flex flex-col h-screen"
>
<div
class=
"text-[#131920] text-[13px] font-medium px-[10px]"
>
登录
</div>
<div
class=
"flex-1 flex flex-col items-center justify-center px-[29px]"
>
<div
class=
"h-[80px] w-[80px]"
>
<svg
width=
"80"
height=
"80"
viewBox=
"0 0 80 80"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<g
clip-path=
"url(#a)"
>
<mask
id=
"b"
style=
"mask-type: alpha"
maskUnits=
"userSpaceOnUse"
x=
"14"
y=
"18"
width=
"38"
height=
"47"
>
<path
d=
"M50.522 64.389H16.588a1.78 1.78 0 0 1-1.78-1.653l-.004-.122v-1.866h33.61a12 12 0 0 0 2.108 3.641m-5.1-46.355c3.616 1.646 6.15 5.237 6.25 9.428l.004.257v5.914c0 3.057-1.296 5.813-3.37 7.755-1.312 1.708-1.509 3.928-.731 5.784l-1.262-.538c-3.59-1.53-4.617-5.959-2.369-8.886a10.6 10.6 0 0 0 3.37-7.754v-5.915c0-2.195-.668-4.235-1.812-5.93z"
fill=
"#fff"
/>
</mask>
<g
mask=
"url(#b)"
>
<path
opacity=
".2"
d=
"M50.522 64.389H16.588a1.78 1.78 0 0 1-1.78-1.653l-.004-.122v-1.866h33.61a12 12 0 0 0 2.108 3.641m-5.1-46.355c3.616 1.646 6.15 5.237 6.25 9.428l.004.257v5.914c0 3.057-1.296 5.813-3.37 7.755-1.312 1.708-1.509 3.928-.731 5.784l-1.262-.538c-3.59-1.53-4.617-5.959-2.369-8.886a10.6 10.6 0 0 0 3.37-7.754v-5.915c0-2.195-.668-4.235-1.812-5.93z"
fill=
"#338cff"
/>
</g>
<path
fill-rule=
"evenodd"
clip-rule=
"evenodd"
d=
"M46.368 24.104v5.915a9.55 9.55 0 0 1-3.063 7.044l-.058.055-.048.063c-1.278 1.664-1.702 3.794-1.165 5.844a6.76 6.76 0 0 0 3.923 4.529l4.152 1.845.265.113.382-.894c-.903-.386-2.612-1.19-4.417-1.959-3.59-1.53-4.617-5.958-2.37-8.885a10.6 10.6 0 0 0 3.37-7.755v-5.915c0-5.88-4.792-10.646-10.704-10.646S25.93 18.224 25.93 24.104v5.915c0 3.076 1.31 5.848 3.409 7.791 2.208 2.928 1.173 7.323-2.4 8.846L13.35 52.449a4.73 4.73 0 0 0-2.884 4.349V59c0 .98.8 1.774 1.785 1.774h35.87v-.971h-35.87a.81.81 0 0 1-.813-.803v-2.203c0-1.506.9-2.861 2.293-3.455L27.32 47.55a6.76 6.76 0 0 0 3.916-4.5 6.73 6.73 0 0 0-1.12-5.825l-.052-.07-.064-.058a9.68 9.68 0 0 1-3.098-7.078v-5.915c0-5.334 4.366-9.673 9.733-9.673s9.733 4.34 9.733 9.673"
fill=
"#338cff"
/>
<mask
id=
"c"
style=
"mask-type: alpha"
maskUnits=
"userSpaceOnUse"
x=
"47"
y=
"46"
width=
"22"
height=
"22"
>
<path
d=
"M65.668 64.045c4.088-4.088 4.088-10.715 0-14.803-4.087-4.088-10.715-4.088-14.803 0-4.087 4.088-4.087 10.715 0 14.803 4.088 4.088 10.716 4.088 14.803 0"
fill=
"#fff"
/>
</mask>
<g
mask=
"url(#c)"
>
<path
fill-rule=
"evenodd"
clip-rule=
"evenodd"
d=
"m65.86 64.237.67-.67-15.064-15.1-.67.67z"
fill=
"#338cff"
/>
</g>
<path
d=
"M66.012 64.388c4.278-4.277 4.278-11.212 0-15.49-4.277-4.277-11.212-4.277-15.49 0-4.277 4.278-4.277 11.213 0 15.49s11.213 4.278 15.49 0Z"
stroke=
"#338cff"
stroke-width=
".963"
/>
</g>
<defs>
<clipPath
id=
"a"
><path
fill=
"#fff"
d=
"M0 0h80v80H0z"
/></clipPath>
</defs>
</svg>
</div>
<div
class=
"text-[#6D7176] text-[12px] mt-[8px] mb-[32px]"
>
暂无客服在线,请选择客服上线
</div>
<div
class=
"w-full"
>
<el-select
v-model=
"cser_user_id"
filterable
placeholder=
"请选择客服"
style=
"width: 100%"
>
<el-option
v-for=
"item in userList"
:key=
"item.zq_user_id"
clearable
:label=
"item.name"
:value=
"item.zq_user_id"
>
</el-option>
</el-select>
</div>
<div
class=
"mt-[16px] w-full mb-[228px]"
>
<el-button
type=
"primary"
size=
"small"
class=
"!w-full"
@
click=
"loginConfirm"
>
上线
</el-button
>
</div>
</div>
</div>
<!--
<div
class=
"loginContent"
>
<div
class=
"loginContentContainer"
>
<p
class=
"loginContentTitle"
>
选择客服:
</p>
<div
class=
"loginContentInput rowFlex alignCenter"
>
...
...
@@ -23,25 +126,25 @@
>
</div>
</div>
</div>
</div>
-->
</
template
>
<
script
>
import
*
as
ww
from
'@wecom/jssdk'
;
import
*
as
ww
from
"@wecom/jssdk"
;
import
{
getOrganization
,
getAuthUser
,
getSignature
,
getUserList
,
cserSelected
,
}
from
'@/api/user'
;
import
Cookies
from
'js-cookie'
;
import
{
getParams
}
from
'@/utils/index'
;
import
{
mapMutations
,
mapState
}
from
'vuex'
;
import
{
getToken
,
setToken
}
from
'@/utils/auth'
;
import
jsApiList
from
'@/utils/jsApiList'
;
}
from
"@/api/user"
;
import
Cookies
from
"js-cookie"
;
import
{
getParams
}
from
"@/utils/index"
;
import
{
mapMutations
,
mapState
}
from
"vuex"
;
import
{
getToken
,
setToken
}
from
"@/utils/auth"
;
import
jsApiList
from
"@/utils/jsApiList"
;
export
default
{
name
:
'login'
,
name
:
"login"
,
components
:
{},
data
()
{
return
{
...
...
@@ -57,10 +160,10 @@ export default {
showRefresh
:
false
,
// 控制刷新按钮显示
qrLoading
:
false
,
// 控制二维码 loading
redirectUri
:
process
.
env
.
NODE_ENV
===
'production'
?
'https://companywx.zwnet.cn/api/api/sidebar_login/ding'
:
'https://companywx.zwwlkj03.top/api/api/sidebar_login/ding'
,
DDTestUrl
:
''
,
process
.
env
.
NODE_ENV
===
"production"
?
"https://companywx.zwnet.cn/api/api/sidebar_login/ding"
:
"https://companywx.zwwlkj03.top/api/api/sidebar_login/ding"
,
DDTestUrl
:
""
,
token
:
getToken
(),
userList
:
[],
cser_user_id
:
null
,
...
...
@@ -72,23 +175,23 @@ export default {
});
},
computed
:
{
...
mapState
(
'user'
,
[
'corp_id'
]),
...
mapState
(
"user"
,
[
"corp_id"
]),
},
methods
:
{
...
mapMutations
(
'user'
,
[
'set_corp_id'
,
'set_userid'
,
'set_userInfo'
,
'set_token'
,
'set_cser_info'
,
'set_signData'
,
'set_cser_id'
,
'set_cser_name'
,
'set_external_userid'
,
...
mapMutations
(
"user"
,
[
"set_corp_id"
,
"set_userid"
,
"set_userInfo"
,
"set_token"
,
"set_cser_info"
,
"set_signData"
,
"set_cser_id"
,
"set_cser_name"
,
"set_external_userid"
,
]),
async
initLogin
()
{
const
urlParams
=
getParams
();
const
userid
=
Cookies
.
get
(
'userid'
);
const
userid
=
Cookies
.
get
(
"userid"
);
if
(
this
.
token
&&
userid
)
{
// 已经钉钉扫码过 重新获取授权 获取签名 注册企微js-sdk
this
.
getUserList
(
userid
);
...
...
@@ -101,20 +204,20 @@ export default {
},
async
getUserList
(
userid
)
{
this
.
urlParams
=
getParams
();
const
corp_id
=
Cookies
.
get
(
'corp_id'
)
||
this
.
urlParams
.
corp_id
;
const
corp_id
=
Cookies
.
get
(
"corp_id"
)
||
this
.
urlParams
.
corp_id
;
const
res
=
await
getUserList
({
userid
:
userid
,
corp_id
:
corp_id
});
this
.
userList
=
res
.
data
;
},
async
userStartLogin
()
{
if
(
!
this
.
cser_user_id
)
{
this
.
$message
.
error
(
'请选择客服人员'
);
this
.
$message
.
error
(
"请选择客服人员"
);
return
;
}
const
cser_user
=
this
.
userList
.
find
(
(
item
)
=>
item
.
zq_user_id
===
this
.
cser_user_id
);
const
corp_id
=
Cookies
.
get
(
'corp_id'
);
const
userid
=
Cookies
.
get
(
'userid'
);
const
corp_id
=
Cookies
.
get
(
"corp_id"
);
const
userid
=
Cookies
.
get
(
"userid"
);
this
.
cacheCser
(
cser_user
.
zq_user_id
,
cser_user
.
name
);
try
{
const
res
=
await
cserSelected
({
...
...
@@ -122,10 +225,10 @@ export default {
corp_id
:
corp_id
,
userid
:
userid
,
});
console
.
log
(
res
,
'选择客服人员登录'
);
console
.
log
(
res
,
"选择客服人员登录"
);
if
(
res
.
status_code
===
1
&&
res
.
data
.
tokens
)
{
this
.
$message
({
type
:
'warning'
,
type
:
"warning"
,
message
:
`当前【
${
cser_user
.
name
}
】已上线,下班后请记得点击下线哦~`
,
duration
:
3
*
1000
,
});
...
...
@@ -137,20 +240,20 @@ export default {
setTimeout
(()
=>
{
window
.
location
.
href
=
window
.
location
.
origin
+
'/company_app/index.html?corp_id='
+
"/company_app/index.html?corp_id="
+
corp_id
+
'&msg=cser_error'
;
"&msg=cser_error"
;
},
5000
);
}
}
catch
(
error
)
{
console
.
log
(
error
,
'选择客服人员登录失败'
);
console
.
log
(
error
,
"选择客服人员登录失败"
);
this
.
$message
.
error
(
error
.
msg
);
setTimeout
(()
=>
{
window
.
location
.
href
=
window
.
location
.
origin
+
'/company_app/index.html?corp_id='
+
"/company_app/index.html?corp_id="
+
corp_id
+
'&msg=cser_error'
;
"&msg=cser_error"
;
},
5000
);
}
},
...
...
@@ -160,32 +263,32 @@ export default {
);
this
.
$confirm
(
`确认登录上线吗,上线后所有会话都会归属到客服【
${
cser_user
.
name
}
】`
,
'提示'
,
"提示"
,
{
confirmButtonText
:
'确定'
,
cancelButtonText
:
'取消'
,
type
:
'warning'
,
confirmButtonText
:
"确定"
,
cancelButtonText
:
"取消"
,
type
:
"warning"
,
}
)
.
then
(()
=>
{
this
.
userStartLogin
();
})
.
catch
(()
=>
{
this
.
$message
.
info
(
'已取消登录'
);
this
.
$message
.
info
(
"已取消登录"
);
});
},
// 设置缓存
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
);
},
cacheuserid
(
userid
)
{
Cookies
.
set
(
'userid'
,
userid
,
{
expires
:
30
});
Cookies
.
set
(
"userid"
,
userid
,
{
expires
:
30
});
this
.
set_userid
(
userid
);
},
cacheCser
(
cser_id
,
cser_name
)
{
Cookies
.
set
(
'cser_id'
,
cser_id
,
{
expires
:
30
});
Cookies
.
set
(
'cser_name'
,
cser_name
,
{
expires
:
30
});
Cookies
.
set
(
"cser_id"
,
cser_id
,
{
expires
:
30
});
Cookies
.
set
(
"cser_name"
,
cser_name
,
{
expires
:
30
});
this
.
set_cser_info
({
cser_id
:
cser_id
,
cser_name
:
cser_name
,
...
...
@@ -194,16 +297,16 @@ export default {
this
.
set_cser_name
(
cser_name
);
},
cacheSignData
(
signData
)
{
Cookies
.
set
(
'signData'
,
JSON
.
stringify
(
signData
),
{
expires
:
30
});
Cookies
.
set
(
"signData"
,
JSON
.
stringify
(
signData
),
{
expires
:
30
});
this
.
set_signData
(
signData
);
},
// 进入的页面地址是 https://companywx.jianshuwenhua.com/company_app/index.html?corp_id=wweaefe716636df3d1
// 1. 企微静默授权
async
startWeComSilentAuth
()
{
this
.
urlParams
=
getParams
();
const
corp_id
=
Cookies
.
get
(
'corp_id'
)
||
this
.
urlParams
.
corp_id
;
const
corp_id
=
Cookies
.
get
(
"corp_id"
)
||
this
.
urlParams
.
corp_id
;
if
(
!
corp_id
)
{
this
.
$message
.
error
(
'当前客服号信息异常,请切换会话后重试'
);
this
.
$message
.
error
(
"当前客服号信息异常,请切换会话后重试"
);
return
;
}
// 确定是第一次进入页面 没有 code 和 state
...
...
@@ -225,17 +328,17 @@ export default {
this
.
cacheuserid
(
res
.
data
.
userid
);
this
.
getUserList
(
res
.
data
.
userid
);
}
else
{
this
.
$message
.
error
(
'获取用户id失败'
);
this
.
$message
.
error
(
"获取用户id失败"
);
return
;
}
}
else
{
console
.
log
(
'获取useid失败'
,
res
);
console
.
log
(
"获取useid失败"
,
res
);
// 错误处理
}
},
async
getSignature
()
{
console
.
log
(
'获取签名'
,
window
.
location
.
href
);
const
corp_id
=
Cookies
.
get
(
'corp_id'
);
console
.
log
(
"获取签名"
,
window
.
location
.
href
);
const
corp_id
=
Cookies
.
get
(
"corp_id"
);
try
{
const
res
=
await
getSignature
({
corp_id
:
corp_id
,
...
...
@@ -247,42 +350,42 @@ export default {
try
{
this
.
registerWeComSDK
();
}
catch
(
err
)
{
console
.
log
(
err
,
'初始化sdk 失败'
);
console
.
log
(
err
,
"初始化sdk 失败"
);
}
}
}
catch
(
err
)
{
console
.
log
(
err
,
'获取签名失败'
);
console
.
log
(
err
,
"获取签名失败"
);
window
.
location
.
href
=
window
.
location
.
origin
+
'/company_app/index.html?corp_id='
+
"/company_app/index.html?corp_id="
+
corp_id
+
'&msg=signerror'
;
"&msg=signerror"
;
}
},
getCurExternalContact
()
{
this
.
$ww
.
getCurExternalContact
({
success
:
(
res
)
=>
{
if
(
res
.
err_msg
===
'getCurExternalContact:ok'
)
{
console
.
log
(
res
,
'重新进入获取企微外部联系人'
);
if
(
res
.
err_msg
===
"getCurExternalContact:ok"
)
{
console
.
log
(
res
,
"重新进入获取企微外部联系人"
);
this
.
set_external_userid
(
res
.
userId
);
// 确保 Vuex 状态更新后再跳转
this
.
$nextTick
(()
=>
{
this
.
$router
.
replace
(
'/'
);
console
.
log
(
window
.
location
.
href
,
'window.location.hrefuserInfo'
);
this
.
$router
.
replace
(
"/"
);
console
.
log
(
window
.
location
.
href
,
"window.location.hrefuserInfo"
);
});
}
},
fail
:
(
err
)
=>
{
console
.
log
(
err
,
'获取企微外部联系人失败'
);
console
.
log
(
err
,
"获取企微外部联系人失败"
);
// 错误处理
},
});
},
// 2. 注册企微JS-SDK
registerWeComSDK
()
{
console
.
log
(
'删除企业签名'
,
1231
);
console
.
log
(
"删除企业签名"
,
1231
);
this
.
$ww
.
register
({
corpId
:
Cookies
.
get
(
'corp_id'
),
corpId
:
Cookies
.
get
(
"corp_id"
),
agentId
:
this
.
signData
.
agent_id
,
jsApiList
:
jsApiList
,
// getConfigSignature: () => Promise.resolve({
...
...
@@ -298,12 +401,12 @@ export default {
signature
:
this
.
signData
.
agent_signature
,
}),
onAgentConfigSuccess
:
(
res
)
=>
{
console
.
log
(
'注册成功可以调用企微 js-sdk'
,
res
);
console
.
log
(
"注册成功可以调用企微 js-sdk"
,
res
);
// 注册成功后不立即获取外部联系人,等钉钉扫码后再获取
this
.
getCurExternalContact
();
},
onAgentConfigFail
:
(
err
)
=>
{
console
.
log
(
'注册失败不能使用企微js-sdk'
,
err
);
console
.
log
(
"注册失败不能使用企微js-sdk"
,
err
);
// 错误处理123
},
});
...
...
@@ -322,15 +425,15 @@ export default {
},
initCurrentApp
()
{
const
currentApp
=
this
.
orgList
.
find
(
(
item
)
=>
item
.
app_key
===
'dingjigp0ksn9nbljdli'
(
item
)
=>
item
.
app_key
===
"dingjigp0ksn9nbljdli"
);
this
.
$set
(
this
,
'currentOrg'
,
currentApp
);
this
.
$set
(
this
,
"currentOrg"
,
currentApp
);
},
// 7. 钉钉扫码回调页面处理
async
handleDingCallback
(
token
)
{
// 在这里处理钉钉扫码成功的回调
const
corp_id
=
Cookies
.
get
(
'corp_id'
);
if
(
token
&&
token
!=
'undefined'
)
{
const
corp_id
=
Cookies
.
get
(
"corp_id"
);
if
(
token
&&
token
!=
"undefined"
)
{
setToken
(
token
);
this
.
set_token
(
token
);
// 获取签名
...
...
@@ -338,9 +441,9 @@ export default {
}
else
{
window
.
location
.
href
=
window
.
location
.
origin
+
'/company_app/index.html?corp_id='
+
"/company_app/index.html?corp_id="
+
corp_id
+
'&msg=notoken'
;
"&msg=notoken"
;
}
},
},
...
...
src/views/userInfo/components/Info.vue
浏览文件 @
c8006204
<
template
>
<div
class=
"info-tab-content"
>
<div
class=
"userDetailsPanel columnFlex"
>
<div
class=
"content"
v-loading=
"viewLoading"
>
<div
class=
"content
px-[10px]
"
v-loading=
"viewLoading"
>
<div
v-if=
"chatUserDetails.is_phishing_account == 1"
class=
"warnText"
>
<p>
高风险玩家,请立即通知组长!!!!
</p>
<p>
...
...
tailwind.config.js
浏览文件 @
c8006204
...
...
@@ -11,7 +11,9 @@ module.exports = {
purge
:
[
'./index.html'
,
'./src/**/*.{vue,js,ts,jsx,tsx}'
],
darkMode
:
false
,
theme
:
{
extend
:
{}
extend
:
{
}
},
variants
:
{
extend
:
{}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论