From c7e4e5e26b09a9c3fe7f4bf9da898a7340a71b38 Mon Sep 17 00:00:00 2001
From: YeMingfei666 <1619116647@qq.com>
Date: Mon, 19 May 2025 09:07:35 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9websocket=E4=B8=BA=E5=85=A8?=
=?UTF-8?q?=E5=B1=80=E5=8F=AA=E6=9C=89=E4=B8=80=E4=B8=AA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
common/js/carts-websocket - 副本.js | 364 ++++
common/js/carts-websocket.js | 41 +-
pages/order/confirm-order.vue | 256 ++-
pages/order/index.vue | 8 +
pages/product/index - 副本.vue | 2632 +++++++++++++++++++++++++++
pages/product/index.vue | 339 ++--
stores/carts-websocket.js | 368 ++++
stores/carts.js | 41 +-
8 files changed, 3780 insertions(+), 269 deletions(-)
create mode 100644 common/js/carts-websocket - 副本.js
create mode 100644 pages/product/index - 副本.vue
create mode 100644 stores/carts-websocket.js
diff --git a/common/js/carts-websocket - 副本.js b/common/js/carts-websocket - 副本.js
new file mode 100644
index 0000000..12558a4
--- /dev/null
+++ b/common/js/carts-websocket - 副本.js
@@ -0,0 +1,364 @@
+import {
+ ref,
+ onMounted,
+ onBeforeUnmount
+} from 'vue';
+
+const useWebSocket = (options = {}) => {
+ const {
+ heartbeatInterval = 10000, //心跳是10秒一次
+ reconnectInterval = 3000, //重新连接间隔时间的一个参数
+ maxReconnectAttempts = 3, //最大重连接次数
+ initialReconnectInterval = 3000, // 初始重连间隔
+ initMessage,
+ initMessageRetryCount = 3, // 新增:初始化消息发送重试次数
+ initMessageRetryInterval = 2000, // 新增:初始化消息重试间隔
+ maxReconnectDuration = Infinity,
+ onMessage
+ } = options;
+ const autoReconnect = ref(true); //是否自动重新连接
+ const socketTask = ref(null);
+ const isConnected = ref(false); //表示是否已连接上。
+ const heartbeatTimer = ref(null); //心跳定时器
+ const reconnectTimer = ref(null); //重连定时器
+ const reconnectAttempts = ref(0); //重连的尝试次数
+ const isNetworkConnected = ref(true); //监听当前网络连接状态
+ const isManuallyClosed = ref(false); //是否是被手动关闭的
+ const receivedMessages = ref(); //储从 WebSocket 服务器接收到的消息
+ const initMessageSendAttempts = ref(0); //初始化连接多少次
+ const reconnectStartTime = ref(0); //新增:记录重连开始时间
+ const isPongReceived = ref(false)
+ const allowReconnect = ref(true); // 新增:控制是否允许重连
+ // 关闭现有连接并清理资源
+ const closeExistingConnection = () => {
+ if (socketTask.value) {
+ // 关闭 WebSocket 连接
+ socketTask.value.close({
+ success: () => {
+ console.log('WebSocket 连接已关闭');
+ },
+ fail: (err) => {
+ console.error('关闭 WebSocket 连接失败:', err);
+ }
+ });
+
+ // 清除心跳定时器
+ clearInterval(heartbeatTimer.value);
+ heartbeatTimer.value = null;
+
+ // 清除重连定时器
+ clearTimeout(reconnectTimer.value);
+ reconnectTimer.value = null;
+
+ // 标记连接已断开
+ isConnected.value = false;
+ }
+ };
+ const websocketsendMessage = (data) => {
+ uni.$u.debounce(sendMessage(data), 500)
+ }
+ // 连接 WebSocket
+ const connect = (connectMsg) => {
+ if (!isNetworkConnected.value) {
+ uni.showToast({
+ title: '网络未连接...',
+ icon: 'none'
+ })
+ setTimeout(() => {
+ uni.pro.switchTab('index/index')
+ }, 1000)
+ console.log('网络未连接,暂不尝试连接 WebSocket');
+ return;
+ }
+
+ // 关闭现有连接并清理资源
+ try{
+ closeExistingConnection();
+ }catch(err){
+
+ }
+ socketTask.value = uni.connectSocket({
+ url: uni.conf.baseUrlwws,
+ success: (res) => {
+ isConnected.value = true;
+ // 监听初始化成功在开启心跳
+ startHeartbeat();
+ },
+ fail: () => {
+ console.error('WebSocket 连接失败,尝试重连');
+ if (autoReconnect.value && allowReconnect.value) {
+ handleReconnect();
+ }
+ }
+ });
+
+ if (socketTask.value) {
+ socketTask.value.onOpen(() => {
+ // 初始化 初始购物车
+ sendMessage(connectMsg ? connectMsg : initMessage)
+ });
+ socketTask.value.onMessage((res) => {
+ receivedMessages.value = JSON.parse(res.data)
+ websocketsendMessage({
+ type: 'receipt',
+ msg_id: receivedMessages.value.msg_id
+ })
+ if (onMessage) {
+ onMessage(receivedMessages.value)
+ }
+ // receivedMessages.value.push(list);
+ if (receivedMessages.value == 'ok' || receivedMessages.value.operate_type == 'init') {
+ console.log('初始化正常,心跳响应正常');
+ // 清除重连定时器
+ clearTimeout(reconnectTimer.value);
+ allowReconnect.value = false
+ reconnectTimer.value = null;
+ }
+
+ });
+
+ socketTask.value.onClose((res) => {
+ console.log(res, 'WebSocket 连接已关闭,尝试重连');
+ isConnected.value = false;
+ clearInterval(heartbeatTimer.value); // 停止心跳定时器
+ clearTimeout(reconnectTimer.value); // 清除重连定时器
+ if (res.code == '1006' && !allowReconnect.value) {
+ uni.showToast({
+ title: '网络异常,请重新扫码',
+ icon: 'none'
+ });
+ autoReconnect.value = false;
+ setTimeout(() => {
+ uni.pro.switchTab('index/index');
+ }, 1000)
+ return false;
+ }
+ if (autoReconnect.value && !isManuallyClosed.value) {
+ handleReconnect();
+ }
+ });
+
+ socketTask.value.onError((err) => {
+ console.error('WebSocket 连接发生错误:', err);
+ isConnected.value = false;
+ clearInterval(heartbeatTimer.value);
+ if (autoReconnect.value && !isManuallyClosed.value) {
+ handleReconnect();
+ }
+ });
+ } else {
+ console.error('socketTask 未正确初始化');
+ }
+ };
+
+ // 启动心跳机制
+ const startHeartbeat = () => {
+ if (!isNetworkConnected.value) {
+ console.log('网络未连接,暂停心跳');
+ uni.showToast({
+ title: '网络未连接...',
+ icon: 'none'
+ });
+ setTimeout(() => {
+ uni.pro.switchTab('index/index');
+ }, 1000);
+ return;
+ }
+ heartbeatTimer.value = setInterval(() => {
+ if (isConnected.value) {
+ console.log('发送心跳消息');
+ isPongReceived.value = false; // 每次发送心跳消息前重置标记
+ socketTask.value.send({
+ data: JSON.stringify({
+ type: 'ping_interval',
+ set: 'shopping'
+ }),
+ success: () => {
+ console.log('心跳消息发送成功');
+ const pongTimer = setTimeout(() => {
+ if (!isPongReceived.value) {
+ console.error('心跳超时,未收到响应,尝试重连');
+ clearInterval(heartbeatTimer.value);
+ if (autoReconnect.value && reconnectAttempts.value <
+ maxReconnectAttempts && allowReconnect.value) {
+ handleReconnect();
+ } else {
+ console.error('重连次数达到上限,停止重连和心跳');
+ clearInterval(heartbeatTimer.value);
+ autoReconnect.value = false;
+ uni.pro.switchTab('index/index');
+ }
+ }
+ }, heartbeatInterval * 1.2);
+
+ const handlePong = (res) => {
+ try {
+ let data = JSON.parse(res.data);
+ if (data.operate_type == "init" || (data.msg === 'ok' &&
+ data.msg_id ==
+ 'ping_interval')) {
+ isPongReceived.value = true;
+ console.log('收到心跳响应,清除超时定时器');
+ clearTimeout(pongTimer);
+ }
+ } catch (error) {
+ console.error('解析心跳响应数据时出错:', error);
+ }
+ };
+ socketTask.value.onMessage(handlePong);
+ },
+ fail: () => {
+ console.error('心跳消息发送失败,尝试重连');
+ clearInterval(heartbeatTimer.value);
+ if (autoReconnect.value && reconnectAttempts.value <
+ maxReconnectAttempts && allowReconnect.value) {
+ handleReconnect();
+ } else {
+ console.error('重连次数达到上限,停止重连和心跳');
+ clearInterval(heartbeatTimer.value);
+ autoReconnect.value = false;
+ uni.pro.switchTab('index/index');
+ }
+ }
+ });
+ }
+ }, heartbeatInterval);
+ };
+
+
+ // 手动关闭连接
+ const closeSocket = () => {
+ isManuallyClosed.value = true;
+ closeExistingConnection();
+ };
+
+ // 发送消息
+ const sendMessage = async (data) => {
+ if (isConnected.value) {
+ await socketTask.value.send({
+ data: JSON.stringify(data),
+ success: () => {
+ // console.log('消息发送成功');
+ },
+ fail: () => {
+ // console.error('消息发送失败');
+ }
+ });
+ } else {
+ console.error('WebSocket 未连接,无法发送消息');
+ }
+ };
+
+ // 处理重连逻辑
+ const handleReconnect = () => {
+ if (!isNetworkConnected.value) {
+ console.log('网络未连接,暂停重连');
+ return;
+ }
+ if (isManuallyClosed.value) {
+ console.log('手动关闭连接,不进行重连');
+ return;
+ }
+
+ if (!allowReconnect.value) {
+ console.log('重连功能已关闭,不进行重连');
+ return;
+ }
+
+ if (reconnectAttempts.value < maxReconnectAttempts) {
+ reconnectAttempts.value++;
+ const reconnectInterval = initialReconnectInterval * Math.pow(2, reconnectAttempts.value - 1);
+ const randomizedInterval = reconnectInterval + Math.floor(Math.random() * 1000);
+ uni.showLoading({
+ title: `正在努力连接..`,
+ mask: true
+ })
+ console.log(`尝试第 ${reconnectAttempts.value} 次重连,重连间隔: ${randomizedInterval}ms...`);
+
+ reconnectTimer.value = setTimeout(() => {
+ connect();
+ }, randomizedInterval);
+ } else {
+ console.error('重连次数达到上限,停止重连');
+ uni.showToast({
+ title: '重连次数达到上限,停止重连',
+ icon: 'none'
+ });
+ clearInterval(heartbeatTimer.value);
+ autoReconnect.value = false;
+ setTimeout(() => {
+ uni.hideLoading();
+ uni.pro.switchTab('index/index');
+ }, 1000)
+ }
+ };
+
+
+ // / 网络状态监听
+ const initNetworkListener = () => {
+ uni.getSystemInfo({
+ success: (res) => {
+ if (res.platform !== 'devtools') {
+ uni.onNetworkStatusChange((statusRes) => {
+ isNetworkConnected.value = statusRes.isConnected;
+ if (statusRes.isConnected && !isManuallyClosed.value) {
+ console.log('网络已连接,尝试重新连接 WebSocket');
+ if (!isConnected.value && autoReconnect.value) {
+ connect();
+ }
+ } else if (!statusRes.isConnected) {
+ console.log('网络已断开,暂停 WebSocket 操作');
+ clearInterval(heartbeatTimer.value);
+ clearTimeout(reconnectTimer.value);
+ if (socketTask.value) {
+ socketTask.value.close();
+ isConnected.value = false;
+ }
+ }
+ });
+ }
+ },
+ fail: (err) => {
+ console.error('获取系统信息失败:', err);
+ }
+ });
+
+ uni.getNetworkType({
+ success: (res) => {
+ isNetworkConnected.value = res.networkType !== 'none';
+ if (!isNetworkConnected.value) {
+ console.log('初始网络未连接,暂不尝试连接 WebSocket');
+ }
+ }
+ });
+ };
+
+ // 页面显示,尝试连接 WebSocket
+ const onShowconnect = () => {
+ if (autoReconnect.value) {
+ uni.showLoading({
+ title: `尝试再次连接`,
+ mask: true
+ })
+ connect();
+ }
+ }
+
+ onBeforeUnmount(() => {
+ closeSocket();
+ });
+
+ return {
+ isConnected,
+ sendMessage,
+ closeSocket,
+ receivedMessages,
+ closeExistingConnection,
+ connect,
+ onShowconnect,
+ initNetworkListener,
+ connect,allowReconnect
+ };
+};
+
+export default useWebSocket;
\ No newline at end of file
diff --git a/common/js/carts-websocket.js b/common/js/carts-websocket.js
index 12558a4..e90cb3b 100644
--- a/common/js/carts-websocket.js
+++ b/common/js/carts-websocket.js
@@ -31,8 +31,7 @@ const useWebSocket = (options = {}) => {
const allowReconnect = ref(true); // 新增:控制是否允许重连
// 关闭现有连接并清理资源
const closeExistingConnection = () => {
- if (socketTask.value) {
- // 关闭 WebSocket 连接
+ try {
socketTask.value.close({
success: () => {
console.log('WebSocket 连接已关闭');
@@ -52,13 +51,32 @@ const useWebSocket = (options = {}) => {
// 标记连接已断开
isConnected.value = false;
+ } catch (error) {
+ console.error(error)
+ //TODO handle the exception
}
+
+
};
const websocketsendMessage = (data) => {
uni.$u.debounce(sendMessage(data), 500)
}
+
+
+ const safeConnect=(connectMsg)=>{
+ return new Promise((resolve,reject)=>{
+ try {
+ sendMessage(connectMsg ? connectMsg : initMessage)
+ resolve(true)
+ } catch (error) {
+ reject(false)
+ //TODO handle the exception
+ }
+ })
+ }
+
// 连接 WebSocket
- const connect = (connectMsg) => {
+ const connect =async (connectMsg) => {
if (!isNetworkConnected.value) {
uni.showToast({
title: '网络未连接...',
@@ -72,13 +90,14 @@ const useWebSocket = (options = {}) => {
}
// 关闭现有连接并清理资源
- try{
- closeExistingConnection();
- }catch(err){
-
+ const sendSuccess= await safeConnect(connectMsg)
+ if(sendSuccess){
+ return
+ }else{
+ closeExistingConnection()
}
socketTask.value = uni.connectSocket({
- url: uni.conf.baseUrlwws,
+ url: uni.conf.baseUrlwws + '?' + Date.now(),
success: (res) => {
isConnected.value = true;
// 监听初始化成功在开启心跳
@@ -228,6 +247,7 @@ const useWebSocket = (options = {}) => {
// 手动关闭连接
const closeSocket = () => {
+ console.log('手动关闭连接');
isManuallyClosed.value = true;
closeExistingConnection();
};
@@ -345,7 +365,7 @@ const useWebSocket = (options = {}) => {
}
onBeforeUnmount(() => {
- closeSocket();
+ // closeSocket();
});
return {
@@ -357,7 +377,8 @@ const useWebSocket = (options = {}) => {
connect,
onShowconnect,
initNetworkListener,
- connect,allowReconnect
+ connect,
+ allowReconnect
};
};
diff --git a/pages/order/confirm-order.vue b/pages/order/confirm-order.vue
index bbd84b6..02960fb 100644
--- a/pages/order/confirm-order.vue
+++ b/pages/order/confirm-order.vue
@@ -63,7 +63,8 @@
-
+
@@ -106,6 +107,9 @@
import {
back
} from '@/utils/uniapp.js'
+ import {
+ onLoad
+ } from '@dcloudio/uni-app'
function onback() {
closeSocket()
@@ -148,12 +152,11 @@
import {
useCartsStore
} from '@/stores/carts.js';
- import useWebSocket from '@/common/js/carts-websocket.js';
+ import {
+ useWebSocket
+ } from '@/stores/carts-websocket.js';
const cartStore = useCartsStore()
- console.log(cartStore.goodsIsloading);
- console.log(cartStore.goodsMap);
async function onMessage(Message) {
- console.log('onMessage');
cartStore.onMessage(Message, cartsSocket)
listinfo.totalPrices = historyTotalPrices * 1 + cartStore.totalPrice * 1
if (Message.operate_type == "init") {
@@ -176,7 +179,6 @@
}, 1000);
return;
}
- console.log(res);
}
}
if (Message.operate_type == "del") {
@@ -192,34 +194,21 @@
.operate_type == 'product_update') {
youhuiReset()
}
+ return Message
}
let cartsSocket = null
- const socketInitOptions = {
- initMessage: {
- type: 'shopping',
- operate_type: 'init',
- table_code: uni.cache.get('tableCode'),
- shop_id: uni.cache.get('shopId'),
- },
- onMessage
+ cartStore.goodsInit()
+ const socketInitPar = {
+ type: 'shopping',
+ operate_type: 'init',
+ table_code: uni.cache.get('tableCode'),
+ shop_id: uni.cache.get('shopId'),
}
- watch(() => cartStore.goodsIsloading, (newValue) => {
- console.log('cartStore.goodsIsloading', cartStore.goodsIsloading);
- if (!newValue) {
- cartsSocket = useWebSocket(socketInitOptions);
- cartsSocket.allowReconnect = true;
- cartsSocket.connect();
- }
- })
- if (cartStore.goodsIsloading) {
- cartStore.goodsInit()
- } else {
- cartsSocket = useWebSocket(socketInitOptions);
- cartsSocket.allowReconnect = true;
- cartsSocket.connect();
- }
-
+ function socketInit() {
+ cartsSocket = useWebSocket();
+ cartsSocket.connect(socketInitPar, onMessage);
+ }
const noPayStatus = {
cancelled: "订单已取消",
done: "订单已关闭",
@@ -233,7 +222,11 @@
listinfo.pointsDiscountAmount = 0
listinfo.Productroll = 0
uniqueIds.value = []
- orderInfoAfterRef.value.IntegralInputclose();
+ try {
+ orderInfoAfterRef.value?.IntegralInputclose();
+ } catch {
+
+ }
}
@@ -308,18 +301,30 @@
let historyTotalPrices = 0;
// * 获取订单详情接口
const orderorderInfo = async () => {
+ console.log('listinfo.id', listinfo.id);
let res = listinfo.id ? await APIgetOrderById({
orderId: listinfo.id
}) : await APIhistoryOrder({
tableCode: options.tableCode
})
- if (options.tableCode) {
+ if (res && res.tableCode) {
+ socketInitPar.table_code = res.tableCode
let tableRes = await getTableInfo({
tableCode: options.tableCode
})
console.log(tableRes);
listinfo.tableName = tableRes.name;
+ } else {
+ if (options.tableCode) {
+ socketInitPar.table_code = options.tableCode
+ let tableRes = await getTableInfo({
+ tableCode: options.tableCode
+ })
+ console.log(tableRes);
+ listinfo.tableName = tableRes.name;
+ }
}
+ socketInit()
console.log(res);
getOrderInfoAfterCalcInit(res)
}
@@ -393,12 +398,9 @@
listinfo.originAmount = Math.round(sum * 100) / 100;
// 打包费packFeess 计算购物车商品费用totalPrices 餐位费Seatcharge 商品卷Productroll 优惠卷coupondiscountAmount 积分listinfo.pointsDiscountAmount
- console.log('listinfo');
- console.log(listinfo);
let sums = nowCartPackFee + historyOrderPackFee + listinfo.totalPrices + seatFee - (listinfo
.Productroll || 0) - (listinfo.coupondiscountAmount || 0) - (listinfo
.pointsDiscountAmount || 0);
- console.log('listinfo', listinfo);
listinfo.totalCost = Math.round(sums * 100) / 100;
// 总价格
@@ -571,51 +573,92 @@
}
+ function isPayBefor() {
+ return ordershopUserInfo.value.registerType == 'before' ? true : false
+ }
- const istoricalorders = async () => {
- // 购物车有数据
- if (!cartStore.isEmpty) {
- await createOrder()
- goToPay()
- }
-
- // 先调用历史订单
- let APIhistoryOrderres = await APIhistoryOrder({
- tableCode: listinfo.tableCode
+ function pay_lock() {
+ cartsSocket.sendMessage({
+ ...socketInitPar,
+ operate_type: 'pay_lock'
})
- // 判断是否有历史订单
- if (APIhistoryOrderres.detailMap) {
- let combinedArray = [];
- for (const key in APIhistoryOrderres.detailMap) {
- if (APIhistoryOrderres.detailMap.hasOwnProperty(key)) {
- let subArray = APIhistoryOrderres.detailMap[key];
- combinedArray = [...combinedArray, ...subArray]
- }
- }
- // 判断支付之前是是否还有新加订单
- if (listinfo.combinedArray.length === combinedArray.length) {
+ }
+
+ function pay_unlock() {
+ clearInterval(payStatusTimer)
+ cartsSocket.sendMessage({
+ ...socketInitPar,
+ operate_type: 'pay_unlock'
+ })
+ }
+ async function search_pay_lock() {
+ cartsSocket.sendMessage({
+ ...socketInitPar,
+ operate_type: 'search_pay_lock'
+ })
+ return new Promise((relove, reject) => {
+ cartsSocket.socketTask.onMessage(res => {
+ relove(JSON.parse(res.data))
+ })
+ })
+ }
+ let payStatusTimer = null
+ let orderIsLock = true;
+ const istoricalorders = async () => {
+ //先付
+ if (isPayBefor()) {
+ console.log('isPayBefor');
+ // 购物车有数据
+ if (!cartStore.isEmpty) {
+ const res = await createOrder()
goToPay()
+ }
+
+
+ } else {
+ //后付
+
+ // 先调用历史订单
+ let APIhistoryOrderres = await APIhistoryOrder({
+ tableCode: listinfo.tableCode
+ })
+ // 判断是否有历史订单
+ if (APIhistoryOrderres.detailMap) {
+ let combinedArray = [];
+ for (const key in APIhistoryOrderres.detailMap) {
+ if (APIhistoryOrderres.detailMap.hasOwnProperty(key)) {
+ let subArray = APIhistoryOrderres.detailMap[key];
+ combinedArray = [...combinedArray, ...subArray]
+ }
+ }
+ // 判断支付之前是是否还有新加订单
+ if (listinfo.combinedArray.length === combinedArray.length) {
+ goToPay()
+ } else {
+ uni.showToast({
+ title: '你的订单已更新!',
+ icon: 'none'
+ })
+ orderorderInfo()
+ }
} else {
uni.showToast({
- title: '你的订单已更新!',
+ title: '你的小伙伴已提交订单~',
icon: 'none'
})
- orderorderInfo()
+ setTimeout(() => {
+ orderorderInfo()
+ }, 1000)
}
- } else {
- uni.showToast({
- title: '你的小伙伴已提交订单~',
- icon: 'none'
- })
- setTimeout(() => {
- orderorderInfo()
- }, 1000)
}
+
+
+
}
// * 去支付
- const goToPay = async () => {
+ const goToPay = async (isCreateOrder = false) => {
// 余额支付
if (paymentmethod.payType == 'accountPay') {
if (orderVIP.value.isVip == 0) {
@@ -659,6 +702,23 @@
}
return false
}
+
+ const canPayRes = await search_pay_lock()
+ console.log('canPayRes', canPayRes);
+ const canPay = canPayRes.status == 1 ? true : false;
+ console.log('canPay', canPay);
+ if (!canPay) {
+ uni.showToast({
+ title: '有人正在付款中!',
+ icon: 'none'
+ })
+ return
+ }
+ pay_lock()
+ payStatusTimer = setInterval(() => {
+ pay_lock()
+ }, 1000)
+
if (orderVIP.value.freeDineConfig.enable && isBwc.value) {
await storeMemberpay.actionspayltPayVip({
shopId: orderVIP.value.shopId,
@@ -670,6 +730,7 @@
buyerRemark: '',
seatNum: is_type.value == 0 ? listinfo.seatNum : 0, //用餐人数
})
+
orderorderInfo()
return false;
} else {
@@ -700,9 +761,11 @@
returnUrl: ''
})
} catch (error) {
+ pay_unlock()
//TODO handle the exception
}
}
+ pay_unlock()
orderorderInfo()
}
@@ -712,7 +775,7 @@
shopUserId: orderVIP.value.id,
orderAmount: listinfo.totalCost,
})
- orderInfoAfterRef.value.getCalcUsablePoints(res)
+ orderInfoAfterRef.value?.getCalcUsablePoints(res)
}
//
const clickPointsamount = (Pointsamount) => {
@@ -760,13 +823,16 @@
onBeforeUnmount(() => {
uni.$off('returnData', handleReturnData);
clearTimeout(backtimer)
+ clearInterval(payStatusTimer)
closeSocket()
});
onHide(() => {
closeSocket()
+ clearInterval(payStatusTimer)
})
function closeSocket() {
+
// cartsSocket.closeExistingConnection()
}
@@ -777,10 +843,9 @@
try {
// 更新数据
if (orderVIP.value) {
- console.log(uni.cache.get('orderVIP'))
orderVIP.value = uni.cache.get('orderVIP')
paymentMethodref.value.orderVIPfun(uni.cache.get('orderVIP'))
- if (listinfo.id) {
+ if (listinfo.id && ordershopUserInfo.value.registerType != 'before') {
orderorderInfo()
}
}
@@ -789,28 +854,7 @@
}
});
let options = {}
- // 监听页面返回事件
- onMounted(async () => {
- // 获取当前页面栈
- const pages = getCurrentPages();
- // 获取当前页面实例
- const currentPage = pages[pages.length - 1];
- // 获取页面参数
- options = currentPage.options;
- listinfo.id = options.orderId;
- if (options.shopId) {
- // 每次进来全局更新shopId
- uni.cache.set('shopId', options.shopId, 30)
- uni.$on('returnData', handleReturnData);
- }
- // * 获取会员信息
- await storeuser.actionsproductqueryProduct()
- await nextTick()
- orderVIP.value = uni.cache.get('orderVIP')
- // 积分信息
- orderorderInfo()
- })
// 跳转到加菜页面
function toJiacai() {
back()
@@ -845,12 +889,41 @@
'cancelled': '已取消'
}
const navTitle = computed(() => {
+ if (!listinfo.id && !cartStore.isEmpty) {
+ return '待确认'
+ }
if (cartStore.isEmpty && listinfo.id) {
return payStatus[listinfo.status] || '待确认'
} else {
return '待确认'
}
})
+
+ async function init(opt) {
+ Object.assign(options, opt)
+ listinfo.id = options.orderId;
+ console.log('init', listinfo);
+ if (options.shopId) {
+ // 每次进来全局更新shopId
+ uni.cache.set('shopId', options.shopId, 30)
+ uni.$on('returnData', handleReturnData);
+ }
+ // * 获取会员信息
+ await storeuser.actionsproductqueryProduct()
+ await nextTick()
+
+ orderVIP.value = uni.cache.get('orderVIP')
+ if (options.tableCode) {
+ socketInitPar.table_code = options.tableCode
+ socketInit()
+ } else {
+ orderorderInfo()
+ }
+
+ }
+ onLoad((opt) => {
+ init(opt)
+ })
\ No newline at end of file
diff --git a/pages/product/index.vue b/pages/product/index.vue
index ab42226..ec7ea40 100644
--- a/pages/product/index.vue
+++ b/pages/product/index.vue
@@ -240,7 +240,7 @@
-
+
singleclick(item1, '-'), 500)">
@@ -418,7 +418,7 @@
已下单菜品
-
+
@@ -472,7 +472,9 @@
// websocket
// import useWebSocket from '@/common/js/websocket.js';
- import useWebSocket from '@/common/js/carts-websocket.js';
+ import {
+ useWebSocket
+ } from '@/stores/carts-websocket.js';
// pinia管理
import {
@@ -1135,16 +1137,8 @@
shop_id: uni.cache.get('shopId')
}
}
- const {
- isConnected,
- sendMessage,
- closeSocket: manualClose,
- receivedMessages,
- closeExistingConnection,
- onShowconnect,
- initNetworkListener
- } = useWebSocket(options);
-
+ const useSocket = useWebSocket();
+ useSocket.connect(options.initMessage, onMessage)
//购物车显示
const showCart = ref(false)
@@ -1154,6 +1148,7 @@
// 更新商品数量的方法
const updateProductQuantities = () => {
+ console.log('updateProductQuantities');
// 先将所有商品的 cartNumber 初始化为 0
shopProductList.hots.forEach((i) => {
i.cartNumber = 0
@@ -1171,7 +1166,7 @@
group.productList.forEach((product) => {
if (product.id == cartItem.product_id && product.skuId == cartItem
.sku_id) {
- product.cartNumber = cartItem.number
+ product.cartNumber = cartItem.number || 0
product.cartListId = cartItem.id
}
});
@@ -1185,7 +1180,7 @@
if (group.id == cartItem.product_id) {
// 更新商品的数量
group.cartListId = cartItem.id
- group.cartNumber = cartItem.number
+ group.cartNumber = cartItem.number || 0
}
});
});
@@ -1193,115 +1188,141 @@
//websocket产值
const websocketsendMessage = (data) => {
- uni.$u.debounce(sendMessage(data), 500)
+ console.log(data);
+ uni.$u.debounce(useSocket.sendMessage(data), 500)
}
// 用于记录已经处理过的消息的 msg_id
const processedMessageIds = new Set();
- // 监听接收到的消息变化
- watchEffect(async () => {
- if (isDataLoaded.value && receivedMessages.value) {
- const Message = receivedMessages.value
- if (Message) {
- console.log(Message.data);
- // 心跳返回 过滤
- if (Message.type == "ping_interval" || Message.msg_id == "ping_interval") {
- isLoading.value = false;
- return false
- }
- // 检查消息是否已经处理过
- if (processedMessageIds.has(Message.msg_id)) {
- return;
- }
- processedMessageIds.add(Message.msg_id);
- // 初始化
- if (Message.operate_type == "init") {
- cartStore.carts = Message.data
- uni.hideLoading();
- isLoading.value = false;
- }
-
- // 清空购物车
- if (Message.operate_type == 'cleanup') {
- cartStore.carts = []
- setTimeout(() => {
- Historicalorders()
- }, 400)
- showCart.value = false
- }
-
- // 删除除购物车
- if (Message.operate_type == 'del' && Message.status == 1) {
- // 优化:使用可选链操作符避免报错
- cartStore.carts = cartStore.carts.filter(item => item.id !== Message.data?.id);
- // cartStore.carts = cartStore.carts.filter(item => item.id != Message.data.id);
- }
-
- // 添加或者减少购物后返回
- if (Message.operate_type == 'add' || Message.operate_type == 'edit') {
- [Message.data].forEach((objA) => {
- const index = cartStore.carts.findIndex((objB) => objB.id == objA.id);
- if (index !== -1) {
- cartStore.carts[index] = objA;
- } else {
- cartStore.carts.push(objA);
- }
- });
- }
-
- // 历史订单
- if (Message.operate_type == 'clearOrder') {
- Historicalorders()
- }
-
- // 购物车数据更新从新请求
- if (Message.type == 'product' && Message.data_type == 'product_update' && Message
- .operate_type == 'product_update') {
- isDataLoaded.value = false;
- productqueryProduct()
- }
-
- // 提示
- if (Message.status == 0 && Message.type != 'no_suit_num') {
- uni.showToast({
- title: Message.msg,
- icon: "none"
- })
- }
-
- if (Message.type == 'no_suit_num') {
- // console.log(specifications)
- uni.showModal({
- title: '提示',
- showCancel: false,
- content: '此商品库存不足起售数量!',
- success: async (data) => {
- await websocketsendMessage({
- id: Message.id,
- type: 'shopping',
- table_code: uni.cache.get('tableCode'),
- shop_id: uni.cache.get('shopId'),
- operate_type: 'del',
- is_print: 1,
- })
- }
- });
- }
-
- //除去p 每次返回都回执消息
- await websocketsendMessage({
- type: 'receipt',
- msg_id: Message.msg_id
- })
-
- // 初始化商品数量
- await updateProductQuantities()
-
- }
+ //设置商品初始选中
+ function setGoodsInitSel(cartsArr) {
+ console.log('setGoodsInitSel');
+ const arr = (cartsArr && cartsArr.length) ? cartsArr : cartStore.carts
+ if (arr.length <= 0) {
+ return
}
- })
+ shopProductList.hots.map(v => {
+ const item = arr.find(cart => cart.product_id == v.id)
+ if (item) {
+ v.cartNumber = `${item.number}`;
+ }
+ })
+ shopProductList.productInfo.map(info => {
+ info.productList.map(v => {
+ const item = arr.find(cart => cart.product_id == v.id)
+ if (item) {
+ v.cartNumber = `${item.number}`;
+ console.log(v.cartNumber);
+ }
+ })
+ })
+ }
+
+ // 收到的消息变化
+ async function onMessage(Message) {
+ if (Message) {
+ console.log('product index 收到消息',Message);
+ // 心跳返回 过滤
+ if (Message.type == "ping_interval" || Message.msg_id == "ping_interval") {
+ isLoading.value = false;
+ return false
+ }
+ // 检查消息是否已经处理过
+ if (processedMessageIds.has(Message.msg_id)) {
+ return;
+ }
+ processedMessageIds.add(Message.msg_id);
+
+ // 初始化
+ if (Message.operate_type == "init") {
+ cartStore.carts = Message.data
+ uni.hideLoading();
+ isLoading.value = false;
+ // 初始化商品数量
+ // setGoodsInitSel(Message.data)
+ }
+
+ // 清空购物车
+ if (Message.operate_type == 'cleanup') {
+ cartStore.carts = []
+ setTimeout(() => {
+ Historicalorders()
+ }, 400)
+ showCart.value = false
+ }
+
+ // 删除除购物车
+ if (Message.operate_type == 'del' && Message.status == 1) {
+ // 优化:使用可选链操作符避免报错
+ cartStore.carts = cartStore.carts.filter(item => item.id !== Message.data?.id);
+ // cartStore.carts = cartStore.carts.filter(item => item.id != Message.data.id);
+ }
+
+ // 添加或者减少购物后返回
+ if (Message.operate_type == 'add' || Message.operate_type == 'edit') {
+ [Message.data].forEach((objA) => {
+ const index = cartStore.carts.findIndex((objB) => objB.id == objA.id);
+ if (index !== -1) {
+ cartStore.carts[index] = objA;
+ } else {
+ cartStore.carts.push(objA);
+ }
+ });
+ }
+
+ // 历史订单
+ if (Message.operate_type == 'clearOrder') {
+ Historicalorders()
+ }
+
+ // 购物车数据更新从新请求
+ if (Message.type == 'product' && Message.data_type == 'product_update' && Message
+ .operate_type == 'product_update') {
+ isDataLoaded.value = false;
+ productqueryProduct()
+ }
+
+ // 提示
+ if (Message.status == 0 && Message.type != 'no_suit_num') {
+ uni.showToast({
+ title: Message.msg,
+ icon: "none"
+ })
+ }
+
+ if (Message.type == 'no_suit_num') {
+ // console.log(specifications)
+ uni.showModal({
+ title: '提示',
+ showCancel: false,
+ content: '此商品库存不足起售数量!',
+ success: async (data) => {
+ await websocketsendMessage({
+ id: Message.id,
+ type: 'shopping',
+ table_code: uni.cache.get('tableCode'),
+ shop_id: uni.cache.get('shopId'),
+ operate_type: 'del',
+ is_print: 1,
+ })
+ }
+ });
+ }
+
+ //除去p 每次返回都回执消息
+ await websocketsendMessage({
+ type: 'receipt',
+ msg_id: Message.msg_id
+ })
+
+ // 初始化商品数量
+ await updateProductQuantities()
+
+ }
+ }
+
// 更新购物车数据shopProductList.hots
const matchedProducts = computed(() => {
@@ -1322,6 +1343,7 @@
for (const group of Specialstop) {
for (const product of group.productList) {
if (product.id == cartItem.product_id) {
+ console.log(cartItem);
return {
...product,
cartListinfo: cartItem,
@@ -1490,29 +1512,50 @@
});
// 定义 ifcartNumber 计算属性方法 展示数量
- const ifcartNumber = computed(() => {
- return (item) => {
- // 如果 item 为空或者 cartNumber 不是字符串类型,返回 0
- if (!item || typeof item.cartNumber !== 'string') {
- return 0;
- }
- let numValue = parseFloat(item.cartNumber);
- if (isNaN(numValue)) {
- // 如果转换结果是 NaN,说明 cartNumber 不是有效的数字字符串,返回 0
- return 0;
- }
- // type string 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
- if (item.type === 'weight') {
- // 如果类型是称重重量,将值保留两位小数
- return parseFloat(numValue.toFixed(2));
- } else {
- // 如果类型是整数,将值转换为整数
- return Math.round(numValue);
- }
- // 如果类型不匹配,返回原始值
- return item.cartNumber;
- };
- })
+ function ifcartNumber(item) {
+ // 如果 item 为空或者 cartNumber 不是字符串类型,返回 0
+ if (!item || item.cartNumber * 1 == 0) {
+ return '';
+ }
+ let numValue = parseFloat(item.cartNumber);
+ if (isNaN(numValue)) {
+ // 如果转换结果是 NaN,说明 cartNumber 不是有效的数字字符串,返回 0
+ return '';
+ }
+ // type string 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
+ if (item.type === 'weight') {
+ // 如果类型是称重重量,将值保留两位小数
+ return parseFloat(numValue.toFixed(2));
+ } else {
+ // 如果类型是整数,将值转换为整数
+ return Math.round(numValue);
+ }
+ // 如果类型不匹配,返回原始值
+ return item.cartNumber;
+ }
+ // const ifcartNumber = computed(() => {
+ // return (item) => {
+ // // 如果 item 为空或者 cartNumber 不是字符串类型,返回 0
+ // if (!item || typeof item.cartNumber !== 'string') {
+ // return 0;
+ // }
+ // let numValue = parseFloat(item.cartNumber);
+ // if (isNaN(numValue)) {
+ // // 如果转换结果是 NaN,说明 cartNumber 不是有效的数字字符串,返回 0
+ // return 0;
+ // }
+ // // type string 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
+ // if (item.type === 'weight') {
+ // // 如果类型是称重重量,将值保留两位小数
+ // return parseFloat(numValue.toFixed(2));
+ // } else {
+ // // 如果类型是整数,将值转换为整数
+ // return Math.round(numValue);
+ // }
+ // // 如果类型不匹配,返回原始值
+ // return item.cartNumber;
+ // };
+ // })
// 计算处理后的购物车列表 // 用于筛选后的购物车数组
const cartListFilter = computed(() => {
@@ -1609,6 +1652,7 @@
isDataLoaded.value = true;
// 历史订单
Historicalorders()
+ updateProductQuantities()
} else {
uni.showToast({
title: '暂无列表数据,请重新扫码',
@@ -1628,27 +1672,28 @@
await proxy.$onLaunched;
})
- onShow(async() => {
+ onShow(async () => {
// 监听页面显示和隐藏
- onShowconnect()
+ useSocket.setOnMessage(onMessage)
+ useSocket.onShowconnect()
let res = await APIhistoryOrder({
tableCode: uni.cache.get('tableCode'),
})
- if(res){
+ if (res) {
orderinfo.value = {
id: res.id,
detailMap: res.detailMap,
placeNum: res.placeNum
}
- }else{
+ } else {
orderinfo.value = {
- id:''
+ id: ''
}
}
})
onHide(() => {
- closeExistingConnection()
+
})
onMounted(async () => {
@@ -1670,7 +1715,7 @@
}
setTimeout(() => {
// 启动网络监听
- initNetworkListener()
+ useSocket.initNetworkListener()
getElementTop()
}, 500)
})
diff --git a/stores/carts-websocket.js b/stores/carts-websocket.js
new file mode 100644
index 0000000..0155f59
--- /dev/null
+++ b/stores/carts-websocket.js
@@ -0,0 +1,368 @@
+import {
+ defineStore
+} from 'pinia';
+import {
+ ref,
+ computed,
+ reactive,
+ onMounted,
+ onBeforeUnmount,
+ watchEffect
+} from 'vue';
+
+
+
+export const useWebSocket = defineStore('socketTask', () => {
+ const options = {}
+ let {
+ heartbeatInterval = 10000, //心跳是10秒一次
+ reconnectInterval = 3000, //重新连接间隔时间的一个参数
+ maxReconnectAttempts = 3, //最大重连接次数
+ initialReconnectInterval = 3000, // 初始重连间隔
+ initMessage,
+ initMessageRetryCount = 3, // 新增:初始化消息发送重试次数
+ initMessageRetryInterval = 2000, // 新增:初始化消息重试间隔
+ maxReconnectDuration = Infinity,
+ } = options;
+ const autoReconnect = ref(true); //是否自动重新连接
+ const socketTask = ref(null);
+ const isConnected = ref(false); //表示是否已连接上。
+ const heartbeatTimer = ref(null); //心跳定时器
+ const reconnectTimer = ref(null); //重连定时器
+ const reconnectAttempts = ref(0); //重连的尝试次数
+ const isNetworkConnected = ref(true); //监听当前网络连接状态
+ const isManuallyClosed = ref(false); //是否是被手动关闭的
+ const receivedMessages = ref(); //储从 WebSocket 服务器接收到的消息
+ const initMessageSendAttempts = ref(0); //初始化连接多少次
+ const reconnectStartTime = ref(0); //新增:记录重连开始时间
+ const isPongReceived = ref(false)
+ const allowReconnect = ref(true); // 新增:控制是否允许重连
+ // 关闭现有连接并清理资源
+ const closeExistingConnection = () => {
+ try {
+ socketTask.value.close({
+ success: () => {
+ console.log('WebSocket 连接已关闭');
+ },
+ fail: (err) => {
+ console.error('关闭 WebSocket 连接失败:', err);
+ }
+ });
+
+ // 清除心跳定时器
+ clearInterval(heartbeatTimer.value);
+ heartbeatTimer.value = null;
+
+ // 清除重连定时器
+ clearTimeout(reconnectTimer.value);
+ reconnectTimer.value = null;
+
+ // 标记连接已断开
+ isConnected.value = false;
+ } catch (error) {
+ console.error(error)
+ //TODO handle the exception
+ }
+
+
+ };
+ const websocketsendMessage = (data) => {
+ uni.$u.debounce(sendMessage(data), 500)
+ }
+
+
+ const handlePong = (res) => {
+ try {
+ let data = JSON.parse(res.data);
+ if (data.operate_type == "init" || (data
+ .msg === 'ok' &&
+ data.msg_id ==
+ 'ping_interval')) {
+ isPongReceived.value = true;
+ console.log('收到心跳响应,清除超时定时器');
+ clearTimeout(pongTimer);
+ }
+ } catch (error) {
+ console.error('解析心跳响应数据时出错:', error);
+ }
+ };
+
+ let onMessage = () => {
+
+ }
+ function setOnMessage(onMessageBallBack){
+ onMessage=onMessageBallBack
+ }
+ // 连接 WebSocket
+ const connect = async (connectMsg, onMessageBallBack) => {
+ if (!isNetworkConnected.value) {
+ uni.showToast({
+ title: '网络未连接...',
+ icon: 'none'
+ })
+ setTimeout(() => {
+ uni.pro.switchTab('index/index')
+ }, 1000)
+ console.log('网络未连接,暂不尝试连接 WebSocket');
+ return;
+ }
+ if (connectMsg) {
+ initMessage = connectMsg
+ }
+ if (onMessageBallBack) {
+ onMessage = onMessageBallBack
+ }
+ if (socketTask.value && isConnected.value) {
+ try {
+ sendMessage(connectMsg ? connectMsg : initMessage)
+ } catch (error) {
+ //TODO handle the exception
+ }
+ return
+ }
+ socketTask.value = uni.connectSocket({
+ url: uni.conf.baseUrlwws + '?' + Date.now(),
+ success: (res) => {
+ console.log('连接成功');
+ isConnected.value = true;
+ // 监听初始化成功在开启心跳
+ startHeartbeat();
+ },
+ fail: () => {
+ console.error('WebSocket 连接失败,尝试重连');
+ if (autoReconnect.value && allowReconnect.value) {
+ handleReconnect();
+ }
+ }
+ });
+
+ if (socketTask.value) {
+ socketTask.value.onOpen(() => {
+ // 初始化 初始购物车
+ sendMessage(connectMsg ? connectMsg : initMessage)
+ isConnected.value = true
+ });
+ socketTask.value.onMessage((res) => {
+ receivedMessages.value = JSON.parse(res.data)
+ console.log('收到消息',receivedMessages.value)
+ sendMessage({
+ type: 'receipt',
+ msg_id: receivedMessages.value.msg_id
+ })
+ if (onMessage) {
+ onMessage(receivedMessages.value)
+ }
+ // receivedMessages.value.push(list);
+ if (receivedMessages.value == 'ok' || receivedMessages.value
+ .operate_type == 'init') {
+ console.log('初始化正常,心跳响应正常');
+ // 清除重连定时器
+ clearTimeout(reconnectTimer.value);
+ allowReconnect.value = false
+ reconnectTimer.value = null;
+ }
+
+ });
+
+ socketTask.value.onClose((res) => {
+ console.log(res, 'WebSocket 连接已关闭,尝试重连');
+ isConnected.value = false;
+ clearInterval(heartbeatTimer.value); // 停止心跳定时器
+ clearTimeout(reconnectTimer.value); // 清除重连定时器
+ if (res.code == '1006' && !allowReconnect.value) {
+ uni.showToast({
+ title: '网络异常,请重新扫码',
+ icon: 'none'
+ });
+ autoReconnect.value = false;
+ setTimeout(() => {
+ uni.pro.switchTab('index/index');
+ }, 1000)
+ return false;
+ }
+ if (autoReconnect.value && !isManuallyClosed.value) {
+ handleReconnect();
+ }
+ });
+
+ socketTask.value.onError((err) => {
+ console.error('WebSocket 连接发生错误:', err);
+ isConnected.value = false;
+ clearInterval(heartbeatTimer.value);
+ if (autoReconnect.value && !isManuallyClosed.value) {
+ handleReconnect();
+ }
+ });
+ } else {
+ console.error('socketTask 未正确初始化');
+ }
+ };
+
+ // 启动心跳机制
+ const startHeartbeat = () => {
+ if (!isNetworkConnected.value) {
+ console.log('网络未连接,暂停心跳');
+ uni.showToast({
+ title: '网络未连接...',
+ icon: 'none'
+ });
+ setTimeout(() => {
+ uni.pro.switchTab('index/index');
+ }, 1000);
+ return;
+ }
+ clearInterval(heartbeatTimer.value)
+ heartbeatTimer.value = setInterval(() => {
+ sendMessage({
+ type: 'ping_interval',
+ set: 'shopping'
+ })
+ }, heartbeatInterval);
+ };
+
+
+ // 手动关闭连接
+ const closeSocket = () => {
+ console.log('手动关闭连接');
+ isManuallyClosed.value = true;
+ closeExistingConnection();
+ };
+
+ // 发送消息
+ const sendMessage = (data) => {
+ if (isConnected.value && data) {
+ // console.log('发送消息', data);
+ socketTask.value.send({
+ data: JSON.stringify(data),
+ success: () => {
+ // console.log('消息发送成功');
+ },
+ fail: () => {
+ // console.error('消息发送失败');
+ }
+ });
+ } else {
+ console.error('WebSocket 未连接,无法发送消息');
+ }
+
+ };
+
+ // 处理重连逻辑
+ const handleReconnect = () => {
+ if (!isNetworkConnected.value) {
+ console.log('网络未连接,暂停重连');
+ return;
+ }
+ if (isManuallyClosed.value) {
+ console.log('手动关闭连接,不进行重连');
+ return;
+ }
+
+ if (!allowReconnect.value) {
+ console.log('重连功能已关闭,不进行重连');
+ return;
+ }
+
+ if (reconnectAttempts.value < maxReconnectAttempts) {
+ reconnectAttempts.value++;
+ const reconnectInterval = initialReconnectInterval * Math.pow(2, reconnectAttempts
+ .value - 1);
+ const randomizedInterval = reconnectInterval + Math.floor(Math.random() * 1000);
+ uni.showLoading({
+ title: `正在努力连接..`,
+ mask: true
+ })
+ console.log(`尝试第 ${reconnectAttempts.value} 次重连,重连间隔: ${randomizedInterval}ms...`);
+
+ reconnectTimer.value = setTimeout(() => {
+ connect();
+ }, randomizedInterval);
+ } else {
+ console.error('重连次数达到上限,停止重连');
+ uni.showToast({
+ title: '重连次数达到上限,停止重连',
+ icon: 'none'
+ });
+ clearInterval(heartbeatTimer.value);
+ autoReconnect.value = false;
+ setTimeout(() => {
+ uni.hideLoading();
+ uni.pro.switchTab('index/index');
+ }, 1000)
+ }
+ };
+
+
+ // / 网络状态监听
+ const initNetworkListener = () => {
+ uni.getSystemInfo({
+ success: (res) => {
+ if (res.platform !== 'devtools') {
+ uni.onNetworkStatusChange((statusRes) => {
+ isNetworkConnected.value = statusRes.isConnected;
+ if (statusRes.isConnected && !isManuallyClosed.value) {
+ console.log('网络已连接,尝试重新连接 WebSocket');
+ if (!isConnected.value && autoReconnect.value) {
+ connect();
+ }
+ } else if (!statusRes.isConnected) {
+ console.log('网络已断开,暂停 WebSocket 操作');
+ clearInterval(heartbeatTimer.value);
+ clearTimeout(reconnectTimer.value);
+ if (socketTask.value) {
+ socketTask.value.close();
+ isConnected.value = false;
+ }
+ }
+ });
+ }
+ },
+ fail: (err) => {
+ console.error('获取系统信息失败:', err);
+ }
+ });
+
+ uni.getNetworkType({
+ success: (res) => {
+ isNetworkConnected.value = res.networkType !== 'none';
+ if (!isNetworkConnected.value) {
+ console.log('初始网络未连接,暂不尝试连接 WebSocket');
+ }
+ }
+ });
+ };
+
+ // 页面显示,尝试连接 WebSocket
+ const onShowconnect = () => {
+ if (autoReconnect.value) {
+ uni.showLoading({
+ title: `尝试再次连接`,
+ mask: true
+ })
+ connect();
+ }
+ }
+
+
+
+ onBeforeUnmount(() => {
+ // closeSocket();
+ });
+
+
+
+
+ return {
+ isConnected,
+ sendMessage,
+ closeSocket,
+ receivedMessages,
+ closeExistingConnection,
+ connect,
+ onShowconnect,
+ initNetworkListener,
+ connect,
+ allowReconnect,
+ socketTask,setOnMessage
+ };
+})
\ No newline at end of file
diff --git a/stores/carts.js b/stores/carts.js
index 5191204..9965c60 100644
--- a/stores/carts.js
+++ b/stores/carts.js
@@ -27,7 +27,7 @@ export const useCartsStore = defineStore('cart',
const goodsMap = reactive({})
//获取商品数据
async function goodsInit() {
- goodsIsloading.value=true;
+ goodsIsloading.value = true;
//获取招牌菜商品
const hotres = await productminiApphotsquery();
for (let product of hotres) {
@@ -102,12 +102,10 @@ export const useCartsStore = defineStore('cart',
return getProductDetails(v)
}).filter(v => v)
}
-
+
//收到socket消息时对购物车进行处理
async function onMessage(Message) {
- console.log('Message');
- console.log(Message);
if (Message) {
// 心跳返回 过滤
if (Message.type == "ping_interval" || Message.msg_id == "ping_interval") {
@@ -184,8 +182,8 @@ export const useCartsStore = defineStore('cart',
}
}
-
-
+
+
//购物车数据
const carts = ref([])
@@ -219,13 +217,13 @@ export const useCartsStore = defineStore('cart',
//是否使用会员价
const useVipPrice = computed(() => {
- const isUse=(orderVIP.value.isVip && shopInfo.value.isMemberPrice)?true:false
- console.log('useVipPrice',isUse);
+ const isUse = (orderVIP.value.isVip && shopInfo.value.isMemberPrice) ? true : false
return isUse
})
- function currentCalcMpneyNumber(item){
- const n=item.number-(item.returnNum||0)
- return n<=0?0:n
+
+ function currentCalcMpneyNumber(item) {
+ const n = item.number - (item.returnNum || 0)
+ return n <= 0 ? 0 : n
}
//历史订单商品价格总和
const oldOrderMoney = computed(() => {
@@ -239,7 +237,7 @@ export const useCartsStore = defineStore('cart',
const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData
.salePrice) : 0
const price = (discount_sale_amount || cur.salePrice || 0)
- const number =currentCalcMpneyNumber(cur)
+ const number = currentCalcMpneyNumber(cur)
return prve + (number <= 0 ? 0 : number) * (discount_sale_amount || (useVipPrice
.value ? memberPrice : price))
}, 0)
@@ -252,7 +250,7 @@ export const useCartsStore = defineStore('cart',
const money = carts.value.reduce((prve, cur) => {
const memberPrice = cur.memberPrice || cur.salePrice
const price = useVipPrice.value ? memberPrice : cur.salePrice;
- const curMoney = price * currentCalcMpneyNumber(cur)
+ const curMoney = price * currentCalcMpneyNumber(cur)
return prve + curMoney
}, 0)
return money
@@ -260,7 +258,7 @@ export const useCartsStore = defineStore('cart',
// 霸王餐购物车原价,不享受任何优惠
const totalOriginPrice = computed(() => {
const money = carts.value.reduce((prve, cur) => {
- const curMoney = cur.salePrice * currentCalcMpneyNumber(cur)
+ const curMoney = cur.salePrice * currentCalcMpneyNumber(cur)
return prve + curMoney
}, 0)
return money
@@ -274,7 +272,7 @@ export const useCartsStore = defineStore('cart',
// return pre + returnProDiscount(cur, index) * 1;
// }, 0);
// });
-
+
//返回打包数量(称重商品打包数量最大为1)
function returnCartPackNumber(cur) {
@@ -285,17 +283,17 @@ export const useCartsStore = defineStore('cart',
pack_number = pack_number <= 0 ? 0 : pack_number
return pack_number * 1
}
-
-
+
+
//当前购物车打包费
const totalPackFee = computed(() => {
const money = carts.value.reduce((prve, cur) => {
- const curMoney = (cur.packFee || 0) * currentCalcMpneyNumber(cur)
+ const curMoney = (cur.packFee || 0) * currentCalcMpneyNumber(cur)
return prve + curMoney
}, 0)
return money
})
-
+
//打包费
const packFee = computed(() => {
const nowPackFee = carts.value.reduce((acc, cur) => {
@@ -351,7 +349,7 @@ export const useCartsStore = defineStore('cart',
console.log('isBwc');
console.log(isBwc);
let cart = matchedProducts.reduce((total, item) => {
- if(isBwc===true){
+ if (isBwc === true) {
return total + (parseFloat(item.price) * parseFloat(item.num - item.returnNum));
}
// 是否启用会员价 0否1是
@@ -447,7 +445,8 @@ export const useCartsStore = defineStore('cart',
totalPrice,
totalPackFee,
updateData,
- useVipPrice,totalOriginPrice
+ useVipPrice,
+ totalOriginPrice
};
}
);
\ No newline at end of file