1263 lines
34 KiB
JavaScript
1263 lines
34 KiB
JavaScript
// 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 +
|
||
"×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;
|
||
} |