代客下单重构
This commit is contained in:
6
App.vue
6
App.vue
@@ -1,7 +1,4 @@
|
||||
<script setup>
|
||||
import {
|
||||
useCartsStore
|
||||
} from '@/stores/carts.js';
|
||||
import {
|
||||
useNavbarStore
|
||||
} from '@/stores/navbarStore';
|
||||
@@ -35,9 +32,6 @@
|
||||
await nextTick()
|
||||
const store = useNavbarStore();
|
||||
await store.initNavbarHeight();
|
||||
getApp().globalData.websocket=null;
|
||||
const cartsStore=useCartsStore()
|
||||
cartsStore.isloading=false;
|
||||
});
|
||||
onShow(async () => {
|
||||
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>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
useCartsStore
|
||||
} from '@/stores/carts.js';
|
||||
const cartStore = useCartsStore()
|
||||
import orderItemVue from './order-item.vue';
|
||||
import {
|
||||
ref,
|
||||
|
||||
@@ -140,8 +140,8 @@
|
||||
} from '@/common/api/shop/index.js'
|
||||
import {
|
||||
useCartsStore
|
||||
} from '@/stores/carts.js';
|
||||
import useWebSocket from '@/common/js/carts-websocket.js';
|
||||
} from '@/stores/carts';
|
||||
import useWebSocket from '@/common/js/carts-websocket';
|
||||
const cartStore = useCartsStore()
|
||||
let cartsSocket = null
|
||||
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 }"
|
||||
@close="close">
|
||||
<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">
|
||||
<view class="list-wrap">
|
||||
<view v-if="cartList.length>0">
|
||||
@@ -29,15 +22,15 @@
|
||||
<up-image :src="item.coverImg" width="80" radius="10" height="80"></up-image>
|
||||
</view>
|
||||
<view class="info">
|
||||
<view class="name"> {{item.cartListinfo.is_temporary == 1?'临时菜' :item.name }}
|
||||
<view class="name"> {{item.is_temporary == 1?'临时菜' :item.name }}
|
||||
</view>
|
||||
<view class="select-sku-wrap" v-if="item.type == 'sku'">
|
||||
<text v-for="i in item.skuList" :key="i.id">
|
||||
{{item.cartListinfo.sku_id == i.id? i.name:"" }}
|
||||
<text >
|
||||
{{item.skuData.name||''}}
|
||||
</text>
|
||||
</view>
|
||||
<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> -->
|
||||
<text v-for="i in a.goods" :key="i.proId" style="margin-left: 4rpx;">
|
||||
{{i.proName }}
|
||||
@@ -47,15 +40,14 @@
|
||||
<view class="price-wrap" style="padding-top: 0;">
|
||||
<view class="price">
|
||||
<text class="i">¥</text>
|
||||
<!-- 会员价与价格 -->
|
||||
<text class="price" v-if="item.type == 'sku'">
|
||||
<text v-for="i in item.skuList" :key="i.id">
|
||||
<!-- -->
|
||||
{{item.cartListinfo.sku_id == i.id?(shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(i.memberPrice || i.salePrice):i.salePrice):''}}
|
||||
<!-- 会员价 -->
|
||||
<text class="price" v-if="shopInfo.isVip ==1 && shopInfo.isMemberPrice==1">
|
||||
<text >
|
||||
{{item.memberPrice || item.salePrice}}
|
||||
</text>
|
||||
</text>
|
||||
<text class="price" v-else>
|
||||
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice || item.salePrice):item.salePrice}}
|
||||
{{item.salePrice}}
|
||||
</text>
|
||||
<!-- <text class="originalprice"
|
||||
v-if="item.originPrice">¥{{item.originPrice}}</text>
|
||||
@@ -66,16 +58,16 @@
|
||||
<view class="operation-wrap">
|
||||
<view class="btn">
|
||||
<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>
|
||||
<text class="num">{{ ifcartNumber(item) }}</text>
|
||||
<text class="num">{{ item.number*1 }}</text>
|
||||
<view class="btn" v-if="item.type !='package'">
|
||||
<!-- <up-icon name="plus-circle-fill"
|
||||
:color="{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? '#CECECE' : '#E9AB7A'"
|
||||
size="25"></up-icon> -->
|
||||
<up-icon name="plus-circle-fill" color="#E8AD7B"
|
||||
size="25"></up-icon>
|
||||
<view class="btnClick" @click="cartListadd(item,'+')"></view>
|
||||
<view class="btnClick" @click="changeNumber(1,item)"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -104,7 +96,7 @@
|
||||
} from '@/stores/user.js';
|
||||
|
||||
// 定义自定义事件
|
||||
const emits = defineEmits(['customevent', 'close', 'clickcancelOrder']);
|
||||
const emits = defineEmits(['changeNumber', 'close', 'clearCarts']);
|
||||
|
||||
const props = defineProps({
|
||||
cartList: {
|
||||
@@ -127,54 +119,16 @@
|
||||
});
|
||||
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 = () => {
|
||||
emits("close", false)
|
||||
}
|
||||
// 购物车加减
|
||||
const cartListadd = async (item, i) => {
|
||||
// 是否起售 如果小于或者大于都是1
|
||||
const cartNumberFloat = parseFloat(item.cartNumber);
|
||||
const suitNum = item.suitNum >= cartNumberFloat && i == '-' ? item.cartNumber : 1;
|
||||
function changeNumber(step,item){
|
||||
emits("changeNumber", step, item);
|
||||
|
||||
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(() => {
|
||||
return (item) => {
|
||||
@@ -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) => {
|
||||
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 = () => {
|
||||
emits('customevent', {
|
||||
type: 'shopping',
|
||||
table_code: uni.cache.get('tableCode'),
|
||||
shop_id: uni.cache.get('shopId'),
|
||||
operate_type: 'cleanup',
|
||||
})
|
||||
emits('clearCarts')
|
||||
}
|
||||
</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 class="panelfour" v-if="shopProductList.hots && shopProductList.hots.length > 0">
|
||||
<view class="panelfour" v-if="carts.hotgoods && carts.hotgoods.length > 0">
|
||||
本店招牌菜
|
||||
</view>
|
||||
<view class="panelfive ">
|
||||
@@ -41,7 +41,7 @@
|
||||
<scroll-view :scroll-x="true" :scroll-with-animation="false">
|
||||
<view class="panelfive_list">
|
||||
<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>
|
||||
<view class="vifgoodsImg flex-center"
|
||||
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>
|
||||
<!-- 会员价与价格 -->
|
||||
<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 class="unit" v-if="item.unitName">/{{item.unitName}}</text>
|
||||
@@ -106,7 +106,7 @@
|
||||
:class="shopInfo.isVip ==0 || shopInfo.isMemberPrice==0?'lineThrough':''">¥</text>
|
||||
<!-- 会员价与价格 -->
|
||||
<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 class="unit" v-if="item.unitName">/{{item.unitName}}</text>
|
||||
<!-- <text v-if="item.suitNum>1 && item.type!= 'sku'"
|
||||
@@ -153,14 +153,14 @@
|
||||
<view class="left" :style="{top: `${store.height}px`}">
|
||||
<scroll-view :scroll-into-view="leftIntoView" :scroll-with-animation="false" :scroll-y="true"
|
||||
: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"
|
||||
@click="leftTap(index)"><text>{{item.name}}</text></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="main">
|
||||
<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">
|
||||
<view class="title">
|
||||
<view>{{item.name}}</view>
|
||||
@@ -175,19 +175,25 @@
|
||||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/index/1.gif" mode="" v-else
|
||||
:lazy-load="true">
|
||||
</image>
|
||||
<view class="vifgoodsImg"
|
||||
v-if="item1.isSale == 0 || (item1.isSaleTime == 0 && !item1.isSaleTimeshow) || item1.isSoldStock == 1 || (item1.isStock == 1 && item1.stockNumber <= 0)">
|
||||
<image v-if="item1.isSale == 0" src="@/static/ztt/icon_goods_yxj.svg"
|
||||
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>
|
||||
</view>
|
||||
<block>
|
||||
<view class="vifgoodsImg" v-if="item1.isSale == 0">
|
||||
<image src="@/static/ztt/icon_goods_yxj.svg" style="width:200rpx; height: 100%;"
|
||||
mode=""></image>
|
||||
</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 class="goods_right" style="overflow: hidden;">
|
||||
<view class="name">{{ item1.name }}</view>
|
||||
@@ -205,8 +211,11 @@
|
||||
<view class="money">
|
||||
<view>¥</view>
|
||||
<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 class="money_num" style="margin-right: 10rpx;">
|
||||
{{carts.useVipPrice ?(item1.memberPrice||item1.salePrice):item1.salePrice}}
|
||||
</text> -->
|
||||
<text v-if="item1.unitName">/{{item1.unitName}}</text>
|
||||
</view>
|
||||
<view class="flex-end">
|
||||
@@ -221,7 +230,7 @@
|
||||
<view class="money">
|
||||
<view>¥</view>
|
||||
<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 class="money_num" v-if="item1.unitName">/{{item1.unitName}}</text>
|
||||
<!-- <text v-if="item1.suitNum>1 && item1.type!= 'sku'"
|
||||
@@ -267,21 +276,17 @@
|
||||
|
||||
</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>
|
||||
<!-- 购物车 -->
|
||||
<shoppingCartes :cartLists_count="cartLists_count" :cartList="matchedProducts" :showCart="showCart"
|
||||
@customevent='websocketsendMessage' @close="showCart = !showCart" :orderinfo="orderinfo"
|
||||
@clickcancelOrder='clickcancelOrder' v-if="cartLists_count > 0">
|
||||
<shoppingCartes :cartLists_count="carts.totalNumber" :cartList="carts.list" :showCart="showCart"
|
||||
@clearCarts="clearCarts" @changeNumber="cartsChangeNumber" @close="showCart = !showCart"
|
||||
:orderinfo="orderinfo" v-if="!carts.isEmpty">
|
||||
</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="left">
|
||||
<view class="iconBox">
|
||||
@@ -289,11 +294,11 @@
|
||||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/shopDetails/shopIcon.png"
|
||||
mode="aspectFill" @click="Historicalorders(true)">
|
||||
</image>
|
||||
<text class="u-badge"> {{cartLists_count<99?cartLists_count:'99+'}} </text>
|
||||
<text class="u-badge"> {{carts.totalNumber <99?carts.totalNumber:'99+'}} </text>
|
||||
</view>
|
||||
|
||||
<text class="i">¥</text>
|
||||
<text class="num">{{totalPrices}}</text>
|
||||
<text class="num">{{carts.payMoney}}</text>
|
||||
</view>
|
||||
<view class="btn" @tap="$u.debounce(orderdetail, 500)">
|
||||
<text class="t">结算</text>
|
||||
@@ -366,7 +371,7 @@
|
||||
<view class="price" v-if="specifications.item.type != 'package' && specifications.item.result">
|
||||
<text class="i">¥</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 v-if="specifications.item.result.suitNum>1">
|
||||
「{{specifications.item.result.suitNum}}{{specifications.item.result.unitName}}起点」
|
||||
@@ -375,7 +380,7 @@
|
||||
<view class="price" v-else>
|
||||
<text class="i">¥</text>
|
||||
<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 class="i" v-if="specifications.item.unitName">
|
||||
/{{specifications.item.unitName}}
|
||||
@@ -418,11 +423,36 @@
|
||||
<image class="img" src="@/static/history.png" mode=""></image>
|
||||
<text>已下单菜品</text>
|
||||
</view>
|
||||
<Loading :isLoading="isLoading" />
|
||||
<Loading :isLoading="!carts.isLinkFinshed" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<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 {
|
||||
ref,
|
||||
reactive,
|
||||
@@ -445,7 +475,7 @@
|
||||
import Nav from '@/components/CustomNavbar.vue';
|
||||
import shopindex from './components/shopindex.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 dayjs from 'dayjs';
|
||||
import isBetween from 'dayjs/plugin/isBetween'
|
||||
@@ -486,11 +516,6 @@
|
||||
const storeMemberpay = Memberpay();
|
||||
const store = useNavbarStore();
|
||||
|
||||
import {
|
||||
productStore
|
||||
} from '@/stores/user.js';
|
||||
|
||||
const userStore = productStore();
|
||||
|
||||
// 金额管理
|
||||
import {
|
||||
@@ -516,8 +541,7 @@
|
||||
//店铺详情
|
||||
const showShopInfoRef = ref(null)
|
||||
|
||||
// 初始加载中
|
||||
const isLoading = ref(true);
|
||||
|
||||
|
||||
//调用shop组件
|
||||
const callChildMethod = () => {
|
||||
@@ -541,7 +565,7 @@
|
||||
|
||||
// * 图片加载
|
||||
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 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 () => {
|
||||
@@ -965,7 +863,7 @@
|
||||
selectedGroupSnap.value = []
|
||||
}
|
||||
|
||||
websocketsendMessage({
|
||||
carts.add({
|
||||
id: res ? res.cartListId : '',
|
||||
type: 'shopping',
|
||||
suitNum: specifications.productListitem.suitNum,
|
||||
@@ -982,6 +880,24 @@
|
||||
is_print: 1,
|
||||
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 = []
|
||||
showShopsku.value = false
|
||||
@@ -1068,6 +984,18 @@
|
||||
return isInRange;
|
||||
}
|
||||
|
||||
|
||||
function addCarts(item, isWeight = false) {
|
||||
if (isWeight) {
|
||||
carts.add({
|
||||
...item
|
||||
});
|
||||
return;
|
||||
}
|
||||
carts.add({
|
||||
...item
|
||||
});
|
||||
}
|
||||
// 单规格
|
||||
const singleclick = async (item, i) => {
|
||||
if (!isProductAvailable(item.days, item.startTime, item.endTime)) {
|
||||
@@ -1077,26 +1005,18 @@
|
||||
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
|
||||
|
||||
// 是否起售 如果小于或者大于都是1
|
||||
let suitNum = 1;
|
||||
const cartNumberFloat = parseFloat(item.cartNumber);
|
||||
if (!res && item.suitNum > cartNumberFloat) {
|
||||
suitNum = item.suitNum;
|
||||
} else if (item.suitNum >= cartNumberFloat && i === '-') {
|
||||
suitNum = item.cartNumber;
|
||||
}
|
||||
console.log(item);
|
||||
addCarts({
|
||||
suitNum: item.suitNum || 1,
|
||||
product_id: item.id,
|
||||
sku_id: item.skuList[0].id,
|
||||
number: item.skuList[0].suitNum || 1,
|
||||
product_type: item.type,
|
||||
});
|
||||
return
|
||||
websocketsendMessage({
|
||||
id: res ? item.cartListId : '',
|
||||
type: 'shopping',
|
||||
@@ -1134,190 +1054,62 @@
|
||||
shop_id: uni.cache.get('shopId')
|
||||
}
|
||||
}
|
||||
const {
|
||||
isConnected,
|
||||
sendMessage,
|
||||
closeSocket: manualClose,
|
||||
receivedMessages,
|
||||
closeExistingConnection,
|
||||
onShowconnect,
|
||||
initNetworkListener
|
||||
} = useWebSocket(options);
|
||||
|
||||
try{
|
||||
carts.init({
|
||||
type: 'shopping',
|
||||
operate_type: 'init',
|
||||
table_code: uni.cache.get('tableCode'),
|
||||
shop_id: uni.cache.get('shopId')
|
||||
}, {});
|
||||
}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 confirmordershow = ref(false)
|
||||
|
||||
|
||||
// 更新商品数量的方法
|
||||
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
|
||||
// 更新购物车数据carts.hotgoods
|
||||
const matchedProducts = computed(() => {
|
||||
if (cartStore.carts.length > 0) {
|
||||
if (carts.list.length > 0) {
|
||||
let Specialstop = null
|
||||
|
||||
try {
|
||||
Specialstop = [...[{
|
||||
id: "",
|
||||
name: "",
|
||||
productList: shopProductList.hots
|
||||
}], ...shopProductList.productInfo]
|
||||
productList: carts.hotgoods
|
||||
}], ...carts.groupGoods]
|
||||
} catch (error) {
|
||||
Specialstop = shopProductList.productInfo
|
||||
Specialstop = carts.groupGoods
|
||||
//TODO handle the exception
|
||||
}
|
||||
return cartStore.carts.flatMap((cartItem) => {
|
||||
return carts.list.flatMap((cartItem) => {
|
||||
for (const group of Specialstop) {
|
||||
for (const product of group.productList) {
|
||||
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 confirmorderref = ref(null)
|
||||
// const confirmorderref = ref(null)
|
||||
|
||||
// 结账
|
||||
const orderdetail = async () => {
|
||||
@@ -1379,17 +1155,12 @@
|
||||
.cache.get(
|
||||
'shopId')
|
||||
})
|
||||
return
|
||||
try {
|
||||
await Historicalorders()
|
||||
} catch (error) {}
|
||||
confirmordershow.value = true
|
||||
showCart.value = false
|
||||
}
|
||||
|
||||
// 历史订单
|
||||
const Historicalorders = async (W) => {
|
||||
|
||||
console.log('Historicalorders');
|
||||
console.log(W);
|
||||
if (W) {
|
||||
showCart.value = !showCart.value
|
||||
} 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 计算属性方法 展示数量
|
||||
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({
|
||||
startTime: '',
|
||||
@@ -1568,80 +1231,25 @@
|
||||
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) => {
|
||||
await proxy.$onLaunched;
|
||||
})
|
||||
|
||||
onShow(async() => {
|
||||
onShow(async () => {
|
||||
// 监听页面显示和隐藏
|
||||
onShowconnect()
|
||||
let res = await APIhistoryOrder({
|
||||
tableCode: uni.cache.get('tableCode'),
|
||||
})
|
||||
if(res){
|
||||
if (res) {
|
||||
orderinfo.value = {
|
||||
id: res.id,
|
||||
detailMap: res.detailMap,
|
||||
placeNum: res.placeNum
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
orderinfo.value = {
|
||||
id:''
|
||||
id: ''
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1662,14 +1270,11 @@
|
||||
tableCode: uni.cache.get('tableCode'),
|
||||
})
|
||||
|
||||
await productqueryProduct()
|
||||
if (res && res.id && shopInfo.registerType == "after") {
|
||||
toHistory()
|
||||
return
|
||||
}
|
||||
setTimeout(() => {
|
||||
// 启动网络监听
|
||||
initNetworkListener()
|
||||
getElementTop()
|
||||
}, 500)
|
||||
})
|
||||
|
||||
@@ -1,65 +1,29 @@
|
||||
<template>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {onLoad} from '@dcloudio/uni-app'
|
||||
import { reactive,ref} from 'vue'
|
||||
import {
|
||||
productStore
|
||||
} from '@/stores/user.js';
|
||||
const store = productStore();
|
||||
const scanCodehandle = async (i) => {
|
||||
await store.scanCodeactions(form)
|
||||
}
|
||||
const show=ref(false);
|
||||
const options=ref({})
|
||||
function popupShow(){
|
||||
show.value=true;
|
||||
}
|
||||
const refForm=ref(null);
|
||||
const form=reactive({
|
||||
tableCode:"40963902920"
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
useCartsStore
|
||||
} from '@/stores/carts'
|
||||
const carts = useCartsStore();
|
||||
console.log(carts);
|
||||
const table = ref({
|
||||
tableCode: '40963902920',
|
||||
})
|
||||
function resetForm(){
|
||||
form.tableCode=""
|
||||
}
|
||||
onLoad((opt)=>{
|
||||
console.log(opt);
|
||||
options.value=opt
|
||||
})
|
||||
function toCreate(){
|
||||
uni.navigateTo({
|
||||
url:'/pages/index/index'
|
||||
})
|
||||
}
|
||||
carts.init({
|
||||
table_code: table.value.tableCode,
|
||||
shop_id:"29",
|
||||
account:29
|
||||
}, {});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gap-20{
|
||||
.gap-20 {
|
||||
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('orderVIP', res)
|
||||
uni.cache.set('ordershopUserInfo', res.shopInfo)
|
||||
resolve(true)
|
||||
resolve(res)
|
||||
} catch (e) {
|
||||
reject(false)
|
||||
}
|
||||
@@ -226,14 +226,16 @@ export const productStore = defineStore('product', {
|
||||
actionsAPIuser() {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let res=null
|
||||
// 获取店铺用户会员信息
|
||||
if (uni.cache.get('shopId')) {
|
||||
this.actionsproductqueryProduct()
|
||||
res = await this.actionsproductqueryProduct()
|
||||
} else {
|
||||
let res = await APIuser()
|
||||
res = await APIuser()
|
||||
uni.cache.set('userInfo', res);
|
||||
}
|
||||
resolve(true)
|
||||
console.log('actionsAPIuser res',res);
|
||||
resolve(res)
|
||||
} catch (e) {
|
||||
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