From dfa40c9b2696748bbf534c37cea3ca0da8e98554 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 04 三月 2026 17:11:45 +0800
Subject: [PATCH] #
---
src/main/webapp/components/MapCanvas.js | 573 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 553 insertions(+), 20 deletions(-)
diff --git a/src/main/webapp/components/MapCanvas.js b/src/main/webapp/components/MapCanvas.js
index c87a755..f04f4ea 100644
--- a/src/main/webapp/components/MapCanvas.js
+++ b/src/main/webapp/components/MapCanvas.js
@@ -1,7 +1,25 @@
Vue.component('map-canvas', {
template: `
<div style="width: 100%; height: 100%; position: relative;">
- <div ref="pixiView"></div>
+ <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 }}
+ </div>
<div style="position: absolute; top: 20px; right: 50px; text-align: right;">
<div>FPS:{{mapFps}}</div>
<div style="margin-top: 6px; display: flex; gap: 6px; justify-content: flex-end;">
@@ -46,6 +64,19 @@
crnList: [],
dualCrnList: [],
rgvList: [],
+ locListMap: new Map(),
+ locListLoaded: false,
+ locListLoading: false,
+ mapRowOffsets: [],
+ mapRowHeights: [],
+ mapColOffsets: [],
+ mapColWidths: [],
+ mapRowColOffsets: [],
+ mapRowColWidths: [],
+ mapRowShelfCells: [],
+ hoveredShelfCell: null,
+ hoverPointer: { x: 0, y: 0 },
+ hoverRaf: null,
objectsContainer: null,
objectsContainer2: null,
tracksContainer: null,
@@ -55,15 +86,35 @@
graphicsCrnTrack: null,
graphicsRgvTrack: null,
graphicsRgv: null,
+ shelfTooltip: {
+ visible: false,
+ x: 0,
+ y: 0,
+ text: '',
+ item: null
+ },
+ shelfTooltipMinScale: 0.4,
+ 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.currentLev = this.lev || 1;
this.createMap();
+ this.startContainerResizeObserve();
this.loadMapTransformConfig();
+ this.loadLocList();
this.connectWs();
setTimeout(() => {
@@ -74,12 +125,16 @@
this.getCrnInfo();
this.getDualCrnInfo();
this.getSiteInfo();
+ this.getCycleCapacityInfo();
this.getRgvInfo();
}, 1000);
},
beforeDestroy() {
if (this.timer) { clearInterval(this.timer); }
+
+ if (this.hoverRaf) { cancelAnimationFrame(this.hoverRaf); this.hoverRaf = null; }
if (this.pixiApp) { this.pixiApp.destroy(true, { children: true }); }
+ if (this.containerResizeObserver) { this.containerResizeObserver.disconnect(); this.containerResizeObserver = null; }
window.removeEventListener('resize', this.resizeToContainer);
if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; }
if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) { try { this.ws.close(); } catch (e) {} }
@@ -158,9 +213,30 @@
this.mapRoot.addChild(this.objectsContainer);
this.mapRoot.addChild(this.objectsContainer2);
this.pixiApp.renderer.roundPixels = true;
+ this.hoveredShelfCell = null;
+ this.hoverPointer = { x: 0, y: 0 };
+ this.hoverRaf = null;
- //*******************鎷栧姩鐢诲竷*******************
+
+ //*******************shelf hover*******************
+ this.pixiApp.renderer.plugins.interaction.on('pointermove', (event) => {
+ if (!this.isShelfTooltipAllowed()) { this.hideShelfTooltip(); return; }
+ if (!this.map || !this.mapRoot) { return; }
+ const pos = event.data.global;
+ this.hoverPointer.x = pos.x;
+ this.hoverPointer.y = pos.y;
+ if (this.hoverRaf) { return; }
+ this.hoverRaf = requestAnimationFrame(() => {
+ this.hoverRaf = null;
+ this.updateShelfHoverFromPointer(this.hoverPointer);
+ });
+ });
+ this.pixiApp.view.addEventListener('mouseleave', () => {
+ this.hoveredShelfCell = null;
+ this.hideShelfTooltip();
+ });
+ //*******************shelf hover*******************
let stageOriginalPos;
let mouseDownPoint;
let touchBlank = false;
@@ -168,7 +244,7 @@
const globalPos = event.data.global;
stageOriginalPos = [this.pixiApp.stage.position.x, this.pixiApp.stage.position.y];
mouseDownPoint = [globalPos.x, globalPos.y];
- if (!event.target) { touchBlank = true; }
+ if (!event.target || (event.target && event.target._kind === 'shelf')) { touchBlank = true; }
});
this.pixiApp.renderer.plugins.interaction.on('pointermove', (event) => {
const globalPos = event.data.global;
@@ -179,7 +255,7 @@
}
});
this.pixiApp.renderer.plugins.interaction.on('pointerup', () => { touchBlank = false; });
- //*******************鎷栧姩鐢诲竷*******************
+
//*******************缂╂斁鐢诲竷*******************
this.pixiApp.view.addEventListener('wheel', (event) => {
@@ -228,11 +304,33 @@
});
//*******************FPS*******************
},
+ startContainerResizeObserve() {
+ if (typeof ResizeObserver === 'undefined' || !this.$el) { return; }
+ this.containerResizeObserver = new ResizeObserver(() => {
+ this.resizeToContainer();
+ });
+ this.containerResizeObserver.observe(this.$el);
+ },
+ getViewportSize() {
+ if (!this.pixiApp || !this.pixiApp.renderer) { return { width: 0, height: 0 }; }
+ const screen = this.pixiApp.renderer.screen;
+ if (screen && screen.width > 0 && screen.height > 0) {
+ return { width: screen.width, height: screen.height };
+ }
+ const rect = this.pixiApp.view ? this.pixiApp.view.getBoundingClientRect() : null;
+ return { width: rect ? rect.width : 0, height: rect ? rect.height : 0 };
+ },
resizeToContainer() {
const w = this.$el.clientWidth || 0;
const h = this.$el.clientHeight || 0;
if (w > 0 && h > 0 && this.pixiApp) {
+ const vw = this.pixiApp.renderer && this.pixiApp.renderer.screen ? this.pixiApp.renderer.screen.width : 0;
+ const vh = this.pixiApp.renderer && this.pixiApp.renderer.screen ? this.pixiApp.renderer.screen.height : 0;
+ if (vw === w && vh === h) { return; }
this.pixiApp.renderer.resize(w, h);
+ if (this.mapContentSize && this.mapContentSize.width > 0 && this.mapContentSize.height > 0) {
+ this.applyMapTransform(true);
+ }
}
},
getMap() {
@@ -240,7 +338,14 @@
},
changeFloor(lev) {
this.currentLev = lev;
+ this.clearLoopStationHighlight();
this.isSwitchingFloor = true;
+ this.hideShelfTooltip();
+ this.hoveredShelfCell = null;
+ this.mapRowOffsets = [];
+ this.mapRowHeights = [];
+ this.mapColOffsets = [];
+ this.mapColWidths = [];
if (this.adjustLabelTimer) { clearTimeout(this.adjustLabelTimer); this.adjustLabelTimer = null; }
this.objectsContainer.removeChildren();
this.objectsContainer2.removeChildren();
@@ -258,6 +363,13 @@
this.getMap();
},
createMapData(map) {
+ this.clearLoopStationHighlight();
+ this.hideShelfTooltip();
+ this.hoveredShelfCell = null;
+ this.mapRowOffsets = [];
+ this.mapRowHeights = [];
+ this.mapColOffsets = [];
+ this.mapColWidths = [];
if (window.gsap) {
this.pixiStaMap && this.pixiStaMap.forEach((s) => { try { window.gsap.killTweensOf(s); } catch (e) {} });
this.pixiCrnMap && this.pixiCrnMap.forEach((s) => { try { window.gsap.killTweensOf(s); } catch (e) {} });
@@ -347,6 +459,8 @@
let val = row[colIndex];
let cellWidth = val.width;
let cellHeight = val.height;
+ val.rowIndex = rowIndex;
+ val.colIndex = colIndex;
if (val.isMergedPart) {
val.posX = anchorX;
val.posY = yOffsets[rowIndex];
@@ -367,12 +481,16 @@
}
});
+ this.buildShelfHitGrid(map, rowHeightScaled, yOffsets);
+
this.drawTracks(map);
map.forEach((item, index) => {
this.pixiStageList[index] = [item.length];
for (let idx = 0; idx < item.length; idx++) {
let val = item[idx];
+ val.rowIndex = index;
+ val.colIndex = idx;
if (val.type === 'merge') { continue; }
if (val.type == undefined || val.type === 'none') { continue; }
if (this.isTrackType(val)) {
@@ -406,7 +524,7 @@
sprite.textObj = text;
sprite.position.set(item.posX, item.posY);
sprite.interactive = true; // 蹇呴』瑕佽缃墠鑳芥帴鏀朵簨浠�
- sprite.buttonMode = true; // 璁╁厜鏍囧湪hover鏃跺彉涓烘墜鍨嬫寚閽�
+ sprite.buttonMode = true; // 璁╁厜鏍囧湪hover鏃跺彉涓烘墜鍨嬫寚浜嬩欢
sprite.on('pointerdown', () => {
if (window.gsap) { window.gsap.killTweensOf(sprite); }
sprite.alpha = 1;
@@ -472,7 +590,7 @@
sprite.textObj = text;
sprite.position.set(item.posX, item.posY);
sprite.interactive = true; // 蹇呴』瑕佽缃墠鑳芥帴鏀朵簨浠�
- sprite.buttonMode = true; // 璁╁厜鏍囧湪hover鏃跺彉涓烘墜鍨嬫寚閽�
+ sprite.buttonMode = true; // 璁╁厜鏍囧湪hover鏃跺彉涓烘墜鍨嬫寚浜嬩欢
sprite.on('pointerdown', () => {
if (window.gsap) { window.gsap.killTweensOf(sprite); }
sprite.alpha = 1;
@@ -560,21 +678,21 @@
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() {
@@ -592,6 +710,38 @@
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);
@@ -747,6 +897,7 @@
if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; }
this.wsReconnectAttempts = 0;
this.getMap(this.currentLev);
+ this.getCycleCapacityInfo();
},
webSocketOnError(e) {
this.scheduleReconnect();
@@ -761,6 +912,8 @@
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));
}
@@ -1108,7 +1261,11 @@
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', () => {
@@ -1310,6 +1467,74 @@
}
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; }
},
@@ -1325,11 +1550,259 @@
getTrackSiteNo(obj) {
if (this.isJson(obj)) { let data = JSON.parse(obj); if (data.trackSiteNo == null || data.trackSiteNo == undefined) { return -1; } return data.trackSiteNo; } else { return -1; }
},
+ buildShelfHitGrid(map, rowHeights, rowOffsets) {
+ if (!map || !Array.isArray(map)) { return; }
+ this.mapRowOffsets = Array.isArray(rowOffsets) ? rowOffsets.slice() : [];
+ this.mapRowHeights = Array.isArray(rowHeights) ? rowHeights.slice() : [];
+ const rowColOffsets = [];
+ const rowColWidths = [];
+ const rowShelfCells = new Array(map.length);
+ let maxCols = 0;
+ for (let r = 0; r < map.length; r++) {
+ const row = map[r];
+ if (row && row.length > maxCols) { maxCols = row.length; }
+ rowShelfCells[r] = [];
+ }
+ const colWidths = new Array(maxCols);
+ for (let c = 0; c < maxCols; c++) {
+ let w = null;
+ for (let r = 0; r < map.length; r++) {
+ const cell = map[r] && map[r][c];
+ if (!cell) { continue; }
+ if (cell.cellWidth != null && cell.cellWidth !== '') {
+ const base = Number(cell.cellWidth);
+ if (isFinite(base) && base > 0) { w = base / 40; break; }
+ }
+ }
+ colWidths[c] = (w && isFinite(w) && w > 0) ? w : 25;
+ }
+ const colOffsets = new Array(maxCols);
+ let xCursor = 0;
+ for (let c = 0; c < maxCols; c++) {
+ colOffsets[c] = xCursor;
+ xCursor += colWidths[c];
+ }
+ for (let r = 0; r < map.length; r++) {
+ const row = map[r];
+ if (!row || row.length === 0) {
+ rowColOffsets[r] = [];
+ rowColWidths[r] = [];
+ continue;
+ }
+ const widths = new Array(row.length);
+ for (let c = 0; c < row.length; c++) {
+ const cell = row[c];
+ let w = null;
+ if (cell && cell.cellWidth != null && cell.cellWidth !== '') {
+ const base = Number(cell.cellWidth);
+ if (isFinite(base) && base > 0) { w = base / 40; }
+ }
+ widths[c] = (w && isFinite(w) && w > 0) ? w : 25;
+ }
+ const offsets = new Array(row.length);
+ let x = 0;
+ for (let c = 0; c < row.length; c++) {
+ offsets[c] = x;
+ x += widths[c];
+ }
+ rowColOffsets[r] = offsets;
+ rowColWidths[r] = widths;
+ }
+ this.mapColWidths = colWidths;
+ this.mapColOffsets = colOffsets;
+ this.mapRowColOffsets = rowColOffsets;
+ this.mapRowColWidths = rowColWidths;
+ this.mapRowShelfCells = rowShelfCells;
+
+ for (let r = 0; r < map.length; r++) {
+ const row = map[r];
+ if (!row) { continue; }
+ for (let c = 0; c < row.length; c++) {
+ const cell = row[c];
+ if (!cell || cell.type !== 'shelf') { continue; }
+ const startRow = this.findIndexByOffsets(this.mapRowOffsets, this.mapRowHeights, cell.posY + 0.01);
+ const endRow = this.findIndexByOffsets(this.mapRowOffsets, this.mapRowHeights, cell.posY + cell.height - 0.01);
+ if (startRow < 0) { continue; }
+ const last = endRow >= 0 ? endRow : startRow;
+ for (let rr = startRow; rr <= last; rr++) {
+ if (!rowShelfCells[rr]) { rowShelfCells[rr] = []; }
+ rowShelfCells[rr].push(cell);
+ }
+ }
+ }
+ },
+ findIndexByOffsets(offsets, sizes, value) {
+ if (!offsets || !sizes || offsets.length === 0) { return -1; }
+ for (let i = 0; i < offsets.length; i++) {
+ const start = offsets[i];
+ const end = start + (sizes[i] || 0);
+ if (value >= start && value < end) { return i; }
+ }
+ return -1;
+ },
+ updateShelfHoverFromPointer(globalPos) {
+ if (!this.map || !this.mapRoot) { return; }
+ if (!this.mapRowOffsets.length || !this.mapColOffsets.length) { return; }
+ const local = this.mapRoot.toLocal(new PIXI.Point(globalPos.x, globalPos.y));
+ const rowIndex = this.findIndexByOffsets(this.mapRowOffsets, this.mapRowHeights, local.y);
+ if (rowIndex < 0) { if (this.hoveredShelfCell) { this.hoveredShelfCell = null; this.hideShelfTooltip(); } return; }
+ let cell = null;
+ if (this.mapRowShelfCells && this.mapRowShelfCells[rowIndex]) {
+ const list = this.mapRowShelfCells[rowIndex];
+ for (let i = 0; i < list.length; i++) {
+ const it = list[i];
+ if (!it) { continue; }
+ if (local.x >= it.posX && local.x < it.posX + it.width &&
+ local.y >= it.posY && local.y < it.posY + it.height) {
+ cell = it;
+ break;
+ }
+ }
+ }
+ if (!cell || cell.type !== 'shelf') { if (this.hoveredShelfCell) { this.hoveredShelfCell = null; this.hideShelfTooltip(); } return; }
+ if (this.hoveredShelfCell !== cell) {
+ this.hoveredShelfCell = cell;
+ this.shelfTooltip.item = cell;
+ this.shelfTooltip.text = this.getShelfArrangeInfo(cell);
+ this.shelfTooltip.visible = true;
+ }
+ this.updateShelfTooltipPositionByGlobal(globalPos);
+ },
+ normalizeLocTypeKey(value) {
+ if (value == null) { return null; }
+ const str = String(value).trim();
+ if (!str) { return null; }
+ const parts = str.split('-').filter(p => p !== '');
+ if (parts.length >= 3) { return parts.slice(0, parts.length - 1).join('-'); }
+ return str;
+ },
+ loadLocList() {
+ if (!window.$ || typeof baseUrl === 'undefined') { return; }
+ if (this.locListLoading) { return; }
+ this.locListLoading = true;
+ $.ajax({
+ url: baseUrl + "/console/map/locList",
+ headers: { 'token': localStorage.getItem('token') },
+ dataType: 'json',
+ method: 'GET',
+ success: (res) => {
+ if (res && !Array.isArray(res)) {
+ if (res.code === 403) { parent.location.href = baseUrl + "/login"; return; }
+ if (res.code !== 200) { return; }
+ }
+ const list = Array.isArray(res) ? res : (res && res.code === 200 ? res.data : null);
+ if (!list || !Array.isArray(list)) { return; }
+ const map = new Map();
+ list.forEach((item) => {
+ if (!item) { return; }
+ const locType = item.locType != null ? item.locType : item.loc_type;
+ if (locType != null && locType !== '') {
+ const normalizedType = this.normalizeLocTypeKey(locType);
+ if (normalizedType && !map.has(normalizedType)) { map.set(normalizedType, item); }
+ }
+ });
+ this.locListMap = map;
+ this.locListLoaded = true;
+ if (this.shelfTooltip.visible) {
+ this.shelfTooltip.text = this.getShelfArrangeInfo(this.shelfTooltip.item);
+ }
+ },
+ complete: () => {
+ this.locListLoading = false;
+ }
+ });
+ },
+ showShelfTooltip(e, item) {
+ if (!item) { return; }
+ if (!this.isShelfTooltipAllowed()) { this.hideShelfTooltip(); return; }
+ if (!this.locListLoaded && !this.locListLoading) { this.loadLocList(); }
+ this.shelfTooltip.item = item;
+ this.shelfTooltip.text = this.getShelfArrangeInfo(item);
+ this.updateShelfTooltipPosition(e);
+ this.shelfTooltip.visible = true;
+ },
+ updateShelfTooltipPosition(e) {
+ if (!e || !e.data || !e.data.global) { return; }
+ this.updateShelfTooltipPositionByGlobal(e.data.global);
+ },
+ updateShelfTooltipPositionByGlobal(globalPos) {
+ if (!this.isShelfTooltipAllowed()) { this.hideShelfTooltip(); return; }
+ if (!globalPos) { return; }
+ this.shelfTooltip.x = globalPos.x + 12;
+ this.shelfTooltip.y = globalPos.y + 12;
+ },
+ hideShelfTooltip() {
+ this.shelfTooltip.visible = false;
+ this.shelfTooltip.item = null;
+ },
+ isShelfTooltipAllowed() {
+ return this.getStageAbsScale() >= this.shelfTooltipMinScale;
+ },
+ getStageAbsScale() {
+ if (!this.pixiApp || !this.pixiApp.stage) { return 1; }
+ return Math.abs(this.pixiApp.stage.scale.x || 1);
+ },
+ updateShelfTooltipVisibilityByScale() {
+ if (this.shelfTooltip.visible && !this.isShelfTooltipAllowed()) {
+ this.hideShelfTooltip();
+ this.hoveredShelfCell = null;
+ }
+ },
+ getShelfArrangeInfo(item) {
+ const parts = [];
+ const matchKey = this.getShelfMatchKey(item);
+ if (matchKey != null) { parts.push('鍧愭爣:' + matchKey); }
+ const locInfo = (matchKey != null) ? this.locListMap.get(matchKey) : null;
+ if (locInfo) {
+ const locNo = locInfo.locNo != null ? locInfo.locNo : locInfo.loc_no;
+ const displayLocNo = this.stripLocLayer(locNo);
+ if (displayLocNo != null) { parts.push('鎺掑垪:' + displayLocNo); }
+ }
+ return parts.join(' ');
+ },
+ getShelfMatchKey(item) {
+ if (!item) { return null; }
+ const direct = item.locType != null ? item.locType : (item.loc_type != null ? item.loc_type : null);
+ const directKey = this.normalizeLocTypeKey(direct);
+ if (directKey) { return directKey; }
+ const rowIndex = item.rowIndex;
+ const colIndex = item.colIndex;
+ if (rowIndex == null || colIndex == null) { return null; }
+ const key0 = rowIndex + '-' + colIndex;
+ if (this.locListLoaded && this.locListMap && this.locListMap.size > 0) {
+ if (this.locListMap.has(key0)) { return key0; }
+ }
+ return null;
+ },
+ stripLocLayer(locNo) {
+ if (locNo == null) { return null; }
+ const str = String(locNo).trim();
+ if (!str) { return null; }
+ const parts = str.split('-').filter(p => p !== '');
+ if (parts.length >= 3) { return parts.slice(0, parts.length - 1).join('-'); }
+ return str;
+ },
+ shelfTooltipStyle() {
+ return {
+ position: 'absolute',
+ left: this.shelfTooltip.x + 'px',
+ top: this.shelfTooltip.y + 'px',
+ background: 'rgba(0,0,0,0.75)',
+ color: '#ffffff',
+ padding: '4px 8px',
+ borderRadius: '4px',
+ fontSize: '12px',
+ pointerEvents: 'none',
+ whiteSpace: 'nowrap',
+ zIndex: 10
+ };
+ },
adjustLabelScale() {
const s = this.pixiApp && this.pixiApp.stage ? Math.abs(this.pixiApp.stage.scale.x || 1) : 1;
const minPx = 14;
- const vw = this.pixiApp.view.width;
- const vh = this.pixiApp.view.height;
+ const viewport = this.getViewportSize();
+ const vw = viewport.width;
+ const vh = viewport.height;
const margin = 50;
const mirrorSign = this.mapMirrorX ? -1 : 1;
const inverseRotation = -((this.mapRotation % 360) * Math.PI / 180);
@@ -1507,8 +1980,9 @@
const contentW = size.width || 0;
const contentH = size.height || 0;
if (contentW <= 0 || contentH <= 0) { return; }
- const vw = this.pixiApp.view.width;
- const vh = this.pixiApp.view.height;
+ const viewport = this.getViewportSize();
+ const vw = viewport.width;
+ const vh = viewport.height;
let scale = Math.min(vw / contentW, vh / contentH) * 0.95;
if (!isFinite(scale) || scale <= 0) { scale = 1; }
const baseW = this.mapContentSize.width || contentW;
@@ -1536,8 +2010,67 @@
if (this.adjustLabelTimer) { clearTimeout(this.adjustLabelTimer); }
this.adjustLabelTimer = setTimeout(() => {
this.adjustLabelScale();
+ this.updateShelfTooltipVisibilityByScale();
this.adjustLabelTimer = null;
}, 20);
}
}
});
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--
Gitblit v1.9.1