| | |
| | | template: ` |
| | | <div style="width: 100%; height: 100%; position: relative;"> |
| | | <div ref="pixiView" style="position: absolute; inset: 0;"></div> |
| | | <div style="position: absolute; top: 12px; left: 14px; z-index: 30; pointer-events: none; max-width: 52%;"> |
| | | <div style="display: flex; flex-direction: column; gap: 6px; align-items: flex-start;"> |
| | | <div v-for="item in cycleCapacity.loopList" |
| | | :key="'loop-' + item.loopNo" |
| | | @mouseenter="handleLoopCardEnter(item)" |
| | | @mouseleave="handleLoopCardLeave(item)" |
| | | style="padding: 6px 10px; border-radius: 4px; background: rgba(11, 35, 58, 0.72); color: #fff; font-size: 12px; line-height: 1.4; white-space: nowrap; pointer-events: auto;"> |
| | | 圈{{ item.loopNo }} | |
| | | 站点: {{ item.stationCount || 0 }} | |
| | | 任务: {{ item.taskCount || 0 }} | |
| | | 承载: {{ formatLoadPercent(item.currentLoad) }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div v-show="shelfTooltip.visible" |
| | | :style="shelfTooltipStyle()"> |
| | | {{ shelfTooltip.text }} |
| | |
| | | containerResizeObserver: null, |
| | | timer: null, |
| | | adjustLabelTimer: null, |
| | | isSwitchingFloor: false |
| | | isSwitchingFloor: false, |
| | | cycleCapacity: { |
| | | loopList: [], |
| | | totalStationCount: 0, |
| | | taskStationCount: 0, |
| | | currentLoad: 0 |
| | | }, |
| | | hoverLoopNo: null, |
| | | hoverLoopStationIdSet: new Set(), |
| | | loopHighlightColor: 0xfff34d |
| | | } |
| | | }, |
| | | mounted() { |
| | |
| | | this.getCrnInfo(); |
| | | this.getDualCrnInfo(); |
| | | this.getSiteInfo(); |
| | | this.getCycleCapacityInfo(); |
| | | this.getRgvInfo(); |
| | | }, 1000); |
| | | }, |
| | |
| | | }, |
| | | changeFloor(lev) { |
| | | this.currentLev = lev; |
| | | this.clearLoopStationHighlight(); |
| | | this.isSwitchingFloor = true; |
| | | this.hideShelfTooltip(); |
| | | this.hoveredShelfCell = null; |
| | |
| | | this.getMap(); |
| | | }, |
| | | createMapData(map) { |
| | | this.clearLoopStationHighlight(); |
| | | this.hideShelfTooltip(); |
| | | this.hoveredShelfCell = null; |
| | | this.mapRowOffsets = []; |
| | |
| | | sta.statusObj = null; |
| | | if (sta.textObj.parent !== sta) { sta.addChild(sta.textObj); sta.textObj.position.set(sta.width / 2, sta.height / 2); } |
| | | } |
| | | let baseColor = 0xb8b8b8; |
| | | if (status === "site-auto") { |
| | | this.updateColor(sta, 0x78ff81); |
| | | baseColor = 0x78ff81; |
| | | } else if (status === "site-auto-run" || status === "site-auto-id" || status === "site-auto-run-id") { |
| | | this.updateColor(sta, 0xfa51f6); |
| | | baseColor = 0xfa51f6; |
| | | } else if (status === "site-unauto") { |
| | | this.updateColor(sta, 0xb8b8b8); |
| | | baseColor = 0xb8b8b8; |
| | | } else if (status === "machine-pakin") { |
| | | this.updateColor(sta, 0x30bffc); |
| | | baseColor = 0x30bffc; |
| | | } else if (status === "machine-pakout") { |
| | | this.updateColor(sta, 0x97b400); |
| | | baseColor = 0x97b400; |
| | | } else if (status === "site-run-block") { |
| | | this.updateColor(sta, 0xe69138); |
| | | } else { |
| | | this.updateColor(sta, 0xb8b8b8); |
| | | baseColor = 0xe69138; |
| | | } |
| | | this.setStationBaseColor(sta, baseColor); |
| | | }); |
| | | }, |
| | | getCrnInfo() { |
| | |
| | | getRgvInfo() { |
| | | if (this.isSwitchingFloor) { return; } |
| | | this.sendWs(JSON.stringify({ url: "/console/latest/data/rgv", data: {} })); |
| | | }, |
| | | getCycleCapacityInfo() { |
| | | if (this.isSwitchingFloor) { return; } |
| | | this.sendWs(JSON.stringify({ url: "/console/latest/data/station/cycle/capacity", data: {} })); |
| | | }, |
| | | setCycleCapacityInfo(res) { |
| | | const payload = res && res.code === 200 ? res.data : null; |
| | | if (res && res.code === 403) { parent.location.href = baseUrl + "/login"; return; } |
| | | if (!payload) { return; } |
| | | const loopList = Array.isArray(payload.loopList) ? payload.loopList : []; |
| | | this.cycleCapacity = { |
| | | loopList: loopList, |
| | | totalStationCount: payload.totalStationCount || 0, |
| | | taskStationCount: payload.taskStationCount || 0, |
| | | currentLoad: typeof payload.currentLoad === 'number' ? payload.currentLoad : parseFloat(payload.currentLoad || 0) |
| | | }; |
| | | if (this.hoverLoopNo != null) { |
| | | const targetLoop = loopList.find(v => v && v.loopNo === this.hoverLoopNo); |
| | | if (targetLoop) { |
| | | this.hoverLoopStationIdSet = this.buildStationIdSet(targetLoop.stationIdList); |
| | | this.applyLoopStationHighlight(); |
| | | } else { |
| | | this.clearLoopStationHighlight(); |
| | | } |
| | | } |
| | | }, |
| | | formatLoadPercent(load) { |
| | | let value = typeof load === 'number' ? load : parseFloat(load || 0); |
| | | if (!isFinite(value)) { value = 0; } |
| | | if (value < 0) { value = 0; } |
| | | if (value > 1) { value = 1; } |
| | | return (value * 100).toFixed(1) + "%"; |
| | | }, |
| | | setCrnInfo(res) { |
| | | let crns = Array.isArray(res) ? res : (res && res.code === 200 ? res.data : null); |
| | |
| | | if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; } |
| | | this.wsReconnectAttempts = 0; |
| | | this.getMap(this.currentLev); |
| | | this.getCycleCapacityInfo(); |
| | | }, |
| | | webSocketOnError(e) { |
| | | this.scheduleReconnect(); |
| | |
| | | this.setDualCrnInfo(JSON.parse(result.data)); |
| | | } else if (result.url === "/console/latest/data/rgv") { |
| | | this.setRgvInfo(JSON.parse(result.data)); |
| | | } else if (result.url === "/console/latest/data/station/cycle/capacity") { |
| | | this.setCycleCapacityInfo(JSON.parse(result.data)); |
| | | } else if (typeof result.url === "string" && result.url.indexOf("/basMap/lev/") === 0) { |
| | | this.setMap(JSON.parse(result.data)); |
| | | } |
| | |
| | | text.position.set(sprite.width / 2, sprite.height / 2); |
| | | sprite.addChild(text); |
| | | sprite.textObj = text; |
| | | if (siteId != null && siteId !== -1) { this.pixiStaMap.set(parseInt(siteId), sprite); } |
| | | const stationIdInt = parseInt(siteId, 10); |
| | | if (!isNaN(stationIdInt)) { this.pixiStaMap.set(stationIdInt, sprite); } |
| | | sprite._stationId = isNaN(stationIdInt) ? null : stationIdInt; |
| | | sprite._baseColor = 0x00ff7f; |
| | | sprite._loopHighlighted = false; |
| | | sprite.interactive = true; |
| | | sprite.buttonMode = true; |
| | | sprite.on('pointerdown', () => { |
| | |
| | | return; |
| | | } |
| | | sprite.tint = color; |
| | | }, |
| | | setStationBaseColor(sprite, color) { |
| | | if (!sprite) { return; } |
| | | sprite._baseColor = color; |
| | | if (this.isStationInHoverLoop(sprite)) { |
| | | this.applyHighlightColor(sprite); |
| | | } else { |
| | | this.updateColor(sprite, color); |
| | | sprite._loopHighlighted = false; |
| | | } |
| | | }, |
| | | applyHighlightColor(sprite) { |
| | | if (!sprite) { return; } |
| | | this.updateColor(sprite, this.loopHighlightColor); |
| | | sprite._loopHighlighted = true; |
| | | }, |
| | | isStationInHoverLoop(sprite) { |
| | | if (!sprite || sprite._stationId == null || !this.hoverLoopStationIdSet) { return false; } |
| | | return this.hoverLoopStationIdSet.has(sprite._stationId); |
| | | }, |
| | | buildStationIdSet(stationIdList) { |
| | | const set = new Set(); |
| | | if (!Array.isArray(stationIdList)) { return set; } |
| | | stationIdList.forEach((id) => { |
| | | const v = parseInt(id, 10); |
| | | if (!isNaN(v)) { set.add(v); } |
| | | }); |
| | | return set; |
| | | }, |
| | | applyLoopStationHighlight() { |
| | | if (!this.pixiStaMap) { return; } |
| | | this.pixiStaMap.forEach((sprite) => { |
| | | if (!sprite) { return; } |
| | | if (this.isStationInHoverLoop(sprite)) { |
| | | this.applyHighlightColor(sprite); |
| | | } else if (sprite._loopHighlighted) { |
| | | const baseColor = (typeof sprite._baseColor === 'number') ? sprite._baseColor : 0xb8b8b8; |
| | | this.updateColor(sprite, baseColor); |
| | | sprite._loopHighlighted = false; |
| | | } |
| | | }); |
| | | }, |
| | | clearLoopStationHighlight() { |
| | | if (this.pixiStaMap) { |
| | | this.pixiStaMap.forEach((sprite) => { |
| | | if (!sprite || !sprite._loopHighlighted) { return; } |
| | | const baseColor = (typeof sprite._baseColor === 'number') ? sprite._baseColor : 0xb8b8b8; |
| | | this.updateColor(sprite, baseColor); |
| | | sprite._loopHighlighted = false; |
| | | }); |
| | | } |
| | | this.hoverLoopNo = null; |
| | | this.hoverLoopStationIdSet = new Set(); |
| | | }, |
| | | handleLoopCardEnter(loopItem) { |
| | | if (!loopItem) { return; } |
| | | this.hoverLoopNo = loopItem.loopNo; |
| | | this.hoverLoopStationIdSet = this.buildStationIdSet(loopItem.stationIdList); |
| | | this.applyLoopStationHighlight(); |
| | | }, |
| | | handleLoopCardLeave(loopItem) { |
| | | if (!loopItem) { |
| | | this.clearLoopStationHighlight(); |
| | | return; |
| | | } |
| | | if (this.hoverLoopNo === loopItem.loopNo) { |
| | | this.clearLoopStationHighlight(); |
| | | } |
| | | }, |
| | | isJson(str) { |
| | | try { JSON.parse(str); return true; } catch (e) { return false; } |
| | |
| | | } |
| | | } |
| | | }); |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |