// 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 ''; }); }, /** * 生命周期函数--监听页面显示 */ 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 + "×tamp=" + 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; }