Commit e0bab0ee by chenxianqi

update code

parent b5c1cfa1
......@@ -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)
}
......@@ -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
......
......@@ -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 {
......
......@@ -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"),
......
......@@ -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"
......
......@@ -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()
......
......@@ -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>
......
......@@ -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
......@@ -75,4 +75,8 @@ export default {
workbenchBgColor(state){
return state.workbenchBgColor
},
// 工单统计
workOrderCounts(state){
return state.workOrderCounts
}
}
\ No newline at end of file
......@@ -75,5 +75,9 @@ export default {
// 是否是登陆状态
onIsLogin(state, isLogin){
state.isLogin = isLogin
}
},
// 工单统计
onChangeWorkOrderCounts(state, counts){
state.workOrderCounts = counts
},
}
\ No newline at end of file
......@@ -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>
......
......@@ -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
......
......@@ -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
}
}
......
<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>
<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>
......@@ -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
......
......@@ -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", {
......
......@@ -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">
......
......@@ -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>"
......
......@@ -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>"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment