You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
327 lines
11 KiB
327 lines
11 KiB
10 months ago
|
define([
|
||
|
'api/kefu',
|
||
|
'api/my',
|
||
|
'kefu-assets/libs/emoji',
|
||
|
'kefu-assets/libs/socket',
|
||
|
'text!./index.html',
|
||
|
'css!./index.css',
|
||
|
"css!/static/css/google.min.css",
|
||
|
"css!/pc/styles/iconfont.css"
|
||
|
], function (kefuApi, myApi, emojiList, Socket, template) {
|
||
|
|
||
|
return {
|
||
|
template,
|
||
|
name: "ChatRoom",
|
||
|
props: {
|
||
|
code_url: String
|
||
|
},
|
||
|
directives: {
|
||
|
drag: {
|
||
|
inserted: function (el) {
|
||
|
let x = 0;
|
||
|
let y = 0;
|
||
|
let l = 0;
|
||
|
let t = 0;
|
||
|
let isDown = false;
|
||
|
el.onmousedown = function (e) {
|
||
|
x = e.clientX;
|
||
|
y = e.clientY;
|
||
|
l = el.parentNode.offsetLeft;
|
||
|
t = el.parentNode.offsetTop;
|
||
|
isDown = true;
|
||
|
el.style.cursor = "move";
|
||
|
window.onmousemove = function (e) {
|
||
|
if (isDown == false) {
|
||
|
return;
|
||
|
}
|
||
|
let nx = e.clientX;
|
||
|
let ny = e.clientY;
|
||
|
let nl = nx - (x - l);
|
||
|
let nt = ny - (y - t);
|
||
|
el.parentNode.style.left = nl + "px";
|
||
|
el.parentNode.style.top = nt + "px";
|
||
|
};
|
||
|
window.onmouseup = function () {
|
||
|
isDown = false;
|
||
|
el.style.cursor = "default";
|
||
|
window.onmousemove = null;
|
||
|
window.onmouseup = null;
|
||
|
};
|
||
|
return false;
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
data() {
|
||
|
return {
|
||
|
emojiList,
|
||
|
emojiShow: false,
|
||
|
recordList: [],
|
||
|
page: 1,
|
||
|
limit: 20,
|
||
|
loading: false,
|
||
|
finished: false,
|
||
|
chatCont: "",
|
||
|
service: {},
|
||
|
serviceList: [],
|
||
|
toUid: 0,
|
||
|
uidTo: 0,
|
||
|
uploadAction: ``,
|
||
|
headers: null,
|
||
|
audio: null,
|
||
|
muted: false,
|
||
|
audioSrc: "/kefu-assets/assets/audio/notice.wav",
|
||
|
chatShow: false,
|
||
|
|
||
|
chatOptions: {
|
||
|
popup: true,
|
||
|
},
|
||
|
|
||
|
myUid: 0
|
||
|
};
|
||
|
},
|
||
|
watch: {
|
||
|
muted(value) {
|
||
|
this.audio.muted = value;
|
||
|
}
|
||
|
},
|
||
|
computed: {
|
||
|
records() {
|
||
|
return this.recordList.map((item, index) => {
|
||
|
if (index) {
|
||
|
if (
|
||
|
item.add_time -
|
||
|
this.recordList[index - 1].add_time >=
|
||
|
300000
|
||
|
) {
|
||
|
item.show = true;
|
||
|
} else {
|
||
|
item.show = false;
|
||
|
}
|
||
|
} else {
|
||
|
item.show = false;
|
||
|
}
|
||
|
return item;
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
created() {
|
||
|
this.$socket = Socket;
|
||
|
this.getToken()
|
||
|
.then(token => {
|
||
|
if (!token) return;
|
||
|
this.initSocket(token);
|
||
|
});
|
||
|
|
||
|
window.addEventListener("click", this.hideEmoji);
|
||
|
|
||
|
},
|
||
|
destroyed() {
|
||
|
window.removeEventListener("click", this.hideEmoji);
|
||
|
this.$socket.then(ws => {
|
||
|
ws.clearEvent();
|
||
|
});
|
||
|
},
|
||
|
mounted() {
|
||
|
this.audio = this.$refs.audio;
|
||
|
},
|
||
|
methods: {
|
||
|
hideEmoji() {
|
||
|
this.emojiShow = false;
|
||
|
},
|
||
|
getSupportInfo() {
|
||
|
if (this.loading) {
|
||
|
return;
|
||
|
}
|
||
|
if (this.finished) {
|
||
|
return;
|
||
|
}
|
||
|
this.loading = true;
|
||
|
kefuApi.get_support_info({
|
||
|
toUid: this.toUid,
|
||
|
page: this.page,
|
||
|
limit: this.limit,
|
||
|
uidTo: this.uidTo
|
||
|
})
|
||
|
.then(res => {
|
||
|
this.myUid = res.data.myUid;
|
||
|
if (!this.toUid) {
|
||
|
this.toUid = res.data.uid;
|
||
|
}
|
||
|
res.data.serviceList.forEach(el => {
|
||
|
if (el.msn_type == 1) {
|
||
|
el.msn = this.replace_em(el.msn);
|
||
|
}
|
||
|
});
|
||
|
let record = res.data.serviceList.length
|
||
|
? res.data.serviceList[0]
|
||
|
: { id: 0 };
|
||
|
this.uidTo = record.id;
|
||
|
this.recordList = res.data.serviceList.concat(this.recordList);
|
||
|
this.loading = false;
|
||
|
this.finished = res.data.serviceList.length < this.limit;
|
||
|
this.service.nickname = res.data.nickname;
|
||
|
this.service.avatar = res.data.avatar;
|
||
|
this.page++;
|
||
|
if (this.page === 2) {
|
||
|
this.$nextTick(() => {
|
||
|
this.$refs.record.scrollTop =
|
||
|
this.$refs.record.scrollHeight - this.$refs.record.clientHeight;
|
||
|
});
|
||
|
|
||
|
if (window.__MSN_TYPE && window.__MSN_ID && window.__MSN_ATTACH_TYPE) {
|
||
|
if (window.__MSN_TYPE == 5) {
|
||
|
this.sendMsg(window.__MSN_ID, window.__MSN_TYPE, window.__MSN_ATTACH_TYPE);
|
||
|
} else if (window.__MSN_TYPE == 21) {
|
||
|
this.sendMsg(window.__MSN_ID, window.__MSN_TYPE, window.__MSN_ATTACH_TYPE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
this.loading = false;
|
||
|
})
|
||
|
.catch(err => {
|
||
|
this.loading = false;
|
||
|
this.$message.error(err.msg || err.message);
|
||
|
});
|
||
|
},
|
||
|
initSocket(token) {
|
||
|
this.$socket.then(ws => {
|
||
|
ws.send({
|
||
|
type: "user_login",
|
||
|
data: token
|
||
|
});
|
||
|
|
||
|
ws.$on(["reply", "chat"], data => {
|
||
|
|
||
|
if (data.is_kefu_send == 1 && data.uid != this.toUid) return;
|
||
|
|
||
|
if (data.msn_type == 1) {
|
||
|
if (data.msn.includes("[") && data.msn.includes("]")) {
|
||
|
data.msn = this.replace_em(data.msn);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.recordList.push(data);
|
||
|
|
||
|
|
||
|
this.$nextTick(function () {
|
||
|
this.$refs.record.scrollTop =
|
||
|
this.$refs.record.scrollHeight - this.$refs.record.clientHeight;
|
||
|
});
|
||
|
|
||
|
|
||
|
if (data.is_kefu_send && this.audio) {
|
||
|
this.audio.play();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
ws.$on("login_success", () => {
|
||
|
this.getSupportInfo();
|
||
|
});
|
||
|
|
||
|
ws.$on("transfer", data => {
|
||
|
this.toUid = data.kefu_id;
|
||
|
});
|
||
|
|
||
|
ws.$on("socket_error", () => {
|
||
|
this.$layer.msg("连接失败");
|
||
|
});
|
||
|
ws.$on("err_tip", data => {
|
||
|
this.$layer.msg(data.msg);
|
||
|
});
|
||
|
});
|
||
|
},
|
||
|
getToken() {
|
||
|
return kefuApi.get_kefu_token()
|
||
|
.then(res => {
|
||
|
return res.msg;
|
||
|
});
|
||
|
},
|
||
|
// enter 发送
|
||
|
ctrlEnter(e) {
|
||
|
if (e.keyCode == 13) {
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
if (this.chatCont.trim()) {
|
||
|
this.sendMessage();
|
||
|
}
|
||
|
},
|
||
|
// 关闭聊天窗口
|
||
|
close() {
|
||
|
this.$forceClose();
|
||
|
},
|
||
|
// 选择表情
|
||
|
selectEmoji(emoji) {
|
||
|
this.emojiShow = false;
|
||
|
let val = `[${emoji}]`;
|
||
|
this.chatCont += val;
|
||
|
},
|
||
|
onScroll(event) {
|
||
|
if (event.target.scrollTop <= 30) {
|
||
|
this.getSupportInfo();
|
||
|
}
|
||
|
},
|
||
|
// 表情包显示隐藏
|
||
|
emojiSwitch() {
|
||
|
this.emojiShow = !this.emojiShow;
|
||
|
},
|
||
|
// 发送消息
|
||
|
sendMessage() {
|
||
|
this.sendMsg(this.chatCont, 1);
|
||
|
this.chatCont = "";
|
||
|
},
|
||
|
toTransfer(data) {
|
||
|
this.socket.send({
|
||
|
data: {
|
||
|
id: data.toUid
|
||
|
},
|
||
|
type: "to_chat"
|
||
|
});
|
||
|
},
|
||
|
// 聊天表情转换
|
||
|
replace_em(str) {
|
||
|
str = str.replace(/\[([^\[\]]+)\]/g, "<span class='em $1'/></span>");
|
||
|
return str;
|
||
|
},
|
||
|
chatEnd() {
|
||
|
this.$forceClose();
|
||
|
},
|
||
|
sendMsg(msn, msn_type, attach_type = 0) {
|
||
|
let obj = {
|
||
|
type: "chat",
|
||
|
data: {
|
||
|
msn,
|
||
|
msn_type,
|
||
|
to_uid: this.toUid,
|
||
|
attach_type,
|
||
|
type: 0
|
||
|
},
|
||
|
};
|
||
|
this.$socket.then((ws) => {
|
||
|
ws.send(obj);
|
||
|
});
|
||
|
},
|
||
|
beforeUpload(file) {
|
||
|
const isImage = file.type === "image/jpeg" || file.type === "image/png";
|
||
|
if (!isImage) {
|
||
|
this.$message.error("上传图片只能是 JPG、PNG 格式!");
|
||
|
}
|
||
|
|
||
|
let param = new FormData(); // 创建form对象
|
||
|
param.append("filename", "file"); // 通过append向form对象添加数据进去
|
||
|
param.append("file", file); // 通过append向form对象添加数据进去
|
||
|
|
||
|
myApi.upload(param)
|
||
|
.then(res => {
|
||
|
if (res.code === 200) {
|
||
|
this.sendMsg(res.data.url, 3);
|
||
|
} else {
|
||
|
this.$message.error(res.msg);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
});
|