Commit 825ca73b by chenxianqi

update code

parent 98c8f64f
var moment = require('moment'); var moment = require('moment');
import axios from "axios";
import * as qiniu from "qiniu-js";
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
var Helps = {}; var Helps = {};
Helps.install = function (Vue, options) { Helps.install = function (Vue, options) {
Vue.prototype.$myMethod = function(){ Vue.prototype.$myMethod = function () {
console.log(options) console.log(options)
} }
// 格式化日期 // 格式化日期
Vue.prototype.$formatUnixDate = function(unix, format){ Vue.prototype.$formatUnixDate = function (unix, format) {
return moment(parseInt(unix + '000')).format(format) return moment(parseInt(unix + '000')).format(format)
} }
// 格式化日期(相对日期) // 格式化日期(相对日期)
Vue.prototype.$formatFromNowDate = function(unix, format = "YYYY-MM-DD HH:mm"){ Vue.prototype.$formatFromNowDate = function (unix, format = "YYYY-MM-DD HH:mm") {
if(moment().format("YYYYMMDD") == moment(parseInt(unix + '000')).format("YYYYMMDD")){ if (moment().format("YYYYMMDD") == moment(parseInt(unix + '000')).format("YYYYMMDD")) {
return "今天 " + moment(parseInt(unix + '000')).format("HH:mm") return "今天 " + moment(parseInt(unix + '000')).format("HH:mm")
} }
return moment(parseInt(unix + '000')).format(format) return moment(parseInt(unix + '000')).format(format)
} }
Vue.prototype.$robotNickname = function(id){ Vue.prototype.$robotNickname = function (id) {
var nickname var nickname
var robots = this.$store.getters.robots var robots = this.$store.getters.robots
for(let i = 0; i< robots.length; i++){ for (let i = 0; i < robots.length; i++) {
if(robots[i].id == id){ if (robots[i].id == id) {
nickname = robots[i].nickname nickname = robots[i].nickname
} }
} }
return nickname return nickname
} }
// 判断是否是全面屏 // 上传文件
Vue.prototype.$judgeBigScreen = function(){ Vue.prototype.$uploadFile = function ({ mode, file, percent, success, fail }) {
let yes = false; var qiniuObservable = null;
const rate = window.screen.height / window.screen.width; const fileName = parseInt(Math.random() * 10000 * new Date().getTime()) + file.name.substr(file.name.lastIndexOf("."));
let limit = window.screen.height == window.screen.availHeight ? 1.8 : 1.65; // 系统内置
if (rate > limit) yes = true; if (mode == 1) {
return yes; let fd = new FormData();
fd.append("file", file);
fd.append("file_name", fileName);
axios
.post("/public/upload", fd)
.then(res => {
if (success) success(res.data.data);
})
.catch(() => {
if (fail) fail();
});
} }
// 七牛云
else if (mode == 2) {
let options = {
quality: 0.92,
noCompressIfLarger: true,
maxWidth: 1500
};
qiniu.compressImage(file, options).then(data => {
const observable = qiniu.upload(
data.dist,
fileName,
self.uploadToken.secret,
{},
{
mimeType: null
}
);
qiniuObservable = observable.subscribe({
next: function (res) {
if (percent) percent(res)
},
error: function () {
// 失败后再次使用FormData上传
var formData = new FormData();
formData.append("fileType", "image");
formData.append("fileName", "file");
formData.append("key", fileName);
formData.append("token", self.uploadToken.secret);
formData.append("file", file);
axios
.post("https://upload.qiniup.com", formData)
.then(() => {
if (success) success(fileName);
})
.catch(() => {
if (fail) fail();
});
},
complete: function (res) {
if (success) success(res.key);
}
});
});
}
return qiniuObservable
}
} }
export default Helps; export default Helps;
\ No newline at end of file
...@@ -5,11 +5,6 @@ ...@@ -5,11 +5,6 @@
</template> </template>
<script> <script>
import axios from "axios";
import { Toast, MessageBox } from "mint-ui";
import * as qiniu from "qiniu-js";
var emojiService = require("../resource/emoji");
import BScroll from "better-scroll";
export default { export default {
name: "app", name: "app",
data() { data() {
...@@ -21,7 +16,6 @@ export default { ...@@ -21,7 +16,6 @@ export default {
}, },
mounted() { mounted() {
console.log(11111)
this.handelUrl() this.handelUrl()
}, },
methods: { methods: {
...@@ -66,7 +60,7 @@ export default { ...@@ -66,7 +60,7 @@ export default {
isArtificial = true isArtificial = true
artificialAccount = parseInt(artificialAccountString) artificialAccount = parseInt(artificialAccountString)
} }
this.$store.commit("updateState", {isShowHeader,isMobile,userAccount,uid,isArtificial,artificialAccount,robotAccount}) this.$store.commit("updateState", {isShowHeader,isMobile,userAccount,uid,isArtificial,artificialAccount,robotAccount, platform})
}, },
// query 转json // query 转json
queryToJson(str) { queryToJson(str) {
...@@ -120,732 +114,5 @@ body { ...@@ -120,732 +114,5 @@ body {
font-size: 23px !important; font-size: 23px !important;
} }
.mint-tabbar {
z-index: 999999999 !important;
background-color: #fff !important;
}
.mint-loadmore-spinner {
width: 15px !important;
height: 15px !important;
}
.mini-im-container {
margin: 0 auto;
padding: 50px 0 100px;
overflow: hidden;
height: 100vh;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
.input-ing {
width: 100vw;
height: 25px;
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #26a2ff !important;
z-index: 9;
color: #fff;
margin: auto;
text-align: center;
font-size: 14px;
line-height: 25px;
}
.mini-im-loading {
display: flex;
min-width: 240px;
width: 100%;
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #fff !important;
margin: auto;
align-items: center;
justify-content: center;
}
}
.mini-im-container-no-pto {
padding-top: 0px !important;
}
.mini-im-tabbar-input {
width: 100%;
padding: 5px 10px;
overflow: hidden;
height: 100px;
display: flex;
align-items: flex-end;
justify-content: space-between;
position: fixed;
bottom: 0;
z-index: 9;
background-color: #fff !important;
border-top: 1px solid #f2f2f2;
left: 0;
right: 0;
margin: 0 auto;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
textarea {
outline: none;
-webkit-appearance: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
border: none;
border-radius: 5px;
height: 65px;
flex-grow: 1;
padding: 8px 0;
font-size: 14px;
color: #666;
background-color: #ffffff;
display: block;
box-sizing: border-box;
resize: none;
flex-shrink: 1;
flex-grow: 1;
width: 100px;
}
span {
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
img {
width: 28px;
}
&.expression-btn {
position: absolute;
left: 45px;
top: 6px;
z-index: 99;
}
&.workorder-btn{
position: absolute;
left: 70px;
top: 6px;
z-index: 99;
width 70px
color #999
font-size 14px
display flex
img{
width 28px
hieght 28px
}
i{
font-style normal
}
}
&.photo-btn {
position: absolute;
left: 10px;
top: 5px;
overflow: hidden;
z-index: 99;
img {
width: 22px;
}
input {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
}
&.serverci {
width: 70px;
position: absolute;
flex-direction: row;
justify-content: flex-end;
top: 5px;
right: 10px;
img {
width: 26px;
}
span {
width: 70px;
background-color: #f3f3f370;
color: #999;
font-size: 14px;
}
&.on {
left: 75px;
justify-content: flex-start;
right: initial;
}
}
}
.mini-input-send {
width: 55px;
height: 30px;
color: #fff;
line-height: 30px;
text-align: center;
border-radius: 3px;
border: none;
font-size: 14px;
background: linear-gradient(to right, #26a2ff, #736cde);
flex-shrink: 0;
&:active {
opacity: 0.8;
}
}
}
.mini-im-emoji {
width: 100%;
height: 100vh;
position: fixed;
top: 0;
left: 0;
right: 0;
padding: 5px 0;
z-index: 9;
margin: 0 auto;
background-color: #fff;
.mini-im-emoji-content {
width: 100%;
height: 100vh;
padding: 50px 0 5px;
position: absolute;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
overflow: hidden;
bottom: 0;
left: 0;
right: 0;
margin: 0 auto;
background-color: #fff;
text-align: center;
box-shadow: 0px 2px 2px 1px rgba(0, 0, 0, 0.1);
span {
display: inline-block;
width: 28px;
height: 28px;
padding: 2px;
text-align: center;
font-size: 23px;
}
}
}
.mini-im-body {
position: relative;
height: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
background-color: #f3f3f3;
margin: 0 auto;
overflow: hidden;
z-index: 1;
ul {
position: absolute;
z-index: 1;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
width: 100%;
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-text-size-adjust: none;
-moz-text-size-adjust: none;
-ms-text-size-adjust: none;
-o-text-size-adjust: none;
text-size-adjust: none;
}
.loading {
height: 100%;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
}
.top-loading {
width: 100%;
height: 35px;
position: absolute;
top: 0;
left: 0;
right: 0;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
z-index: 9;
span {
color: #999;
font-size: 13px;
margin-left: 5px;
}
}
}
.mini-im-knowledge {
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.2);
position: fixed;
z-index: 8;
top: 0;
left: 0;
right: 0;
margin: 0 auto;
box-sizing: border-box;
padding-bottom: 100px;
display: flex;
flex-direction: column;
justify-content: flex-end;
.mask {
flex-grow: 1;
width: 100vw;
height: 100px;
}
span {
background-color: #fff;
font-size: 14px;
color: #666;
padding: 10px;
}
ul {
background-color: white;
li {
font-size: 13px;
cursor: pointer;
color: #56b7ff;
padding: 6px 10px;
border-top: 1px solid #f2f2f2;
}
}
}
.mint-loadmore {
height: 100%;
}
.mint-loadmore-text {
color: #666;
font-size: 14px;
}
.mini-im-chat-list {
padding: 20px 10px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
.message-loading {
padding-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.mini-im-chat-item {
display: flex;
margin-bottom: 15px;
.chat-avatar {
width: 30px;
height: 30px;
flex-grow: 0;
flex-shrink: 0;
overflow: hidden;
margin-top: 2px;
box-shadow: 1px 1px 2px 0px rgba(0, 0, 0, 0.3);
border-radius: 100%;
img {
width: 100%;
height: 100%;
border-radius: 100%;
}
}
.chat-content {
width: 100%;
padding-left: 10px;
.chat-username {
display: flex;
align-items: center;
padding-bottom: 5px;
span {
font-size: 12px;
color: #666;
font-weight: 500;
}
em {
color: #666;
font-size: 12px;
margin-left: 8px;
}
}
.chat-body {
display: flex;
align-items: flex-end;
.cancel-btn {
font-size: 12px;
color: #26a2ff !important;
margin-right: 5px;
}
.text {
padding: 5px 8px;
background-color: #fff;
border-radius: 3px;
font-size: 14px;
color: #333;
max-width: 85%;
position: relative;
box-shadow: 1px 2px 2px 0px rgba(0, 0, 0, 0.1);
-webkit-user-select: text;
-moz-user-select: text;
-o-user-select: text;
user-select: text;
word-break: break-all;
&:before {
content: '';
display: block;
position: absolute;
top: 5px;
left: -9px;
width: 0;
height: 0;
overflow: hidden;
font-size: 0;
line-height: 0;
border: 5px;
border-radius: 2px;
border-style: dashed solid dashed dashed;
border-color: transparent #fff transparent transparent;
}
}
.photo {
display: flex;
align-items: flex-end;
img {
width: 120px;
display: block;
border-radius: 5px;
cursor: pointer;
}
span {
font-size: 12px;
color: #999;
padding-right: 5px;
}
}
.system {
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
span {
text-align: center;
font-size: 12px;
color: #999;
}
.content {
margin-top: 1.5px;
height: 25px;
text-align: center;
span {
padding: 0 10px;
text-align: center;
font-size: 12px;
border-radius: 5px;
display: inline-block;
line-height: 22px;
height: 22px;
min-width: 80px;
color: #949393;
}
}
}
.knowledge {
padding: 5px 8px;
background-color: #fff;
border-radius: 3px;
font-size: 13px;
color: #333;
max-width: 80%;
position: relative;
box-shadow: 1px 2px 2px 0px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
align-items: flex-start;
.title {
min-height: 25px;
font-size: 14px;
}
a {
font-size: 13px;
color: #26a2ff;
text-decoration: none;
width: 100%;
display: flex;
min-height: 25px;
}
}
}
}
&.self {
justify-content: flex-end;
.chat-content {
padding-right: 10px;
}
.chat-body {
justify-content: flex-end;
.text {
box-shadow: -1px 1px 3px 0px rgba(0, 0, 0, 0.1);
background-color: #26a2ff;
color: #fff;
-webkit-user-select: text;
-moz-user-select: text;
-o-user-select: text;
user-select: text;
word-break: break-all;
&:before {
left: inherit;
right: -9px;
border-style: dashed dashed dashed solid;
border-color: transparent transparent transparent #26a2ff;
}
}
}
.chat-avatar {
order: 1;
}
.chat-username {
justify-content: flex-end;
em {
order: -2;
margin-right: 5px;
}
}
}
}
}
// PC端兼容样式
.mini-im-pc-container {
width: 360px;
height: 500px;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
display: flex;
flex-direction: column;
padding: 0 !important;
overflow: hidden;
box-shadow: 1px 1px 8px 2px #ccc;
.mini-im-loading, .mini-im-emoji {
width: 360px !important;
height: 500px !important;
bottom: 0;
margin: auto !important;
}
.mini-im-emoji {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
.cancel-btn {
cursor: pointer;
}
.mini-im-emoji-content {
padding: 8px !important;
height: 465px !important;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
span {
width: 26px;
height: 26px;
cursor: pointer;
}
}
.mini-im-body {
width: 360px;
height: 500px;
position: static !important;
.mini-im-chat-list {
padding: 15px !important;
}
}
.mini-im-pc-header {
z-index: 999999999 !important;
height: 45px;
background: linear-gradient(to right, #26a2ff, #736cde);
flex-shrink: 0;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
color: #fff;
.right {
display: flex;
align-items: center;
cursor: pointer;
img {
width: 20px;
margin-right: 5px;
}
}
.title {
font-size: 14px;
display: flex;
align-items: center;
img {
width: 20px;
margin-right: 5px;
}
}
span {
font-size: 14px;
}
.close-btn {
width: 20px;
height: 35px;
text-align: right;
line-height: 35px;
cursor: pointer;
}
}
.mini-im-tabbar-input {
height: 130px;
overflow: hidden;
padding: 5px;
position: relative;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
z-index: 9;
textarea {
height: 65px;
padding-right: 5px;
margin: 0;
}
.mini-input-send {
height: 70px;
width: 60px;
background: linear-gradient(to right, #26a2ff, #736cde);
color: #fff;
border: 0;
cursor: pointer;
border-radius: 2px;
}
span.photo-btn {
left: 3px;
}
span.expression-btn {
left: 30px;
}
}
}
.bscroll-vertical-scrollbar {
right: 0px !important;
height: 100% !important;
.bscroll-indicator {
width: 4px !important;
border: 0 !important;
background: rgba(0, 0, 0, 0.2) !important;
right: 0 !important;
}
}
</style> </style>
...@@ -7,7 +7,11 @@ const router = new Router({ ...@@ -7,7 +7,11 @@ const router = new Router({
routes: [ routes: [
{ {
path: '/', path: '/',
name: 'kefu', redirect: '/index'
},
{
path: '/index',
name: 'index',
component: () => import('./views/kefu.vue') component: () => import('./views/kefu.vue')
}, },
{ {
......
const axios = require('axios') import axios from "axios";
export default { export default {
ON_CHANGE_CAR_LIST(context, params) { // 获取消息列表
context.commit('onChangeCarList', params) // params.timestamp
// params.callback
// params.oldMsg old msgs
onGetMessages(context, params) {
const pageSize = 20;
axios
.post("/public/messages", {
timestamp: params.timestamp,
page_size: pageSize
})
.then(response => {
let newMessage = [];
let messages = response.data.data.list || [];
if (messages.length < pageSize) {
context.commit('updateState', { isLoadMorEnd: true })
}
if (params.oldMsg.length == 0 && messages.length > 0) {
newMessage = response.data.data.list
} else if (messages.length > 0) {
newMessage = messages.concat(params.oldMsg);
}
context.commit('updateState', { messages: newMessage })
if (params.callback) params.callback()
})
.catch(error => {
console.log(error);
});
}, },
// 获取用户位置
// APPKey 高德地图web应用key
onGetLocal(context, APPKey) {
axios
.get("https://restapi.amap.com/v3/ip?key=" + APPKey)
.then(response => {
if (response.data.province) {
context.commit('updateState', { userLocal: response.data.province + response.data.city })
}
})
.catch(error => {
console.error(error);
});
},
// 清除未读消息
onCleanRead() {
axios.get("/public/clean_read/");
},
// 上报最后活动时间
onUpdateLastActivity() {
axios.get("/public/activity/");
},
// 用户是否在当前聊天页面
onToggleWindow(context, window) {
axios.put("/public/window/", { window });
},
// 用户是否在当前聊天页面
onGetCompanyInfo(context) {
axios
.get("/public/company")
.then(response => {
context.commit('updateState', { companyInfo: response.data.data })
})
.catch(error => {
console.error(error);
});
},
// 获取上传配置
onGetUploadSecret(context){
axios.get("/public/secret").then(response => {
context.commit('updateState', { uploadToken: response.data.data })
});
}
} }
\ No newline at end of file
...@@ -25,5 +25,42 @@ export default { ...@@ -25,5 +25,42 @@ export default {
}, },
robotAccount(state) { robotAccount(state) {
return state.robotAccount return state.robotAccount
},
isLoadMorEnd(state) {
return state.isLoadMorEnd
},
messages(state) {
return state.messages || []
},
userLocal(state) {
return state.userLocal
},
isLoadMorLoading(state) {
return state.isLoadMorLoading
},
userInfo(state) {
return state.userInfo
},
companyInfo(state) {
return state.companyInfo
},
uploadToken(state) {
return state.uploadToken
},
isIOS() {
return !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
},
isSafari() {
return (
navigator.userAgent.indexOf("Safari") > -1 &&
navigator.userAgent.indexOf("Chrome") < 1
);
},
isJudgeBigScreen() {
let yes = false;
const rate = window.screen.height / window.screen.width;
let limit = window.screen.height == window.screen.availHeight ? 1.8 : 1.65;
if (rate > limit) yes = true;
return yes;
} }
} }
\ No newline at end of file
export default { export default {
updateState(state, newObj){ updateState(state, newObj){
var oldState = state
for (var i in newObj) { for (var i in newObj) {
if(newObj[i] == undefined) continue if(newObj[i] == undefined) continue
state[i] = newObj[i] oldState[i] = newObj[i]
} }
state = oldState
} }
} }
\ No newline at end of file
...@@ -8,4 +8,12 @@ export default { ...@@ -8,4 +8,12 @@ export default {
artificialAccount: null, // 客服账号ID artificialAccount: null, // 客服账号ID
robotInfo: null, // 机器人信息 robotInfo: null, // 机器人信息
robotAccount: null, // 机器人账号ID robotAccount: null, // 机器人账号ID
messages: [], // 消息列表
isLoadMorEnd: false, // 是否已经到末尾
userLocal: "", // 用户地理位置
AmapAPPKey: "", // 高德地图web appkey
isLoadMorLoading: false, // 是否在加装更多消息loading
userInfo: {}, // 用户信息
companyInfo: null, // 公司信息
uploadToken: null, // 上传token
} }
\ No newline at end of file
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
>{{inputPongIngString}}</span> >{{inputPongIngString}}</span>
<mt-header v-if="isShowHeader" fixed :title="isInputPongIng ? inputPongIngString : '在线客服'"> <mt-header v-if="isShowHeader" fixed :title="isInputPongIng ? inputPongIngString : '在线客服'">
<div slot="left"> <div slot="left">
<mt-button @click="back" icon="back"></mt-button> <mt-button @click="$router.go(-1)" icon="back"></mt-button>
</div> </div>
<mt-button @click="headRightBtn" slot="right"> <mt-button @click="headRightBtn" slot="right">
<img title="人工客服" v-if="!isArtificial" src="http://qiniu.cmp520.com/kefu_icon_2000.png" alt /> <img title="人工客服" v-if="!isArtificial" src="http://qiniu.cmp520.com/kefu_icon_2000.png" alt />
...@@ -162,7 +162,6 @@ ...@@ -162,7 +162,6 @@
<span>正在连接中~</span> <span>正在连接中~</span>
</div> </div>
</div> </div>
<div class="mini-im-loading" v-if="isLoading"> <div class="mini-im-loading" v-if="isLoading">
<mt-spinner type="triple-bounce" color="#26a2ff"></mt-spinner> <mt-spinner type="triple-bounce" color="#26a2ff"></mt-spinner>
</div> </div>
...@@ -229,32 +228,23 @@ ...@@ -229,32 +228,23 @@
</template> </template>
<script> <script>
import axios from "axios";
import { Toast, MessageBox } from "mint-ui"; import { Toast, MessageBox } from "mint-ui";
import * as qiniu from "qiniu-js";
var emojiService = require("../../resource/emoji"); var emojiService = require("../../resource/emoji");
import BScroll from "better-scroll"; import BScroll from "better-scroll";
import { mapGetters } from 'vuex' import { mapGetters } from "vuex";
export default { export default {
name: "app", name: "app",
data() { data() {
return { return {
messages: [],
isLoading: true, isLoading: true,
isShowTopLoading: true, isShowTopLoading: true,
userLocal: "", // 用户地理位置
isFirstGetMessage: true, // 第一次获取本地消息 isFirstGetMessage: true, // 第一次获取本地消息
chatValue: "", // 发送消息的内容 chatValue: "", // 发送消息的内容
emojis: emojiService.emojiData, // emoji数据 emojis: emojiService.emojiData, // emoji数据
showEmoji: false, // 是否显示emoji面板 showEmoji: false, // 是否显示emoji面板
userInfo: {}, // 用户信息
companyInfo: null, // 公司信息
uploadToken: null, // 上传token
isLoadMorEnd: false,
isUserSendLongTimeSystemMessage: false, // 本次用户会话超时了是否发送了结束前提示语 isUserSendLongTimeSystemMessage: false, // 本次用户会话超时了是否发送了结束前提示语
isAdminSendLongTimeSystemMessage: false, // 本次客服会话超时了是否发送了结束前提示语 isAdminSendLongTimeSystemMessage: false, // 本次客服会话超时了是否发送了结束前提示语
isInputPongIng: false, isInputPongIng: false,
isLoadMorLoading: false,
isSendPong: false, isSendPong: false,
qiniuObservable: null, qiniuObservable: null,
inputPongIngString: "对方正在输入...", inputPongIngString: "对方正在输入...",
...@@ -271,18 +261,6 @@ export default { ...@@ -271,18 +261,6 @@ export default {
account() { account() {
return this.isArtificial ? this.artificialAccount : this.robotAccount; return this.isArtificial ? this.artificialAccount : this.robotAccount;
}, },
isIOS() {
return !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
},
isSafari() {
return (
navigator.userAgent.indexOf("Safari") > -1 &&
navigator.userAgent.indexOf("Chrome") < 1
);
},
isJudgeBigScreen() {
return this.$judgeBigScreen();
},
viewMessage() { viewMessage() {
var messages = this.messages; var messages = this.messages;
for (let i = 0; i < messages.length; i++) { for (let i = 0; i < messages.length; i++) {
...@@ -295,21 +273,31 @@ export default { ...@@ -295,21 +273,31 @@ export default {
} }
return messages; return messages;
}, },
messages() {
return this.$store.getters.messages.map(i => this.handlerMessage(i));
},
...mapGetters([ ...mapGetters([
'platform', "platform",
'isArtificial', "isArtificial",
'isShowHeader', "isShowHeader",
'isMobile', "isMobile",
'uid', "uid",
'userAccount', "userAccount",
'artificialAccount', "artificialAccount",
'robotInfo', "robotInfo",
'robotAccount', "robotAccount",
"isLoadMorEnd",
"userLocal",
"isLoadMorLoading",
"userInfo",
"isSafari",
"isIOS",
"isJudgeBigScreen"
]) ])
}, },
mounted() { mounted() {
setTimeout(() => { setTimeout(() => {
this.isLoading = false; this.isLoading = true;
this.scroll = new BScroll(this.$refs.miniImBody, { this.scroll = new BScroll(this.$refs.miniImBody, {
click: true, click: true,
tab: true, tab: true,
...@@ -337,12 +325,11 @@ export default { ...@@ -337,12 +325,11 @@ export default {
document.addEventListener("paste", this.inputPaste, false); document.addEventListener("paste", this.inputPaste, false);
}, },
beforeDestroy() { beforeDestroy() {
this.toggleWindow(0); this.$store.dispatch("onToggleWindow", 0);
}, },
methods: { methods: {
// runApp // runApp
runApp() { runApp() {
const IM = this.$mimcInstance;
const user = this.$mimcInstance.getLocalCacheUser(); const user = this.$mimcInstance.getLocalCacheUser();
if ( if (
user && user &&
...@@ -352,7 +339,7 @@ export default { ...@@ -352,7 +339,7 @@ export default {
) { ) {
localStorage.clear(); localStorage.clear();
} }
IM.init( this.$mimcInstance.init(
{ {
type: 0, // 默认0 type: 0, // 默认0
address: this.userLocal, address: this.userLocal,
...@@ -365,31 +352,31 @@ export default { ...@@ -365,31 +352,31 @@ export default {
if (!user) { if (!user) {
setTimeout(() => this.runApp(), 1000); setTimeout(() => this.runApp(), 1000);
} else { } else {
this.isLoading = false;
// handelEvent // handelEvent
this.handelEvent(); this.handelEvent();
// user // user
this.userInfo = user; this.$store.commit("updateState", { userAccount: user.id, userInfo: user });
this.$store.commit("updateState", { userAccount: user.id });
// robot // robot
var robot = IM.robot var robot = this.$mimcInstance.robot;
console.log(robot) console.log(robot);
localStorage.setItem("robot_" + robot.id, JSON.stringify(robot)); localStorage.setItem("robot_" + robot.id, JSON.stringify(robot));
this.$store.commit("updateState", { this.$store.commit("updateState", {
robotAccount: robot.id, robotAccount: robot.id,
robotInfo: robot robotInfo: robot
}); });
// 清除未读消息 // 清除未读消息
this.cleanRead(user.id); this.$store.dispatch("onCleanRead");
// 更换toggle // 更换toggle
this.toggleWindow(1); this.$store.dispatch("onToggleWindow", 1);
// 登录完成发送一条握手消息给机器人 // 登录完成发送一条握手消息给机器人
IM.login(() => { this.$mimcInstance.login(() => {
setTimeout(() => { setTimeout(() => {
// 获取消息记录 // 获取消息记录
this.getMessageRecord(); this.getMessageRecord();
if (!this.artificialAccount) { if (!this.artificialAccount) {
console.log("握手消息"); console.log("握手消息");
IM.sendMessage("handshake", this.robotAccount, ""); this.$mimcInstance.sendMessage("handshake", this.robotAccount, "");
} }
this.scrollIntoBottom(); this.scrollIntoBottom();
}, 500); }, 500);
...@@ -403,8 +390,12 @@ export default { ...@@ -403,8 +390,12 @@ export default {
}, },
// handelEvent // handelEvent
handelEvent() { handelEvent() {
// 发起请求
this.getAllhttp(); // 获取公司信息
this.$store.dispatch("onGetCompanyInfo")
// 获取上传配置信息
this.$store.dispatch("onGetUploadSecret")
// 上报活动时间 // 上报活动时间
this.upLastActivity(); this.upLastActivity();
...@@ -445,25 +436,14 @@ export default { ...@@ -445,25 +436,14 @@ export default {
// 计算用户是否长时间未回复弹出给出提示 // 计算用户是否长时间未回复弹出给出提示
this.onCheckIsloogTimeNotCallBack(); this.onCheckIsloogTimeNotCallBack();
// 关闭top loading
setTimeout(()=> this.isShowTopLoading = false, 1000)
}, },
// 根据IP获取用户地理位置 // 根据IP获取用户地理位置
getLocal() { getLocal() {
var APPKey = ""; // 高德地图web应用key this.$store.dispatch("onGetLocal", this.$store.state.AmapAPPKey);
axios
.get("https://restapi.amap.com/v3/ip?key=" + APPKey)
.then(response => {
if (response.data.province) {
console.log(response.data.province + response.data.city);
this.userLocal = response.data.province + response.data.city;
}
})
.catch(error => {
console.error(error);
});
},
// 刷新页面
resetLoad() {
window.location.reload();
}, },
// 快捷键换行 // 快捷键换行
enterShift(event) { enterShift(event) {
...@@ -499,18 +479,6 @@ export default { ...@@ -499,18 +479,6 @@ export default {
); );
} }
}, },
// 清除未读消息
cleanRead(id) {
axios.get("/public/clean_read/");
},
// 用户是否在当前聊天页面
toggleWindow(window) {
axios.put("/public/window/", { window: window });
},
// 返回上一页按钮
back() {
history.go(-1);
},
// 是否显示用户头像信息(系统消息隐藏) // 是否显示用户头像信息(系统消息隐藏)
isShowInfo(biz_type) { isShowInfo(biz_type) {
return ( return (
...@@ -535,7 +503,7 @@ export default { ...@@ -535,7 +503,7 @@ export default {
upLastActivity() { upLastActivity() {
this.onCheckIsOutSession(); this.onCheckIsOutSession();
const user = this.$mimcInstance.getLocalCacheUser(); const user = this.$mimcInstance.getLocalCacheUser();
if (user) axios.get("/public/activity/"); if (user) this.$store.dispatch("onUpdateLastActivity");
if (this.isArtificial) { if (this.isArtificial) {
localStorage.setItem("artificialTime", Date.now()); localStorage.setItem("artificialTime", Date.now());
} }
...@@ -554,15 +522,15 @@ export default { ...@@ -554,15 +522,15 @@ export default {
} }
} }
}, },
// 获取本地更多数据 // 获取更多数据
loadMorData() { loadMorData() {
if (this.isLoadMorLoading) return; if (this.isLoadMorLoading) return;
if (this.isLoadMorEnd) return; if (this.isLoadMorEnd) return;
this.isLoadMorLoading = true; this.$store.commit("updateState", { isLoadMorLoading: true });
setTimeout(() => { setTimeout(() => {
// 获取消息记录 // 获取消息记录
this.getMessageRecord(); this.getMessageRecord();
this.isLoadMorLoading = false; this.$store.commit("updateState", { isLoadMorLoading: false });
}, 1000); }, 1000);
}, },
// 获取本地缓存的客服信息 // 获取本地缓存的客服信息
...@@ -606,8 +574,7 @@ export default { ...@@ -606,8 +574,7 @@ export default {
Toast({ Toast({
message: "上传失败,请重新上传!" message: "上传失败,请重新上传!"
}); });
const IM = self.$mimcInstance; var message = this.$mimcInstance.createLocalMessage(
var message = IM.createLocalMessage(
"system", "system",
self.account, self.account,
"您刚刚上传的图片失败了,请重新上传!" "您刚刚上传的图片失败了,请重新上传!"
...@@ -641,39 +608,12 @@ export default { ...@@ -641,39 +608,12 @@ export default {
self.$previewRefresh(); self.$previewRefresh();
self.scrollIntoBottom(); self.scrollIntoBottom();
// 系统内置 // 上传
if (self.uploadToken.mode == 1) { self.qiniuObservable = self.$uploadFile({
let fd = new FormData(); file,
fd.append("file", file); mode: self.uploadToken.mode,
fd.append("file_name", fileName); // 七牛才会执行
axios percent(res){
.post("/public/upload", fd)
.then(res => {
uploadSuccess(res.data.data);
})
.catch(() => {
uploadError();
});
}
// 七牛云
else if (self.uploadToken.mode == 2) {
let options = {
quality: 0.92,
noCompressIfLarger: true,
maxWidth: 1500
};
qiniu.compressImage(file, options).then(data => {
const observable = qiniu.upload(
data.dist,
fileName,
self.uploadToken.secret,
{},
{
mimeType: null
}
);
self.qiniuObservable = observable.subscribe({
next: function(res) {
localMessage.percent = Math.ceil(res.total.percent); localMessage.percent = Math.ceil(res.total.percent);
if (res.total.size < 1) { if (res.total.size < 1) {
self.qiniuObservable.unsubscribe(); self.qiniuObservable.unsubscribe();
...@@ -683,29 +623,15 @@ export default { ...@@ -683,29 +623,15 @@ export default {
}); });
} }
}, },
error: function() { success(src){
// 失败后再次使用FormData上传 uploadSuccess(src);
var formData = new FormData();
formData.append("fileType", "image");
formData.append("fileName", "file");
formData.append("key", fileName);
formData.append("token", self.uploadToken.secret);
formData.append("file", file);
axios
.post("https://upload.qiniup.com", formData)
.then(() => {
uploadSuccess(fileName);
})
.catch(() => {
uploadError();
});
}, },
complete: function(res) { fail(){
uploadSuccess(res.key); uploadError();
} }
}); });
});
}
}; };
}, },
// 滚动条置底 // 滚动条置底
...@@ -725,36 +651,6 @@ export default { ...@@ -725,36 +651,6 @@ export default {
window.chatInputInterval = null; window.chatInputInterval = null;
window.scroll(0, 0); window.scroll(0, 0);
}, },
// 获取上传配置
getUploadSecret() {
return axios.get("/public/secret").then(response => {
this.uploadToken = response.data.data;
});
},
// 获取公司信息
getCompanyInfo() {
return axios
.get("/public/company")
.then(response => {
this.companyInfo = response.data.data;
})
.catch(error => {
Toast({
message: error.response.data.message
});
});
},
// 发起并发请求
getAllhttp() {
axios
.all([this.getCompanyInfo(), this.getUploadSecret()])
.then(
axios.spread(() => {
this.isShowTopLoading = false;
})
)
.catch(() => setTimeout(() => this.getAllhttp(), 1000));
},
// 接收消息 // 接收消息
receiveP2PMsg(message) { receiveP2PMsg(message) {
console.log(message); console.log(message);
...@@ -849,8 +745,7 @@ export default { ...@@ -849,8 +745,7 @@ export default {
} }
var chatValue = this.chatValue.trim(); var chatValue = this.chatValue.trim();
if (chatValue == "") return; if (chatValue == "") return;
const IM = this.$mimcInstance; const message = this.$mimcInstance.sendMessage("text", this.account, chatValue);
const message = IM.sendMessage("text", this.account, chatValue);
message.isShowCancel = true; message.isShowCancel = true;
setTimeout(() => (message.isShowCancel = false), 10000); setTimeout(() => (message.isShowCancel = false), 10000);
this.messagesPushMemory(message); this.messagesPushMemory(message);
...@@ -859,8 +754,7 @@ export default { ...@@ -859,8 +754,7 @@ export default {
}, },
// 撤回消息 // 撤回消息
cancelMessage(key) { cancelMessage(key) {
const IM = this.$mimcInstance; const message = this.$mimcInstance.sendMessage("cancel", this.account, key);
const message = IM.sendMessage("cancel", this.account, key);
this.messagesPushMemory(message); this.messagesPushMemory(message);
this.removeMessage(this.userInfo.id, key); this.removeMessage(this.userInfo.id, key);
if (this.qiniuObservable) this.qiniuObservable.unsubscribe(); if (this.qiniuObservable) this.qiniuObservable.unsubscribe();
...@@ -868,8 +762,7 @@ export default { ...@@ -868,8 +762,7 @@ export default {
// 点击知识库消息 // 点击知识库消息
sendKnowledgeMessage(content) { sendKnowledgeMessage(content) {
this.handshakeKeywordList = []; this.handshakeKeywordList = [];
const IM = this.$mimcInstance; const message = this.$mimcInstance.sendMessage("text", this.account, content);
const message = IM.sendMessage("text", this.account, content);
this.messagesPushMemory(message); this.messagesPushMemory(message);
this.chatValue = ""; this.chatValue = "";
}, },
...@@ -927,32 +820,15 @@ export default { ...@@ -927,32 +820,15 @@ export default {
}, },
// 获取服务器消息列表 // 获取服务器消息列表
getMessageRecord() { getMessageRecord() {
const pageSize = 20;
let uid = this.userInfo.id;
let timestamp = let timestamp =
this.messages.length == 0 this.messages.length == 0
? parseInt((new Date().getTime() + " ").substr(0, 10)) ? parseInt((new Date().getTime() + " ").substr(0, 10))
: this.messages[0].timestamp; : this.messages[0].timestamp;
axios let oldMsg = this.messages;
.post("/public/messages", { this.$store.dispatch("onGetMessages", {
timestamp: timestamp, timestamp,
page_size: pageSize oldMsg,
}) callback: () => this.scrollIntoBottom()
.then(response => {
let messages = response.data.data.list || [];
if (messages.length < pageSize) this.isLoadMorEnd = true;
if (this.messages.length == 0 && messages.length > 0) {
this.messages = response.data.data.list.map(i =>
this.handlerMessage(i)
);
this.scrollIntoBottom();
} else if (messages.length > 0) {
messages = messages.map(i => this.handlerMessage(i));
this.messages = messages.concat(this.messages);
}
})
.catch(error => {
console.log(error);
}); });
}, },
// 敲键盘发送pong事件消息 // 敲键盘发送pong事件消息
...@@ -974,7 +850,7 @@ export default { ...@@ -974,7 +850,7 @@ export default {
continue; continue;
newMessages.push(this.messages[i]); newMessages.push(this.messages[i]);
} }
this.messages = newMessages; this.$store.commit("updateState", { messages: newMessages });
}, },
// 生成query // 生成query
createLinkQuery() { createLinkQuery() {
...@@ -987,7 +863,11 @@ export default { ...@@ -987,7 +863,11 @@ export default {
let uid = this.uid ? "&uid=" + this.uid : ""; let uid = this.uid ? "&uid=" + this.uid : "";
let query = let query =
"?h=" + h + "&m=" + m + "&p=" + p + "&r=" + r + "&a=" + a + u + uid; "?h=" + h + "&m=" + m + "&p=" + p + "&r=" + r + "&a=" + a + u + uid;
history.replaceState(null, null, query); history.replaceState(
null,
null,
location.origin + "/#" + this.$route.path + query
);
if ( if (
this.userAccount != null && this.userAccount != null &&
this.userAccount != "null" && this.userAccount != "null" &&
...@@ -1009,8 +889,7 @@ export default { ...@@ -1009,8 +889,7 @@ export default {
!this.isUserSendLongTimeSystemMessage && !this.isUserSendLongTimeSystemMessage &&
Date.now() - lastCallBackMessageTime >= 1000 * 60 * 5 Date.now() - lastCallBackMessageTime >= 1000 * 60 * 5
) { ) {
const IM = this.$mimcInstance; var message = this.$mimcInstance.createLocalMessage(
var message = IM.createLocalMessage(
"system", "system",
this.account, this.account,
"您已超过5分钟未回复消息,系统3分钟后将结束对话" "您已超过5分钟未回复消息,系统3分钟后将结束对话"
...@@ -1034,8 +913,7 @@ export default { ...@@ -1034,8 +913,7 @@ export default {
loogTimeWaitText.trim() != "" && loogTimeWaitText.trim() != "" &&
Date.now() - lastCallBackMessageTime >= 1000 * 60 * 2 Date.now() - lastCallBackMessageTime >= 1000 * 60 * 2
) { ) {
const IM = this.$mimcInstance; var message = this.$mimcInstance.createLocalMessage(
var message = IM.createLocalMessage(
"text", "text",
this.account, this.account,
loogTimeWaitText loogTimeWaitText
...@@ -1054,9 +932,8 @@ export default { ...@@ -1054,9 +932,8 @@ export default {
return; return;
} }
if (this.searchHandshakeTimer) clearTimeout(this.searchHandshakeTimer); if (this.searchHandshakeTimer) clearTimeout(this.searchHandshakeTimer);
const IM = this.$mimcInstance;
this.searchHandshakeTimer = setTimeout(() => { this.searchHandshakeTimer = setTimeout(() => {
IM.sendMessage("search_knowledge", this.robotAccount, this.chatValue); this.$mimcInstance.sendMessage("search_knowledge", this.robotAccount, this.chatValue);
this.searchHandshakeTimer = null; this.searchHandshakeTimer = null;
}, 500); }, 500);
}, },
...@@ -1126,40 +1003,6 @@ export default { ...@@ -1126,40 +1003,6 @@ export default {
</script> </script>
<style lang="stylus"> <style lang="stylus">
body {
min-width: 240px;
overflow: hidden;
height: 100vh;
background-color: #f3f3f3;
}
.mint-header.is-fixed {
height: 50px !important;
background: -webkit-linear-gradient(to right, #26a2ff, #736cde);
background: -o-linear-gradient(to right, #26a2ff, #736cde);
background: -moz-linear-gradient(to right, #26a2ff, #736cde);
background: linear-gradient(to right, #26a2ff, #736cde);
.mint-header-title {
font-size: 15px;
}
}
.mint-header, .mint-tabbar {
min-width: 240px;
z-index: 999999999 !important;
}
.mint-header .is-right {
img {
width: 25px;
}
}
.mint-header .mint-button .mintui {
font-size: 23px !important;
}
.mint-tabbar { .mint-tabbar {
z-index: 999999999 !important; z-index: 999999999 !important;
background-color: #fff !important; background-color: #fff !important;
...@@ -1198,11 +1041,12 @@ body { ...@@ -1198,11 +1041,12 @@ body {
.mini-im-loading { .mini-im-loading {
display: flex; display: flex;
min-width: 240px;
width: 100%; width: 100%;
position: fixed; position: fixed;
height 100vh
top: 0; top: 0;
left: 0; left: 0;
z-index: 9;
right: 0; right: 0;
background-color: #fff !important; background-color: #fff !important;
margin: auto; margin: auto;
...@@ -1456,7 +1300,7 @@ body { ...@@ -1456,7 +1300,7 @@ body {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 9; z-index: 8;
span { span {
color: #999; color: #999;
......
<template> <template>
<div class="container"> <div class="container">
<mt-header v-if="isShowHeader" fixed :title="isInputPongIng ? inputPongIngString : '在线客服'"> <mt-header v-if="isShowHeader" fixed title="工单">
<div slot="left"> <div slot="left">
<mt-button @click="back" icon="back"></mt-button> <mt-button @click="$router.go(-1)" icon="back"></mt-button>
</div> </div>
<mt-button @click="headRightBtn" slot="right"> <mt-button @click="$router.push('/workorder/create')" slot="right">
<img title="人工客服" v-if="!isArtificial" src="http://qiniu.cmp520.com/kefu_icon_2000.png" alt /> <span>创建工单</span>
<span v-else>结束会话</span>
</mt-button> </mt-button>
</mt-header> </mt-header>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'
export default { export default {
name: "workorder", name: "workorder",
components: {}, components: {},
data() { data() {
return {}; return {};
}, },
computed: {
...mapGetters([
'isShowHeader'
])
},
mounted() {}, mounted() {},
methods: {} methods: {
}
}; };
</script> </script>
<style lang="stylus" scoped> <style lang="stylus" scoped>
......
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