yuminge-app/yun-min-program-plugin-master/packageH/chitchat/chatWindow/chatWindow.js

1263 lines
34 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// packageH/chitchat/chatWindow/chatWindow.js
const app = getApp();
let emojiList = [],
emojiObjs = {};
Page({
/**
* 页面的初始数据
*/
data: {
msgText: "",
heartBeatInterval: null,
msg_id_list: [],
chatType: 1,
employeeId: 0,
groupId: 0,
userUid: 0,
queue_id: 0, //会话ID
emojiList: [],
emojiObjs: {},
chatList: [],
emojisTmp: [],
goodsList: [],
goodsPopupShow: false,
goodsSearchKwd: "",
orderList: [],
orderPopupShow: false,
orderSearchKeyword: "",
replyList: [],
replyPopupShow: false,
replySearchKwd: "",
transferEmployeeList: [],
transferPopupShow: false,
transferSearchKwd: "",
websock: null,
timeout: 3 * 1000, //todo 30秒一次心跳
timeoutObj: null, //心跳心跳倒计时
serverTimeoutObj: null, //心跳倒计时
timeoutnum: null, //断开 重连倒计时
isClosed: false,
lockReconnect: false, //锁定重连状态
maxReconnectNum: 10, //最大重连次数
currentReconnectNum: 0, //当前重连次数
scrollTopTarget: "", //滚动目标
scrollTopAnimation: false,
chatLoadedPage: 1,
chatFinished: false,
chatGetLoading: false,
operation: {
iptFocus: false, //当前是否聚焦
flag: false, //状态,默认关闭/降下
height: 50, //键盘高度默认50单位px
riseHeight: 220, //升起默认265
dropHeight: 50, //降下默认高度 50
isRiseFlag: false, //是否已经获取键盘高度了
safeBottom: 0, //底部安全距离
emotion: false, //表情框是否打开
iptCursor: 0, //光标位置
},
chat_opt_setting: {},
goodsObj: {
//从商品进来,该商品的相关数据
show: false,
info: {},
},
withdrawObj: {
//撤回相关坐标和信息
left: 0,
top: 0,
height: 30,
width: 75,
show: false,
item: {}, //操作的item
direction: 0, //0表示在消息上面1表示在消息下面
},
show_tool_bar:0,
chat_tool_bars:[]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
if (options.goods_id && options.goods_id != 0) {
this.getGoodsDetails(options.goods_id);
}
console.log(this.data.chatType);
console.log(options);
this.setData({
emojiList: emojiList,
emojiObjs: emojiObjs,
chatType: options.chatType,
employeeId: options.employeeId,
groupId: options.groupId,
userUid: options.user_id,
});
let screenHeight = wx.getSystemInfoSync().screenHeight;
let bottom = wx.getSystemInfoSync().safeArea.bottom;
this.setData({
"operation.safeBottom": screenHeight - bottom,
});
this.init();
if (this.data.chatType == 2) {
this.getReplyList();
}
this.getOrderList();
},
handClickChatToolBars(evt){
let item = evt.currentTarget.dataset.item;
if(item.type==0){
this.data.msgText = item.key_word;
this.sendMsg(0);
}else if(item.type==1) {
wx.navigateTo({
url: item.mini_app_link,
fail: (err) => {
app.tips("客服路由出错");
}
});
}
},
bindClickInput(e) {
console.log("点击", e);
let {
operation
} = this.data;
if (!operation.isRiseFlag) return;
console.log(operation.iptFocus, operation.flag);
this.setData({
"operation.iptFocus": true,
"operation.flag": true,
"operation.height": operation.riseHeight + operation.dropHeight,
},
() => {
this.scrollBottom();
}
);
console.log("点击");
},
inputFocus(e) {
console.log("获取光标", e);
let height = e.detail.height;
let {
operation
} = this.data;
if (operation.isRiseFlag) return;
if (height == 0) height = 220;
if (height != operation.riseHeight) {
this.setData({
"operation.riseHeight": height,
});
}
this.setData({
"goodsObj.show": false,
"operation.isRiseFlag": true,
"operation.iptFocus": true,
"operation.flag": true,
"operation.height": operation.riseHeight + operation.dropHeight,
});
this.scrollBottom();
console.log(e);
},
handLongpress(evt) {
let {
index,
item
} = evt.currentTarget.dataset;
let target = "#my-info-" + index;
console.log(target);
wx.createSelectorQuery()
.select(target)
.boundingClientRect((res) => {
console.log(res);
let {
top,
width,
left,
bottom
} = res;
let {
withdrawObj
} = this.data;
let lt = left - (withdrawObj.width - width) / 2;
let tp = top - withdrawObj.height - 15;
let direction = 0;
console.log(withdrawObj.width - width);
if (top < 80) {
direction = 1;
tp = bottom + 15;
}
this.setData({
"withdrawObj.direction": direction,
"withdrawObj.left": lt,
"withdrawObj.top": tp,
"withdrawObj.show": true,
"withdrawObj.item": item,
});
})
.exec();
},
inputBlur(e) {
this.data.operation.iptCursor = e.detail.cursor;
setTimeout(() => {
console.log("我先执行2");
this.setData({
"operation.iptFocus": false,
});
}, 300);
},
handClickAddIcon() {
wx.hideKeyboard();
this.setOpetFlag();
},
setOpetFlag() {
let {
operation
} = this.data;
console.log("我先执行", operation);
if (operation.flag == false) {
//升高
this.setData({
"goodsObj.show": false,
"operation.flag": true,
"operation.height": operation.riseHeight + operation.dropHeight,
},
() => {
this.scrollBottom();
}
);
} else if (operation.iptFocus == false) {
//降下
this.setData({
"operation.flag": false,
"operation.height": operation.dropHeight,
});
}
},
setEmotionFlag() {
wx.hideKeyboard();
this.setData({
"operation.emotion": !this.data.operation.emotion,
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {},
viewPicture(e) {
let src = e.currentTarget.dataset.src;
let arr = [];
let chatList = this.data.chatList;
chatList.forEach((item) => {
if (item.content_type == 1) {
arr.push(item.content);
}
});
wx.previewImage({
urls: arr,
current: src,
});
console.log(src, this.data.chatList);
},
floatDeFocus() {
this.setData({
"withdrawObj.show": false,
"operation.emotion": false,
});
},
getGoodsDetails(id) {
let url = app.getNetAddresss("plugin.yun-chat.frontend.goods.queryOne");
let json = {
id
};
app._postNetWork({
url: url,
data: json,
success: (resdata) => {
let res = resdata.data;
if (res.result === 1) {
this.setData({
"goodsObj.info": res.data,
"goodsObj.show": true,
});
setTimeout(() => {
this.setData({
"goodsObj.show": false,
});
}, 5000);
}
},
});
},
bindSendGoods() {
this.setData({
"goodsObj.show": false,
});
let goods = this.data.goodsObj.info;
let goodsTmp = {};
goodsTmp["id"] = goods.id;
goodsTmp["title"] = goods.title;
goodsTmp["thumb"] = goods.thumb;
goodsTmp["price"] = goods.price;
console.log(JSON.stringify(goodsTmp));
this.data.msgText = encodeURIComponent(JSON.stringify(goodsTmp));
this.sendMsg(2);
},
backMsg() {
this.floatDeFocus();
let id = this.data.withdrawObj.item.id;
let url = "";
if (this.data.chatType == 1) {
url = app.getNetAddresss("plugin.yun-chat.frontend.h5.chat.backed-msg");
} else if (this.data.chatType == 2) {
url = app.getNetAddresss("plugin.yun-chat.frontend.chat.backed-msg");
}
app._postNetWork({
url: url,
data: {
id
},
success: (resdata) => {
let res = resdata.data;
if (res.result != 1) return app.tips(res.msg);
let chatListTemp = [];
for (let i = 0; i < this.data.chatList.length; i++) {
if (this.data.chatList[i]["id"] == id) {
this.data.chatList[i]["is_backed"] = 1;
}
chatListTemp.push(this.data.chatList[i]);
}
this.setData({
chatList: chatListTemp
});
},
});
},
sendMsgBtn() {
this.sendMsg(0);
},
sendMsg(content_type) {
if (!this.data.msgText) {
return;
}
let lastChat = this.data.chatList[this.data.chatList.length - 1];
let addTime = false;
if (lastChat) {
let timeDiff = getTimeDiff(Date.now(), lastChat["created_at"]);
if (timeDiff.minutes > 5 || timeDiff.hours > 0 || timeDiff.datys > 0) {
addTime = true;
}
}
let text = this.data.msgText;
for (let i = 0; i < this.data.emojisTmp.length; i++) {
text = text.replace(this.data.emojisTmp[i]["text"], this.data.emojisTmp[i]["name"]);
}
let json = {
text: text,
content_type: content_type,
queue_id: this.data.queue_id
};
let url = "";
let receiveTextObj;
if (this.data.chatType == 1) {
receiveTextObj = this.generateChatData(text, 1, this.getNowDateTime(), content_type);
url = app.getNetAddresss("plugin.yun-chat.frontend.h5.chat.sendMsg");
// json.employee_id = this.data.employeeId;
} else if (this.data.chatType == 2) {
receiveTextObj = this.generateChatData(text, 0, this.getNowDateTime(), content_type);
url = app.getNetAddresss("plugin.yun-chat.frontend.chat.sendMsg");
// json.user_uid = this.data.userUid;
}
// let chatListTemp = this.data.chatList;
// chatListTemp.push(receiveTextObj);
// this.setData({chatList:chatListTemp});
let msgIndex = this.data.chatList.length;
this.setData({
["chatList[" + msgIndex + "]"]:receiveTextObj
});
this.scrollBottom();
app._postNetWork({
url: url,
data: json,
success: (resdata) => {
let res = resdata.data;
if (res.result === 1) {
// 直接获取返回的格式插入
this.fmtChatList(res.data);
//this.data.chatList.push(res.data);
this.setData({
["chatList[" + msgIndex + "]"]:res.data
});
// let target = "chatList["+msgIndex+"].id";
// this.setData({
// // [target]:res.data.id,
// chatList: this.data.chatList,
// });
if (addTime) {
let chatList = this.data.chatList;
chatList.splice(msgIndex-1, 0, {
_is_time: true,
_message_time: formatDate(Date.now(), "h:i"),
});
this.setData({
chatList
});
}
// console.log(res.data, this.data.chatList, "this.data.chatList2");
} else {
this.data.chatList.push({
...receiveTextObj,
send_fail: 1
});
this.setData({
chatList: this.data.chatList
});
app.tips(res.msg);
}
},
fail:()=>{
let indexStr = "chatList["+msgIndex+"].send_fail";
this.setData({
[indexStr]:1
});
}
});
this.setData({
msgText: "",
});
},
generateChatData(content, direction_type, time, content_type) {
let res = {};
res["id"] = 0;
if (content_type == 2 || content_type == 3) {
res["content"] = JSON.parse(decodeURIComponent(content));
} else if (content_type == 1) {
res["content"] = content;
} else if (content_type == 0) {
res["content"] = this.replaceEmoji(content);
}
res["content_type"] = content_type;
res["direction_type"] = direction_type;
res["created_at"] = time;
return res;
},
replaceEmoji(content) {
let that = this;
return content.replace(/face\[([^\s\[\]]+?)\]/g, function (i) {
return '<img src="' + that.data.emojiObjs[i]["url"] + '" style="width:30px;height:30px;"/>';
});
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
this.clearHeartBeat();
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
this.clearHeartBeat();
this.data.isClosed = true;
if (this.data.websock) {
this.data.websock.close();
}
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {},
selectImage() {
wx.chooseImage({
count: 9,
sizeType: ["original", "compressed"],
sourceType: ["album", "camera"],
success: (res) => {
// var tempFilePaths = res.tempFilePaths
console.log(res.tempFilePaths);
this.unload({
tempFilePaths: res.tempFilePaths,
});
},
});
},
//多张上传方法
unload(data) {
if (data.tempFilePaths.length == 0) return;
wx.showLoading({
title: "上传中",
});
let urlStr = app.getNetAddresss("upload.uploadPic");
wx.uploadFile({
url: urlStr,
filePath: data.tempFilePaths[0],
name: "file",
formData: null,
success: (resdata) => {
var res = JSON.parse(resdata.data);
res.data.img_url;
this.data.msgText = res.data.img_url;
this.sendMsg(1);
},
complete: (e) => {
wx.hideLoading();
data.tempFilePaths.shift();
this.unload(data);
},
});
},
init() {
let url = app.getNetAddresss("plugin.yun-chat.frontend.h5.chat.index");
if (this.data.chatType == 2) url = app.getNetAddresss("plugin.yun-chat.frontend.chat.index");
app._postNetWork({
url: url,
data: {
group_id: this.data.groupId,
employee_id: this.data.employeeId,
user_uid: this.data.userUid
},
success: (resdata) => {
let res = resdata.data;
if (res.result !== 1) return app.tips(res.msg);
if (!res.data.employee_info) return app.tips("客服都不在线");
let emojiList = res.data.emoji_list;
let emojiObjs = {};
for (let i = 0; i < emojiList.length; i++) {
emojiObjs[emojiList[i]["name"]] = emojiList[i];
}
this.setData({
emojiList,
emojiObjs,
employeeInfo: res.data.employee_info,
userUid: res.data.member_info.uid,
memberInfo: res.data.member_info,
employeeId: res.data.employee_info.id,
});
if (res.data.queue_info) {
this.setData({
queue_id: res.data.queue_info.id,
});
}
if (res.data.queue_list) {
let userObj = res.data.queue_list.filter((item) => {
return item.uid == this.data.userUid;
})[0];
if (userObj && userObj.id) {
this.setData({
queue_id: userObj.id,
});
}
}
wx.setNavigationBarTitle({
title: this.data.chatType == 2 ? this.data.memberInfo.nickname : this.data.employeeInfo.nickname,
});
this.initWebSocket();
this.getChatList();
},
});
},
getChatList() {
if (this.data.chatGetLoading || this.data.chatFinished) return;
this.setData({
chatGetLoading: true
});
let url = app.getNetAddresss("plugin.yun-chat.frontend.h5.chat.chats");
if (this.data.chatType == 2) url = app.getNetAddresss("plugin.yun-chat.frontend.chat.chats");
let json = {
page: this.data.chatLoadedPage,
queue_id: this.data.queue_id
};
// if (this.data.chatType == 1) json.employee_id = this.data.employeeId;
// if (this.data.chatType == 2) json.user_uid = this.data.userUid;
app._postNetWork({
url: url,
data: json,
success: (resdata) => {
this.setData({
chatGetLoading: false
});
let res = resdata.data;
if (res.result !== 1) return app.tips(res.msg);
if (res.data.last_page == res.data.current_page || res.data.data.length < res.data.per_page) {
this.setData({
chatFinished: true
});
}
let chatList = JSON.parse(JSON.stringify(res.data.data));
let localLastChat = this.data.chatList[0];
let addTimeIndexs = [];
let addTimeSourceDataIndex = [];
chatList.reduce((previous, current, currentIndex, list) => {
if (previous === undefined) {
previous = list[currentIndex - 1];
}
if (previous) {
const {
minutes,
hours,
days
} = getTimeDiff(current["created_at"], previous["created_at"]);
if (minutes > 5 || hours > 1 || days > 1) {
addTimeIndexs.push(currentIndex + addTimeIndexs.length);
addTimeSourceDataIndex.push(currentIndex);
}
}
});
for (let index = 0; index < addTimeIndexs.length; index++) {
const chatIndex = addTimeIndexs[index];
chatList.splice(chatIndex, 0, {
_is_time: true,
_message_time: formatDate(res.data.data[addTimeSourceDataIndex[index]]["created_at"], "h:i"),
});
}
let listData = this.data.chatList;
listData.unshift(...this.fmtChatList(chatList));
if (localLastChat && chatList.length > 0) {
const {
hours,
minutes,
days
} = getTimeDiff(localLastChat["created_at"], chatList[chatList.length - 1]["created_at"]);
if (minutes > 5 || hours > 1 || days > 1) {
listData.unshift({
_is_time: true,
_message_time: formatDate(res.data.data[0]["created_at"], "y年m月d日 h:i:s"),
});
}
} else {
// Toast(msg);
}
if (this.data.chatLoadedPage == 1) {
let scrollTopTarget = "listItem" + (listData.length - 1);
this.setData({
chatList: listData
}, () => {
setTimeout(() => {
this.setData({
scrollTopTarget
}, () => {
this.setData({
scrollTopAnimation: true
});
});
}, 100);
});
} else {
this.setData({
scrollTopAnimation: false
});
console.log(chatList.length);
let scrollTopTarget = "listItem" + (chatList.length - 1);
this.setData({
scrollTopTarget,
chatList: listData
}, () => {});
}
this.data.chatLoadedPage++;
},
});
},
selectEmoji(evt) {
let item = evt.currentTarget.dataset.item;
let emoji_text = item.text;
let msgText = this.data.msgText;
let iptCursor = this.data.operation.iptCursor;
this.setData({
msgText: msgText.substring(0, iptCursor) + emoji_text + msgText.substring(iptCursor, msgText.length),
"operation.emotion": false,
});
this.data.operation.iptCursor += emoji_text.length;
this.data.emojisTmp.push(item);
},
//滚动到底部
scrollBottom() {
console.log("执行");
this.setData({
scrollTopAnimation: true
});
setTimeout(() => {
console.log("延迟滚动");
if (this.data.scrollTopTarget == "listItemBottom1") {
this.setData({
scrollTopTarget: "listItemBottom2"
});
} else {
this.setData({
scrollTopTarget: "listItemBottom1"
});
}
}, 400);
},
handInput(e) {
console.log("输入时触发", e);
},
handPageTouchStart() {
console.log("zhix handPageTouchStart");
this.floatDeFocus();
let {
operation
} = this.data;
if (!operation.flag) return;
wx.hideKeyboard();
this.setData({
"operation.flag": false,
"operation.height": operation.dropHeight,
});
},
getNowDateTime() {
let date = new Date();
let seperator1 = "-";
let seperator2 = ":";
let month = date.getMonth() + 1;
let strDate = date.getDate();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
let currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate + " " + date.getHours() + seperator2 + date.getMinutes() + seperator2 + date.getSeconds(); //年月日时分秒
return currentdate;
},
fmtChatList(chatList) {
// 处理商品或表情消息
if (chatList instanceof Array) {
for (let i = 0; i < chatList.length; i++) {
if (chatList[i]["content_type"] == 2 || chatList[i]["content_type"] == 3) {
chatList[i]["content"] = JSON.parse(decodeURIComponent(chatList[i]["content"]));
} else if (chatList[i]["content_type"] == 0) {
chatList[i]["content"] = this.replaceEmoji(chatList[i]["content"]);
}
}
} else if (chatList instanceof Object) {
if (chatList["content_type"] == 2 || chatList["content_type"] == 3) {
chatList["content"] = JSON.parse(decodeURIComponent(chatList["content"]));
} else if (chatList["content_type"] == 0) {
chatList["content"] = this.replaceEmoji(chatList["content"]);
}
}
return chatList;
},
getGoodsList() {
let url = app.getNetAddresss("plugin.yun-chat.frontend.goods.queryList");
app._postNetWork({
url: url,
data: {
kwd: this.data.goodsSearchKwd
},
success: (resdata) => {
let res = resdata.data;
if (res.result !== 1) return app.tips(res.msg);
this.setData({
goodsList: res.data,
});
},
});
},
selectGoods(evt) {
let item = evt.currentTarget.dataset.item;
// 发送商品消息
let goodsTmp = {};
goodsTmp["id"] = item.id;
goodsTmp["title"] = item.title;
goodsTmp["thumb"] = item.thumb;
goodsTmp["price"] = item.price;
console.log(JSON.stringify(goodsTmp));
this.data.msgText = encodeURIComponent(JSON.stringify(goodsTmp));
console.log(this.msgText);
this.sendMsg(2);
this.setGoodsPopupShow();
},
setGoodsPopupShow() {
this.setData({
goodsPopupShow: !this.data.goodsPopupShow,
});
},
getOrderList() {
let url = "";
let json = {};
if (this.data.chatType == 1) {
url = app.getNetAddresss("order.list");
json = {
keyword: this.data.orderSearchKeyword
};
} else if (this.data.chatType == 2) {
url = app.getNetAddresss("plugin.yun-chat.frontend.order-list.get-data");
json = {
user_uid: this.data.userUid,
order_sn: this.data.orderSearchKeyword
};
}
app._postNetWork({
url: url,
data: json,
success: (resdata) => {
let res = resdata.data;
if (res.result !== 1) return app.tips(res.msg);
let orderList;
if (this.data.chatType == 1) {
orderList = res.data.data;
} else if (this.data.chatType == 2) {
orderList = res.data;
}
this.setData({
orderList
});
},
});
},
selectOrder(evt) {
let item = evt.currentTarget.dataset.item;
// 发送订单消息
this.data.msgText = encodeURIComponent(JSON.stringify(item));
this.sendMsg(3);
this.setOrderPopupShow();
},
setOrderPopupShow() {
this.setData({
orderPopupShow: !this.data.orderPopupShow,
});
},
getReplyList() {
let url = app.getNetAddresss("plugin.yun-chat.frontend.common-reply.query");
app._postNetWork({
url: url,
data: {
kwd: this.data.replySearchKwd
},
success: (resdata) => {
let res = resdata.data;
if (res.result !== 1) return app.tips(res.msg);
this.setData({
replyList: res.data,
});
},
});
},
selectReply(evt) {
let item = evt.currentTarget.dataset.item;
// 发送订单消息
this.data.msgText = item.content;
this.sendMsg(0);
this.setReplyPopupShow();
},
setReplyPopupShow() {
this.setData({
replyPopupShow: !this.data.replyPopupShow,
});
},
getTransferEmployeeList() {
let url = app.getNetAddresss("plugin.yun-chat.frontend.employee.queryList");
app._postNetWork({
url: url,
data: {
kwd: this.data.transferSearchKwd
},
success: (resdata) => {
let res = resdata.data;
if (res.result !== 1) return app.tips(res.msg);
this.setData({
transferEmployeeList: res.data,
});
},
});
},
async selectTransfer(evt) {
let item = evt.currentTarget.dataset.item;
let confirmFlag = await app.confirm(`确定转接给(${item.nickname})对接?`);
if (!confirmFlag) return;
let url = app.getNetAddresss("plugin.yun-chat.frontend.chat.transfer");
app._postNetWork({
url: url,
data: {
employee_id: item.id,
user_uid: this.data.userUid
},
success: (resdata) => {
let res = resdata.data;
if (res.result !== 1) return app.tips(res.msg);
wx.navigateBack();
},
});
},
setTransferPopupShow() {
this.setData({
transferPopupShow: !this.data.transferPopupShow,
});
},
initWebSocket() {
console.log("执行---initWebSocket");
this.setData({
msg_id_list: [],
});
this.clearHeartBeat();
let url = app.getNetAddresss("plugin.yun-chat.frontend.h5.chat.get-ws-setting");
if (this.data.chatType == 2) url = app.getNetAddresss("plugin.yun-chat.frontend.chat.get-ws-setting");
url += url + "&employee_id=" + this.data.employeeId;
app._getNetWork({
url: url,
success: (resdata) => {
let res = resdata.data;
if (res.result !== 1) return app.tips(res.msg);
this.setData({
chat_opt_setting: res.data.chat_opt_setting,
show_tool_bar:res.data.show_tool_bar||0,
chat_tool_bars:res.data.chat_tool_bars||[]
});
let wssParams = res.data.wss_params;
const wsuri =
wssParams.host +
"?appId=" +
wssParams.appId +
"&signature=" +
wssParams.signature +
"&nonceStr=" +
wssParams.nonceStr +
"&timestamp=" +
wssParams.timestamp +
"&clientid=" +
wssParams.clientid +
"&agent_id=" +
wssParams.agent_id;
this.data.websock = wx.connectSocket({
url: wsuri
});
this.data.websock.onMessage((e) => {
this.websocketonmessage(e);
});
this.data.websock.onOpen(() => {
this.websocketonopen();
});
this.data.websock.onError(() => {
this.websocketonerror();
});
this.data.websock.onClose((e) => {
this.websocketclose(e);
});
},
});
},
websocketonmessage(e) {
console.log("message", e);
let message = JSON.parse(e.data);
if (message.msg_id) {
this.data.websock.send({
data: JSON.stringify({
type: "msg_ack",
msg_id: message.msg_id
})
});
if (this.data.msg_id_list.indexOf(message.msg_id) > -1) {
return;
}
this.data.msg_id_list.push(message.msg_id);
}
let chatListTemp = [];
switch (message.type) {
case "init":
//this.bind(message.client_id);
return;
case "text":
if ((this.data.chatType == 1 && this.data.employeeId == message.employee_id) || (this.data.chatType == 2 && this.data.userUid == message.uid)) {
let directionType = message.direction_type ? message.direction_type : 0;
let receiveTextObj;
if (this.data.chatType == 1) {
receiveTextObj = this.generateChatData(message.data, directionType, message.time, message.content_type);
} else if (this.data.chatType == 2) {
receiveTextObj = this.generateChatData(message.data, directionType, message.time, message.content_type);
}
receiveTextObj["id"] = parseInt(message.id);
for (let i = 0; i < this.data.chatList.length; i++) {
chatListTemp.push(this.data.chatList[i]);
}
chatListTemp.push(receiveTextObj);
this.setData({
chatList: chatListTemp
});
//this.chatList.push(receiveTextObj);
} else {
if (message.employee_id != this.data.employee_id) {
if (this.data.websock) {
this.data.websock.close();
}
this.data.employeeId = message.employee_id;
this.data.chatList = [];
this.data.chatFinished = false;
this.data.chatLoading = false;
this.data.chatLoadedPage = 1;
this.init();
} else {
app.tips("转接失败");
}
}
if (this.data.chatType == 1) {
let url = app.getNetAddresss("plugin.yun-chat.frontend.h5.chat.is-read");
app._postNetWork({
url: url,
data: {
chats_id: message.id
},
success: () => {},
});
} else {
let url = app.getNetAddresss("plugin.yun-chat.frontend.chat.is-read");
app._postNetWork({
url: url,
data: {
chats_id: message.id
},
success: () => {},
});
}
this.scrollBottom();
return;
case "backed":
for (let i = 0; i < this.data.chatList.length; i++) {
if (this.data.chatList[i].id == message.data) {
this.data.chatList[i]["is_backed"] = 1;
}
chatListTemp.push(this.data.chatList[i]);
}
this.setData({
chatList: chatListTemp
});
this.scrollBottom();
return;
}
},
websocketonopen() {
console.log("链接打开");
this.heartBeatStart();
},
websocketonerror() {
this.clearHeartBeat();
if (!this.data.isClosed) {
this.reconnect();
}
},
websocketclose(e) {
console.log("断开连接", e);
this.clearHeartBeat();
if (!this.data.isClosed) {
this.reconnect();
}
},
heartBeatStart() {
//重置并开启心跳
this.data.timeoutObj && clearTimeout(this.data.timeoutObj);
this.data.serverTimeoutObj && clearTimeout(this.data.serverTimeoutObj);
this.data.timeoutObj = setTimeout(() => {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
console.log(this.data.websock, this.data.websock.readyState, 'websock');
if (this.data.websock.readyState == 1) {
//如果连接正常
this.data.websock.send({
data: JSON.stringify({
type: "ping"
})
});
this.keepHeartBeat();
this.data.currentReconnectNum = 0; //连接成功归零
} else {
//否则重连
this.reconnect();
}
}, this.data.timeout);
},
clearHeartBeat() {
clearInterval(this.data.heartBeatInterval);
this.data.heartBeatInterval = null;
},
keepHeartBeat() {
this.data.heartBeatInterval = setInterval(() => {
// 每隔一分钟发送一个心跳包消息
this.data.websock.send({
data: JSON.stringify({
type: "ping"
})
});
}, 60 * 1000);
},
reconnect() {
//重新连接
if (this.data.lockReconnect || this.data.isClosed || this.data.currentReconnectNum >= this.data.maxReconnectNum) {
if (this.data.websock) {
this.data.websock.close();
}
return;
}
this.data.lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
this.data.timeoutnum && clearTimeout(this.data.timeoutnum);
this.data.timeoutnum = setTimeout(() => {
console.log(this.data.currentReconnectNum);
this.data.currentReconnectNum += 1;
//新连接
this.initWebSocket();
this.data.lockReconnect = false;
}, 5000);
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {},
});
function getTimeElBySeconds(microseconds) {
let seconds = Math.floor(microseconds % 60);
let minutes = Math.floor(microseconds / 60) % 60;
let hours = Math.floor(microseconds / 60 / 60) % 24;
let days = Math.floor(microseconds / 60 / 60 / 24);
return {
days,
hours,
minutes,
seconds,
};
}
function getTimeDiff(time1, time2) {
if (isNaN(Number(time1))) {
time1 = new Date(time1).getTime();
}
if (isNaN(Number(time2))) {
time2 = new Date(time2).getTime();
}
return getTimeElBySeconds((time1 - time2) / 1000);
}
function formatDate(timestamp = null, format = "y-m-d h:i:s") {
if (timestamp === null) {
timestamp = Date.now();
}
const {
year,
month,
day,
hour,
minute,
second,
week
} = getTime(timestamp);
const chineseNumbers = ["一", "二", "三", "四", "五", "六", "日"];
format = format.replace(/y/gi, year);
format = format.replace(/m/gi, dateAddZero(month));
format = format.replace(/d/gi, dateAddZero(day));
format = format.replace(/h/gi, dateAddZero(hour));
format = format.replace(/i/gi, dateAddZero(minute));
format = format.replace(/s/gi, dateAddZero(second));
format = format.replace(/w/g, week);
format = format.replace(/W/g, chineseNumbers[week - 1]);
return format;
}
function getTime(timestamp) {
if (timestamp === null) {
timestamp = Date.now();
}
const date = new Date(timestamp);
const year = date.getFullYear();
const month = dateAddZero(date.getMonth() + 1);
const day = dateAddZero(date.getDate());
const hour = dateAddZero(date.getHours());
const minute = dateAddZero(date.getMinutes());
const second = dateAddZero(date.getSeconds());
const week = date.getDay();
return {
year,
month,
day,
hour,
minute,
second,
week,
};
}
export function dateAddZero(dateEl) {
dateEl = parseInt(dateEl);
return dateEl < 10 ? `0${dateEl}` : dateEl;
}