代客下单重构
This commit is contained in:
6
App.vue
6
App.vue
@@ -1,7 +1,4 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {
|
|
||||||
useCartsStore
|
|
||||||
} from '@/stores/carts.js';
|
|
||||||
import {
|
import {
|
||||||
useNavbarStore
|
useNavbarStore
|
||||||
} from '@/stores/navbarStore';
|
} from '@/stores/navbarStore';
|
||||||
@@ -35,9 +32,6 @@
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
const store = useNavbarStore();
|
const store = useNavbarStore();
|
||||||
await store.initNavbarHeight();
|
await store.initNavbarHeight();
|
||||||
getApp().globalData.websocket=null;
|
|
||||||
const cartsStore=useCartsStore()
|
|
||||||
cartsStore.isloading=false;
|
|
||||||
});
|
});
|
||||||
onShow(async () => {
|
onShow(async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,360 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭现有连接并清理资源
|
|
||||||
closeExistingConnection();
|
|
||||||
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
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useWebSocket;
|
|
||||||
244
common/js/carts-websocket.ts
Normal file
244
common/js/carts-websocket.ts
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
import { error } from "../../uni_modules/uview-plus";
|
||||||
|
|
||||||
|
// import qs from "qs";
|
||||||
|
const qs = {
|
||||||
|
stringify: (obj) => {
|
||||||
|
const str= Object.keys(obj).reduce((prve, key) => {
|
||||||
|
return prve + `${key}=${obj[key]}&`
|
||||||
|
}, '?')
|
||||||
|
|
||||||
|
return str.substring(0,str.length-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function ElMessage() {
|
||||||
|
|
||||||
|
}
|
||||||
|
function ElMessageBox() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
userInfo: {
|
||||||
|
shopId: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApifoxModel {
|
||||||
|
account : string;
|
||||||
|
operate_type : string;
|
||||||
|
shop_id : string;
|
||||||
|
table_code ?: string;
|
||||||
|
type : string;
|
||||||
|
[property : string] : string | number | undefined; // 限制额外属性类型
|
||||||
|
}
|
||||||
|
|
||||||
|
export type msgType = 'add' | 'reduce' | 'remove' | 'edit' | 'init' | 'cleanup' | 'del' | 'rottable' | 'batch' | 'disconnect' | 'clearOrder';
|
||||||
|
|
||||||
|
class WebSocketManager {
|
||||||
|
private client : WebSocket | null = null;
|
||||||
|
private connected : boolean = false;
|
||||||
|
private shop_id = user.userInfo.shopId ? String(user.userInfo.shopId) : '';
|
||||||
|
private autoConnect : boolean = true;
|
||||||
|
private initParams : ApifoxModel = {
|
||||||
|
type: 'shopping',
|
||||||
|
account: this.shop_id || '', // 提供默认值
|
||||||
|
operate_type: 'init',
|
||||||
|
table_code: '',
|
||||||
|
shop_id: this.shop_id || '', // 提供默认值
|
||||||
|
};
|
||||||
|
private onMessage : (message : any) => void = () => { };
|
||||||
|
private messageHandlers : Map<string, ((message : string) => void)[]> = new Map();
|
||||||
|
private type : string = 'shopping';
|
||||||
|
private reconnectAttempts = 0;
|
||||||
|
private maxReconnectAttempts = Infinity; // 自定义最大重试次数
|
||||||
|
private reconnectDelay = 5000; // 重试延迟(单位:毫秒)
|
||||||
|
private timer : any | null = null;
|
||||||
|
private reconnectTimer : any | null = null
|
||||||
|
|
||||||
|
connectSocketSuccsss(){
|
||||||
|
if(!this.client){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.client.onOpen(() => {
|
||||||
|
this.connected = true;
|
||||||
|
console.log("WebSocket 连接已建立");
|
||||||
|
console.log(this.initParams);
|
||||||
|
this.sendMessage(this.initParams);
|
||||||
|
this.clearTimer();
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
this.sendMessage({ type: "ping_interval", set: 'shopping' }, false);
|
||||||
|
}, 1000 * 10);
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.onClose(() => {
|
||||||
|
this.clearTimer();
|
||||||
|
this.connected = false;
|
||||||
|
console.log("WebSocket 连接已断开");
|
||||||
|
if (this.autoConnect) {
|
||||||
|
this.reconnect(); // 自动重连
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.onError((error : Event) => {
|
||||||
|
this.clearTimer();
|
||||||
|
console.error("WebSocket 发生错误:", error);
|
||||||
|
this.reconnect(); // 自动重连
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.onMessage((event : MessageEvent) => {
|
||||||
|
try {
|
||||||
|
const message = JSON.parse(event.data);
|
||||||
|
if (message && message.msg_id) {
|
||||||
|
this.onMessageHandler({ msg_id: message.msg_id });
|
||||||
|
}
|
||||||
|
this.onMessage(message);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("消息解析失败:", e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 WebSocket 客户端
|
||||||
|
setupWebSocket() {
|
||||||
|
// #ifdef H5
|
||||||
|
const endpoint = "http://192.168.1.31:2348/"
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
const endpoint = "ws://192.168.1.31:2348/"
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
if (!endpoint) {
|
||||||
|
console.warn("WebSocket 已被禁用,请在配置文件中配置 VITE_APP_WS_ENDPOINT");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.client && this.connected) {
|
||||||
|
console.log("客户端已存在并且连接正常");
|
||||||
|
return this.client;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = qs.stringify(this.initParams);
|
||||||
|
// this.client = new WebSocket(endpoint + '?' + url);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
this.client = uni.connectSocket({
|
||||||
|
url: endpoint + url,
|
||||||
|
success: (res) => {
|
||||||
|
console.log('连接成功');
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error(error(err))
|
||||||
|
console.error('WebSocket 连接失败,尝试重连');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.connectSocketSuccsss()
|
||||||
|
console.log('this.client');
|
||||||
|
console.log(this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 消息回执
|
||||||
|
public onMessageHandler(data : any) {
|
||||||
|
if (this.client && this.connected) {
|
||||||
|
this.client.send({data:JSON.stringify({ ...data, type: 'receipt' })});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订阅主题
|
||||||
|
public subscribeToTopic(initParams : ApifoxModel, onMessage : (message : any) => void) {
|
||||||
|
console.log(`正在订阅主题: `, initParams);
|
||||||
|
this.initParams = { ...this.initParams, ...initParams };
|
||||||
|
this.disconnect();
|
||||||
|
this.setupWebSocket();
|
||||||
|
this.onMessage = onMessage;
|
||||||
|
this.autoConnect = true
|
||||||
|
}
|
||||||
|
|
||||||
|
public sendMessage(message : any, isSendInitParams : boolean = true) {
|
||||||
|
if (!this.client || !this.connected) {
|
||||||
|
// ElMessage.error('发送失败,已重新连接,请重新操作');
|
||||||
|
this.reconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (message.operate_type == 'disconnect') {
|
||||||
|
this.disconnect();
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const msg = JSON.stringify(isSendInitParams ? { ...this.initParams, ...message } : message);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.client?.send({data:msg});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("发送消息失败:", error);
|
||||||
|
// ElMessage.error('发送失败,已重新连接,请重新操作');
|
||||||
|
this.reconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public canSendMessage() {
|
||||||
|
return this.client && this.connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 断开 WebSocket 连接
|
||||||
|
public disconnect() {
|
||||||
|
if (this.client && this.connected) {
|
||||||
|
console.log("断开 WebSocket 连接");
|
||||||
|
this.clearTimer();
|
||||||
|
try {
|
||||||
|
if(this.client){
|
||||||
|
this.client.closeSocket();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
//TODO handle the exception
|
||||||
|
console.error('关闭WebSocket连接失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client = null;
|
||||||
|
this.connected = false;
|
||||||
|
this.autoConnect = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 自动重连机制
|
||||||
|
private reconnect() {
|
||||||
|
if (!this.autoConnect) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||||
|
this.reconnectAttempts++;
|
||||||
|
console.log(`尝试第 ${this.reconnectAttempts} 次重连...`);
|
||||||
|
this.reconnectTimer = setTimeout(() => {
|
||||||
|
this.setupWebSocket();
|
||||||
|
}, this.reconnectDelay);
|
||||||
|
} else {
|
||||||
|
clearTimeout(this.reconnectTimer);
|
||||||
|
console.error("达到最大重连次数,停止重连");
|
||||||
|
ElMessageBox.confirm('达到最大重连次数' + this.maxReconnectAttempts + '次,已停止重连,是否立即重连?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
|
||||||
|
callback: (action : string) => {
|
||||||
|
console.log(action);
|
||||||
|
if (action == 'confirm') {
|
||||||
|
this.setupWebSocket();
|
||||||
|
this.reconnectAttempts = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除定时器
|
||||||
|
private clearTimer() {
|
||||||
|
if (this.timer) {
|
||||||
|
clearInterval(this.timer);
|
||||||
|
this.timer = null;
|
||||||
|
}
|
||||||
|
if (this.reconnectTimer) {
|
||||||
|
clearInterval(this.reconnectTimer);
|
||||||
|
this.reconnectTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new WebSocketManager();
|
||||||
@@ -260,10 +260,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
|
||||||
useCartsStore
|
|
||||||
} from '@/stores/carts.js';
|
|
||||||
const cartStore = useCartsStore()
|
|
||||||
import orderItemVue from './order-item.vue';
|
import orderItemVue from './order-item.vue';
|
||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
|
|||||||
@@ -140,8 +140,8 @@
|
|||||||
} from '@/common/api/shop/index.js'
|
} from '@/common/api/shop/index.js'
|
||||||
import {
|
import {
|
||||||
useCartsStore
|
useCartsStore
|
||||||
} from '@/stores/carts.js';
|
} from '@/stores/carts';
|
||||||
import useWebSocket from '@/common/js/carts-websocket.js';
|
import useWebSocket from '@/common/js/carts-websocket';
|
||||||
const cartStore = useCartsStore()
|
const cartStore = useCartsStore()
|
||||||
let cartsSocket = null
|
let cartsSocket = null
|
||||||
watch(() => cartStore.goodsIsloading, (newValue) => {
|
watch(() => cartStore.goodsIsloading, (newValue) => {
|
||||||
|
|||||||
1406
pages/product/components/confirmorder - 副本.vue
Normal file
1406
pages/product/components/confirmorder - 副本.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,13 +3,6 @@
|
|||||||
<up-popup :show="showCart" :round="20" :safeAreaInsetBottom="false" :zIndex="98" :overlayStyle="{ zIndex: 98 }"
|
<up-popup :show="showCart" :round="20" :safeAreaInsetBottom="false" :zIndex="98" :overlayStyle="{ zIndex: 98 }"
|
||||||
@close="close">
|
@close="close">
|
||||||
<view class="cart-list-wrap">
|
<view class="cart-list-wrap">
|
||||||
<!-- <view class="cart-header flex-between">
|
|
||||||
<view class="num">已点 {{ cartLists_count }} 份</view>
|
|
||||||
<view class="clear" @click="cartclear">
|
|
||||||
<up-icon name="trash" color="#999"></up-icon>
|
|
||||||
<text class="t">清空</text>
|
|
||||||
</view>
|
|
||||||
</view> -->
|
|
||||||
<scroll-view scroll-y class="scroll-view">
|
<scroll-view scroll-y class="scroll-view">
|
||||||
<view class="list-wrap">
|
<view class="list-wrap">
|
||||||
<view v-if="cartList.length>0">
|
<view v-if="cartList.length>0">
|
||||||
@@ -29,15 +22,15 @@
|
|||||||
<up-image :src="item.coverImg" width="80" radius="10" height="80"></up-image>
|
<up-image :src="item.coverImg" width="80" radius="10" height="80"></up-image>
|
||||||
</view>
|
</view>
|
||||||
<view class="info">
|
<view class="info">
|
||||||
<view class="name"> {{item.cartListinfo.is_temporary == 1?'临时菜' :item.name }}
|
<view class="name"> {{item.is_temporary == 1?'临时菜' :item.name }}
|
||||||
</view>
|
</view>
|
||||||
<view class="select-sku-wrap" v-if="item.type == 'sku'">
|
<view class="select-sku-wrap" v-if="item.type == 'sku'">
|
||||||
<text v-for="i in item.skuList" :key="i.id">
|
<text >
|
||||||
{{item.cartListinfo.sku_id == i.id? i.name:"" }}
|
{{item.skuData.name||''}}
|
||||||
</text>
|
</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="select-sku-wrap" v-if="item.type == 'package'">
|
<view class="select-sku-wrap" v-if="item.type == 'package'">
|
||||||
<view v-for="(a,b) in dataprocessing(item.cartListinfo)" :key="b">
|
<view v-for="(a,b) in dataprocessing(item)" :key="b">
|
||||||
<!-- <view>{{a.title}}</view> -->
|
<!-- <view>{{a.title}}</view> -->
|
||||||
<text v-for="i in a.goods" :key="i.proId" style="margin-left: 4rpx;">
|
<text v-for="i in a.goods" :key="i.proId" style="margin-left: 4rpx;">
|
||||||
{{i.proName }}
|
{{i.proName }}
|
||||||
@@ -47,15 +40,14 @@
|
|||||||
<view class="price-wrap" style="padding-top: 0;">
|
<view class="price-wrap" style="padding-top: 0;">
|
||||||
<view class="price">
|
<view class="price">
|
||||||
<text class="i">¥</text>
|
<text class="i">¥</text>
|
||||||
<!-- 会员价与价格 -->
|
<!-- 会员价 -->
|
||||||
<text class="price" v-if="item.type == 'sku'">
|
<text class="price" v-if="shopInfo.isVip ==1 && shopInfo.isMemberPrice==1">
|
||||||
<text v-for="i in item.skuList" :key="i.id">
|
<text >
|
||||||
<!-- -->
|
{{item.memberPrice || item.salePrice}}
|
||||||
{{item.cartListinfo.sku_id == i.id?(shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(i.memberPrice || i.salePrice):i.salePrice):''}}
|
|
||||||
</text>
|
</text>
|
||||||
</text>
|
</text>
|
||||||
<text class="price" v-else>
|
<text class="price" v-else>
|
||||||
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice || item.salePrice):item.salePrice}}
|
{{item.salePrice}}
|
||||||
</text>
|
</text>
|
||||||
<!-- <text class="originalprice"
|
<!-- <text class="originalprice"
|
||||||
v-if="item.originPrice">¥{{item.originPrice}}</text>
|
v-if="item.originPrice">¥{{item.originPrice}}</text>
|
||||||
@@ -66,16 +58,16 @@
|
|||||||
<view class="operation-wrap">
|
<view class="operation-wrap">
|
||||||
<view class="btn">
|
<view class="btn">
|
||||||
<up-icon color="#E8AD7B" name="minus-circle" size="25"></up-icon>
|
<up-icon color="#E8AD7B" name="minus-circle" size="25"></up-icon>
|
||||||
<view class="btnClick" @click="cartListadd(item,'-')"></view>
|
<view class="btnClick" @click="changeNumber(-1,item)"></view>
|
||||||
</view>
|
</view>
|
||||||
<text class="num">{{ ifcartNumber(item) }}</text>
|
<text class="num">{{ item.number*1 }}</text>
|
||||||
<view class="btn" v-if="item.type !='package'">
|
<view class="btn" v-if="item.type !='package'">
|
||||||
<!-- <up-icon name="plus-circle-fill"
|
<!-- <up-icon name="plus-circle-fill"
|
||||||
:color="{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? '#CECECE' : '#E9AB7A'"
|
:color="{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? '#CECECE' : '#E9AB7A'"
|
||||||
size="25"></up-icon> -->
|
size="25"></up-icon> -->
|
||||||
<up-icon name="plus-circle-fill" color="#E8AD7B"
|
<up-icon name="plus-circle-fill" color="#E8AD7B"
|
||||||
size="25"></up-icon>
|
size="25"></up-icon>
|
||||||
<view class="btnClick" @click="cartListadd(item,'+')"></view>
|
<view class="btnClick" @click="changeNumber(1,item)"></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -104,7 +96,7 @@
|
|||||||
} from '@/stores/user.js';
|
} from '@/stores/user.js';
|
||||||
|
|
||||||
// 定义自定义事件
|
// 定义自定义事件
|
||||||
const emits = defineEmits(['customevent', 'close', 'clickcancelOrder']);
|
const emits = defineEmits(['changeNumber', 'close', 'clearCarts']);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
cartList: {
|
cartList: {
|
||||||
@@ -127,55 +119,17 @@
|
|||||||
});
|
});
|
||||||
const shopInfo = uni.cache.get('shopInfo')
|
const shopInfo = uni.cache.get('shopInfo')
|
||||||
|
|
||||||
// 定义 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;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
emits("close", false)
|
emits("close", false)
|
||||||
}
|
}
|
||||||
// 购物车加减
|
function changeNumber(step,item){
|
||||||
const cartListadd = async (item, i) => {
|
emits("changeNumber", step, item);
|
||||||
// 是否起售 如果小于或者大于都是1
|
|
||||||
const cartNumberFloat = parseFloat(item.cartNumber);
|
|
||||||
const suitNum = item.suitNum >= cartNumberFloat && i == '-' ? item.cartNumber : 1;
|
|
||||||
|
|
||||||
emits('customevent', {
|
|
||||||
id: item.cartListId ? item.cartListId : '',
|
|
||||||
type: 'shopping',
|
|
||||||
table_code: uni.cache.get('tableCode'),
|
|
||||||
shop_id: uni.cache.get('shopId'),
|
|
||||||
operate_type: calculateValue(item.cartNumber, i, suitNum) == 'del' ? 'del' : item.cartListId &&
|
|
||||||
item.cartNumber > 0 ? 'edit' : 'add',
|
|
||||||
product_id: item.id,
|
|
||||||
sku_id: item.skuId,
|
|
||||||
number: await calculateValue(item.cartNumber, i, suitNum),
|
|
||||||
is_print: 1,
|
|
||||||
suitNum: item.suitNum,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const dataprocessing = computed(() => {
|
const dataprocessing = computed(() => {
|
||||||
return (item) => {
|
return (item) => {
|
||||||
let res = null
|
let res = null
|
||||||
@@ -188,18 +142,6 @@
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
const clickcancelOrder = (i, key) => {
|
|
||||||
emits('clickcancelOrder', {
|
|
||||||
i,
|
|
||||||
key
|
|
||||||
})
|
|
||||||
emits('customevent', {
|
|
||||||
type: 'shopping',
|
|
||||||
table_code: uni.cache.get('tableCode'),
|
|
||||||
shop_id: uni.cache.get('shopId'),
|
|
||||||
operate_type: 'clearOrder',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const calculateValue = (cartNumber, i, step = 1) => {
|
const calculateValue = (cartNumber, i, step = 1) => {
|
||||||
if (i == '+') {
|
if (i == '+') {
|
||||||
@@ -212,30 +154,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 菜品备注修改
|
|
||||||
const productBlur = (item) => {
|
|
||||||
let params = {
|
|
||||||
"skuId": item.skuId,
|
|
||||||
"num": item.number, //数量
|
|
||||||
"type": item.type,
|
|
||||||
"isVip": item.isVip,
|
|
||||||
"productId": item.productId, //商品id
|
|
||||||
"note": item.note,
|
|
||||||
"shopId": this.shopId,
|
|
||||||
"userId": uni.cache.get('userInfo').id,
|
|
||||||
"tableId": this.tableCode,
|
|
||||||
}
|
|
||||||
this.$emit("addCart", params)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清空购物车
|
// 清空购物车
|
||||||
const cartclear = () => {
|
const cartclear = () => {
|
||||||
emits('customevent', {
|
emits('clearCarts')
|
||||||
type: 'shopping',
|
|
||||||
table_code: uni.cache.get('tableCode'),
|
|
||||||
shop_id: uni.cache.get('shopId'),
|
|
||||||
operate_type: 'cleanup',
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
2631
pages/product/index - 副本.vue
Normal file
2631
pages/product/index - 副本.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 本店招牌菜 -->
|
<!-- 本店招牌菜 -->
|
||||||
<view class="panelfour" v-if="shopProductList.hots && shopProductList.hots.length > 0">
|
<view class="panelfour" v-if="carts.hotgoods && carts.hotgoods.length > 0">
|
||||||
本店招牌菜
|
本店招牌菜
|
||||||
</view>
|
</view>
|
||||||
<view class="panelfive ">
|
<view class="panelfive ">
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<scroll-view :scroll-x="true" :scroll-with-animation="false">
|
<scroll-view :scroll-x="true" :scroll-with-animation="false">
|
||||||
<view class="panelfive_list">
|
<view class="panelfive_list">
|
||||||
<view class="panelfiveitem" @click="clickspecifications(item,index,index,'热销')"
|
<view class="panelfiveitem" @click="clickspecifications(item,index,index,'热销')"
|
||||||
v-for="(item,index) in shopProductList.hots" :key="index">
|
v-for="(item,index) in carts.hotgoods" :key="index">
|
||||||
<image class="panelfiveitemimage" :src="item.coverImg" mode="aspectFill"></image>
|
<image class="panelfiveitemimage" :src="item.coverImg" mode="aspectFill"></image>
|
||||||
<view class="vifgoodsImg flex-center"
|
<view class="vifgoodsImg flex-center"
|
||||||
v-if="item.isSale == 0 || (item.isSaleTime == 0 && !item.isSaleTimeshow) || item.isSoldStock == 1 || (item.isStock == 1 && item.stockNumber <= 0)">
|
v-if="item.isSale == 0 || (item.isSaleTime == 0 && !item.isSaleTimeshow) || item.isSoldStock == 1 || (item.isStock == 1 && item.stockNumber <= 0)">
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
:class="shopInfo.isVip == 0 || shopInfo.isMemberPrice==0?'lineThrough':''">¥</text>
|
:class="shopInfo.isVip == 0 || shopInfo.isMemberPrice==0?'lineThrough':''">¥</text>
|
||||||
<!-- 会员价与价格 -->
|
<!-- 会员价与价格 -->
|
||||||
<text class="price">
|
<text class="price">
|
||||||
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice||item.salePrice):item.salePrice}}
|
{{carts.useVipPrice?(item.memberPrice||item.salePrice):item.salePrice}}
|
||||||
</text>
|
</text>
|
||||||
<!-- 单位 -->
|
<!-- 单位 -->
|
||||||
<text class="unit" v-if="item.unitName">/{{item.unitName}}</text>
|
<text class="unit" v-if="item.unitName">/{{item.unitName}}</text>
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
:class="shopInfo.isVip ==0 || shopInfo.isMemberPrice==0?'lineThrough':''">¥</text>
|
:class="shopInfo.isVip ==0 || shopInfo.isMemberPrice==0?'lineThrough':''">¥</text>
|
||||||
<!-- 会员价与价格 -->
|
<!-- 会员价与价格 -->
|
||||||
<text class="price">
|
<text class="price">
|
||||||
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice|| item.salePrice):item.salePrice}}
|
{{carts.useVipPrice?(item.memberPrice|| item.salePrice):item.salePrice}}
|
||||||
</text>
|
</text>
|
||||||
<text class="unit" v-if="item.unitName">/{{item.unitName}}</text>
|
<text class="unit" v-if="item.unitName">/{{item.unitName}}</text>
|
||||||
<!-- <text v-if="item.suitNum>1 && item.type!= 'sku'"
|
<!-- <text v-if="item.suitNum>1 && item.type!= 'sku'"
|
||||||
@@ -153,14 +153,14 @@
|
|||||||
<view class="left" :style="{top: `${store.height}px`}">
|
<view class="left" :style="{top: `${store.height}px`}">
|
||||||
<scroll-view :scroll-into-view="leftIntoView" :scroll-with-animation="false" :scroll-y="true"
|
<scroll-view :scroll-into-view="leftIntoView" :scroll-with-animation="false" :scroll-y="true"
|
||||||
:style="{height:`${store.screenHeight - store.height}px`}" style="padding-bottom: 200rpx;">
|
:style="{height:`${store.screenHeight - store.height}px`}" style="padding-bottom: 200rpx;">
|
||||||
<view class="item" v-for="(item,index) in shopProductList.productInfo" :key="index"
|
<view class="item" v-for="(item,index) in carts.groupGoods" :key="index"
|
||||||
:class="{ 'active':index==leftIndex }" :id="'left-'+index" :data-index="index"
|
:class="{ 'active':index==leftIndex }" :id="'left-'+index" :data-index="index"
|
||||||
@click="leftTap(index)"><text>{{item.name}}</text></view>
|
@click="leftTap(index)"><text>{{item.name}}</text></view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
<view class="main">
|
<view class="main">
|
||||||
<view>
|
<view>
|
||||||
<view class="item main-item" v-for="(item,index) in shopProductList.productInfo" :key="index"
|
<view class="item main-item" v-for="(item,index) in carts.groupGoods" :key="index"
|
||||||
:id="'item-'+index">
|
:id="'item-'+index">
|
||||||
<view class="title">
|
<view class="title">
|
||||||
<view>{{item.name}}</view>
|
<view>{{item.name}}</view>
|
||||||
@@ -175,19 +175,25 @@
|
|||||||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/index/1.gif" mode="" v-else
|
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/index/1.gif" mode="" v-else
|
||||||
:lazy-load="true">
|
:lazy-load="true">
|
||||||
</image>
|
</image>
|
||||||
<view class="vifgoodsImg"
|
<block>
|
||||||
v-if="item1.isSale == 0 || (item1.isSaleTime == 0 && !item1.isSaleTimeshow) || item1.isSoldStock == 1 || (item1.isStock == 1 && item1.stockNumber <= 0)">
|
<view class="vifgoodsImg" v-if="item1.isSale == 0">
|
||||||
<image v-if="item1.isSale == 0" src="@/static/ztt/icon_goods_yxj.svg"
|
<image src="@/static/ztt/icon_goods_yxj.svg" style="width:200rpx; height: 100%;"
|
||||||
style="width:200rpx; height: 100%;" mode=""></image>
|
|
||||||
<image v-else-if="(item1.isSaleTime == 0 && !item1.isSaleTimeshow)"
|
|
||||||
src="@/static/ztt/icon_goods_wks.svg" style="width:200rpx; height: 100%;"
|
|
||||||
mode=""></image>
|
|
||||||
<image v-else-if="item1.isSoldStock == 1" src="@/static/ztt/icon_goods_sq.svg"
|
|
||||||
style="width:200rpx; height: 100%;" mode=""></image>
|
|
||||||
<image v-else-if="item1.isStock == 1 && item1.stockNumber <= 0"
|
|
||||||
src="@/static/ztt/icon_goods_kcbz.svg" style="width:200rpx; height: 100%;"
|
|
||||||
mode=""></image>
|
mode=""></image>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="vifgoodsImg"
|
||||||
|
v-else-if="item1.isSaleTime == 0 && !item1.isSaleTimeshow">
|
||||||
|
<image src="@/static/ztt/icon_goods_wks.svg" style="width:200rpx; height: 100%;"
|
||||||
|
mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="vifgoodsImg" v-else-if="item1.isSoldStock == 1">
|
||||||
|
<image src="@/static/ztt/icon_goods_sq.svg" style="width:200rpx; height: 100%;"
|
||||||
|
mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="vifgoodsImg" v-else-if="item1.isStock == 1 && item1.stockNumber <= 0">
|
||||||
|
<image src="@/static/ztt/icon_goods_kcbz.svg"
|
||||||
|
style="width:200rpx; height: 100%;" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
<view v-if="index=='0'" class="topSort" :class="'c'+(index1+1)">TOP{{index1+1}}</view>
|
<view v-if="index=='0'" class="topSort" :class="'c'+(index1+1)">TOP{{index1+1}}</view>
|
||||||
<view class="goods_right" style="overflow: hidden;">
|
<view class="goods_right" style="overflow: hidden;">
|
||||||
<view class="name">{{ item1.name }}</view>
|
<view class="name">{{ item1.name }}</view>
|
||||||
@@ -205,8 +211,11 @@
|
|||||||
<view class="money">
|
<view class="money">
|
||||||
<view>¥</view>
|
<view>¥</view>
|
||||||
<text class="money_num" style="margin-right: 10rpx;">
|
<text class="money_num" style="margin-right: 10rpx;">
|
||||||
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1 ?(item1.memberPrice||item1.salePrice):item1.salePrice}}
|
{{carts.useVipPrice?(item1.memberPrice||item1.salePrice):item1.salePrice}}
|
||||||
</text>
|
</text>
|
||||||
|
<!-- <text class="money_num" style="margin-right: 10rpx;">
|
||||||
|
{{carts.useVipPrice ?(item1.memberPrice||item1.salePrice):item1.salePrice}}
|
||||||
|
</text> -->
|
||||||
<text v-if="item1.unitName">/{{item1.unitName}}</text>
|
<text v-if="item1.unitName">/{{item1.unitName}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="flex-end">
|
<view class="flex-end">
|
||||||
@@ -221,7 +230,7 @@
|
|||||||
<view class="money">
|
<view class="money">
|
||||||
<view>¥</view>
|
<view>¥</view>
|
||||||
<text class="money_num">
|
<text class="money_num">
|
||||||
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item1.memberPrice||item1.salePrice):item1.salePrice}}
|
{{carts.useVipPrice?(item1.memberPrice||item1.salePrice):item1.salePrice}}
|
||||||
</text>
|
</text>
|
||||||
<text class="money_num" v-if="item1.unitName">/{{item1.unitName}}</text>
|
<text class="money_num" v-if="item1.unitName">/{{item1.unitName}}</text>
|
||||||
<!-- <text v-if="item1.suitNum>1 && item1.type!= 'sku'"
|
<!-- <text v-if="item1.suitNum>1 && item1.type!= 'sku'"
|
||||||
@@ -267,21 +276,17 @@
|
|||||||
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<confirmorder ref="confirmorderref" :cartLists_count="cartLists_count" :cartList="matchedProducts"
|
|
||||||
:totalPrices='totalPrices' :confirmordershow="confirmordershow"
|
|
||||||
@close="confirmordershow = !confirmordershow" @customevent='websocketsendMessage' :orderinfo="orderinfo">
|
|
||||||
</confirmorder>
|
|
||||||
|
|
||||||
<!-- 店铺详情 -->
|
<!-- 店铺详情 -->
|
||||||
<shopindex ref="showShopInfoRef"></shopindex>
|
<shopindex ref="showShopInfoRef"></shopindex>
|
||||||
<!-- 购物车 -->
|
<!-- 购物车 -->
|
||||||
<shoppingCartes :cartLists_count="cartLists_count" :cartList="matchedProducts" :showCart="showCart"
|
<shoppingCartes :cartLists_count="carts.totalNumber" :cartList="carts.list" :showCart="showCart"
|
||||||
@customevent='websocketsendMessage' @close="showCart = !showCart" :orderinfo="orderinfo"
|
@clearCarts="clearCarts" @changeNumber="cartsChangeNumber" @close="showCart = !showCart"
|
||||||
@clickcancelOrder='clickcancelOrder' v-if="cartLists_count > 0">
|
:orderinfo="orderinfo" v-if="!carts.isEmpty">
|
||||||
</shoppingCartes>
|
</shoppingCartes>
|
||||||
|
|
||||||
<!-- 显示购物车栏 -->
|
<!-- 显示购物车栏 -->
|
||||||
<view class="cart-wrap" v-if="cartLists_count > 0 && !confirmordershow && isBusinessTime">
|
<view class="cart-wrap" v-if="!carts.isEmpty && isBusinessTime">
|
||||||
<view class="cart-content">
|
<view class="cart-content">
|
||||||
<view class="left">
|
<view class="left">
|
||||||
<view class="iconBox">
|
<view class="iconBox">
|
||||||
@@ -289,11 +294,11 @@
|
|||||||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/shopIcon.png"
|
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/shopIcon.png"
|
||||||
mode="aspectFill" @click="Historicalorders(true)">
|
mode="aspectFill" @click="Historicalorders(true)">
|
||||||
</image>
|
</image>
|
||||||
<text class="u-badge"> {{cartLists_count<99?cartLists_count:'99+'}} </text>
|
<text class="u-badge"> {{carts.totalNumber <99?carts.totalNumber:'99+'}} </text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<text class="i">¥</text>
|
<text class="i">¥</text>
|
||||||
<text class="num">{{totalPrices}}</text>
|
<text class="num">{{carts.payMoney}}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn" @tap="$u.debounce(orderdetail, 500)">
|
<view class="btn" @tap="$u.debounce(orderdetail, 500)">
|
||||||
<text class="t">结算</text>
|
<text class="t">结算</text>
|
||||||
@@ -366,7 +371,7 @@
|
|||||||
<view class="price" v-if="specifications.item.type != 'package' && specifications.item.result">
|
<view class="price" v-if="specifications.item.type != 'package' && specifications.item.result">
|
||||||
<text class="i">¥</text>
|
<text class="i">¥</text>
|
||||||
<text
|
<text
|
||||||
class="num">{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? (specifications.item.result.memberPrice||specifications.item.result.salePrice):specifications.item.result.salePrice}}</text>
|
class="num">{{carts.useVipPrice? (specifications.item.result.memberPrice||specifications.item.result.salePrice):specifications.item.result.salePrice}}</text>
|
||||||
<text class="i" v-if="specifications.item.unitName">/{{specifications.item.unitName}}</text>
|
<text class="i" v-if="specifications.item.unitName">/{{specifications.item.unitName}}</text>
|
||||||
<text v-if="specifications.item.result.suitNum>1">
|
<text v-if="specifications.item.result.suitNum>1">
|
||||||
「{{specifications.item.result.suitNum}}{{specifications.item.result.unitName}}起点」
|
「{{specifications.item.result.suitNum}}{{specifications.item.result.unitName}}起点」
|
||||||
@@ -375,7 +380,7 @@
|
|||||||
<view class="price" v-else>
|
<view class="price" v-else>
|
||||||
<text class="i">¥</text>
|
<text class="i">¥</text>
|
||||||
<text class="num">
|
<text class="num">
|
||||||
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? (specifications.item.memberPrice||specifications.item.salePrice):specifications.item.salePrice}}
|
{{carts.useVipPrice? (specifications.item.memberPrice||specifications.item.salePrice):specifications.item.salePrice}}
|
||||||
</text>
|
</text>
|
||||||
<text class="i" v-if="specifications.item.unitName">
|
<text class="i" v-if="specifications.item.unitName">
|
||||||
/{{specifications.item.unitName}}
|
/{{specifications.item.unitName}}
|
||||||
@@ -418,11 +423,36 @@
|
|||||||
<image class="img" src="@/static/history.png" mode=""></image>
|
<image class="img" src="@/static/history.png" mode=""></image>
|
||||||
<text>已下单菜品</text>
|
<text>已下单菜品</text>
|
||||||
</view>
|
</view>
|
||||||
<Loading :isLoading="isLoading" />
|
<Loading :isLoading="!carts.isLinkFinshed" />
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import {productStore} from '@/stores/user'
|
||||||
|
import {
|
||||||
|
useCartsStore
|
||||||
|
} from '@/stores/carts'
|
||||||
|
//购物车
|
||||||
|
const carts = useCartsStore();
|
||||||
|
function cartsChangeNumber(step, item) {
|
||||||
|
carts.changeNumber(step * 1, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearCarts() {
|
||||||
|
carts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//用户信息
|
||||||
|
const userStore=productStore()
|
||||||
|
// 获取用户信息
|
||||||
|
userStore.actionsAPIuser(res=>{
|
||||||
|
console.log('userStore.actionsAPIuser');
|
||||||
|
console.log(res);
|
||||||
|
carts.changeUser(user)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
reactive,
|
reactive,
|
||||||
@@ -445,7 +475,7 @@
|
|||||||
import Nav from '@/components/CustomNavbar.vue';
|
import Nav from '@/components/CustomNavbar.vue';
|
||||||
import shopindex from './components/shopindex.vue'
|
import shopindex from './components/shopindex.vue'
|
||||||
import shoppingCartes from './components/shoppingCartes.vue'
|
import shoppingCartes from './components/shoppingCartes.vue'
|
||||||
import confirmorder from './components/confirmorder.vue'
|
// import confirmorder from './components/confirmorder.vue'
|
||||||
import Loading from '@/components/Loading.vue';
|
import Loading from '@/components/Loading.vue';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import isBetween from 'dayjs/plugin/isBetween'
|
import isBetween from 'dayjs/plugin/isBetween'
|
||||||
@@ -486,11 +516,6 @@
|
|||||||
const storeMemberpay = Memberpay();
|
const storeMemberpay = Memberpay();
|
||||||
const store = useNavbarStore();
|
const store = useNavbarStore();
|
||||||
|
|
||||||
import {
|
|
||||||
productStore
|
|
||||||
} from '@/stores/user.js';
|
|
||||||
|
|
||||||
const userStore = productStore();
|
|
||||||
|
|
||||||
// 金额管理
|
// 金额管理
|
||||||
import {
|
import {
|
||||||
@@ -516,8 +541,7 @@
|
|||||||
//店铺详情
|
//店铺详情
|
||||||
const showShopInfoRef = ref(null)
|
const showShopInfoRef = ref(null)
|
||||||
|
|
||||||
// 初始加载中
|
|
||||||
const isLoading = ref(true);
|
|
||||||
|
|
||||||
//调用shop组件
|
//调用shop组件
|
||||||
const callChildMethod = () => {
|
const callChildMethod = () => {
|
||||||
@@ -541,7 +565,7 @@
|
|||||||
|
|
||||||
// * 图片加载
|
// * 图片加载
|
||||||
const imageLoaded = (item, index, index1) => {
|
const imageLoaded = (item, index, index1) => {
|
||||||
// shopProductList.productInfo[index].products[index1]['imgLoad'] = true;
|
// carts.groupGoods[index].products[index1]['imgLoad'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算左侧位置
|
// 计算左侧位置
|
||||||
@@ -812,132 +836,6 @@
|
|||||||
//添加购物车数量
|
//添加购物车数量
|
||||||
const shopCartNumber = ref(0)
|
const shopCartNumber = ref(0)
|
||||||
|
|
||||||
// 多规格 套餐添加数量
|
|
||||||
const shopCart = async (i) => {
|
|
||||||
if (i == '-' && shopCartNumber.value >= 0) {
|
|
||||||
shopCartNumber.value = 0
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
let res = await shoppingcart()
|
|
||||||
if (i == '-') {
|
|
||||||
if (!res && shopCartNumber.value == specifications.item.suitNum) {
|
|
||||||
uni.showToast({
|
|
||||||
title: `起点${specifications.item.suitNum}个`,
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
shopCartNumber.value--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!res && shopCartNumber.value < 1) {
|
|
||||||
console.log(res, specifications)
|
|
||||||
if (specifications.type == 'sku') {
|
|
||||||
shopCartNumber.value = parseFloat(specifications.item.result.suitNum);
|
|
||||||
} else {
|
|
||||||
shopCartNumber.value = parseFloat(specifications.item.suitNum);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
shopCartNumber.value++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 套餐比较两个对象是否相等
|
|
||||||
function isObjectEqual(obj1, obj2) {
|
|
||||||
if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
|
|
||||||
return obj1 === obj2;
|
|
||||||
}
|
|
||||||
const keys1 = Object.keys(obj1);
|
|
||||||
const keys2 = Object.keys(obj2);
|
|
||||||
if (keys1.length !== keys2.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (const key of keys1) {
|
|
||||||
if (Array.isArray(obj1[key]) && Array.isArray(obj2[key])) {
|
|
||||||
if (!isArrayEqual(obj1[key], obj2[key])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (!isObjectEqual(obj1[key], obj2[key])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 比较两个数组是否相等(忽略顺序)
|
|
||||||
function isArrayEqual(arr1, arr2) {
|
|
||||||
if (arr1.length !== arr2.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const usedIndices = new Array(arr2.length).fill(false);
|
|
||||||
for (const item1 of arr1) {
|
|
||||||
let found = false;
|
|
||||||
for (let i = 0; i < arr2.length; i++) {
|
|
||||||
if (!usedIndices[i] && isObjectEqual(item1, arr2[i])) {
|
|
||||||
usedIndices[i] = true;
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据购物车的数据匹配选中的商品查找是否有匹配的数组
|
|
||||||
const matchingProduct = async (data) => {
|
|
||||||
return matchedProducts.value.find((product, index) => {
|
|
||||||
if (specifications.type == 'package') {
|
|
||||||
// 套餐
|
|
||||||
let result = false;
|
|
||||||
try {
|
|
||||||
if (product.type == "package") {
|
|
||||||
let res = JSON.parse(product.cartListinfo.pro_group_info);
|
|
||||||
result = isArrayEqual(res, selectedGroupSnap.value);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
//TODO handle the exception
|
|
||||||
}
|
|
||||||
// 直接返回布尔值
|
|
||||||
return result;
|
|
||||||
} else if (specifications.item.type == 'sku') {
|
|
||||||
// 多规格
|
|
||||||
return product.cartListinfo.sku_id == data.id && product.cartListinfo.product_id == data
|
|
||||||
.productId
|
|
||||||
} else {
|
|
||||||
// 其他
|
|
||||||
return product.skuId == data.skuId && product.id == data.id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断多规格和套餐 商品是否在购物车有数据
|
|
||||||
const shoppingcart = async () => {
|
|
||||||
let res = null
|
|
||||||
if (specifications.item.type == "package") {
|
|
||||||
if (!allConditionsSatisfied.value) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 是否是套餐package
|
|
||||||
selectedGroupSnap.value = specifications.item.groupSnap.map((setmenu, index) => {
|
|
||||||
return {
|
|
||||||
...setmenu,
|
|
||||||
goods: selectedOptions.value[index]
|
|
||||||
};
|
|
||||||
});
|
|
||||||
res = await matchingProduct(selectedGroupSnap.value)
|
|
||||||
} else {
|
|
||||||
if (!canSubmit.value) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
res = await matchingProduct(specifications.item.result)
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 提交选择并执行下一步操作的方法
|
// 提交选择并执行下一步操作的方法
|
||||||
const submitSelection = async () => {
|
const submitSelection = async () => {
|
||||||
@@ -965,7 +863,7 @@
|
|||||||
selectedGroupSnap.value = []
|
selectedGroupSnap.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
websocketsendMessage({
|
carts.add({
|
||||||
id: res ? res.cartListId : '',
|
id: res ? res.cartListId : '',
|
||||||
type: 'shopping',
|
type: 'shopping',
|
||||||
suitNum: specifications.productListitem.suitNum,
|
suitNum: specifications.productListitem.suitNum,
|
||||||
@@ -982,6 +880,24 @@
|
|||||||
is_print: 1,
|
is_print: 1,
|
||||||
product_type: specifications.item.type
|
product_type: specifications.item.type
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// websocketsendMessage({
|
||||||
|
// id: res ? res.cartListId : '',
|
||||||
|
// type: 'shopping',
|
||||||
|
// suitNum: specifications.productListitem.suitNum,
|
||||||
|
// table_code: uni.cache.get('tableCode'),
|
||||||
|
// shop_id: uni.cache.get('shopId'),
|
||||||
|
// operate_type: res ? 'edit' : 'add',
|
||||||
|
// product_id: specifications.product_id,
|
||||||
|
// sku_id: specifications.sku_id,
|
||||||
|
// number: res ? await calculateValue(res.cartNumber, '+', shopCartNumber.value) :
|
||||||
|
// shopCartNumber
|
||||||
|
// .value,
|
||||||
|
// pro_group_info: selectedGroupSnap.value,
|
||||||
|
// goods_type: specifications.item.type == "package" ? 'package' : '',
|
||||||
|
// is_print: 1,
|
||||||
|
// product_type: specifications.item.type
|
||||||
|
// })
|
||||||
// 清空套餐选中
|
// 清空套餐选中
|
||||||
selectedGroupSnap.value = []
|
selectedGroupSnap.value = []
|
||||||
showShopsku.value = false
|
showShopsku.value = false
|
||||||
@@ -1068,6 +984,18 @@
|
|||||||
return isInRange;
|
return isInRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function addCarts(item, isWeight = false) {
|
||||||
|
if (isWeight) {
|
||||||
|
carts.add({
|
||||||
|
...item
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
carts.add({
|
||||||
|
...item
|
||||||
|
});
|
||||||
|
}
|
||||||
// 单规格
|
// 单规格
|
||||||
const singleclick = async (item, i) => {
|
const singleclick = async (item, i) => {
|
||||||
if (!isProductAvailable(item.days, item.startTime, item.endTime)) {
|
if (!isProductAvailable(item.days, item.startTime, item.endTime)) {
|
||||||
@@ -1077,26 +1005,18 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 判断购物车是否有该选中商品
|
// 判断购物车是否有该选中商品
|
||||||
let res = null
|
|
||||||
try {
|
|
||||||
res = matchedProducts.value.find((product, index) => {
|
|
||||||
return product.skuId == item.skuId && product.id == item.id
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
//TODO handle the exception
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存这次点击的
|
// 保存这次点击的
|
||||||
specifications.productListitem = item
|
specifications.productListitem = item
|
||||||
|
console.log(item);
|
||||||
// 是否起售 如果小于或者大于都是1
|
addCarts({
|
||||||
let suitNum = 1;
|
suitNum: item.suitNum || 1,
|
||||||
const cartNumberFloat = parseFloat(item.cartNumber);
|
product_id: item.id,
|
||||||
if (!res && item.suitNum > cartNumberFloat) {
|
sku_id: item.skuList[0].id,
|
||||||
suitNum = item.suitNum;
|
number: item.skuList[0].suitNum || 1,
|
||||||
} else if (item.suitNum >= cartNumberFloat && i === '-') {
|
product_type: item.type,
|
||||||
suitNum = item.cartNumber;
|
});
|
||||||
}
|
return
|
||||||
websocketsendMessage({
|
websocketsendMessage({
|
||||||
id: res ? item.cartListId : '',
|
id: res ? item.cartListId : '',
|
||||||
type: 'shopping',
|
type: 'shopping',
|
||||||
@@ -1134,190 +1054,62 @@
|
|||||||
shop_id: uni.cache.get('shopId')
|
shop_id: uni.cache.get('shopId')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const {
|
|
||||||
isConnected,
|
try{
|
||||||
sendMessage,
|
carts.init({
|
||||||
closeSocket: manualClose,
|
type: 'shopping',
|
||||||
receivedMessages,
|
operate_type: 'init',
|
||||||
closeExistingConnection,
|
table_code: uni.cache.get('tableCode'),
|
||||||
onShowconnect,
|
shop_id: uni.cache.get('shopId')
|
||||||
initNetworkListener
|
}, {});
|
||||||
} = useWebSocket(options);
|
}catch(err){
|
||||||
|
console.error('购物车数据初始化失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function sendMessage() {}
|
||||||
|
|
||||||
|
function closeSocket() {}
|
||||||
|
|
||||||
|
function receivedMessages() {}
|
||||||
|
|
||||||
|
function closeExistingConnection() {}
|
||||||
|
|
||||||
|
function onShowconnect() {}
|
||||||
|
|
||||||
|
function initNetworkListener() {}
|
||||||
|
// const {
|
||||||
|
// isConnected,
|
||||||
|
// sendMessage,
|
||||||
|
// closeSocket: manualClose,
|
||||||
|
// receivedMessages,
|
||||||
|
// closeExistingConnection,
|
||||||
|
// onShowconnect,
|
||||||
|
// initNetworkListener
|
||||||
|
// } = useWebSocket(options);
|
||||||
|
|
||||||
//购物车显示
|
//购物车显示
|
||||||
const showCart = ref(false)
|
const showCart = ref(false)
|
||||||
|
|
||||||
// 提交订单显示
|
|
||||||
const confirmordershow = ref(false)
|
|
||||||
|
|
||||||
|
|
||||||
// 更新商品数量的方法
|
// 更新购物车数据carts.hotgoods
|
||||||
const updateProductQuantities = () => {
|
|
||||||
// 先将所有商品的 cartNumber 初始化为 0
|
|
||||||
shopProductList.hots.forEach((i) => {
|
|
||||||
i.cartNumber = 0
|
|
||||||
})
|
|
||||||
// 遍历商品列表二维数组
|
|
||||||
shopProductList.productInfo.forEach((group) => {
|
|
||||||
group.productList.forEach((product) => {
|
|
||||||
product.cartNumber = 0
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 再去更新数组的值
|
|
||||||
cartListFilter.value.forEach((cartItem) => {
|
|
||||||
shopProductList.productInfo.forEach((group) => {
|
|
||||||
group.productList.forEach((product) => {
|
|
||||||
if (product.id == cartItem.product_id && product.skuId == cartItem
|
|
||||||
.sku_id) {
|
|
||||||
product.cartNumber = cartItem.number
|
|
||||||
product.cartListId = cartItem.id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// 遍历购物车数组
|
|
||||||
cartListFilter.value.forEach((cartItem) => {
|
|
||||||
// 遍历商品列表二维数组
|
|
||||||
shopProductList.hots.forEach((group) => {
|
|
||||||
// 商品 id 匹配
|
|
||||||
if (group.id == cartItem.product_id) {
|
|
||||||
// 更新商品的数量
|
|
||||||
group.cartListId = cartItem.id
|
|
||||||
group.cartNumber = cartItem.number
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//websocket产值
|
|
||||||
const websocketsendMessage = (data) => {
|
|
||||||
uni.$u.debounce(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()
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 更新购物车数据shopProductList.hots
|
|
||||||
const matchedProducts = computed(() => {
|
const matchedProducts = computed(() => {
|
||||||
if (cartStore.carts.length > 0) {
|
if (carts.list.length > 0) {
|
||||||
let Specialstop = null
|
let Specialstop = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Specialstop = [...[{
|
Specialstop = [...[{
|
||||||
id: "",
|
id: "",
|
||||||
name: "",
|
name: "",
|
||||||
productList: shopProductList.hots
|
productList: carts.hotgoods
|
||||||
}], ...shopProductList.productInfo]
|
}], ...carts.groupGoods]
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Specialstop = shopProductList.productInfo
|
Specialstop = carts.groupGoods
|
||||||
//TODO handle the exception
|
//TODO handle the exception
|
||||||
}
|
}
|
||||||
return cartStore.carts.flatMap((cartItem) => {
|
return carts.list.flatMap((cartItem) => {
|
||||||
for (const group of Specialstop) {
|
for (const group of Specialstop) {
|
||||||
for (const product of group.productList) {
|
for (const product of group.productList) {
|
||||||
if (product.id == cartItem.product_id) {
|
if (product.id == cartItem.product_id) {
|
||||||
@@ -1351,26 +1143,10 @@
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
//删除某一个待支付订单
|
|
||||||
const clickcancelOrder = async (data) => {
|
|
||||||
if (data.i == 'all') {
|
|
||||||
await APIcancelOrder({
|
|
||||||
shopId: uni.cache.get('shopId'),
|
|
||||||
orderId: orderinfo.value.id,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
await APIrmPlaceOrder({
|
|
||||||
shopId: uni.cache.get('shopId'),
|
|
||||||
orderId: orderinfo.value.id,
|
|
||||||
placeNum: data.key
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Historicalorders()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 储存是否存在多次下单
|
// 储存是否存在多次下单
|
||||||
const orderinfo = ref({})
|
const orderinfo = ref({})
|
||||||
const confirmorderref = ref(null)
|
// const confirmorderref = ref(null)
|
||||||
|
|
||||||
// 结账
|
// 结账
|
||||||
const orderdetail = async () => {
|
const orderdetail = async () => {
|
||||||
@@ -1379,17 +1155,12 @@
|
|||||||
.cache.get(
|
.cache.get(
|
||||||
'shopId')
|
'shopId')
|
||||||
})
|
})
|
||||||
return
|
|
||||||
try {
|
|
||||||
await Historicalorders()
|
|
||||||
} catch (error) {}
|
|
||||||
confirmordershow.value = true
|
|
||||||
showCart.value = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 历史订单
|
// 历史订单
|
||||||
const Historicalorders = async (W) => {
|
const Historicalorders = async (W) => {
|
||||||
|
console.log('Historicalorders');
|
||||||
|
console.log(W);
|
||||||
if (W) {
|
if (W) {
|
||||||
showCart.value = !showCart.value
|
showCart.value = !showCart.value
|
||||||
} else {
|
} else {
|
||||||
@@ -1404,89 +1175,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提取合并 orderinfo.detailMap 数组的逻辑
|
|
||||||
function combineOrderInfoDetailMap(orderinfo) {
|
|
||||||
if (!orderinfo) return [];
|
|
||||||
let combinedArray = [];
|
|
||||||
for (const key in orderinfo.detailMap) {
|
|
||||||
if (orderinfo.detailMap.hasOwnProperty(key)) {
|
|
||||||
let subArray = orderinfo.detailMap[key];
|
|
||||||
combinedArray = [...combinedArray, ...subArray];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return combinedArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算购物车商品费用
|
|
||||||
const totalPrices = computed(() => {
|
|
||||||
// 待支付订单
|
|
||||||
let cartone = 0
|
|
||||||
if (orderinfo.value) {
|
|
||||||
let combinedArray = [];
|
|
||||||
for (const key in orderinfo.value.detailMap) {
|
|
||||||
if (orderinfo.value.detailMap.hasOwnProperty(key)) {
|
|
||||||
let subArray = orderinfo.value.detailMap[key];
|
|
||||||
combinedArray = [...combinedArray, ...subArray]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 购物车总数价格
|
|
||||||
cartone = combinedArray.reduce((total, item) => {
|
|
||||||
// 是否启用会员价 0否1是
|
|
||||||
if (shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1) {
|
|
||||||
// memberPrice会员价
|
|
||||||
return total + (parseFloat(item.memberPrice || item.price) * parseFloat(item.num - item
|
|
||||||
.returnNum));
|
|
||||||
} else {
|
|
||||||
// salePrice销售价
|
|
||||||
return total + (parseFloat(item.price || 0) * parseFloat(item.num - item.returnNum));
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
// 购物车总数价格
|
|
||||||
let cart = 0
|
|
||||||
if (matchedProducts.value.length > 0) {
|
|
||||||
// 购物车总数价格
|
|
||||||
cart = matchedProducts.value.reduce((total, item) => {
|
|
||||||
if (item.type == 'sku') {
|
|
||||||
item.skuList.forEach((i, t) => {
|
|
||||||
if (item.cartListinfo.sku_id == i.id) {
|
|
||||||
item.memberPrice = i.memberPrice
|
|
||||||
item.salePrice = i.salePrice
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 是否启用会员价 0否1是
|
|
||||||
if (shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1) {
|
|
||||||
// memberPrice会员价
|
|
||||||
return total + parseFloat(item.memberPrice || item.salePrice) * parseFloat(item
|
|
||||||
.cartNumber);
|
|
||||||
} else {
|
|
||||||
// salePrice销售价
|
|
||||||
return total + parseFloat(item.salePrice || 0) * parseFloat(item.cartNumber);
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
cart = parseFloat(cart)
|
|
||||||
// 向上取整并保留两位小数
|
|
||||||
return parseFloat(cart.toFixed(2));
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算购物车商品总数量
|
|
||||||
const cartLists_count = computed(() => {
|
|
||||||
const combinedOrderInfo = combineOrderInfoDetailMap(orderinfo.value);
|
|
||||||
const orderInfoCount = combinedOrderInfo.reduce((sum, item) => {
|
|
||||||
return sum + parseFloat(item.num);
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
const matchedProductsCount = matchedProducts.value.reduce((sum, item) => {
|
|
||||||
const num = typeof item.cartNumber === 'string' ? parseFloat(item.cartNumber) : item
|
|
||||||
.cartNumber;
|
|
||||||
return sum + num;
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
const totalCount = matchedProductsCount;
|
|
||||||
return parseFloat(totalCount.toFixed(2));
|
|
||||||
});
|
|
||||||
|
|
||||||
// 定义 ifcartNumber 计算属性方法 展示数量
|
// 定义 ifcartNumber 计算属性方法 展示数量
|
||||||
const ifcartNumber = computed(() => {
|
const ifcartNumber = computed(() => {
|
||||||
@@ -1513,31 +1201,6 @@
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
// 计算处理后的购物车列表 // 用于筛选后的购物车数组
|
|
||||||
const cartListFilter = computed(() => {
|
|
||||||
// 使用 reduce 方法对 cartList 进行处理
|
|
||||||
const grouped = cartStore.carts.reduce((acc, item) => {
|
|
||||||
const productId = item.product_id;
|
|
||||||
const num = parseFloat(item.number);
|
|
||||||
|
|
||||||
if (!acc[productId]) {
|
|
||||||
// 如果 acc 中还没有该 product_id 的记录,创建一个新对象
|
|
||||||
acc[productId] = {
|
|
||||||
...item,
|
|
||||||
number: num
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// 如果已经有该 product_id 的记录,将当前对象的 number 值累加到已有记录的 number 属性上
|
|
||||||
acc[productId].number += num;
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
// 将累加结果保留两位小数,并将对象转换为数组
|
|
||||||
return Object.values(grouped).map(item => ({
|
|
||||||
...item,
|
|
||||||
number: item.number.toFixed(2)
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
|
|
||||||
const endTimeref = reactive({
|
const endTimeref = reactive({
|
||||||
startTime: '',
|
startTime: '',
|
||||||
@@ -1568,61 +1231,6 @@
|
|||||||
return currentTime >= startTime && currentTime <= endTime;
|
return currentTime >= startTime && currentTime <= endTime;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// 列表请求
|
|
||||||
const productqueryProduct = async () => {
|
|
||||||
cartStore.goodsIsloading = false;
|
|
||||||
try {
|
|
||||||
shopProductList.hots = await productminiApphotsquery()
|
|
||||||
shopProductList.productInfo = await APIgroupquery()
|
|
||||||
} catch (error) {
|
|
||||||
uni.showToast({
|
|
||||||
title: '网络不稳定,请重新扫码进入',
|
|
||||||
icon: 'none'
|
|
||||||
})
|
|
||||||
setTimeout(() => {
|
|
||||||
uni.pro.switchTab('index/index')
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
if (shopProductList.productInfo.length > 0 || shopProductList.hots.length > 0) {
|
|
||||||
//TODO handle the exception
|
|
||||||
//第一步:将所有商品的 cartNumber 初始化为 0
|
|
||||||
shopProductList.productInfo.forEach((group) => {
|
|
||||||
group.productList.forEach(async (product) => {
|
|
||||||
product.cartNumber = 0;
|
|
||||||
product.isSaleTimeshow = await isProductAvailable(product.days, product
|
|
||||||
.startTime, product.endTime)
|
|
||||||
cartStore.setGoodsMap(product.id, product)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
shopProductList.hots.forEach(async (i) => {
|
|
||||||
i.cartNumber = 0
|
|
||||||
i.isSaleTimeshow = await isProductAvailable(i.days, i.startTime, i.endTime)
|
|
||||||
cartStore.setGoodsMap(i.id, i)
|
|
||||||
})
|
|
||||||
cartStore.goodsIsloading = true;
|
|
||||||
scrollTopSize.value = 0
|
|
||||||
topArr.value = []
|
|
||||||
// userStore.actionsAPIuser()
|
|
||||||
// 数据可以更新
|
|
||||||
isDataLoaded.value = true;
|
|
||||||
// 历史订单
|
|
||||||
Historicalorders()
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: '暂无列表数据,请重新扫码',
|
|
||||||
icon: "none"
|
|
||||||
});
|
|
||||||
isDataLoaded.value = false;
|
|
||||||
setTimeout(() => {
|
|
||||||
uni.pro.switchTab('index/index')
|
|
||||||
}, 1000)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoad(async (e) => {
|
onLoad(async (e) => {
|
||||||
await proxy.$onLaunched;
|
await proxy.$onLaunched;
|
||||||
})
|
})
|
||||||
@@ -1662,14 +1270,11 @@
|
|||||||
tableCode: uni.cache.get('tableCode'),
|
tableCode: uni.cache.get('tableCode'),
|
||||||
})
|
})
|
||||||
|
|
||||||
await productqueryProduct()
|
|
||||||
if (res && res.id && shopInfo.registerType == "after") {
|
if (res && res.id && shopInfo.registerType == "after") {
|
||||||
toHistory()
|
toHistory()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 启动网络监听
|
|
||||||
initNetworkListener()
|
|
||||||
getElementTop()
|
getElementTop()
|
||||||
}, 500)
|
}, 500)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,65 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="u-p-30">
|
<view class="u-p-30">
|
||||||
<view>
|
|
||||||
<up-button type="warning" @click="popupShow">初始化</up-button>
|
|
||||||
</view>
|
|
||||||
<view class="u-m-t-30">
|
|
||||||
<up-button type="primary" @click="toCreate">去下单</up-button>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<up-popup :show="show" mode="bottom" close-on-click-overlay @close="resetForm">
|
|
||||||
<view class="u-p-30">
|
|
||||||
<up-form label-width="80" ref="refForm">
|
|
||||||
<up-form-item label="台桌码">
|
|
||||||
<up-input v-model="form.tableCode" placeholder="请输入台桌码"></up-input>
|
|
||||||
</up-form-item>
|
|
||||||
</up-form>
|
|
||||||
<view class="u-flex gap-20 u-m-t-30">
|
|
||||||
<up-button @click="show=false">取消</up-button>
|
|
||||||
<up-button type="primary" @click="scanCodehandle">确定</up-button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
</up-popup>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {onLoad} from '@dcloudio/uni-app'
|
|
||||||
import { reactive,ref} from 'vue'
|
|
||||||
import {
|
import {
|
||||||
productStore
|
ref
|
||||||
} from '@/stores/user.js';
|
} from 'vue';
|
||||||
const store = productStore();
|
import {
|
||||||
const scanCodehandle = async (i) => {
|
useCartsStore
|
||||||
await store.scanCodeactions(form)
|
} from '@/stores/carts'
|
||||||
}
|
const carts = useCartsStore();
|
||||||
const show=ref(false);
|
console.log(carts);
|
||||||
const options=ref({})
|
const table = ref({
|
||||||
function popupShow(){
|
tableCode: '40963902920',
|
||||||
show.value=true;
|
|
||||||
}
|
|
||||||
const refForm=ref(null);
|
|
||||||
const form=reactive({
|
|
||||||
tableCode:"40963902920"
|
|
||||||
})
|
})
|
||||||
function resetForm(){
|
carts.init({
|
||||||
form.tableCode=""
|
table_code: table.value.tableCode,
|
||||||
}
|
shop_id:"29",
|
||||||
onLoad((opt)=>{
|
account:29
|
||||||
console.log(opt);
|
}, {});
|
||||||
options.value=opt
|
|
||||||
})
|
|
||||||
function toCreate(){
|
|
||||||
uni.navigateTo({
|
|
||||||
url:'/pages/index/index'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.gap-20 {
|
.gap-20 {
|
||||||
gap: 20rpx;
|
gap: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
452
stores/carts.js
452
stores/carts.js
@@ -1,452 +0,0 @@
|
|||||||
import {
|
|
||||||
defineStore
|
|
||||||
} from 'pinia';
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
computed,
|
|
||||||
reactive,
|
|
||||||
watchEffect
|
|
||||||
} from 'vue';
|
|
||||||
import {
|
|
||||||
productminiApphotsquery,
|
|
||||||
APIgroupquery,
|
|
||||||
} from "@/common/api/product/product.js";
|
|
||||||
export const useCartsStore = defineStore('cart',
|
|
||||||
() => {
|
|
||||||
// const dinersNum = uni.cache.get('dinersNum')
|
|
||||||
// const isVip = uni.cache.get('orderVIP').isVip //此用户是否是会员
|
|
||||||
// const isMemberPrice = uni.cache.get('ordershopUserInfo').isMemberPrice //此店是否可以用会员
|
|
||||||
// const isTableFee = uni.cache.get('ordershopUserInfo').isTableFee //此店是否免桌位费
|
|
||||||
// const tableFee = uni.cache.get('ordershopUserInfo').tableFee //一个餐位费多钱
|
|
||||||
|
|
||||||
const goodsIsloading = ref(true);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//商品数据Map
|
|
||||||
const goodsMap = reactive({})
|
|
||||||
//获取商品数据
|
|
||||||
async function goodsInit() {
|
|
||||||
goodsIsloading.value=true;
|
|
||||||
//获取招牌菜商品
|
|
||||||
const hotres = await productminiApphotsquery();
|
|
||||||
for (let product of hotres) {
|
|
||||||
setGoodsMap(product.id, product)
|
|
||||||
}
|
|
||||||
//获取分组商品
|
|
||||||
const groupres = await APIgroupquery()
|
|
||||||
for (let group of groupres) {
|
|
||||||
for (let product of group.productList) {
|
|
||||||
setGoodsMap(product.id, product)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goodsIsloading.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function setGoodsMap(product_id, data) {
|
|
||||||
goodsMap[product_id] = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//websocket回执
|
|
||||||
const websocketsendMessage = (data) => {
|
|
||||||
uni.$u.debounce(sendMessage(data), 500)
|
|
||||||
}
|
|
||||||
|
|
||||||
const isLoading = ref(true);
|
|
||||||
|
|
||||||
function getProductDetails(v) {
|
|
||||||
const goods = goodsMap[v.product_id]
|
|
||||||
if (!goods) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
let skuData = undefined;
|
|
||||||
skuData = goods?.skuList.find((sku) => sku.id == v.sku_id);
|
|
||||||
|
|
||||||
// if (goods.type == 'package') {
|
|
||||||
// //套餐商品
|
|
||||||
// const SnapSku = findInGroupSnapSku(goods.groupSnap, v.sku_id)
|
|
||||||
// skuData = { ...SnapSku, salePrice: SnapSku ? SnapSku.price : 0 }
|
|
||||||
// } else {
|
|
||||||
// skuData = goods?.skuList.find((sku: { id: string, salePrice: number }) => sku.id == v.sku_id);
|
|
||||||
// }
|
|
||||||
skuData = goods?.skuList.find((sku) => sku.id == v.sku_id);
|
|
||||||
|
|
||||||
if (skuData) {
|
|
||||||
return {
|
|
||||||
...v,
|
|
||||||
productId: v.product_id,
|
|
||||||
salePrice: skuData ? skuData.salePrice : 0,
|
|
||||||
price: skuData ? skuData.salePrice : 0,
|
|
||||||
memberPrice: skuData ? skuData.memberPrice : 0,
|
|
||||||
coverImg: goods.coverImg,
|
|
||||||
productImg: goods.coverImg,
|
|
||||||
name: goods.name,
|
|
||||||
productName: goods.name,
|
|
||||||
specInfo: skuData.specInfo,
|
|
||||||
packFee: goods.packFee || 0,
|
|
||||||
type: goods.type,
|
|
||||||
skuData,
|
|
||||||
skuName: skuData.name,
|
|
||||||
num: v.number * 1
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 用于记录已经处理过的消息的 msg_id
|
|
||||||
const processedMessageIds = new Set();
|
|
||||||
|
|
||||||
//购物车商品信息补全初始化
|
|
||||||
function cartsGoodsInfoInit(arr) {
|
|
||||||
carts.value = arr.map(v => {
|
|
||||||
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") {
|
|
||||||
isLoading.value = false;
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// 检查消息是否已经处理过
|
|
||||||
if (processedMessageIds.has(Message.msg_id)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
processedMessageIds.add(Message.msg_id);
|
|
||||||
const msgData = Message.data
|
|
||||||
// 初始化
|
|
||||||
if (Message.operate_type == "init") {
|
|
||||||
console.log('carts init', msgData);
|
|
||||||
cartsGoodsInfoInit(msgData)
|
|
||||||
uni.hideLoading();
|
|
||||||
isLoading.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清空购物车
|
|
||||||
if (Message.operate_type == 'cleanup') {
|
|
||||||
carts.value = []
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除除购物车
|
|
||||||
if (Message.operate_type == 'del' && Message.status == 1) {
|
|
||||||
// 优化:使用可选链操作符避免报错
|
|
||||||
carts.value = carts.value.filter(item => item.id !== msgData?.id);
|
|
||||||
// carts.value = carts.value.filter(item => item.id != Message.data.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加或者减少购物后返回
|
|
||||||
if (Message.operate_type == 'add' || Message.operate_type == 'edit') {
|
|
||||||
const index = carts.value.findIndex((v => v.id == msgData.id))
|
|
||||||
if (index !== -1) {
|
|
||||||
carts.value[index] = getProductDetails(msgData);
|
|
||||||
} else {
|
|
||||||
carts.value.push(getProductDetails(msgData));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 历史订单
|
|
||||||
if (Message.operate_type == 'clearOrder') {}
|
|
||||||
|
|
||||||
// 购物车数据更新从新请求
|
|
||||||
if (Message.type == 'product' && Message.data_type == 'product_update' && Message
|
|
||||||
.operate_type == 'product_update') {
|
|
||||||
await goodsInit()
|
|
||||||
await cartsGoodsInfoInit()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提示
|
|
||||||
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) => {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//购物车数据
|
|
||||||
const carts = ref([])
|
|
||||||
|
|
||||||
//历史订单数据
|
|
||||||
const oldOrder = ref({
|
|
||||||
detailMap: {},
|
|
||||||
originAmount: 0
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// 会员信息
|
|
||||||
const orderVIP = ref(uni.cache.get('orderVIP') || {
|
|
||||||
isVip: false
|
|
||||||
})
|
|
||||||
|
|
||||||
function updateData(key, newval) {
|
|
||||||
if (key === 'orderVIP') {
|
|
||||||
uni.cache.set('orderVIP', newval)
|
|
||||||
return orderVIP.value = newval
|
|
||||||
}
|
|
||||||
if (key === 'shopInfo') {
|
|
||||||
uni.cache.set('shopInfo', newval)
|
|
||||||
return shopInfo.value = newval
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 商品订单会员
|
|
||||||
const shopInfo = ref(uni.cache.get('shopInfo') || {
|
|
||||||
isMemberPrice: 0
|
|
||||||
})
|
|
||||||
|
|
||||||
//是否使用会员价
|
|
||||||
const useVipPrice = computed(() => {
|
|
||||||
const isUse=(orderVIP.value.isVip && shopInfo.value.isMemberPrice)?true:false
|
|
||||||
console.log('useVipPrice',isUse);
|
|
||||||
return isUse
|
|
||||||
})
|
|
||||||
function currentCalcMpneyNumber(item){
|
|
||||||
const n=item.number-(item.returnNum||0)
|
|
||||||
return n<=0?0:n
|
|
||||||
}
|
|
||||||
//历史订单商品价格总和
|
|
||||||
const oldOrderMoney = computed(() => {
|
|
||||||
let total = 0
|
|
||||||
for (let i in oldOrder.value.detailMap) {
|
|
||||||
total += oldOrder.value.detailMap[i].reduce((prve, cur) => {
|
|
||||||
if (cur.isGift) {
|
|
||||||
return prve + 0
|
|
||||||
}
|
|
||||||
const discount_sale_amount = cur.discount_sale_amount * 1 || 0
|
|
||||||
const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData
|
|
||||||
.salePrice) : 0
|
|
||||||
const price = (discount_sale_amount || cur.salePrice || 0)
|
|
||||||
const number =currentCalcMpneyNumber(cur)
|
|
||||||
return prve + (number <= 0 ? 0 : number) * (discount_sale_amount || (useVipPrice
|
|
||||||
.value ? memberPrice : price))
|
|
||||||
}, 0)
|
|
||||||
}
|
|
||||||
return total
|
|
||||||
})
|
|
||||||
|
|
||||||
//当前购物车总价格
|
|
||||||
const totalPrice = computed(() => {
|
|
||||||
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)
|
|
||||||
return prve + curMoney
|
|
||||||
}, 0)
|
|
||||||
return money
|
|
||||||
})
|
|
||||||
// 霸王餐购物车原价,不享受任何优惠
|
|
||||||
const totalOriginPrice = computed(() => {
|
|
||||||
const money = carts.value.reduce((prve, cur) => {
|
|
||||||
const curMoney = cur.salePrice * currentCalcMpneyNumber(cur)
|
|
||||||
return prve + curMoney
|
|
||||||
}, 0)
|
|
||||||
return money
|
|
||||||
})
|
|
||||||
|
|
||||||
//商品券抵扣金额
|
|
||||||
// const productCouponDiscountAmount = computed(() => {
|
|
||||||
// let index = -1;
|
|
||||||
// return quansSelArr.value.reduce((pre, cur) => {
|
|
||||||
// index++;
|
|
||||||
// return pre + returnProDiscount(cur, index) * 1;
|
|
||||||
// }, 0);
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
//返回打包数量(称重商品打包数量最大为1)
|
|
||||||
function returnCartPackNumber(cur) {
|
|
||||||
const maxReturnNum = cur.number - (cur.returnNum || 0);
|
|
||||||
let pack_number = cur.number;
|
|
||||||
pack_number = (cur.product_type == 'weight' && pack_number > 1) ? 1 : pack_number;
|
|
||||||
pack_number = Math.min(maxReturnNum, pack_number);
|
|
||||||
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)
|
|
||||||
return prve + curMoney
|
|
||||||
}, 0)
|
|
||||||
return money
|
|
||||||
})
|
|
||||||
|
|
||||||
//打包费
|
|
||||||
const packFee = computed(() => {
|
|
||||||
const nowPackFee = carts.value.reduce((acc, cur) => {
|
|
||||||
return acc + (cur.packFee || 0) * returnCartPackNumber(cur)
|
|
||||||
}, 0)
|
|
||||||
let oldPackfee = 0;
|
|
||||||
for (let i in oldOrder.value.detailMap) {
|
|
||||||
oldPackfee += oldOrder.value.detailMap[i].reduce((prve, cur) => {
|
|
||||||
return prve + (cur.packFee || 0) * returnCartPackNumber(cur)
|
|
||||||
}, 0)
|
|
||||||
}
|
|
||||||
return nowPackFee + oldPackfee
|
|
||||||
})
|
|
||||||
|
|
||||||
//购物车是否为空
|
|
||||||
const isEmpty = computed(() => {
|
|
||||||
return !carts.value || carts.value.length <= 0
|
|
||||||
})
|
|
||||||
// 计算向上取整
|
|
||||||
const roundUpToTwoDecimals = (num, i) => {
|
|
||||||
// 先将数字乘以 100 并转换为字符串保留足够的小数位
|
|
||||||
let temp = (num * 100).toFixed(10);
|
|
||||||
// 向上取整
|
|
||||||
let rounded = null
|
|
||||||
if (i == 'upward') {
|
|
||||||
rounded = Math.ceil(parseFloat(temp));
|
|
||||||
} else {
|
|
||||||
rounded = Math.floor(parseFloat(temp));
|
|
||||||
}
|
|
||||||
// 再除以 100 得到保留两位小数的结果
|
|
||||||
return rounded / 100;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 精确计算函数
|
|
||||||
const preciseCalculation = (num1, num2) => {
|
|
||||||
// 将数字转换为整数,乘以 100 以保留两位小数
|
|
||||||
const int1 = BigInt(Math.round(num1 * 100));
|
|
||||||
const int2 = BigInt(Math.round(num2 * 100));
|
|
||||||
// 执行乘法运算
|
|
||||||
const result = int1 * int2;
|
|
||||||
// 再除以 10000 以还原为原来的小数
|
|
||||||
return Number(result) / 10000;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 计算购物车商品总价格
|
|
||||||
const getTotalTotalPrices = (matchedProducts, isBwc = true) => {
|
|
||||||
if (!matchedProducts || !Array.isArray(matchedProducts)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// console.log(uni.cache.get('orderVIP').isVip, uni.cache.get('ordershopUserInfo').isMemberPrice,
|
|
||||||
// 111)
|
|
||||||
// 购物车总数价格
|
|
||||||
console.log('isBwc');
|
|
||||||
console.log(isBwc);
|
|
||||||
let cart = matchedProducts.reduce((total, item) => {
|
|
||||||
if(isBwc===true){
|
|
||||||
return total + (parseFloat(item.price) * parseFloat(item.num - item.returnNum));
|
|
||||||
}
|
|
||||||
// 是否启用会员价 0否1是
|
|
||||||
if (useVipPrice.value) {
|
|
||||||
// memberPrice会员价
|
|
||||||
return total + (parseFloat(item.memberPrice || item.price) * parseFloat(item
|
|
||||||
.num - item
|
|
||||||
.returnNum));
|
|
||||||
} else {
|
|
||||||
// salePrice销售价
|
|
||||||
return total + (parseFloat(item.price) * parseFloat(item.num - item.returnNum));
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
cart = cart.toFixed(2)
|
|
||||||
console.log(parseFloat(cart))
|
|
||||||
// 向上取整并保留两位小数
|
|
||||||
// let result = roundUpToTwoDecimals(cart, 'upward')
|
|
||||||
return parseFloat(cart);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 计算商品卷所选择的总价格
|
|
||||||
const getTotalProductroll = (matchedProducts) => computed(() => {
|
|
||||||
if (!matchedProducts || !Array.isArray(matchedProducts)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// 购物车总数价格
|
|
||||||
let cart = matchedProducts.reduce((total, item) => {
|
|
||||||
// 是否启用会员价 0否1是
|
|
||||||
if (useVipPrice.value) {
|
|
||||||
// memberPrice会员价
|
|
||||||
return total + parseFloat(item.memberPrice || item.price)
|
|
||||||
} else {
|
|
||||||
// salePrice销售价
|
|
||||||
return total + parseFloat(item.price)
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
// 向上取整并保留两位小数
|
|
||||||
let result = roundUpToTwoDecimals(cart, 'upward')
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 桌位置
|
|
||||||
const getTotalSeatcharge = (seatNum) => computed(() => {
|
|
||||||
// 是否免除桌位费 0 否 1 是
|
|
||||||
let cart = 0
|
|
||||||
|
|
||||||
if (uni.cache.get('ordershopUserInfo').isTableFee == 0 && seatNum) {
|
|
||||||
cart = parseFloat(seatNum) * parseFloat(uni.cache.get('ordershopUserInfo').tableFee)
|
|
||||||
|
|
||||||
// Math.ceil(parseFloat(seatNum) * parseFloat(
|
|
||||||
// uni.cache.get('ordershopUserInfo').tableFee) * 100) / 100;
|
|
||||||
}
|
|
||||||
// 向下取整并保留两位小数
|
|
||||||
let result = roundUpToTwoDecimals(cart, 'downward')
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算购物车总打包费用(向下取整并保留两位小数)
|
|
||||||
const getTotalPackFee = (cartList) => computed(() => {
|
|
||||||
const total = cartList.reduce((sum, item) => {
|
|
||||||
return sum + (parseFloat(item.packAmount) * (parseFloat(item.packNumber) || (
|
|
||||||
parseFloat(item.num) - parseFloat(item.returnNum))));
|
|
||||||
}, 0);
|
|
||||||
// 向下取整并保留两位小数
|
|
||||||
let result = roundUpToTwoDecimals(total, 'downward')
|
|
||||||
return result;
|
|
||||||
// return Math.floor(total * 100) / 100;
|
|
||||||
});
|
|
||||||
|
|
||||||
//获取热门商品
|
|
||||||
async function getHotProduct() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取分组商品
|
|
||||||
async function getGroupProduct() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
getTotalPackFee,
|
|
||||||
getTotalSeatcharge,
|
|
||||||
getTotalTotalPrices,
|
|
||||||
getTotalProductroll,
|
|
||||||
carts,
|
|
||||||
isEmpty,
|
|
||||||
setGoodsMap,
|
|
||||||
goodsIsloading,
|
|
||||||
goodsInit,
|
|
||||||
onMessage,
|
|
||||||
totalPrice,
|
|
||||||
totalPackFee,
|
|
||||||
updateData,
|
|
||||||
useVipPrice,totalOriginPrice
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
821
stores/carts.ts
Normal file
821
stores/carts.ts
Normal file
@@ -0,0 +1,821 @@
|
|||||||
|
import { computed, reactive, ref } from "vue";
|
||||||
|
import WebSocketManager, { type ApifoxModel, msgType } from "@/common/js/carts-websocket";
|
||||||
|
import {
|
||||||
|
productminiApphotsquery,
|
||||||
|
APIgroupquery,
|
||||||
|
APIminiAppinfo,
|
||||||
|
APIminiAppskuinfo
|
||||||
|
} from "@/common/api/product/product.js";
|
||||||
|
const shopInfo = uni.cache.get('shopInfo') || { isMemberPrice: false }
|
||||||
|
export interface CartsState {
|
||||||
|
id : string | number;
|
||||||
|
[property : string] : any;
|
||||||
|
}
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { isProductAvailable, goodsInitParamsFull } from '@/utils/product.js'
|
||||||
|
function ElMessage() {
|
||||||
|
|
||||||
|
}
|
||||||
|
export const useCartsStore = defineStore("carts", () => {
|
||||||
|
//选择用户
|
||||||
|
const vipUser = ref<{ id ?: string | number, isVip ?: boolean }>(uni.cache.get('orderVIP') || {});
|
||||||
|
function changeUser(user : any) {
|
||||||
|
vipUser.value = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
//就餐类型 dine-in take-out
|
||||||
|
let dinnerType = ref<string>('dine-in');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//是否启用会员价
|
||||||
|
const useVipPrice = computed(() => {
|
||||||
|
return (shopInfo.isMemberPrice && vipUser.value.id && vipUser.value.isVip) ? true : false
|
||||||
|
})
|
||||||
|
|
||||||
|
//台桌id
|
||||||
|
// const table_code = useStorage('Instead_table_code', '');
|
||||||
|
const table_code = ref('')
|
||||||
|
|
||||||
|
//购物车是否初始化连接加载完成
|
||||||
|
const isLinkFinshed = ref(false)
|
||||||
|
//当前购物车数据
|
||||||
|
const list = ref<any[]>([]);
|
||||||
|
//历史订单数据
|
||||||
|
// const oldOrder = useStorage<any>("Instead_olold_order", {
|
||||||
|
// detailMap: [],
|
||||||
|
// originAmount: 0
|
||||||
|
// });
|
||||||
|
const oldOrder = ref({
|
||||||
|
detailMap: [],
|
||||||
|
originAmount: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
//代客下单页面全部商品缓存,包括招牌菜和分组
|
||||||
|
const goods = ref([])
|
||||||
|
const hotgoods = ref([])
|
||||||
|
const groupGoods = ref([])
|
||||||
|
async function getGoods(query : any) {
|
||||||
|
// 招牌菜
|
||||||
|
const hotsRes = await productminiApphotsquery({
|
||||||
|
...query,
|
||||||
|
});
|
||||||
|
//分组
|
||||||
|
const groupGoodsRes = await APIgroupquery({
|
||||||
|
...query,
|
||||||
|
});
|
||||||
|
hotgoods.value = hotsRes.map(product => {
|
||||||
|
return goodsInitParamsFull(product)
|
||||||
|
})
|
||||||
|
groupGoods.value = groupGoodsRes.map(v => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
productList: v.productList.map(product => {
|
||||||
|
return goodsInitParamsFull(product)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
goods.value = [...hotsRes, ...groupGoodsRes.reduce((prve, cur) => {
|
||||||
|
prve.push(...cur.productList)
|
||||||
|
return prve
|
||||||
|
}, [])]
|
||||||
|
setGoodsMap(goods.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setGoodsMap(goods : any[]) {
|
||||||
|
for (let item of goods) {
|
||||||
|
goodsMap[item.id] = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//赠菜
|
||||||
|
const giftList = ref([])
|
||||||
|
let goodsMap : { [key : string] : any } = reactive({});
|
||||||
|
//当前选中cart
|
||||||
|
let selListIndex = ref(-1);
|
||||||
|
|
||||||
|
//当前选中商品是否是赠菜
|
||||||
|
const isSelGift = ref(false);
|
||||||
|
//当前选中是否是历史订单
|
||||||
|
const isOldOrder = ref(false);
|
||||||
|
//选中历史订单中的第几次下单
|
||||||
|
const selPlaceNum = ref(-1);
|
||||||
|
const defaultCart = {
|
||||||
|
id: '',
|
||||||
|
number: 0,
|
||||||
|
}
|
||||||
|
//购物车是否为空
|
||||||
|
const isEmpty = computed(() => {
|
||||||
|
return list.value.length === 0 && giftList.value.length === 0
|
||||||
|
})
|
||||||
|
//当前购物车选中数据
|
||||||
|
const selCart = computed(() => {
|
||||||
|
if (isOldOrder.value && selPlaceNum.value >= 0) {
|
||||||
|
return oldOrder.value.detailMap[selPlaceNum.value][selListIndex.value]
|
||||||
|
}
|
||||||
|
if (isSelGift.value) {
|
||||||
|
return giftList.value[selListIndex.value] || defaultCart
|
||||||
|
}
|
||||||
|
return list.value[selListIndex.value] || defaultCart
|
||||||
|
})
|
||||||
|
//当前购物车选中对应商品数据
|
||||||
|
const selGoods = computed(() => {
|
||||||
|
return goodsMap[selCart.value.product_id]
|
||||||
|
})
|
||||||
|
//当前选中购物车数据是否是可选套餐商品
|
||||||
|
const isCanSelectGroup = computed(() => {
|
||||||
|
if (!selGoods.value) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return selGoods.value.type == 'package' && selGoods.value.groupType == 1
|
||||||
|
})
|
||||||
|
function returnOneGoodsTotalMoney(cur : any) {
|
||||||
|
const memberPrice = cur.memberPrice || cur.salePrice
|
||||||
|
const total = cur.number * (useVipPrice.value ? memberPrice : cur.salePrice)
|
||||||
|
if (cur.type == 'weight') {
|
||||||
|
return customTruncateToTwoDecimals(total)
|
||||||
|
} else {
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//赠菜总价
|
||||||
|
const giftMoney = computed(() => {
|
||||||
|
let oldGiftMoney = 0
|
||||||
|
for (let i in oldOrder.value.detailMap) {
|
||||||
|
oldGiftMoney += oldOrder.value.detailMap[i].filter((v : any) => v.isGift).reduce((prve : number, cur : any) => {
|
||||||
|
const memberPrice = cur.memberPrice || cur.salePrice
|
||||||
|
return prve + cur.number * (useVipPrice.value ? memberPrice : cur.salePrice)
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
const nowTotal = giftList.value.reduce((acc : number, cur : any) => {
|
||||||
|
const memberPrice = cur.memberPrice || cur.salePrice
|
||||||
|
return acc + cur.number * (useVipPrice.value ? memberPrice : cur.salePrice)
|
||||||
|
}, 0)
|
||||||
|
return (nowTotal + oldGiftMoney)
|
||||||
|
})
|
||||||
|
//返回打包数量(称重商品打包数量最大为1)
|
||||||
|
function returnCartPackNumber(cur : any) {
|
||||||
|
const maxReturnNum = cur.number - (cur.returnNum || 0);
|
||||||
|
let pack_number = (dinnerType.value == 'take-out' ? cur.number : cur.pack_number * 1);
|
||||||
|
pack_number = (cur.product_type == 'weight' && pack_number > 1) ? 1 : pack_number;
|
||||||
|
pack_number = Math.min(maxReturnNum, pack_number);
|
||||||
|
pack_number = pack_number <= 0 ? 0 : pack_number
|
||||||
|
return pack_number * 1
|
||||||
|
}
|
||||||
|
//打包数量
|
||||||
|
const packNum = computed(() => {
|
||||||
|
const nowCartNumber = list.value.reduce((acc : number, cur : any) => {
|
||||||
|
return acc + returnCartPackNumber(cur)
|
||||||
|
}, 0)
|
||||||
|
const giftNumber = giftList.value.reduce((acc : number, cur : any) => {
|
||||||
|
return acc + returnCartPackNumber(cur)
|
||||||
|
}, 0)
|
||||||
|
let oldNumber = 0
|
||||||
|
for (let i in oldOrder.value.detailMap) {
|
||||||
|
oldNumber += oldOrder.value.detailMap[i].reduce((prve : number, cur : any) => {
|
||||||
|
return prve + returnCartPackNumber(cur)
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
return nowCartNumber + giftNumber + oldNumber
|
||||||
|
})
|
||||||
|
|
||||||
|
//打包费
|
||||||
|
const packFee = computed(() => {
|
||||||
|
const nowPackFee = list.value.reduce((acc : number, cur : any) => {
|
||||||
|
return acc + (cur.packFee || 0) * returnCartPackNumber(cur)
|
||||||
|
}, 0)
|
||||||
|
const giftPackFee = giftList.value.reduce((acc : number, cur : any) => {
|
||||||
|
return acc + (cur.packFee || 0) * returnCartPackNumber(cur)
|
||||||
|
}, 0)
|
||||||
|
let oldPackfee = 0;
|
||||||
|
for (let i in oldOrder.value.detailMap) {
|
||||||
|
oldPackfee += oldOrder.value.detailMap[i].reduce((prve : number, cur : any) => {
|
||||||
|
return prve + (cur.packFee || 0) * returnCartPackNumber(cur)
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
return nowPackFee + giftPackFee + oldPackfee
|
||||||
|
})
|
||||||
|
//会员优惠
|
||||||
|
const vipDiscount = computed(() => {
|
||||||
|
if (!useVipPrice.value) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
const listTotal = list.value.reduce((acc : number, cur : any) => {
|
||||||
|
const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number
|
||||||
|
return acc + (n <= 0 ? 0 : n)
|
||||||
|
}, 0)
|
||||||
|
const giftTotal = giftList.value.reduce((acc : number, cur : any) => {
|
||||||
|
const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number
|
||||||
|
return acc + (n <= 0 ? 0 : n)
|
||||||
|
}, 0)
|
||||||
|
let oldTotal = 0;
|
||||||
|
for (let i in oldOrder.value.detailMap) {
|
||||||
|
oldTotal += oldOrder.value.detailMap[i].reduce((prve : number, cur : any) => {
|
||||||
|
const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number
|
||||||
|
return prve + (n <= 0 ? 0 : n)
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
return listTotal + giftTotal + oldTotal
|
||||||
|
})
|
||||||
|
//单品改价优惠
|
||||||
|
const singleDiscount = computed(() => {
|
||||||
|
const listTotal = list.value.reduce((acc : number, cur : any) => {
|
||||||
|
if (cur.discount_sale_amount * 1 <= 0) {
|
||||||
|
return acc + 0
|
||||||
|
}
|
||||||
|
const originPrice = useVipPrice.value ? (cur.memberPrice || cur.salePrice) : cur.salePrice
|
||||||
|
const n = (originPrice * 1 - cur.discount_sale_amount * 1) * cur.number
|
||||||
|
return acc + (n <= 0 ? 0 : n)
|
||||||
|
}, 0)
|
||||||
|
return listTotal
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 优惠
|
||||||
|
const yiyouhui = computed(() => {
|
||||||
|
const youhui = giftMoney.value * 1 + vipDiscount.value * 1 + singleDiscount.value * 1
|
||||||
|
if (youhui > 0) {
|
||||||
|
return '已优惠¥' + youhui.toFixed(2)
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
|
||||||
|
//历史订单价格
|
||||||
|
const oldOrderMoney = computed(() => {
|
||||||
|
let total = 0
|
||||||
|
for (let i in oldOrder.value.detailMap) {
|
||||||
|
total += oldOrder.value.detailMap[i].reduce((prve : number, cur : any) => {
|
||||||
|
if (cur.isGift) {
|
||||||
|
return prve + 0
|
||||||
|
}
|
||||||
|
const discount_sale_amount = cur.discount_sale_amount * 1 || 0
|
||||||
|
const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData.salePrice) : 0
|
||||||
|
const price = (discount_sale_amount || cur.salePrice || 0)
|
||||||
|
const number = (cur.number - cur.returnNum)
|
||||||
|
return prve + (number <= 0 ? 0 : number) * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
return total
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
//支付总价
|
||||||
|
const payMoney = computed(() => {
|
||||||
|
const money = list.value.reduce((acc : number, cur : any) => {
|
||||||
|
const discount_sale_amount = cur.discount_sale_amount * 1 || 0
|
||||||
|
const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData.salePrice) : 0
|
||||||
|
const price = (cur.discount_sale_amount * 1 || cur.salePrice || 0)
|
||||||
|
return acc + cur.number * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
|
||||||
|
}, 0)
|
||||||
|
return (money + packFee.value * 1 + oldOrderMoney.value * 1).toFixed(2)
|
||||||
|
})
|
||||||
|
//只算商品的总价
|
||||||
|
const goodsTotal = computed(() => {
|
||||||
|
const money = list.value.reduce((acc : number, cur : any) => {
|
||||||
|
const discount_sale_amount = cur.discount_sale_amount * 1 || 0
|
||||||
|
const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData.salePrice) : 0
|
||||||
|
const price = (cur.discount_sale_amount * 1 || cur.salePrice || 0)
|
||||||
|
return acc + cur.number * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
|
||||||
|
}, 0)
|
||||||
|
return (money + oldOrderMoney.value * 1).toFixed(2)
|
||||||
|
})
|
||||||
|
//总计数量
|
||||||
|
const totalNumber = computed(() => {
|
||||||
|
const cartNumber = list.value.reduce((acc : number, cur : any) => {
|
||||||
|
return acc + cur.number * 1
|
||||||
|
}, 0)
|
||||||
|
const giftNumber = giftList.value.reduce((acc : number, cur : any) => {
|
||||||
|
return acc + cur.number * 1
|
||||||
|
}, 0)
|
||||||
|
let oldNumber = 0
|
||||||
|
|
||||||
|
for (let i in oldOrder.value.detailMap) {
|
||||||
|
oldNumber += oldOrder.value.detailMap[i].reduce((prve : number, cur : any) => {
|
||||||
|
return prve + cur.number * 1
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
return cartNumber + giftNumber + oldNumber
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
function changeNumber(step : number, item : CartsState) {
|
||||||
|
if (item.number * 1 + step <= 0) {
|
||||||
|
del(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newNumber = item.number * 1 + step * 1;
|
||||||
|
let pack_number = newNumber < item.pack_number ? (item.pack_number * 1 + step * 1) : item.pack_number * 1;
|
||||||
|
if (dinnerType.value == 'take-out') {
|
||||||
|
pack_number = newNumber
|
||||||
|
}
|
||||||
|
if (item.product_type == 'weight' && item.pack_number * 1 >= 1) {
|
||||||
|
pack_number = 1
|
||||||
|
}
|
||||||
|
update({ ...item, number: newNumber, pack_number });
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSelCart(cart : CartsState) {
|
||||||
|
console.log(cart)
|
||||||
|
if (!cart.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (cart.placeNum) {
|
||||||
|
selPlaceNum.value = cart.placeNum
|
||||||
|
isOldOrder.value = true
|
||||||
|
console.log(oldOrder.value.detailMap[cart.placeNum])
|
||||||
|
selListIndex.value = oldOrder.value.detailMap[cart.placeNum].findIndex((item : CartsState) => {
|
||||||
|
return item.id == cart.id
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selPlaceNum.value = -1;
|
||||||
|
isOldOrder.value = false;
|
||||||
|
|
||||||
|
if (cart.is_gift) {
|
||||||
|
isSelGift.value = true
|
||||||
|
selListIndex.value = giftList.value.findIndex((item : CartsState) => item.id === cart.id);
|
||||||
|
console.log(selListIndex.value)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
isSelGift.value = false
|
||||||
|
selListIndex.value = list.value.findIndex((item : CartsState) => item.id === cart.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const basic_msg = {
|
||||||
|
number: 1,
|
||||||
|
is_gift: 0,
|
||||||
|
is_temporary: 0,
|
||||||
|
discount_sale_amount: 0,
|
||||||
|
discount_sale_note: "",
|
||||||
|
is_print: 1,
|
||||||
|
pro_group_info: '',
|
||||||
|
is_wait_call: 0,
|
||||||
|
product_name: "",
|
||||||
|
remark: "",
|
||||||
|
sku_id: '',
|
||||||
|
product_type: '',
|
||||||
|
suitNum: 1
|
||||||
|
}
|
||||||
|
//当前购物车直接添加
|
||||||
|
function cartsPush(data : any) {
|
||||||
|
sendMessage('add', {
|
||||||
|
...basic_msg,
|
||||||
|
...data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function add(data : any) {
|
||||||
|
const msg = {
|
||||||
|
...basic_msg,
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
const hasCart = list.value.find((cartItem) => {
|
||||||
|
return cartItem.product_id == msg.product_id && cartItem.sku_id == msg.sku_id;
|
||||||
|
});
|
||||||
|
if (hasCart) {
|
||||||
|
update({ ...hasCart, ...msg, number: hasCart.number * 1 + msg.number * 1 })
|
||||||
|
} else {
|
||||||
|
console.log(msg);
|
||||||
|
sendMessage('add', msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 换桌
|
||||||
|
function changeTable(newVal : string | undefined) {
|
||||||
|
table_code.value = `${newVal}`;
|
||||||
|
$initParams.table_code = newVal
|
||||||
|
concocatSocket()
|
||||||
|
}
|
||||||
|
//转桌
|
||||||
|
function rotTable(newVal : string | number, cart_id = []) {
|
||||||
|
sendMessage('rottable', {
|
||||||
|
new_table_code: newVal,
|
||||||
|
table_code: table_code.value,
|
||||||
|
cart_id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//清空历史订单
|
||||||
|
function clearHistory() {
|
||||||
|
sendMessage('clearOrder', {});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function del(data : any) {
|
||||||
|
sendMessage('del', { id: data.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(data : any) {
|
||||||
|
console.log(data);
|
||||||
|
const suitNum = data.skuData ? (data.skuData.suitNum || 1) : 1;
|
||||||
|
if (data.number * 1 < suitNum * 1) {
|
||||||
|
return sendMessage('del', data);
|
||||||
|
}
|
||||||
|
const pack_number = dinnerType.value == 'take-out' ? data.number : data.pack_number
|
||||||
|
sendMessage('edit', { ...data, suitNum, pack_number });
|
||||||
|
}
|
||||||
|
function updateTag(key : string, val : any, cart : CartsState = selCart.value) {
|
||||||
|
const skuData = cart.skuData || { suitNum: 1 }
|
||||||
|
if (cart.number * 1 < skuData.suitNum * 1) {
|
||||||
|
return sendMessage('del', cart);
|
||||||
|
}
|
||||||
|
console.log(key, val)
|
||||||
|
if (key == 'discount_sale_amount' && val * 1 <= 0) {
|
||||||
|
// ElMessage.error('价格不能为0!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const msg = { ...cart, [key]: val }
|
||||||
|
if (key == 'number' && dinnerType.value == 'take-out') {
|
||||||
|
msg.pack_number == val
|
||||||
|
msg.suitNum == skuData.suitNum
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage('edit', msg);
|
||||||
|
}
|
||||||
|
// 更改全部商品打包状态
|
||||||
|
function changePack(is_pack : number | string) {
|
||||||
|
if (!isEmpty.value) {
|
||||||
|
sendMessage('batch', { is_pack });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
sendMessage('cleanup', {});
|
||||||
|
}
|
||||||
|
function dataReset() {
|
||||||
|
selListIndex.value = -1;
|
||||||
|
selPlaceNum.value = 1
|
||||||
|
isOldOrder.value = false
|
||||||
|
isSelGift.value = false
|
||||||
|
list.value = [];
|
||||||
|
giftList.value = [];
|
||||||
|
oldOrder.value = {
|
||||||
|
detailMap: [],
|
||||||
|
originAmount: 0
|
||||||
|
}
|
||||||
|
vipUser.value = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function nowCartsClear() {
|
||||||
|
if (selPlaceNum.value == 1) {
|
||||||
|
selListIndex.value = -1;
|
||||||
|
}
|
||||||
|
list.value = [];
|
||||||
|
giftList.value = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 寻找套餐商品sku
|
||||||
|
interface GroupSnap {
|
||||||
|
goods : { [key : string] : any }[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function findInGroupSnapSku(groupSnap : GroupSnap[], sku_id : string | number) {
|
||||||
|
for (let i in groupSnap) {
|
||||||
|
const sku = groupSnap[i].goods.find(v => v.sku_id == sku_id)
|
||||||
|
if (sku) {
|
||||||
|
return sku
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取历史订单
|
||||||
|
async function getOldOrder(table_code : string | number) {
|
||||||
|
const res = await orderApi.getHistoryList({ tableCode: table_code })
|
||||||
|
console.log('getOldOrder');
|
||||||
|
console.log(res);
|
||||||
|
if (res) {
|
||||||
|
setOldOrder(res)
|
||||||
|
} else {
|
||||||
|
oldOrder.value = {
|
||||||
|
detailMap: [],
|
||||||
|
originAmount: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProductDetails(v : { product_id : string, sku_id : string }) {
|
||||||
|
const goods = goodsMap[v.product_id]
|
||||||
|
if (!goods) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
let skuData = undefined;
|
||||||
|
skuData = goods?.skuList.find((sku : { id : string, salePrice : number }) => sku.id == v.sku_id);
|
||||||
|
|
||||||
|
// if (goods.type == 'package') {
|
||||||
|
// //套餐商品
|
||||||
|
// const SnapSku = findInGroupSnapSku(goods.groupSnap, v.sku_id)
|
||||||
|
// skuData = { ...SnapSku, salePrice: SnapSku ? SnapSku.price : 0 }
|
||||||
|
// } else {
|
||||||
|
// skuData = goods?.skuList.find((sku: { id: string, salePrice: number }) => sku.id == v.sku_id);
|
||||||
|
// }
|
||||||
|
skuData = goods?.skuList.find((sku : { id : string, salePrice : number }) => sku.id == v.sku_id);
|
||||||
|
|
||||||
|
if (skuData) {
|
||||||
|
return {
|
||||||
|
salePrice: skuData ? skuData.salePrice : 0,
|
||||||
|
memberPrice: skuData ? skuData.memberPrice : 0,
|
||||||
|
coverImg: goods.coverImg,
|
||||||
|
name: goods.name,
|
||||||
|
specInfo: skuData.specInfo,
|
||||||
|
packFee: goods.packFee || 0,
|
||||||
|
type: goods.type,
|
||||||
|
skuData
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function returnDetailMap(data : any) {
|
||||||
|
const newData : { [key : string] : any } = {}
|
||||||
|
for (let i in data) {
|
||||||
|
newData[i] = data[i].map((v : any) => {
|
||||||
|
const skuData = getProductDetails({ product_id: v.productId, sku_id: v.skuId })
|
||||||
|
console.log(skuData)
|
||||||
|
console.log(v)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
...skuData,
|
||||||
|
skuData: {
|
||||||
|
...skuData,
|
||||||
|
salePrice: v.price,
|
||||||
|
memberPrice: v.memberPrice
|
||||||
|
},
|
||||||
|
placeNum: v.placeNum,
|
||||||
|
number: v.num,
|
||||||
|
id: v.id,
|
||||||
|
salePrice: v.price,
|
||||||
|
memberPrice: v.memberPrice,
|
||||||
|
pack_number: v.packNumber,
|
||||||
|
discount_sale_amount: v.discountSaleAmount * 1 || 0,
|
||||||
|
is_print: v.isPrint,
|
||||||
|
is_wait_call: v.isWaitCall,
|
||||||
|
is_gift: v.isGift,
|
||||||
|
is_temporary: v.isTemporary,
|
||||||
|
discount_sale_note: v.discountSaleNote,
|
||||||
|
product_name: v.productName,
|
||||||
|
sku_name: v.skuName,
|
||||||
|
sku_id: v.skuId,
|
||||||
|
product_type: v.productType,
|
||||||
|
packFee: v.packAmount,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log('newData', newData)
|
||||||
|
return newData
|
||||||
|
}
|
||||||
|
|
||||||
|
function setOldOrder(data : any) {
|
||||||
|
oldOrder.value = {
|
||||||
|
...data,
|
||||||
|
detailMap: returnDetailMap(data.detailMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let $initParams = {} as ApifoxModel
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param initParams 购物车初始化参数
|
||||||
|
* @param $goodsMap 商品id对应的map
|
||||||
|
* @param oldOrder 历史订单数据
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function init(initParams : ApifoxModel, $oldOrder : any | undefined) {
|
||||||
|
// 商品id对应的数据map
|
||||||
|
await getGoods({})
|
||||||
|
|
||||||
|
if ($oldOrder) {
|
||||||
|
setOldOrder($oldOrder)
|
||||||
|
} else {
|
||||||
|
oldOrder.value = { detailMap: [], originAmount: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('oldOrder.detailMap', oldOrder.value.detailMap)
|
||||||
|
// const cache_table_code = localStorage.getItem('cache_table_code');
|
||||||
|
// const randomTableCode = cache_table_code ? cache_table_code : ('APC' + (1000 + Math.floor(Math.random() * 9000)))
|
||||||
|
if (initParams) {
|
||||||
|
initParams.table_code = initParams.table_code ? initParams.table_code : ''
|
||||||
|
table_code.value = initParams.table_code
|
||||||
|
$initParams = initParams;
|
||||||
|
}
|
||||||
|
console.log($initParams)
|
||||||
|
// localStorage.setItem('cache_table_code', table_code.value);
|
||||||
|
concocatSocket($initParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
function concocatSocket(initParams = $initParams) {
|
||||||
|
console.log("初始化参数", initParams);
|
||||||
|
WebSocketManager.subscribeToTopic(initParams, (msg) => {
|
||||||
|
console.log("收到消息:", msg);
|
||||||
|
if (msg.hasOwnProperty('status') && msg.status != 1) {
|
||||||
|
if (msg.type === 'no_suit_num' && selListIndex.value != -1) {
|
||||||
|
return uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
showCancel: false,
|
||||||
|
content: `${list.value[selListIndex.value].name}库存不足`,
|
||||||
|
success() {
|
||||||
|
if (res.confirm) {
|
||||||
|
list.value.splice(selListIndex.value, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
uni.showToast({
|
||||||
|
title: msg.message || msg.msg || '操作失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (msg && msg.data) {
|
||||||
|
if (Array.isArray(msg.data) && msg.data.length && msg.data[0].table_code) {
|
||||||
|
table_code.value = msg.data[0].table_code
|
||||||
|
}
|
||||||
|
if (msg.data.table_code) {
|
||||||
|
table_code.value = table_code.value ? table_code.value : msg.data.table_code
|
||||||
|
}
|
||||||
|
if (msg.table_code) {
|
||||||
|
table_code.value = table_code.value ? table_code.value : msg.table_code
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
if (msg.operate_type === "init") {
|
||||||
|
isLinkFinshed.value = true
|
||||||
|
// 设置单价
|
||||||
|
list.value = msg.data.filter((v : Record<string, any>) => {
|
||||||
|
if (v.is_temporary) {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
const skuData = getProductDetails({ product_id: v.product_id, sku_id: v.sku_id })
|
||||||
|
if (skuData) {
|
||||||
|
(Object.keys(skuData) as (keyof typeof skuData)[]).forEach((key) => {
|
||||||
|
v[key] = skuData[key];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// del({ id: v.id })
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !v.is_gift
|
||||||
|
})
|
||||||
|
giftList.value = msg.data.filter((v : Record<string, any>) => {
|
||||||
|
if (v.is_temporary) {
|
||||||
|
return v && v.is_gift
|
||||||
|
}
|
||||||
|
const skuData = getProductDetails({ product_id: v.product_id, sku_id: v.sku_id })
|
||||||
|
if (skuData) {
|
||||||
|
(Object.keys(skuData) as (keyof typeof skuData)[]).forEach((key) => {
|
||||||
|
v[key] = skuData[key];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
del({ id: v.id })
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return v.is_gift
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//广播
|
||||||
|
if (msg.type === "bc") {
|
||||||
|
msg.operate_type = 'shopping_' + msg.operate_type
|
||||||
|
}
|
||||||
|
if (msg.operate_type === "add") {
|
||||||
|
if (list.value.find(v => v.id == msg.data.id)) {
|
||||||
|
console.error('该商品已存在')
|
||||||
|
// ElMessage.warning(msg.message || '该商品已存在')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const skuData = getProductDetails({ product_id: msg.data.product_id, sku_id: msg.data.sku_id })
|
||||||
|
if (skuData || msg.data.is_temporary) {
|
||||||
|
const newGoods = { ...skuData, ...msg.data }
|
||||||
|
console.log('新增商品', newGoods)
|
||||||
|
list.value.push(newGoods)
|
||||||
|
console.log('添加成功')
|
||||||
|
// ElMessage.success(msg.message || '添加成功')
|
||||||
|
return
|
||||||
|
}else{
|
||||||
|
console.error('未找到对应商品');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if (msg.operate_type === "edit") {
|
||||||
|
const newCart = msg.data
|
||||||
|
const index = list.value.findIndex((item) => item.id === newCart.id)
|
||||||
|
const giftIndex = giftList.value.findIndex((item) => item.id === newCart.id)
|
||||||
|
const cartItem = list.value[index] || { is_gift: false };
|
||||||
|
const giftItem = giftList.value[giftIndex];
|
||||||
|
|
||||||
|
if (giftItem) {
|
||||||
|
//操作赠菜
|
||||||
|
if (!newCart.is_gift) {
|
||||||
|
giftList.value.splice(giftIndex, 1)
|
||||||
|
list.value.push({ ...giftItem, ...newCart })
|
||||||
|
selListIndex.value = -1
|
||||||
|
} else {
|
||||||
|
giftList.value[giftIndex] = { ...giftItem, ...newCart }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cartItem) {
|
||||||
|
//操作非赠菜
|
||||||
|
if (newCart.is_gift) {
|
||||||
|
list.value.splice(index, 1)
|
||||||
|
giftList.value.push({ ...cartItem, ...newCart })
|
||||||
|
selListIndex.value = -1
|
||||||
|
} else {
|
||||||
|
list.value[index] = { ...cartItem, ...newCart }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ElMessage.success(msg.message || '修改成功')
|
||||||
|
}
|
||||||
|
if (msg.operate_type === "del") {
|
||||||
|
const cartId = Array.isArray(msg.data) ? msg.data[0].id : msg.data.id
|
||||||
|
const listIndex = list.value.findIndex((item) => item.id == cartId)
|
||||||
|
if (listIndex > -1) {
|
||||||
|
list.value.splice(listIndex, 1)
|
||||||
|
}
|
||||||
|
const giftIndex = giftList.value.findIndex((item) => item.id == cartId)
|
||||||
|
if (giftIndex > -1) {
|
||||||
|
giftList.value.splice(giftIndex, 1)
|
||||||
|
}
|
||||||
|
// ElMessage.success(msg.message || '删除成功')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (msg.operate_type === "cleanup") {
|
||||||
|
nowCartsClear()
|
||||||
|
getOldOrder(msg.data.table_code)
|
||||||
|
}
|
||||||
|
if (msg.operate_type === "batch") {
|
||||||
|
concocatSocket({ ...$initParams, table_code: table_code.value })
|
||||||
|
}
|
||||||
|
if (msg.operate_type === "clearOrder") {
|
||||||
|
getOldOrder(msg.data.table_code)
|
||||||
|
}
|
||||||
|
if (msg.operate_type === "product_update") {
|
||||||
|
console.log('商品更新')
|
||||||
|
init($initParams, oldOrder.value)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function disconnect() {
|
||||||
|
sendMessage('disconnect', undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
const delArr = ['skuData', 'coverImg', 'specInfo', 'placeNum', 'update_time', 'create_time', 'packFee', 'memberPrice', 'type']
|
||||||
|
function sendMessage(operate_type : msgType, message : any) {
|
||||||
|
const msg = { ...message, operate_type: operate_type, table_code: table_code.value }
|
||||||
|
for (let i in delArr) {
|
||||||
|
delete msg[delArr[i]]
|
||||||
|
}
|
||||||
|
console.log('send msg', msg)
|
||||||
|
WebSocketManager.sendMessage(msg);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
clearHistory,
|
||||||
|
disconnect,
|
||||||
|
dinnerType,
|
||||||
|
changePack,
|
||||||
|
giftMoney,
|
||||||
|
goodsTotal,
|
||||||
|
isLinkFinshed,
|
||||||
|
setOldOrder,
|
||||||
|
singleDiscount,
|
||||||
|
vipDiscount,
|
||||||
|
dataReset,
|
||||||
|
useVipPrice,
|
||||||
|
changeUser,
|
||||||
|
packNum, packFee,
|
||||||
|
isOldOrder,
|
||||||
|
oldOrder,
|
||||||
|
isCanSelectGroup,
|
||||||
|
goods,
|
||||||
|
selGoods,
|
||||||
|
cartsPush,
|
||||||
|
table_code,
|
||||||
|
updateTag,
|
||||||
|
list,
|
||||||
|
add,
|
||||||
|
del,
|
||||||
|
update,
|
||||||
|
init,
|
||||||
|
changeNumber, isEmpty,
|
||||||
|
selCart, totalNumber,
|
||||||
|
changeSelCart, payMoney,
|
||||||
|
clear, yiyouhui, giftList,
|
||||||
|
changeTable,
|
||||||
|
rotTable,
|
||||||
|
getGoods,
|
||||||
|
setGoodsMap,
|
||||||
|
hotgoods, groupGoods
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -214,7 +214,7 @@ export const productStore = defineStore('product', {
|
|||||||
uni.cache.set('shopUserInfo', res);
|
uni.cache.set('shopUserInfo', res);
|
||||||
uni.cache.set('orderVIP', res)
|
uni.cache.set('orderVIP', res)
|
||||||
uni.cache.set('ordershopUserInfo', res.shopInfo)
|
uni.cache.set('ordershopUserInfo', res.shopInfo)
|
||||||
resolve(true)
|
resolve(res)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reject(false)
|
reject(false)
|
||||||
}
|
}
|
||||||
@@ -226,14 +226,16 @@ export const productStore = defineStore('product', {
|
|||||||
actionsAPIuser() {
|
actionsAPIuser() {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
|
let res=null
|
||||||
// 获取店铺用户会员信息
|
// 获取店铺用户会员信息
|
||||||
if (uni.cache.get('shopId')) {
|
if (uni.cache.get('shopId')) {
|
||||||
this.actionsproductqueryProduct()
|
res = await this.actionsproductqueryProduct()
|
||||||
} else {
|
} else {
|
||||||
let res = await APIuser()
|
res = await APIuser()
|
||||||
uni.cache.set('userInfo', res);
|
uni.cache.set('userInfo', res);
|
||||||
}
|
}
|
||||||
resolve(true)
|
console.log('actionsAPIuser res',res);
|
||||||
|
resolve(res)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reject(false)
|
reject(false)
|
||||||
}
|
}
|
||||||
|
|||||||
47
utils/product.js
Normal file
47
utils/product.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import dayjs from 'dayjs';
|
||||||
|
import isBetween from 'dayjs/plugin/isBetween'
|
||||||
|
dayjs.extend(isBetween)
|
||||||
|
// 判断商品是否在可售时间内
|
||||||
|
export const isProductAvailable = (sellDaysStr, startTimeStr, endTimeStr) => {
|
||||||
|
// 将后端返回的字符串转换为数组
|
||||||
|
const sellDays = sellDaysStr.split(',');
|
||||||
|
const now = dayjs();
|
||||||
|
const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||||
|
const currentDay = days[now.day()];
|
||||||
|
|
||||||
|
// console.log('当前日期:', currentDay);
|
||||||
|
// console.log('可售日期列表:', sellDays);
|
||||||
|
|
||||||
|
// 检查当前周几是否在可售周几列表中
|
||||||
|
if (!sellDays.includes(currentDay)) {
|
||||||
|
// console.log('当前日期不在可售日期列表中');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const startTime = dayjs(`${now.format('YYYY-MM-DD')} ${startTimeStr}`);
|
||||||
|
let endTime = dayjs(`${now.format('YYYY-MM-DD')} ${endTimeStr}`);
|
||||||
|
|
||||||
|
// 处理跨天情况
|
||||||
|
if (endTime.isBefore(startTime)) {
|
||||||
|
endTime = endTime.add(1, 'day');
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('当前时间:', now.format('YYYY-MM-DD HH:mm:ss'));
|
||||||
|
// console.log('开始时间:', startTime.format('YYYY-MM-DD HH:mm:ss'));
|
||||||
|
// console.log('结束时间:', endTime.format('YYYY-MM-DD HH:mm:ss'));
|
||||||
|
|
||||||
|
const isInRange = now.isBetween(startTime, endTime, null, '[)');
|
||||||
|
// console.log('当前时间是否在可售时间范围内:', isInRange);
|
||||||
|
|
||||||
|
return isInRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
//点单页面商品数据补充格式化,增加购物车选中数量,增加是否在可售时段内
|
||||||
|
export function goodsInitParamsFull(product) {
|
||||||
|
return {
|
||||||
|
...product,
|
||||||
|
cartNumber: 0,
|
||||||
|
isSaleTimeshow: isProductAvailable(product.days, product
|
||||||
|
.startTime, product.endTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user