Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
杨树贤
/
kefu_server
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
e0bab0ee
authored
Mar 27, 2020
by
chenxianqi
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
update code
parent
b5c1cfa1
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
227 additions
and
81 deletions
controllers/base_controller.go
controllers/public_controller.go
main.go
routers/router.go
static/uploads/images/2020-03-27/2500171221313452.zip
static/uploads/images/2020-03-27/5325709067400059.jpg
task/app.go
ui/kefu_admin/src/App.vue
ui/kefu_admin/src/components/me-aside.vue
ui/kefu_admin/src/store/actions.js
ui/kefu_admin/src/store/getters.js
ui/kefu_admin/src/store/mutations.js
ui/kefu_admin/src/store/state.js
ui/kefu_admin/src/views/workbench/chat_window.vue
ui/kefu_admin/src/views/workbench/index.vue
ui/kefu_admin/src/views/workorder/index.vue
ui/kefu_admin/src/views/workorder/workorder-types-view.vue
ui/kefu_admin/src/views/workorder/workorder-view.vue
ui/kefu_client/src/main.js
ui/kefu_client/src/views/kefu.vue
ui/kefu_client/src/views/workorder.vue
ui/kefu_client/src/views/workorder_create.vue
ui/kefu_client/src/views/workorder_detail.vue
controllers/base_controller.go
View file @
e0bab0ee
...
...
@@ -60,9 +60,5 @@ func (c *BaseController) GetUserInfo() *models.User {
return
nil
}
var
userRepository
=
services
.
GetUserRepositoryInstance
()
user
:=
userRepository
.
GetUserWithToken
(
token
)
if
user
==
nil
{
logs
.
Warn
(
"GetUserInfo get current user info error------------用户效验失败!"
)
}
return
user
return
userRepository
.
GetUserWithToken
(
token
)
}
controllers/public_controller.go
View file @
e0bab0ee
...
...
@@ -103,11 +103,6 @@ func (c *PublicController) Register() {
/// old user
if
user
!=
nil
{
// The last login address is inconsistent with this time and the token is not empty
// if user.Token != "" && user.RemoteAddr != "" && currentRemoteAddr != user.RemoteAddr {
// c.JSON(configs.ResponseFail, "注册失败,请稍等重试!", "")
// }
// fetchResult
fetchResult
,
fetchError
=
utils
.
CreateMiMcToken
(
strconv
.
FormatInt
(
user
.
ID
,
10
))
if
err
:=
json
.
Unmarshal
([]
byte
(
fetchResult
),
&
imTokenDto
);
err
!=
nil
{
...
...
@@ -211,6 +206,7 @@ func (c *PublicController) Read() {
if
err
==
nil
{
readCount
=
0
}
c
.
JSON
(
configs
.
ResponseSucess
,
"查询成功!"
,
readCount
)
}
...
...
@@ -369,6 +365,7 @@ func (c *PublicController) LastActivity() {
// get user
user
:=
c
.
GetUserInfo
()
// user
if
user
!=
nil
{
_
,
err
:=
c
.
UserRepository
.
Update
(
user
.
ID
,
orm
.
Params
{
...
...
@@ -390,6 +387,7 @@ func (c *PublicController) LastActivity() {
}
c
.
JSON
(
configs
.
ResponseSucess
,
"上报成功!"
,
nil
)
}
// GetCompanyInfo get Company info
...
...
main.go
View file @
e0bab0ee
...
...
@@ -19,7 +19,8 @@ import (
func
initLog
()
{
if
isDev
:=
beego
.
AppConfig
.
String
(
"runmode"
);
isDev
==
"prod"
{
_
=
logs
.
SetLogger
(
logs
.
AdapterFile
,
`{"filename":"project.log","level":7,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`
)
_
=
logs
.
SetLogger
(
logs
.
AdapterFile
,
`{"filename":"project.log","level":3,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`
)
beego
.
SetLevel
(
beego
.
LevelError
)
fmt
.
Print
(
"当前环境为生产环境"
)
_
=
beego
.
BeeLogger
.
DelLogger
(
"console"
)
}
else
{
...
...
routers/router.go
View file @
e0bab0ee
...
...
@@ -32,9 +32,10 @@ func routers(prefix string) *beego.Namespace {
beego
.
NSRouter
(
"/secret"
,
&
controllers
.
PublicController
{},
"get:UploadSecret"
),
beego
.
NSRouter
(
"/activity"
,
&
controllers
.
PublicController
{},
"get:LastActivity"
),
// compatible
// compatible
v1
beego
.
NSRouter
(
"/activity/?:id"
,
&
controllers
.
PublicController
{},
"get:LastActivity"
),
beego
.
NSRouter
(
"/clean_read/?:id"
,
&
controllers
.
PublicController
{},
"get:CleanRead"
),
beego
.
NSRouter
(
"/read/?:id"
,
&
controllers
.
PublicController
{},
"get:Read"
),
beego
.
NSRouter
(
"/company"
,
&
controllers
.
PublicController
{},
"get:GetCompanyInfo"
),
beego
.
NSRouter
(
"/robot_info/:id"
,
&
controllers
.
PublicController
{},
"get:RobotInfo"
),
...
...
static/uploads/images/2020-03-27/2500171221313452.zip
0 → 100644
View file @
e0bab0ee
No preview for this file type
static/uploads/images/2020-03-27/5325709067400059.jpg
0 → 100644
View file @
e0bab0ee
108 KB
task/app.go
View file @
e0bab0ee
...
...
@@ -14,12 +14,12 @@ import (
func
appTask
()
{
// Task scheduling (will be executed once every 5 minute)
checkOnLineTk
:=
toolbox
.
NewTask
(
"checkOnLine"
,
"0
*/5
* * * *"
,
func
()
error
{
checkOnLineTk
:=
toolbox
.
NewTask
(
"checkOnLine"
,
"0
/30 *
* * * *"
,
func
()
error
{
// timers
userOffLineUnixTimer
:=
time
.
Now
()
.
Unix
()
-
(
60
*
10
)
// User's last activity time T out online status rule
adminOffLineUnixTimer
:=
time
.
Now
()
.
Unix
()
-
(
60
*
30
)
// Final reply time
lastMessageUnixTimer
:=
time
.
Now
()
.
Unix
()
-
(
60
*
8
)
// Determine if the user will not use it for a certain period of time and force them to go offline
lastMessageUnixTimer
:=
time
.
Now
()
.
Unix
()
-
(
30
*
1
)
// Determine if the user will not use it for a certain period of time and force them to go offline
// user
userOfflineCount
:=
services
.
GetUserRepositoryInstance
()
.
CheckUsersLoginTimeOutAndSetOffline
(
userOffLineUnixTimer
)
...
...
@@ -47,39 +47,24 @@ func appTask() {
continue
}
_lastBackAdmin
:=
services
.
GetAdminRepositoryInstance
()
.
GetAdmin
(
contact
.
LastAccount
)
robot
:=
robots
[
0
]
// message body
//
timeout
message body
message
:=
models
.
Message
{}
message
.
BizType
=
"timeout"
message
.
Read
=
0
message
.
FromAccount
=
robot
.
ID
message
.
Timestamp
=
time
.
Now
()
.
Unix
()
message
.
Payload
=
"您长时间未回复,本次会话超时了"
if
_lastBackAdmin
==
nil
{
message
.
Payload
=
"客服长时间未回复,会话结束,您可以重新发起人工"
}
message
.
Payload
=
"由于双方长时间未互动,本次会话结束"
message
.
ToAccount
=
contact
.
FromAccount
var
messageString
string
messageString
=
utils
.
InterfaceToString
(
message
)
utils
.
PushMessage
(
contact
.
FromAccount
,
messageString
)
utils
.
MessageInto
(
message
)
// Send a reminder message to customer service
message
.
FromAccount
=
robot
.
ID
message
.
ToAccount
=
contact
.
ToAccount
message
.
Payload
=
"用户长时间无应答,会话结束"
if
_lastBackAdmin
==
nil
{
message
.
Read
=
1
message
.
Payload
=
"您长时间未回复客户,会话结束"
}
messageString
=
utils
.
InterfaceToString
(
message
)
utils
.
PushMessage
(
contact
.
ToAccount
,
messageString
)
utils
.
PushMessage
(
contact
.
FromAccount
,
messageString
)
utils
.
MessageInto
(
message
)
// Message after timeout
if
robot
.
TimeoutText
!=
""
&&
_lastBackAdmin
!=
nil
{
if
robot
.
TimeoutText
!=
""
{
message
.
FromAccount
=
robot
.
ID
message
.
ToAccount
=
contact
.
FromAccount
message
.
BizType
=
"text"
...
...
ui/kefu_admin/src/App.vue
View file @
e0bab0ee
...
...
@@ -24,12 +24,14 @@ export default {
this
.
$store
.
dispatch
(
'ON_GET_UPLOADS_CONFIG'
)
this
.
$store
.
dispatch
(
'ON_GET_ROBOTS'
)
this
.
$store
.
dispatch
(
'ON_GET_CONTACTS'
)
this
.
$store
.
dispatch
(
'ON_GET_WORKORDER_COUNTS'
)
setInterval
(()
=>
this
.
$store
.
dispatch
(
'ON_GET_WORKORDER_COUNTS'
),
30000
)
// 一分钟上报一次我的活动时间
this
.
upLastActivity
()
// 获取会话表
setInterval
(()
=>
this
.
getContacts
(),
2000
)
this
.
getContacts
(
)
// Mimc 初始化
this
.
initMimc
()
...
...
ui/kefu_admin/src/components/me-aside.vue
View file @
e0bab0ee
...
...
@@ -24,14 +24,14 @@
</div>
</el-badge>
</el-menu-item>
<
!--
<
el-menu-item
index=
"/workorder"
>
<el-badge
:hidden=
"$store.getters.
readCount == 0"
:value=
"$store.getters.readCount
"
:max=
"99"
style=
"width: 100%;"
>
<el-menu-item
index=
"/workorder"
>
<el-badge
:hidden=
"$store.getters.
workOrderCounts.status0 == 0"
:value=
"$store.getters.workOrderCounts.status0
"
:max=
"99"
style=
"width: 100%;"
>
<div>
<i
class=
"el-icon-tickets"
></i>
<span
slot=
"title"
>
工单管理
</span>
</div>
</el-badge>
</el-menu-item>
-->
</el-menu-item>
<el-menu-item
index=
"/knowledge"
>
<i
class=
"el-icon-reading"
></i>
<span
slot=
"title"
>
知识库
</span>
...
...
@@ -58,12 +58,12 @@
</el-menu-item>
</el-menu>
<
!--
<
div
class=
"fix-bottom"
>
<div
class=
"fix-bottom"
>
<a
title=
"去给作者Star"
target=
"_blank"
href=
"https://github.com/chenxianqi/kefu_server.git"
>
<svg
class=
"github-logo"
height=
"23"
viewBox=
"0 0 16 16"
version=
"1.1"
width=
"23"
aria-hidden=
"true"
><path
fill=
"#fff"
fill-rule=
"evenodd"
d=
"M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
></path></svg>
<span>
Github
</span>
</a>
</div>
-->
</div>
</el-aside>
</
template
>
<
script
>
...
...
ui/kefu_admin/src/store/actions.js
View file @
e0bab0ee
...
...
@@ -76,5 +76,12 @@ export default {
.
catch
(()
=>
{
this
.
loading
=
false
});
},
// 获取工单系统counts
ON_GET_WORKORDER_COUNTS
(
context
){
axios
.
get
(
'/workorder/counts'
)
.
then
(
response
=>
{
context
.
commit
(
'onChangeWorkOrderCounts'
,
response
.
data
.
data
)
})
}
}
\ No newline at end of file
ui/kefu_admin/src/store/getters.js
View file @
e0bab0ee
...
...
@@ -75,4 +75,8 @@ export default {
workbenchBgColor
(
state
){
return
state
.
workbenchBgColor
},
// 工单统计
workOrderCounts
(
state
){
return
state
.
workOrderCounts
}
}
\ No newline at end of file
ui/kefu_admin/src/store/mutations.js
View file @
e0bab0ee
...
...
@@ -75,5 +75,9 @@ export default {
// 是否是登陆状态
onIsLogin
(
state
,
isLogin
){
state
.
isLogin
=
isLogin
}
},
// 工单统计
onChangeWorkOrderCounts
(
state
,
counts
){
state
.
workOrderCounts
=
counts
},
}
\ No newline at end of file
ui/kefu_admin/src/store/state.js
View file @
e0bab0ee
...
...
@@ -17,6 +17,12 @@ export default {
messageRecord
:
{
// 当前聊天面板聊天消息记录
list
:
[]
},
workOrderCounts
:
{
// 工单统计
"status0"
:
0
,
"status2"
:
0
,
"status3"
:
0
,
"delete_count"
:
0
},
avatar
:
"data:image/png;base64,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"
,
pushIcon
:
"data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMfaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0MCA3OS4xNjA0NTEsIDIwMTcvMDUvMDYtMDE6MDg6MjEgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkJEMURFODg4MTlDRjExRUFBQjY5RTZDMUM4OUFGOUNDIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkJEMURFODg3MTlDRjExRUFBQjY5RTZDMUM4OUFGOUNDIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IE1hY2ludG9zaCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJFRUE0ODZCQ0Q5QzUzN0E5MkNBQzNDRDdGODRCMUE4NSIgc3RSZWY6ZG9jdW1lbnRJRD0iRUVBNDg2QkNEOUM1MzdBOTJDQUMzQ0Q3Rjg0QjFBODUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwM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"
,
workbenchBgColor
:
"#646b6f"
// 工作台背景颜色
...
...
ui/kefu_admin/src/views/workbench/chat_window.vue
View file @
e0bab0ee
...
...
@@ -74,7 +74,6 @@
<em>
{{
$formatFromNowDate
(
item
.
timestamp
)
}}
</em>
<span
v-if=
"item.to_account != adminInfo.id"
>
你结束了会话
</span>
<span
v-else
>
对方结束了会话
</span>
<em>
{{
$formatFromNowDate
(
item
.
timestamp
)
}}
</em>
</div>
</
template
>
...
...
ui/kefu_admin/src/views/workbench/index.vue
View file @
e0bab0ee
...
...
@@ -632,7 +632,7 @@ export default {
});
}
// 是否是否当前会话消息
if
(
message
.
from_account
!=
this
.
seviceCurrentUser
.
from_account
)
return
if
(
message
.
from_account
!=
this
.
seviceCurrentUser
.
from_account
&&
message
.
biz_type
!=
"timeout"
)
return
if
(
message
.
biz_type
==
'end'
){
var
seviceCurrentUser
=
this
.
seviceCurrentUser
seviceCurrentUser
.
is_session_end
=
1
...
...
ui/kefu_admin/src/views/workorder/index.vue
View file @
e0bab0ee
...
...
@@ -5,17 +5,21 @@
<span>
<i
class=
"el-icon-tickets"
></i>
<span
slot=
"title"
>
工单管理
</span>
<span
style=
"font-size:15px;margin-left: 30px;color:#e7a646"
>
当前有
<strong
style=
"color: #f56c6c"
>
5
</strong>
条待处理, 和
<strong
style=
"color: #f56c6c"
>
8
</strong>
条待回复工单
</span>
<span
style=
"font-size:15px;margin-left: 30px;color:#e7a646"
>
<template
v-if=
"workOrderCounts.status0 > 0"
>
当前有
<strong
style=
"color: #f56c6c"
>
{{
workOrderCounts
.
status0
}}
</strong>
条待处理,
</
template
>
<
template
v-if=
"workOrderCounts.status2 > 0"
>
<strong
style=
"color: #f56c6c"
>
{{
workOrderCounts
.
status2
}}
</strong>
条待回复工单
</
template
>
</span>
</span>
<div>
<el-button
size=
"mini"
>
分类设置
</el-button>
<el-button
size=
"mini"
@
click=
"isShowTypesView = true"
>
分类设置
</el-button>
</div>
</div>
<el-divider
/>
<
div
class=
"container-box
"
>
<
el-row
class=
"container-box"
type=
"flex"
justify=
"space-between
"
>
<div
class=
"menu"
>
<el-tabs
@
tab-click=
"tabsChange"
tab-position=
"left"
style=
"width:200px;height: 80vh;"
>
<
template
size=
"small"
v-for=
"item in workorderTypes"
border
>
...
...
@@ -29,14 +33,19 @@
<el-table-column
prop=
"title"
label=
"工单标题"
></el-table-column>
<el-table-column
prop=
"status"
label=
"当前状态"
>
<
template
slot-scope=
"scope"
>
<el-tag
type=
"warning"
v-if=
"scope.row.status == 0"
>
等待客服处理
</el-tag>
<el-tag
type=
"warning"
v-if=
"scope.row.status == 2"
>
等待客服回复
</el-tag>
<el-tag
type=
"success"
v-if=
"scope.row.status == 1"
>
已有客服回复
</el-tag>
<template
v-if=
"workorderTypes.length-1 == tabIndex"
>
<span
style=
"color:#f56c6b"
>
已删除
</span>
</
template
>
<
template
v-else
>
<el-tag
type=
"danger"
v-if=
"scope.row.status == 0"
>
待客服处理
</el-tag>
<el-tag
type=
"warning"
v-if=
"scope.row.status == 2"
>
待客服回复
</el-tag>
<el-tag
type=
"success"
v-if=
"scope.row.status == 1"
>
客服已回复
</el-tag>
<el-tag
type=
"info"
v-if=
"scope.row.status == 3"
>
工单已结束
</el-tag>
</
template
>
</template>
</el-table-column>
<el-table-column
prop=
"u_nickname"
label=
"用户
(发布者)
"
></el-table-column>
<el-table-column
prop=
"a_nickname"
label=
"最
后回复者
(客服)"
>
<el-table-column
prop=
"u_nickname"
label=
"用户"
></el-table-column>
<el-table-column
prop=
"a_nickname"
label=
"最
近处理
(客服)"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
a_nickname
||
'-----'
}}
</
template
>
...
...
@@ -63,22 +72,27 @@
></el-pagination>
</el-row>
</div>
</
div
>
</
el-row
>
<WorkOrderView
:workorderTypes=
"workorderTypes"
:prop=
"showWorkOrder"
v-model=
"isShowWorkOrderView"
/>
<WorkOrderTypesView
:workorderTypes=
"workorderTypes"
v-model=
"isShowTypesView"
/>
</div>
</template>
<
script
>
import
axios
from
"axios"
;
import
WorkOrderView
from
"./workorder-view"
import
WorkOrderTypesView
from
"./workorder-types-view"
import
{
mapGetters
}
from
'vuex'
export
default
{
name
:
"workorder-index"
,
components
:
{
WorkOrderView
WorkOrderView
,
WorkOrderTypesView
},
data
()
{
return
{
loading
:
true
,
isShowWorkOrderView
:
false
,
isShowTypesView
:
false
,
showWorkOrder
:
{},
tableData
:
{
list
:
[],
...
...
@@ -105,8 +119,14 @@ export default {
if
(
this
.
tabIndex
==
this
.
workorderTypes
.
length
-
1
&&
this
.
workorderTypes
.
length
>
1
){
return
'0,1,2,3'
}
return
"0,1,2"
if
(
this
.
tabIndex
==
this
.
workorderTypes
.
length
-
2
&&
this
.
workorderTypes
.
length
>
1
){
return
'3'
}
return
"0,1,2"
},
...
mapGetters
([
"workOrderCounts"
,
])
},
created
()
{
this
.
getWorkorderList
();
...
...
@@ -161,12 +181,12 @@ export default {
}
this
.
workorderTypes
.
push
({
"id"
:
-
1
,
"count"
:
0
,
"count"
:
this
.
workOrderCounts
.
status3
,
"title"
:
"已结单"
})
this
.
workorderTypes
.
push
({
"id"
:
-
2
,
"count"
:
0
,
"count"
:
this
.
workOrderCounts
.
delete_count
,
"title"
:
"回收站"
})
})
...
...
@@ -208,12 +228,12 @@ export default {
}
}
.container-box
{
display
flex
.menu{
flex-shrink
:
0
;
width
180px;
}
.table-content
{
width
500px;
flex-grow
1
}
}
...
...
ui/kefu_admin/src/views/workorder/workorder-types-view.vue
0 → 100644
View file @
e0bab0ee
<
template
>
<div
class=
"workorder-view"
v-show=
"value"
>
<div
class=
"mask"
@
dblclick=
"close"
></div>
<div
class=
"content-box"
>
<el-row
type=
"flex"
class=
"title"
>
<span><i
class=
"el-icon-tickets"
></i>
分类设置
</span>
<div>
<el-button
size=
"mini"
type=
"primary"
>
添加分类
</el-button>
</div>
</el-row
>
<span
class=
"close"
@
click=
"close"
>
<i
class=
"el-icon-close"
></i>
</span>
<div
class=
"content"
>
<div
class=
"scroll"
>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
"workorder-view"
,
data
()
{
return
{
isSubmit
:
false
,
comments
:
[],
request
:
{
source
:
""
,
content
:
""
}
};
},
props
:
{
value
:
{
default
:
false
,
type
:
Boolean
},
workorderTypes
:
Array
},
created
()
{
this
.
comments
=
[];
},
computed
:
{
isShowAside
()
{
return
this
.
$store
.
state
.
isShowAside
;
},
},
methods
:
{
// 按钮操作
close
()
{
this
.
$emit
(
"input"
,
false
);
},
},
watch
:
{
}
};
</
script
>
<
style
scoped
lang=
"stylus"
>
.workorder-view
{
width
:
100vw
;
height
:
100vh
;
position
:
fixed
;
right
:
0
;
top
:
0px
;
left
:
0px
;
background-color
:
rgba
(
0
,
0
,
0
,
0.8
);
z-index
:
9
;
.mask
{
width
:
100%
;
height
:
100%
;
}
.content-box
{
width
:
400px
;
height
:
100%
;
background-color
:
#fff
;
position
:
fixed
;
right
:
0px
;
margin
:
0
auto
;
top
:
0px
;
overflow
:
hidden
;
padding-top
:
40px
;
padding-bottom
:
135px
;
box-sizing
:
border-box
;
.title
{
width
:
100%
;
height
:
60px
;
border-bottom
:
1px
solid
#ddd
;
position
:
absolute
;
top
:
0
;
left
:
0
;
padding
0
10px
background-color
:
#fff
;
box-sizing
:
border-box
;
&>span{
width
260px;
}
align-content
center
align-items
center
}
.buttons
{
position
:
absolute
;
top
:
5px
;
right
:
50px
;
}
.close
{
position
:
absolute
;
top
:
15px
;
right
:
5px
;
font-size
:
25px
;
color
:
#ccc
;
cursor
:
pointer
;
}
}
}
</
style
>
ui/kefu_admin/src/views/workorder/workorder-view.vue
View file @
e0bab0ee
<
template
>
<div
class=
"workorder-view"
:class=
"
{'is-show-aside': !isShowAside}"
v-show="value">
<div
class=
"workorder-view"
v-show=
"value"
>
<div
class=
"mask"
@
dblclick=
"close"
></div>
<transition
name=
"el-zoom-in-bottom"
>
<div
class=
"content-box"
:class=
"
{'padding-bottom30': showData.status == 3}" v-show="value">
...
...
@@ -50,9 +50,9 @@
<div
class=
"form-line"
>
<span
class=
"lable"
>
状态:
</span>
<div
class=
"con"
>
<span
style=
"color:#
e6a23c;"
v-if=
"showData.status == 0"
>
等
待客服处理
</span>
<span
style=
"color:#e6a23c;"
v-if=
"showData.status == 2"
>
等
待客服回复
</span>
<span
style=
"color:#67c23a;"
v-if=
"showData.status == 1"
>
已有客服
回复
</span>
<span
style=
"color:#
f56c6b"
v-if=
"showData.status == 0"
>
待客服处理
</span>
<span
style=
"color:#e6a23c;"
v-if=
"showData.status == 2"
>
待客服回复
</span>
<span
style=
"color:#67c23a;"
v-if=
"showData.status == 1"
>
客服已
回复
</span>
<span
style=
"color:#909399;"
v-if=
"showData.status == 3"
>
工单已结束
</span>
</div>
</div>
...
...
@@ -295,7 +295,7 @@ export default {
var
fileType
=
src
.
substr
(
src
.
lastIndexOf
(
"."
)
+
1
);
if
(
"jpg,jpeg,png,JPG,JPEG,PNG"
.
indexOf
(
fileType
)
!=
-
1
)
{
html
=
"
<
br
><
img
style
=
'max-width:45%'
preview
=
'1'
src
=
'" +
"
<
br
><
img
style
=
'max-width:45%
;margin-top:5px;
'
preview
=
'1'
src
=
'" +
fullPath +
"'
/>
";
} else {
...
...
@@ -561,14 +561,6 @@ export default {
}
}
}
&
.is-show-aside
{
left
:
0
;
.content
{
left
:
0px
;
}
}
}
</
style
>
ui/kefu_client/src/main.js
View file @
e0bab0ee
...
...
@@ -18,10 +18,14 @@ axios.defaults.baseURL = '/api'
// axios添加请求拦截器
axios
.
interceptors
.
request
.
use
(
function
(
config
)
{
if
(
config
.
url
.
indexOf
(
"https://restapi.amap.com/v3/ip"
)
!=
-
1
){
return
config
;
}
const
token
=
localStorage
.
getItem
(
'Token'
)
||
""
config
.
headers
=
Object
.
assign
({},
{
'Token'
:
token
,
},
config
.
headers
)
return
config
;
},
function
(
error
)
{
// eslint-disable-next-line no-console
...
...
ui/kefu_client/src/views/kefu.vue
View file @
e0bab0ee
...
...
@@ -193,14 +193,14 @@
<span
class=
"expression-btn"
@
click=
"showEmoji = !showEmoji"
>
<img
src=
"../assets/expression.png"
alt
/>
</span>
<
!-- <
span
<span
class=
"workorder-btn"
:class=
"{'show-header': !isShowHeader && isMobile}"
@
click=
"$router.push('/workorder')"
>
<img
src=
"../assets/workorder.png"
/>
<i>
工单
</i>
</span>
-->
</span>
<span
v-show=
"isMobile && !isShowHeader"
@
click=
"headRightBtn"
...
...
@@ -340,6 +340,9 @@ export default {
return
}
// 关闭loading
this
.
$store
.
commit
(
"updateState"
,
{
isShowPageLoading
:
false
})
// handelEvent
this
.
handelEvent
();
...
...
@@ -355,9 +358,6 @@ export default {
this
.
scrollIntoBottom
();
// 关闭loading
setTimeout
(()
=>
this
.
$store
.
commit
(
"updateState"
,
{
isShowPageLoading
:
false
}),
500
)
// 计算客服最后回复时间
this
.
onServciceLastMessageTimeNotCallBack
();
...
...
@@ -593,7 +593,6 @@ export default {
// 接收消息
receiveP2PMsg
(
message
)
{
console
.
log
(
message
);
if
(
message
.
biz_type
==
"contacts"
)
return
// 是否是转接客服消息
if
(
message
.
biz_type
==
"transfer"
)
{
this
.
$store
.
commit
(
"updateState"
,
{
...
...
ui/kefu_client/src/views/workorder.vue
View file @
e0bab0ee
...
...
@@ -12,7 +12,7 @@
<div
class=
"list"
:class=
"
{'hide-header': !isShowHeader}">
<div
class=
"no-data"
v-if=
"workorders.length
<
=
0
"
>
<img
src=
"../assets/workorder.png"
alt=
""
>
<div>
您
还没有发布
过工单~
</div>
<div>
您
没有发布相关
过工单~
</div>
</div>
<ul
v-else
>
<template
v-for=
"(item,index) in workorders"
>
...
...
ui/kefu_client/src/views/workorder_create.vue
View file @
e0bab0ee
...
...
@@ -130,7 +130,7 @@ export default {
var
fullPath
=
self
.
uploadToken
.
host
+
"/"
+
src
;
var
fileType
=
src
.
substr
(
src
.
lastIndexOf
(
"."
)
+
1
);
if
(
"jpg,jpeg,png,JPG,JPEG,PNG"
.
indexOf
(
fileType
)
!=
-
1
)
{
html
=
"
<
br
><
img
style
=
'max-width:45%'
preview
=
'1'
src
=
'" + fullPath + "'
/>
"
html
=
"
<
br
><
img
style
=
'max-width:45%
;margin-top:5px;
'
preview
=
'1'
src
=
'" + fullPath + "'
/>
"
}else{
html = "
<
br
><
img
style
=
'width:20px;height:20px;top:3px; right:3px;position: relative;'
preview
=
'1'
src
=
'http://qiniu.cmp520.com/fj.png'
/>
"
html += "
<
a
target
=
'_blank'
style
=
'color: #2e9dfc;'
href
=
'"+fullPath+"'
>
下载附件
<
/a>
"
...
...
ui/kefu_client/src/views/workorder_detail.vue
View file @
e0bab0ee
...
...
@@ -219,7 +219,7 @@ export default {
var
fullPath
=
self
.
uploadToken
.
host
+
"/"
+
src
;
var
fileType
=
src
.
substr
(
src
.
lastIndexOf
(
"."
)
+
1
);
if
(
"jpg,jpeg,png,JPG,JPEG,PNG"
.
indexOf
(
fileType
)
!=
-
1
)
{
html
=
"
<
br
><
img
style
=
'max-width:45%'
preview
=
'1'
src
=
'" + fullPath + "'
/>
"
html
=
"
<
br
><
img
style
=
'max-width:45%
;margin-top:5px;
'
preview
=
'1'
src
=
'" + fullPath + "'
/>
"
}else{
html = "
<
br
><
img
style
=
'width:20px;height:20px;top:3px; right:3px;position: relative;'
preview
=
'1'
src
=
'http://qiniu.cmp520.com/fj.png'
/>
"
html += "
<
a
target
=
'_blank'
style
=
'color: #2e9dfc;'
href
=
'"+fullPath+"'
>
下载附件
<
/a>
"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment