Commit 825ca73b by chenxianqi

update code

parent 98c8f64f
var moment = require('moment');
import axios from "axios";
import * as qiniu from "qiniu-js";
// eslint-disable-next-line no-undef
var Helps = {};
Helps.install = function (Vue, options) {
Vue.prototype.$myMethod = function(){
Vue.prototype.$myMethod = function () {
console.log(options)
}
// 格式化日期
Vue.prototype.$formatUnixDate = function(unix, format){
Vue.prototype.$formatUnixDate = function (unix, format) {
return moment(parseInt(unix + '000')).format(format)
}
// 格式化日期(相对日期)
Vue.prototype.$formatFromNowDate = function(unix, format = "YYYY-MM-DD HH:mm"){
if(moment().format("YYYYMMDD") == moment(parseInt(unix + '000')).format("YYYYMMDD")){
Vue.prototype.$formatFromNowDate = function (unix, format = "YYYY-MM-DD HH:mm") {
if (moment().format("YYYYMMDD") == moment(parseInt(unix + '000')).format("YYYYMMDD")) {
return "今天 " + moment(parseInt(unix + '000')).format("HH:mm")
}
return moment(parseInt(unix + '000')).format(format)
}
Vue.prototype.$robotNickname = function(id){
Vue.prototype.$robotNickname = function (id) {
var nickname
var robots = this.$store.getters.robots
for(let i = 0; i< robots.length; i++){
if(robots[i].id == id){
for (let i = 0; i < robots.length; i++) {
if (robots[i].id == id) {
nickname = robots[i].nickname
}
}
return nickname
}
// 判断是否是全面屏
Vue.prototype.$judgeBigScreen = function(){
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;
// 上传文件
Vue.prototype.$uploadFile = function ({ mode, file, percent, success, fail }) {
var qiniuObservable = null;
const fileName = parseInt(Math.random() * 10000 * new Date().getTime()) + file.name.substr(file.name.lastIndexOf("."));
// 系统内置
if (mode == 1) {
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;
\ No newline at end of file
......@@ -5,11 +5,6 @@
</template>
<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 {
name: "app",
data() {
......@@ -21,7 +16,6 @@ export default {
},
mounted() {
console.log(11111)
this.handelUrl()
},
methods: {
......@@ -66,7 +60,7 @@ export default {
isArtificial = true
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
queryToJson(str) {
......@@ -120,732 +114,5 @@ body {
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>
......@@ -7,7 +7,11 @@ const router = new Router({
routes: [
{
path: '/',
name: 'kefu',
redirect: '/index'
},
{
path: '/index',
name: 'index',
component: () => import('./views/kefu.vue')
},
{
......
const axios = require('axios')
import axios from "axios";
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 {
},
robotAccount(state) {
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 {
updateState(state, newObj){
var oldState = state
for (var i in newObj) {
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 {
artificialAccount: null, // 客服账号ID
robotInfo: null, // 机器人信息
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 @@
>{{inputPongIngString}}</span>
<mt-header v-if="isShowHeader" fixed :title="isInputPongIng ? inputPongIngString : '在线客服'">
<div slot="left">
<mt-button @click="back" icon="back"></mt-button>
<mt-button @click="$router.go(-1)" icon="back"></mt-button>
</div>
<mt-button @click="headRightBtn" slot="right">
<img title="人工客服" v-if="!isArtificial" src="http://qiniu.cmp520.com/kefu_icon_2000.png" alt />
......@@ -162,7 +162,6 @@
<span>正在连接中~</span>
</div>
</div>
<div class="mini-im-loading" v-if="isLoading">
<mt-spinner type="triple-bounce" color="#26a2ff"></mt-spinner>
</div>
......@@ -229,32 +228,23 @@
</template>
<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";
import { mapGetters } from 'vuex'
import { mapGetters } from "vuex";
export default {
name: "app",
data() {
return {
messages: [],
isLoading: true,
isShowTopLoading: true,
userLocal: "", // 用户地理位置
isFirstGetMessage: true, // 第一次获取本地消息
chatValue: "", // 发送消息的内容
emojis: emojiService.emojiData, // emoji数据
showEmoji: false, // 是否显示emoji面板
userInfo: {}, // 用户信息
companyInfo: null, // 公司信息
uploadToken: null, // 上传token
isLoadMorEnd: false,
isUserSendLongTimeSystemMessage: false, // 本次用户会话超时了是否发送了结束前提示语
isAdminSendLongTimeSystemMessage: false, // 本次客服会话超时了是否发送了结束前提示语
isInputPongIng: false,
isLoadMorLoading: false,
isSendPong: false,
qiniuObservable: null,
inputPongIngString: "对方正在输入...",
......@@ -271,18 +261,6 @@ export default {
account() {
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() {
var messages = this.messages;
for (let i = 0; i < messages.length; i++) {
......@@ -295,21 +273,31 @@ export default {
}
return messages;
},
messages() {
return this.$store.getters.messages.map(i => this.handlerMessage(i));
},
...mapGetters([
'platform',
'isArtificial',
'isShowHeader',
'isMobile',
'uid',
'userAccount',
'artificialAccount',
'robotInfo',
'robotAccount',
"platform",
"isArtificial",
"isShowHeader",
"isMobile",
"uid",
"userAccount",
"artificialAccount",
"robotInfo",
"robotAccount",
"isLoadMorEnd",
"userLocal",
"isLoadMorLoading",
"userInfo",
"isSafari",
"isIOS",
"isJudgeBigScreen"
])
},
mounted() {
setTimeout(() => {
this.isLoading = false;
this.isLoading = true;
this.scroll = new BScroll(this.$refs.miniImBody, {
click: true,
tab: true,
......@@ -337,12 +325,11 @@ export default {
document.addEventListener("paste", this.inputPaste, false);
},
beforeDestroy() {
this.toggleWindow(0);
this.$store.dispatch("onToggleWindow", 0);
},
methods: {
// runApp
runApp() {
const IM = this.$mimcInstance;
const user = this.$mimcInstance.getLocalCacheUser();
if (
user &&
......@@ -352,7 +339,7 @@ export default {
) {
localStorage.clear();
}
IM.init(
this.$mimcInstance.init(
{
type: 0, // 默认0
address: this.userLocal,
......@@ -365,31 +352,31 @@ export default {
if (!user) {
setTimeout(() => this.runApp(), 1000);
} else {
this.isLoading = false;
// handelEvent
this.handelEvent();
// user
this.userInfo = user;
this.$store.commit("updateState", { userAccount: user.id });
this.$store.commit("updateState", { userAccount: user.id, userInfo: user });
// robot
var robot = IM.robot
console.log(robot)
var robot = this.$mimcInstance.robot;
console.log(robot);
localStorage.setItem("robot_" + robot.id, JSON.stringify(robot));
this.$store.commit("updateState", {
robotAccount: robot.id,
robotInfo: robot
});
// 清除未读消息
this.cleanRead(user.id);
this.$store.dispatch("onCleanRead");
// 更换toggle
this.toggleWindow(1);
this.$store.dispatch("onToggleWindow", 1);
// 登录完成发送一条握手消息给机器人
IM.login(() => {
this.$mimcInstance.login(() => {
setTimeout(() => {
// 获取消息记录
this.getMessageRecord();
if (!this.artificialAccount) {
console.log("握手消息");
IM.sendMessage("handshake", this.robotAccount, "");
this.$mimcInstance.sendMessage("handshake", this.robotAccount, "");
}
this.scrollIntoBottom();
}, 500);
......@@ -403,8 +390,12 @@ export default {
},
// handelEvent
handelEvent() {
// 发起请求
this.getAllhttp();
// 获取公司信息
this.$store.dispatch("onGetCompanyInfo")
// 获取上传配置信息
this.$store.dispatch("onGetUploadSecret")
// 上报活动时间
this.upLastActivity();
......@@ -445,25 +436,14 @@ export default {
// 计算用户是否长时间未回复弹出给出提示
this.onCheckIsloogTimeNotCallBack();
// 关闭top loading
setTimeout(()=> this.isShowTopLoading = false, 1000)
},
// 根据IP获取用户地理位置
getLocal() {
var APPKey = ""; // 高德地图web应用key
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();
this.$store.dispatch("onGetLocal", this.$store.state.AmapAPPKey);
},
// 快捷键换行
enterShift(event) {
......@@ -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) {
return (
......@@ -535,7 +503,7 @@ export default {
upLastActivity() {
this.onCheckIsOutSession();
const user = this.$mimcInstance.getLocalCacheUser();
if (user) axios.get("/public/activity/");
if (user) this.$store.dispatch("onUpdateLastActivity");
if (this.isArtificial) {
localStorage.setItem("artificialTime", Date.now());
}
......@@ -554,15 +522,15 @@ export default {
}
}
},
// 获取本地更多数据
// 获取更多数据
loadMorData() {
if (this.isLoadMorLoading) return;
if (this.isLoadMorEnd) return;
this.isLoadMorLoading = true;
this.$store.commit("updateState", { isLoadMorLoading: true });
setTimeout(() => {
// 获取消息记录
this.getMessageRecord();
this.isLoadMorLoading = false;
this.$store.commit("updateState", { isLoadMorLoading: false });
}, 1000);
},
// 获取本地缓存的客服信息
......@@ -606,8 +574,7 @@ export default {
Toast({
message: "上传失败,请重新上传!"
});
const IM = self.$mimcInstance;
var message = IM.createLocalMessage(
var message = this.$mimcInstance.createLocalMessage(
"system",
self.account,
"您刚刚上传的图片失败了,请重新上传!"
......@@ -641,39 +608,12 @@ export default {
self.$previewRefresh();
self.scrollIntoBottom();
// 系统内置
if (self.uploadToken.mode == 1) {
let fd = new FormData();
fd.append("file", file);
fd.append("file_name", fileName);
axios
.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) {
// 上传
self.qiniuObservable = self.$uploadFile({
file,
mode: self.uploadToken.mode,
// 七牛才会执行
percent(res){
localMessage.percent = Math.ceil(res.total.percent);
if (res.total.size < 1) {
self.qiniuObservable.unsubscribe();
......@@ -683,29 +623,15 @@ export default {
});
}
},
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(() => {
uploadSuccess(fileName);
})
.catch(() => {
uploadError();
});
success(src){
uploadSuccess(src);
},
complete: function(res) {
uploadSuccess(res.key);
fail(){
uploadError();
}
});
});
}
};
},
// 滚动条置底
......@@ -725,36 +651,6 @@ export default {
window.chatInputInterval = null;
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) {
console.log(message);
......@@ -849,8 +745,7 @@ export default {
}
var chatValue = this.chatValue.trim();
if (chatValue == "") return;
const IM = this.$mimcInstance;
const message = IM.sendMessage("text", this.account, chatValue);
const message = this.$mimcInstance.sendMessage("text", this.account, chatValue);
message.isShowCancel = true;
setTimeout(() => (message.isShowCancel = false), 10000);
this.messagesPushMemory(message);
......@@ -859,8 +754,7 @@ export default {
},
// 撤回消息
cancelMessage(key) {
const IM = this.$mimcInstance;
const message = IM.sendMessage("cancel", this.account, key);
const message = this.$mimcInstance.sendMessage("cancel", this.account, key);
this.messagesPushMemory(message);
this.removeMessage(this.userInfo.id, key);
if (this.qiniuObservable) this.qiniuObservable.unsubscribe();
......@@ -868,8 +762,7 @@ export default {
// 点击知识库消息
sendKnowledgeMessage(content) {
this.handshakeKeywordList = [];
const IM = this.$mimcInstance;
const message = IM.sendMessage("text", this.account, content);
const message = this.$mimcInstance.sendMessage("text", this.account, content);
this.messagesPushMemory(message);
this.chatValue = "";
},
......@@ -927,32 +820,15 @@ export default {
},
// 获取服务器消息列表
getMessageRecord() {
const pageSize = 20;
let uid = this.userInfo.id;
let timestamp =
this.messages.length == 0
? parseInt((new Date().getTime() + " ").substr(0, 10))
: this.messages[0].timestamp;
axios
.post("/public/messages", {
timestamp: timestamp,
page_size: pageSize
})
.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);
let oldMsg = this.messages;
this.$store.dispatch("onGetMessages", {
timestamp,
oldMsg,
callback: () => this.scrollIntoBottom()
});
},
// 敲键盘发送pong事件消息
......@@ -974,7 +850,7 @@ export default {
continue;
newMessages.push(this.messages[i]);
}
this.messages = newMessages;
this.$store.commit("updateState", { messages: newMessages });
},
// 生成query
createLinkQuery() {
......@@ -987,7 +863,11 @@ export default {
let uid = this.uid ? "&uid=" + this.uid : "";
let query =
"?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 (
this.userAccount != null &&
this.userAccount != "null" &&
......@@ -1009,8 +889,7 @@ export default {
!this.isUserSendLongTimeSystemMessage &&
Date.now() - lastCallBackMessageTime >= 1000 * 60 * 5
) {
const IM = this.$mimcInstance;
var message = IM.createLocalMessage(
var message = this.$mimcInstance.createLocalMessage(
"system",
this.account,
"您已超过5分钟未回复消息,系统3分钟后将结束对话"
......@@ -1034,8 +913,7 @@ export default {
loogTimeWaitText.trim() != "" &&
Date.now() - lastCallBackMessageTime >= 1000 * 60 * 2
) {
const IM = this.$mimcInstance;
var message = IM.createLocalMessage(
var message = this.$mimcInstance.createLocalMessage(
"text",
this.account,
loogTimeWaitText
......@@ -1054,9 +932,8 @@ export default {
return;
}
if (this.searchHandshakeTimer) clearTimeout(this.searchHandshakeTimer);
const IM = this.$mimcInstance;
this.searchHandshakeTimer = setTimeout(() => {
IM.sendMessage("search_knowledge", this.robotAccount, this.chatValue);
this.$mimcInstance.sendMessage("search_knowledge", this.robotAccount, this.chatValue);
this.searchHandshakeTimer = null;
}, 500);
},
......@@ -1126,40 +1003,6 @@ export default {
</script>
<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 {
z-index: 999999999 !important;
background-color: #fff !important;
......@@ -1198,11 +1041,12 @@ body {
.mini-im-loading {
display: flex;
min-width: 240px;
width: 100%;
position: fixed;
height 100vh
top: 0;
left: 0;
z-index: 9;
right: 0;
background-color: #fff !important;
margin: auto;
......@@ -1456,7 +1300,7 @@ body {
display: flex;
align-items: center;
justify-content: center;
z-index: 9;
z-index: 8;
span {
color: #999;
......
<template>
<div class="container">
<mt-header v-if="isShowHeader" fixed :title="isInputPongIng ? inputPongIngString : '在线客服'">
<mt-header v-if="isShowHeader" fixed title="工单">
<div slot="left">
<mt-button @click="back" icon="back"></mt-button>
<mt-button @click="$router.go(-1)" icon="back"></mt-button>
</div>
<mt-button @click="headRightBtn" slot="right">
<img title="人工客服" v-if="!isArtificial" src="http://qiniu.cmp520.com/kefu_icon_2000.png" alt />
<span v-else>结束会话</span>
<mt-button @click="$router.push('/workorder/create')" slot="right">
<span>创建工单</span>
</mt-button>
</mt-header>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: "workorder",
components: {},
data() {
return {};
},
computed: {
...mapGetters([
'isShowHeader'
])
},
mounted() {},
methods: {}
methods: {
}
};
</script>
<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