diff --git a/.env.development b/.env.development index 9aea75f..fc90eae 100644 --- a/.env.development +++ b/.env.development @@ -13,7 +13,7 @@ VITE_APP_API_URL=https://tapi.cashier.sxczgkj.cn/ # 正式 # VITE_APP_API_URL=http://localhost:8989 # 本地 # WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws -VITE_APP_WS_ENDPOINT= +VITE_APP_WS_ENDPOINT=wss://sockets.sxczgkj.com/wss # 启用 Mock 服务 VITE_MOCK_DEV_SERVER=false diff --git a/README.md b/README.md index a9c6529..97fb75b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ 订单,支付相关: 商品,耗材相关: 系统相关: +购物车websocket + ## 项目特色 diff --git a/package.json b/package.json index d093947..14f1072 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "path-to-regexp": "^8.2.0", "pinia": "^2.3.1", "qs": "^6.14.0", + "sockjs-client": "^1.6.1", "sortablejs": "^1.15.6", "vue": "^3.5.13", "vue-i18n": "^11.1.0", diff --git a/src/api/account/activate.ts b/src/api/account/activate.ts new file mode 100644 index 0000000..e3d46b5 --- /dev/null +++ b/src/api/account/activate.ts @@ -0,0 +1,85 @@ +import request from "@/utils/request"; +import { Account_BaseUrl } from "@/api/config"; +const baseURL = Account_BaseUrl + "/admin/activate"; +const API = { + + getList() { + return request({ + url: `${baseURL}`, + method: "get", + }); + }, + edit(data: editRequest) { + return request({ + url: `${baseURL}`, + method: "put", + data: data, + }); + }, + add(data: addRequest) { + return request({ + url: `${baseURL}`, + method: "post", + data: data, + }); + } +} +export default API; + +export interface addRequest { + /** + * 充值金额 + */ + amount?: number; + /** + * 优惠卷id + */ + couponId?: number; + /** + * 赠送金额 + */ + giftAmount?: number; + /** + * 赠送积分 + */ + giftPoints?: number; + /** + * 是否赠送优惠卷 0否 1是 + */ + isGiftCoupon?: number; + /** + * 优惠卷数量 + */ + num?: number; + [property: string]: any; +} + +export interface editRequest { + /** + * 充值金额 + */ + amount: number; + /** + * 优惠卷id + */ + couponId?: number; + /** + * 赠送金额 + */ + giftAmount?: number; + /** + * 赠送积分 + */ + giftPoints?: number; + id: number; + /** + * 是否赠送优惠卷 0否 1是 + */ + isGiftCoupon?: number; + /** + * 优惠卷数量 + */ + num?: number; + shopId?: number; + [property: string]: any; +} \ No newline at end of file diff --git a/src/api/account/permission.ts b/src/api/account/permission.ts new file mode 100644 index 0000000..038b653 --- /dev/null +++ b/src/api/account/permission.ts @@ -0,0 +1,22 @@ +import request from "@/utils/request"; +import { Account_BaseUrl } from "@/api/config"; +const baseURL = Account_BaseUrl + "/admin"; +const ShopStaffApi = { + // 获取店铺权限列表 + getshopPermission() { + return request({ + url: `${baseURL}/shopPermission`, + method: "get", + }); + }, + // 获取员工对应的权限id + getPermission(id: number | string) { + return request({ + url: `${baseURL}/shopStaff/permission`, + method: "get", + params: { id } + }); + }, +}; + +export default ShopStaffApi; diff --git a/src/api/account/table.ts b/src/api/account/table.ts new file mode 100644 index 0000000..0991f28 --- /dev/null +++ b/src/api/account/table.ts @@ -0,0 +1,128 @@ +import request from "@/utils/request"; +import { Account_BaseUrl } from "@/api/config"; +const baseURL = Account_BaseUrl + "/admin/shopTable"; +const API = { + // 批量生成桌码 + fasetAdd(num: number) { + return request({ + url: `${baseURL}/code`, + method: "post", + data: { num }, + }); + }, + getList(data: getListRequest) { + return request({ + url: `${baseURL}`, + method: "get", + params: data + }); + }, + edit(data: editRequest) { + return request({ + url: `${baseURL}`, + method: "put", + data: data, + }); + }, + add(data: addRequest) { + return request({ + url: `${baseURL}`, + method: "post", + data: data, + }); + }, + delete(id: number | string) { + return request({ + url: `${baseURL}`, + method: "post", + data: { id }, + }); + } +} +export default API; +/** + * ShopTableAddDTO + */ +export interface addRequest { + /** + * 区域id + */ + areaId?: number | null; + /** + * 是否自动清台 + */ + autoClear?: number | null; + /** + * 客座数 + */ + capacity: number | null; + /** + * 结束数字 + */ + end: number | null; + /** + * 台桌前缀 + */ + sign: null | string; + /** + * 起始数字 + */ + start: number | null; + [property: string]: any; +} + +/** + * ShopTableDTO + */ +export interface editRequest { + /** + * 区域Id + */ + areaId?: number | null; + /** + * 自动清台 0手动 1自动 + */ + autoClear?: number | null; + /** + * 自增id + */ + id: number | null; + /** + * 是否接受网络预定 + */ + isPredate?: number | null; + /** + * 客座数,允许的客座数量 + */ + maxCapacity?: number | null; + name?: null | string; + /** + * 网络预定台桌支付金额 + */ + predateAmount?: number | null; + /** + * 二维码 + */ + qrcode?: null | string; + /** + * 台桌排序 + */ + sort?: number | null; + /** + * idle-空闲 using-使用中 subscribe预定,closed--关台, opening 开台中,cleaning 台桌清理中 + */ + status?: null | string; + [property: string]: any; +} + +export interface getListRequest { + /** + * 区域id + */ + areaId?: number; + /** + * 桌码 + */ + tableCode?: string; + [property: string]: any; +} \ No newline at end of file diff --git a/src/router/index.ts b/src/router/index.ts index 0b680b4..a13620e 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -321,7 +321,7 @@ export const constantRoutes: RouteRecordRaw[] = [ }, { path: "table", - component: () => import("@/views/tool/table.vue"), + component: () => import("@/views/tool/table/index.vue"), name: "table", meta: { title: "台桌管理", @@ -473,7 +473,7 @@ export const constantRoutes: RouteRecordRaw[] = [ }, { path: "active", - component: () => import("@/views/user/active.vue"), + component: () => import("@/views/user/active/index.vue"), name: "userActive", meta: { title: "活动管理", diff --git a/src/utils/websocket copy.ts b/src/utils/websocket copy.ts new file mode 100644 index 0000000..bd8fadb --- /dev/null +++ b/src/utils/websocket copy.ts @@ -0,0 +1,93 @@ +import { Client } from "@stomp/stompjs"; +import { getToken } from "@/utils/auth"; + +class WebSocketManager { + private client: Client | null = null; + private messageHandlers: Map void)[]> = new Map(); + private reconnectAttempts = 0; + private maxReconnectAttempts = 3; // 自定义最大重试次数 + private reconnectDelay = 5000; // 重试延迟(单位:毫秒) + + // 初始化 WebSocket 客户端 + setupWebSocket() { + const endpoint = import.meta.env.VITE_APP_WS_ENDPOINT; + + // 如果没有配置 WebSocket 端点或显式关闭,直接返回 + if (!endpoint) { + console.log("WebSocket 已被禁用,如需打开请在配置文件中配置 VITE_APP_WS_ENDPOINT"); + return; + } + + if (this.client && this.client.connected) { + console.log("客户端已存在并且连接正常"); + return this.client; + } + + this.client = new Client({ + brokerURL: endpoint, + connectHeaders: { + Authorization: getToken(), + }, + heartbeatIncoming: 30000, + heartbeatOutgoing: 30000, + reconnectDelay: 0, // 设置为 0 禁用重连 + onConnect: () => { + console.log(`连接到 WebSocket 服务器: ${endpoint}`); + this.reconnectAttempts = 0; // 重置重连计数 + this.messageHandlers.forEach((handlers, topic) => { + handlers.forEach((handler) => { + this.subscribeToTopic(topic, handler); + }); + }); + }, + onStompError: (frame) => { + console.error(`连接错误: ${frame.headers["message"]}`); + console.error(`错误详情: ${frame.body}`); + }, + onDisconnect: () => { + console.log(`WebSocket 连接已断开: ${endpoint}`); + this.reconnectAttempts++; + if (this.reconnectAttempts < this.maxReconnectAttempts) { + console.log(`正在尝试重连... 尝试次数: ${this.reconnectAttempts}`); + } else { + console.log("重连次数已达上限,停止重连"); + this.client?.deactivate(); + } + }, + }); + + this.client.activate(); + } + + // 订阅主题 + public subscribeToTopic(topic: string, onMessage: (message: string) => void) { + console.log(`正在订阅主题: ${topic}`); + if (!this.client || !this.client.connected) { + this.setupWebSocket(); + } + + if (this.messageHandlers.has(topic)) { + this.messageHandlers.get(topic)?.push(onMessage); + } else { + this.messageHandlers.set(topic, [onMessage]); + } + + if (this.client?.connected) { + this.client.subscribe(topic, (message) => { + const handlers = this.messageHandlers.get(topic); + handlers?.forEach((handler) => handler(message.body)); + }); + } + } + + // 断开 WebSocket 连接 + public disconnect() { + if (this.client) { + console.log("断开 WebSocket 连接"); + this.client.deactivate(); + this.client = null; + } + } +} + +export default new WebSocketManager(); diff --git a/src/utils/websocket.ts b/src/utils/websocket.ts index bd8fadb..e0202af 100644 --- a/src/utils/websocket.ts +++ b/src/utils/websocket.ts @@ -1,9 +1,10 @@ -import { Client } from "@stomp/stompjs"; -import { getToken } from "@/utils/auth"; class WebSocketManager { - private client: Client | null = null; + private client: WebSocket | null = null; + private connected: boolean = false; + private onMessage: (message: any) => void = function () { }; private messageHandlers: Map void)[]> = new Map(); + private type: string = 'manage'; private reconnectAttempts = 0; private maxReconnectAttempts = 3; // 自定义最大重试次数 private reconnectDelay = 5000; // 重试延迟(单位:毫秒) @@ -18,73 +19,52 @@ class WebSocketManager { return; } - if (this.client && this.client.connected) { + if (this.client && this.connected) { console.log("客户端已存在并且连接正常"); return this.client; } - - this.client = new Client({ - brokerURL: endpoint, - connectHeaders: { - Authorization: getToken(), - }, - heartbeatIncoming: 30000, - heartbeatOutgoing: 30000, - reconnectDelay: 0, // 设置为 0 禁用重连 - onConnect: () => { - console.log(`连接到 WebSocket 服务器: ${endpoint}`); - this.reconnectAttempts = 0; // 重置重连计数 - this.messageHandlers.forEach((handlers, topic) => { - handlers.forEach((handler) => { - this.subscribeToTopic(topic, handler); - }); - }); - }, - onStompError: (frame) => { - console.error(`连接错误: ${frame.headers["message"]}`); - console.error(`错误详情: ${frame.body}`); - }, - onDisconnect: () => { - console.log(`WebSocket 连接已断开: ${endpoint}`); - this.reconnectAttempts++; - if (this.reconnectAttempts < this.maxReconnectAttempts) { - console.log(`正在尝试重连... 尝试次数: ${this.reconnectAttempts}`); - } else { - console.log("重连次数已达上限,停止重连"); - this.client?.deactivate(); - } - }, - }); - - this.client.activate(); + this.client = new WebSocket(endpoint) + this.client.onopen = () => { + this.connected = true; + console.log("WebSocket 连接已建立"); + this.sendMessage('test') + }; + this.client.onclose = () => { + this.connected = false; + console.log("WebSocket 连接已断开"); + }; + this.client.onerror = (error) => { + console.error("WebSocket 发生错误:", error); + }; + this.client.onmessage = (event) => { + const message = event.data; + this.getMessage(message) + }; + } + private getMessage(message: any) { + console.log("收到消息:", message); } // 订阅主题 public subscribeToTopic(topic: string, onMessage: (message: string) => void) { console.log(`正在订阅主题: ${topic}`); - if (!this.client || !this.client.connected) { + if (!this.client || !this.connected) { this.setupWebSocket(); } - - if (this.messageHandlers.has(topic)) { - this.messageHandlers.get(topic)?.push(onMessage); - } else { - this.messageHandlers.set(topic, [onMessage]); - } - - if (this.client?.connected) { - this.client.subscribe(topic, (message) => { - const handlers = this.messageHandlers.get(topic); - handlers?.forEach((handler) => handler(message.body)); - }); + if (this.connected) { + this.onMessage = onMessage; + } + } + public sendMessage(message: any) { + if (this.client) { + this.client.send(message); } } - // 断开 WebSocket 连接 public disconnect() { if (this.client) { console.log("断开 WebSocket 连接"); - this.client.deactivate(); + this.client.close(); this.client = null; } } diff --git a/src/views/shop/staff/components/select-permission.vue b/src/views/shop/staff/components/select-permission.vue new file mode 100644 index 0000000..3a0794d --- /dev/null +++ b/src/views/shop/staff/components/select-permission.vue @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/views/shop/staff/index.vue b/src/views/shop/staff/index.vue index 3a0c571..ad70a37 100644 --- a/src/views/shop/staff/index.vue +++ b/src/views/shop/staff/index.vue @@ -43,9 +43,8 @@ -