diff --git a/src/api/haianWarehouse/autoJ1SortingBoard.js b/src/api/haianWarehouse/autoJ1SortingBoard.js new file mode 100644 index 0000000..79884d4 --- /dev/null +++ b/src/api/haianWarehouse/autoJ1SortingBoard.js @@ -0,0 +1,4 @@ +import { createAPI } from '@/utils/httpRequest.js' + +// 自动J1H独立看板查询,显式传site及sortingStation;失败交由对应页面展示 - rqrq +export const getAutoJ1SortingBoard = data => createAPI('/api/dashboard/haian/sorting/getAutoJ1SortingBoard', 'post', data) diff --git a/src/api/haianWarehouse/autoJ2SortingBoard.js b/src/api/haianWarehouse/autoJ2SortingBoard.js new file mode 100644 index 0000000..dc0d4c0 --- /dev/null +++ b/src/api/haianWarehouse/autoJ2SortingBoard.js @@ -0,0 +1,4 @@ +import { createAPI } from '@/utils/httpRequest.js' + +// 自动J2H独立看板查询,显式传site及sortingStation;失败交由对应页面展示 - rqrq +export const getAutoJ2SortingBoard = data => createAPI('/api/dashboard/haian/sorting/getAutoJ2SortingBoard', 'post', data) diff --git a/src/api/haianWarehouse/manualSortingBoard.js b/src/api/haianWarehouse/manualSortingBoard.js new file mode 100644 index 0000000..503067b --- /dev/null +++ b/src/api/haianWarehouse/manualSortingBoard.js @@ -0,0 +1,4 @@ +import { createAPI } from '@/utils/httpRequest.js' + +// 人工R1H-R4H共用看板查询,显式传site及sortingStation;失败交由对应页面展示 - rqrq +export const getManualSortingBoard = data => createAPI('/api/dashboard/haian/sorting/getManualSortingBoard', 'post', data) diff --git a/src/api/haianWarehouse/sortingBoardConfig.js b/src/api/haianWarehouse/sortingBoardConfig.js new file mode 100644 index 0000000..df77995 --- /dev/null +++ b/src/api/haianWarehouse/sortingBoardConfig.js @@ -0,0 +1,4 @@ +import { createAPI } from '@/utils/httpRequest.js' + +// 海安看板启动前读取独立开关,显式传site;本接口不触发WCS/WMS业务查询 - rqrq +export const getSortingBoardConfig = data => createAPI('/api/dashboard/haian/sorting/getSortingBoardConfig', 'post', data) diff --git a/src/router/index.js b/src/router/index.js index bedb6ab..631d9d8 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -21,9 +21,9 @@ const _import = require('./import-' + process.env.NODE_ENV) const globalRoutes = [ { path: '/404', component: _import('common/404'), name: '404', meta: { title: '404未找到' } }, { path: '/login', component: _import('common/login'), name: 'login', meta: { title: '登录' } }, - // 海安六个看板独立入口共用海安展示页,固定分拣位防串屏;工厂由页面初始化并显式传给后端 - rqrq - { path: '/dashboard-haian-sorting-j1h', component: _import('modules/haianWarehouse/dashboard/sortingBoard54'), name: 'haian-sorting-j1h', props: { sortingStation: 'J1H', boardTitle: '自动分拣 1' }, meta: { title: '海安自动分拣1' } }, - { path: '/dashboard-haian-sorting-j2h', component: _import('modules/haianWarehouse/dashboard/sortingBoard54'), name: 'haian-sorting-j2h', props: { sortingStation: 'J2H', boardTitle: '自动分拣 2' }, meta: { title: '海安自动分拣2' } }, + // 海安人工四屏共用页面,自动J1H/J2H各自独立页面,固定分拣位防串屏;工厂由页面初始化并显式传给后端 - rqrq + { path: '/dashboard-haian-sorting-j1h', component: _import('modules/haianWarehouse/dashboard/autoJ1SortingBoard54'), name: 'haian-sorting-j1h', meta: { title: '海安自动分拣1' } }, + { path: '/dashboard-haian-sorting-j2h', component: _import('modules/haianWarehouse/dashboard/autoJ2SortingBoard54'), name: 'haian-sorting-j2h', meta: { title: '海安自动分拣2' } }, { path: '/dashboard-haian-sorting-r1h', component: _import('modules/haianWarehouse/dashboard/sortingBoard54'), name: 'haian-sorting-r1h', props: { sortingStation: 'R1H', boardTitle: '人工分拣 1' }, meta: { title: '海安人工分拣1' } }, { path: '/dashboard-haian-sorting-r2h', component: _import('modules/haianWarehouse/dashboard/sortingBoard54'), name: 'haian-sorting-r2h', props: { sortingStation: 'R2H', boardTitle: '人工分拣 2' }, meta: { title: '海安人工分拣2' } }, { path: '/dashboard-haian-sorting-r3h', component: _import('modules/haianWarehouse/dashboard/sortingBoard54'), name: 'haian-sorting-r3h', props: { sortingStation: 'R3H', boardTitle: '人工分拣 3' }, meta: { title: '海安人工分拣3' } }, diff --git a/src/utils/haianBoardSocket.js b/src/utils/haianBoardSocket.js new file mode 100644 index 0000000..7edf4b3 --- /dev/null +++ b/src/utils/haianBoardSocket.js @@ -0,0 +1,119 @@ +import SockJS from 'sockjs-client' +import Stomp from 'stompjs' + +// 海安专用传输实例:仅管理连接/心跳/订阅,不包含看板字段与业务;每页独立实例防止互相断连 - rqrq +export default class HaianBoardSocket { + constructor (url, topic, onMessage, onState) { + this.url = url + this.topic = topic + this.onMessage = onMessage + this.onState = onState + this.client = null + this.socket = null + this.retryTimer = null + this.connectTimer = null + this.healthTimer = null + this.attempts = 0 + this.generation = 0 + this.stopped = true + } + + // 主动开启仅执行一次;页面必须先取得enabled=true,工具本身不查询开关或数据库 - rqrq + start () { + if (!this.stopped) return + this.stopped = false + this.connect() + } + + // 使用旧看板同一SockJS/STOMP端点,每次连接成功重新订阅;代次校验隔离旧连接迟到回调 - rqrq + connect () { + if (this.stopped) return + this.release() + const generation = this.generation + const current = () => !this.stopped && generation === this.generation + this.onState('connecting') + try { + const socket = new SockJS(this.url) + this.socket = socket + const client = Stomp.over(socket) + this.client = client + client.debug = null + client.heartbeat.outgoing = 10000 + client.heartbeat.incoming = 10000 + // 建连超时防止网络黑洞永久停在connecting;STOMP握手成功才显示绿灯 - rqrq + this.connectTimer = setTimeout(() => { if (current()) this.fail() }, 20000) + client.connect({}, () => { + if (!current()) return + clearTimeout(this.connectTimer) + this.connectTimer = null + try { + client.subscribe(this.topic, message => { + if (!current()) return + try { + this.onMessage(JSON.parse(message.body)) + } catch (error) { + // 非法消息触发断连重订阅,避免绿灯掩盖持续无法消费的数据 - rqrq + this.fail() + } + }) + this.attempts = 0 + this.onState('connected') + // STOMP负责心跳超时关闭;额外检测浏览器离线和SockJS状态,最长5秒反映显式断网 - rqrq + this.healthTimer = setInterval(() => { + if (current() && (window.navigator.onLine === false || socket.readyState !== 1)) this.fail() + }, 5000) + } catch (error) { + if (current()) this.fail() + } + }, () => { if (current()) this.fail() }) + } catch (error) { + if (current()) this.fail() + } + } + + // 断线立即红灯,10/20/30…60秒无限重试;同一代异常只安排一次,恢复后重新从10秒计时 - rqrq + fail () { + if (this.stopped || this.retryTimer) return + this.release() + this.onState('disconnected') + const delay = Math.min(++this.attempts * 10000, 60000) + this.retryTimer = setTimeout(() => { + this.retryTimer = null + this.connect() + }, delay) + } + + // 完整释放STOMP自身心跳及页面健康检测,关闭旧连接前先失效回调,防止关闭又触发重连 - rqrq + release () { + this.generation++ + clearTimeout(this.connectTimer) + clearInterval(this.healthTimer) + this.connectTimer = null + this.healthTimer = null + const client = this.client + const socket = this.socket + this.client = null + this.socket = null + try { + if (client) client.disconnect(() => {}) + } catch (error) { + // 连接尚未打开时DISCONNECT可能失败,仍清理SockJS;该失败不恢复业务连接 - rqrq + } finally { + // stompjs 2.3.3在发送DISCONNECT抛错时不会进入自身清理,补充释放内部心跳定时器 - rqrq + if (client) client._cleanUp() + } + if (socket) { + socket.onclose = null + socket.onerror = null + try { socket.close() } catch (error) { /* 已关闭连接无需重复处理 - rqrq */ } + } + } + + // 页面销毁、切换工厂或配置关闭时取消全部重试,手动停用后绝不自动重连 - rqrq + stop () { + this.stopped = true + clearTimeout(this.retryTimer) + this.retryTimer = null + this.release() + } +} diff --git a/src/views/modules/haianWarehouse/dashboard/autoJ1SortingBoard54.vue b/src/views/modules/haianWarehouse/dashboard/autoJ1SortingBoard54.vue new file mode 100644 index 0000000..226958f --- /dev/null +++ b/src/views/modules/haianWarehouse/dashboard/autoJ1SortingBoard54.vue @@ -0,0 +1,353 @@ + + + + + + + 海安 · {{ boardTitle }} + + + + 分拣位 {{ sortingStation }} · 工厂 {{ site || '未设置' }} + + {{ currentTime }} + + + + + 标签 {{ visibleRows.length }} + 未完成 {{ pendingCount }} + 已完成 {{ completedCount }} + + + {{ connectionText }} + {{ displayMessage }} + 刷新 + + + + + + + + + + + + + + + + + + 序号工单号产品编码物料编码物料名称RFID / 标签号状态说明 + + + + {{ index + 1 }} + {{ item.orderNo || '-' }} + {{ item.orderPartNo || '-' }} + {{ item.partNo || '-' }} + {{ item.partDesc || '-' }} + {{ item.rfidBarcode }} + {{ item.status }} + {{ item.message || '-' }} + + + {{ displayMessage }} + + + + + + + + + + + + diff --git a/src/views/modules/haianWarehouse/dashboard/autoJ2SortingBoard54.vue b/src/views/modules/haianWarehouse/dashboard/autoJ2SortingBoard54.vue new file mode 100644 index 0000000..8b2c5b2 --- /dev/null +++ b/src/views/modules/haianWarehouse/dashboard/autoJ2SortingBoard54.vue @@ -0,0 +1,353 @@ + + + + + + + 海安 · {{ boardTitle }} + + + + 分拣位 {{ sortingStation }} · 工厂 {{ site || '未设置' }} + + {{ currentTime }} + + + + + 标签 {{ visibleRows.length }} + 未完成 {{ pendingCount }} + 已完成 {{ completedCount }} + + + {{ connectionText }} + {{ displayMessage }} + 刷新 + + + + + + + + + + + + + + + + + + 序号工单号产品编码物料编码物料名称RFID / 标签号状态说明 + + + + {{ index + 1 }} + {{ item.orderNo || '-' }} + {{ item.orderPartNo || '-' }} + {{ item.partNo || '-' }} + {{ item.partDesc || '-' }} + {{ item.rfidBarcode }} + {{ item.status }} + {{ item.message || '-' }} + + + {{ displayMessage }} + + + + + + + + + + + + diff --git a/src/views/modules/haianWarehouse/dashboard/sortingBoard54.vue b/src/views/modules/haianWarehouse/dashboard/sortingBoard54.vue index 9a7fe95..49dd4fe 100644 --- a/src/views/modules/haianWarehouse/dashboard/sortingBoard54.vue +++ b/src/views/modules/haianWarehouse/dashboard/sortingBoard54.vue @@ -4,7 +4,10 @@ - 海安 · {{ boardTitle }} + 海安 · {{ boardTitle }} + + + 分拣位 {{ sortingStation }} · 工厂 {{ site || '未设置' }} {{ currentTime }} @@ -17,9 +20,9 @@ 已完成 {{ completedCount }} - + {{ connectionText }} {{ displayMessage }} - 刷新 + 刷新 @@ -58,7 +61,7 @@ @@ -66,9 +69,11 @@