Fix:5967 【商城小程序】已发过消息的聊天页面,进行图片相关操作后页面出现白屏

This commit is contained in:
linxi
2026-09-11 16:22:35 +08:00
parent 0e04c560bc
commit 77fee4ea46
+90 -37
View File
@@ -108,8 +108,11 @@ export default {
uploadToken: null, //上传token uploadToken: null, //上传token
socketOpen: false, socketOpen: false,
socketConnecting: false, // 是否正在建连
socketTask: null, socketTask: null,
socketMsgQueue: [], socketMsgQueue: [],
hasConnected: false, // 是否成功建过连接
reconnectHistory: false, // 重连后用服务端历史整体替换本地列表,防止消息重复
roomId: null, //房间ID roomId: null, //房间ID
content: "", //消息内容 content: "", //消息内容
@@ -136,30 +139,22 @@ export default {
}, },
onShow() { onShow() {
this.content = uni.getStorageSync(this.merName+this.uid+this.storeId) this.content = uni.getStorageSync(this.merName+this.uid+this.storeId)
this.connectSocketInit(); // 已连接/连接中不重复建连;清空 list 会导致图片操作(触发 onHide/onShow)后页面白屏
this.list = [] if (!this.socketOpen && !this.socketConnecting) {
this.connectSocketInit();
}
}, },
onUnload() { onUnload() {
if (this.socketOpen) { this.closeSocket();
this.socketTask.close();
}
uni.onSocketClose(res => {
console.log('WebSocket 已关闭!', res);
});
uni.setStorageSync(this.merName+this.uid+this.storeId, this.content) uni.setStorageSync(this.merName+this.uid+this.storeId, this.content)
}, },
onHide() { onHide() {
if (this.socketOpen) { this.closeSocket();
this.socketTask.close();
}
uni.onSocketClose(res => {
console.log('WebSocket 已关闭!', res);
});
uni.setStorageSync(this.merName+this.uid+this.storeId, this.content) uni.setStorageSync(this.merName+this.uid+this.storeId, this.content)
}, },
methods: { methods: {
toGoods(item) { toGoods(item) {
const itemJson = JSON.parse(item.msg_content) const itemJson = this.wsJson(item.msg_content)
if(!itemJson.goodsId) { if(!itemJson.goodsId) {
// 提示数据错误 // 提示数据错误
// uni.showToast({ // uni.showToast({
@@ -177,7 +172,12 @@ export default {
}) })
}, },
wsJson(json) { wsJson(json) {
return JSON.parse(json) // 兼容脏数据,避免渲染时报错导致白屏
try {
return JSON.parse(json) || {}
} catch (e) {
return {}
}
}, },
// 拼接图片完整地址:七牛上传后消息里只存 key,需要补上资源域名;http 统一转 https // 拼接图片完整地址:七牛上传后消息里只存 key,需要补上资源域名;http 统一转 https
imgUrl(content) { imgUrl(content) {
@@ -255,33 +255,68 @@ export default {
}); });
}, },
// 进入这个页面的时候创建websocket连接【整个页面随时使用】 // 进入页面时创建websocket连接【整个页面随时使用】
connectSocketInit() { connectSocketInit() {
if (this.socketOpen || this.socketConnecting) return;
this.socketConnecting = true;
// 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】 // 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】
this.socketTask = uni.connectSocket({ const task = uni.connectSocket({
url: this.$SOCKET_URL, url: this.$SOCKET_URL,
success: () => { success: () => {
} }
}) })
if (!task) {
this.socketConnecting = false;
return;
}
this.socketTask = task;
uni.onSocketOpen(res => { // 任务级回调:全局 uni.onSocket* 每次进页面都会重复注册,导致消息重复处理、连接串台
console.log('WebSocket连接已打开!', res); const isCurrent = () => this.socketTask === task;
task.onOpen(() => {
if (!isCurrent()) return;
this.socketOpen = true; this.socketOpen = true;
this.socketConnecting = false;
// 断线重连后重新加入房间;本地已有历史时用服务端历史整体替换,避免重复
this.reconnectHistory = this.hasConnected && this.list.length > 0;
this.hasConnected = true;
this.createRoom(); this.createRoom();
// 补发连接未就绪期间排队的消息(如发图片时连接被隐藏页关闭)
if (this.socketMsgQueue.length) {
const queue = this.socketMsgQueue.splice(0);
queue.forEach(msg => this.sendSocketMessage(msg));
}
}); });
uni.onSocketError(err => { task.onMessage(res => {
console.log('WebSocket连接打开失败,请检查!', err); if (!isCurrent()) return;
});
uni.onSocketMessage(res => {
console.log('收到服务器内容:', res.data);
this.handleMessage(res.data); this.handleMessage(res.data);
}); });
uni.onSocketClose(res => { task.onError(err => {
console.log('WebSocket 已关闭', res); console.log('WebSocket连接打开失败,请检查', err);
if (!isCurrent()) return;
this.socketOpen = false;
this.socketConnecting = false;
}); });
task.onClose(() => {
if (!isCurrent()) return;
this.socketOpen = false;
this.socketConnecting = false;
});
},
closeSocket() {
this.socketOpen = false;
this.socketConnecting = false;
if (this.socketTask) {
try {
this.socketTask.close({});
} catch (e) {}
}
}, },
userInput(event) { userInput(event) {
@@ -321,11 +356,14 @@ export default {
}, },
sendSocketMessage(msg) { sendSocketMessage(msg) {
if (this.socketOpen) { if (this.socketOpen && this.socketTask) {
uni.sendSocketMessage({ this.socketTask.send({
data: msg, data: msg,
success(res) { fail: () => {
console.log("消息发送成功", res,msg); // 发送失败说明连接可能已断开,重新排队并尝试重连后补发
this.socketMsgQueue.push(msg);
this.closeSocket();
this.connectSocketInit();
} }
}); });
} else { } else {
@@ -334,7 +372,12 @@ export default {
}, },
handleMessage(str) { handleMessage(str) {
let data = JSON.parse(str); let data;
try {
data = JSON.parse(str);
} catch (e) {
return;
}
switch (data.type) { switch (data.type) {
case "room_id": case "room_id":
this.roomId = data.msg_content; this.roomId = data.msg_content;
@@ -344,13 +387,23 @@ export default {
case "leave": case "leave":
break; break;
case "msg": case "msg":
this.list.push(data.msg_content); if (data.msg_content) {
this.scrollLast(); this.list.push(data.msg_content);
this.scrollLast();
}
break; break;
case "msg_history": case "msg_history": {
this.list = data.msg_content.concat(this.list); const history = data.msg_content || [];
if (this.reconnectHistory) {
// 重连后服务端重发历史:整体替换,避免消息重复
this.reconnectHistory = false;
this.list = history;
} else {
this.list = history.concat(this.list);
}
this.scrollLast(); this.scrollLast();
break; break;
}
default: default:
break; break;
} }