From c5d7868e9e5fb8013edb088a70e75fc83d575690 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期六, 07 三月 2026 10:36:05 +0800
Subject: [PATCH] #
---
src/main/webapp/components/MapCanvas.js | 987 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 868 insertions(+), 119 deletions(-)
diff --git a/src/main/webapp/components/MapCanvas.js b/src/main/webapp/components/MapCanvas.js
index 3147540..b5ced58 100644
--- a/src/main/webapp/components/MapCanvas.js
+++ b/src/main/webapp/components/MapCanvas.js
@@ -1,21 +1,55 @@
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="cycleCapacityPanelStyle()">
+ <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;">
- <button type="button" @click="rotateMap" style="padding: 2px 8px; font-size: 12px; cursor: pointer;">鏃嬭浆</button>
- <button type="button" @click="toggleMirror" style="padding: 2px 8px; font-size: 12px; cursor: pointer;">{{ mapMirrorX ? '鍙栨秷闀滃儚' : '闀滃儚' }}</button>
+ <div style="position: absolute; top: 18px; right: 34px; z-index: 30; display: flex; flex-direction: column; align-items: flex-end; gap: 8px;">
+ <div :style="mapToolFpsStyle()">FPS {{ mapFps }}</div>
+ <button type="button" @click="toggleMapToolPanel" :style="mapToolToggleStyle(showMapToolPanel)">{{ showMapToolPanel ? '鏀惰捣鎿嶄綔' : '鍦板浘鎿嶄綔' }}</button>
+ <div v-show="showMapToolPanel" :style="mapToolBarStyle()">
+ <div :style="mapToolRowStyle()">
+ <button type="button" @click="toggleStationDirection" :style="mapToolButtonStyle(showStationDirection)">{{ showStationDirection ? '闅愯棌绔欑偣鏂瑰悜' : '鏄剧ず绔欑偣鏂瑰悜' }}</button>
+ <button type="button" @click="resetMapView" :style="mapToolButtonStyle(false)">閲嶇疆瑙嗗浘</button>
+ <button type="button" @click="rotateMap" :style="mapToolButtonStyle(false)">鏃嬭浆</button>
+ <button type="button" @click="toggleMirror" :style="mapToolButtonStyle(mapMirrorX)">{{ mapMirrorX ? '鍙栨秷闀滃儚' : '闀滃儚' }}</button>
+ </div>
+ <div :style="mapToolRowStyle()">
+ <button type="button" @click="openStationColorConfigPage" :style="mapToolButtonStyle(false)">绔欑偣棰滆壊</button>
+ </div>
+ <div v-if="levList && levList.length > 1" :style="mapToolFloorSectionStyle()">
+ <div :style="mapToolSectionLabelStyle()">妤煎眰</div>
+ <div :style="mapToolFloorListStyle()">
+ <button
+ v-for="floor in levList"
+ :key="'tool-floor-' + floor"
+ type="button"
+ @click="selectFloorFromTool(floor)"
+ :style="mapToolFloorButtonStyle(currentLev == floor)"
+ >{{ floor }}F</button>
+ </div>
+ </div>
</div>
</div>
</div>
`,
- props: ['lev', 'crnParam', 'rgvParam', 'devpParam', 'highlightOnParamChange'],
+ props: ['lev', 'levList', 'crnParam', 'rgvParam', 'devpParam', 'stationTaskRange', 'highlightOnParamChange', 'viewportPadding', 'hudPadding'],
data() {
return {
map: [],
@@ -47,6 +81,10 @@
pixiDevpTextureMap: new Map(),
pixiCrnColorTextureMap: new Map(),
pixiRgvColorTextureMap: new Map(),
+ shelfChunkList: [],
+ shelfChunkSize: 2048,
+ shelfCullPadding: 160,
+ shelfCullRaf: null,
crnList: [],
dualCrnList: [],
rgvList: [],
@@ -80,18 +118,44 @@
item: null
},
shelfTooltipMinScale: 0.4,
+ containerResizeObserver: null,
timer: null,
adjustLabelTimer: null,
- isSwitchingFloor: false
+ isSwitchingFloor: false,
+ cycleCapacity: {
+ loopList: [],
+ totalStationCount: 0,
+ taskStationCount: 0,
+ currentLoad: 0
+ },
+ showMapToolPanel: false,
+ showStationDirection: false,
+ hoverLoopNo: null,
+ hoverLoopStationIdSet: new Set(),
+ loopHighlightColor: 0xfff34d,
+ stationDirectionColor: 0xff5a36,
+ stationStatusColors: {
+ 'site-auto': 0x78ff81,
+ 'site-auto-run': 0xfa51f6,
+ 'site-auto-id': 0xc4c400,
+ 'site-auto-run-id': 0x30bffc,
+ 'site-enable-in': 0xA81DEE,
+ 'site-unauto': 0xb8b8b8,
+ 'machine-pakin': 0x30bffc,
+ 'machine-pakout': 0x97b400,
+ 'site-run-block': 0xe69138
+ }
}
},
mounted() {
this.currentLev = this.lev || 1;
this.createMap();
+ this.startContainerResizeObserve();
this.loadMapTransformConfig();
+ this.loadStationColorConfig();
this.loadLocList();
this.connectWs();
-
+
setTimeout(() => {
this.getMap(this.currentLev);
}, 1000);
@@ -100,6 +164,7 @@
this.getCrnInfo();
this.getDualCrnInfo();
this.getSiteInfo();
+ this.getCycleCapacityInfo();
this.getRgvInfo();
}, 1000);
},
@@ -107,7 +172,10 @@
if (this.timer) { clearInterval(this.timer); }
if (this.hoverRaf) { cancelAnimationFrame(this.hoverRaf); this.hoverRaf = null; }
+ if (this.shelfCullRaf) { cancelAnimationFrame(this.shelfCullRaf); this.shelfCullRaf = null; }
+ if (window.gsap && this.pixiApp && this.pixiApp.stage) { window.gsap.killTweensOf(this.pixiApp.stage.position); }
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) {} }
@@ -115,6 +183,14 @@
watch: {
lev(newLev) {
if (newLev != null) { this.changeFloor(newLev); }
+ },
+ viewportPadding: {
+ deep: true,
+ handler(newVal, oldVal) {
+ if (this.mapContentSize && this.mapContentSize.width > 0 && this.mapContentSize.height > 0) {
+ this.adjustStageForViewportPadding(oldVal, newVal);
+ }
+ }
},
crnParam: {
deep: true,
@@ -160,6 +236,139 @@
}
},
methods: {
+ cycleCapacityPanelStyle() {
+ const hud = this.hudPadding || {};
+ const left = Math.max(14, Number(hud.left) || 0);
+ const rightReserve = 220;
+ return {
+ position: 'absolute',
+ top: '12px',
+ left: left + 'px',
+ zIndex: 30,
+ pointerEvents: 'none',
+ maxWidth: 'calc(100% - ' + (left + rightReserve) + 'px)'
+ };
+ },
+ mapToolBarStyle() {
+ return {
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '8px',
+ alignItems: 'stretch',
+ padding: '7px',
+ borderRadius: '14px',
+ background: 'rgba(255, 255, 255, 0.72)',
+ border: '1px solid rgba(160, 180, 205, 0.3)',
+ boxShadow: '0 8px 20px rgba(37, 64, 97, 0.08)',
+ backdropFilter: 'blur(4px)'
+ };
+ },
+ mapToolRowStyle() {
+ return {
+ display: 'flex',
+ gap: '8px',
+ alignItems: 'center',
+ justifyContent: 'flex-end',
+ flexWrap: 'wrap'
+ };
+ },
+ mapToolFloorSectionStyle() {
+ return {
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '4px',
+ paddingTop: '6px',
+ borderTop: '1px solid rgba(160, 180, 205, 0.22)'
+ };
+ },
+ mapToolSectionLabelStyle() {
+ return {
+ color: '#6a7f95',
+ fontSize: '10px',
+ lineHeight: '14px',
+ textAlign: 'right'
+ };
+ },
+ mapToolFloorListStyle() {
+ return {
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '4px',
+ alignItems: 'stretch'
+ };
+ },
+ mapToolFpsStyle() {
+ return {
+ padding: '4px 10px',
+ borderRadius: '999px',
+ background: 'rgba(255, 255, 255, 0.7)',
+ border: '1px solid rgba(160, 180, 205, 0.28)',
+ color: '#48617c',
+ fontSize: '12px',
+ lineHeight: '18px',
+ letterSpacing: '0.04em',
+ boxShadow: '0 6px 16px rgba(37, 64, 97, 0.06)',
+ userSelect: 'none'
+ };
+ },
+ mapToolToggleStyle(active) {
+ return {
+ appearance: 'none',
+ border: '1px solid ' + (active ? 'rgba(96, 132, 170, 0.36)' : 'rgba(160, 180, 205, 0.3)'),
+ background: active ? 'rgba(235, 243, 251, 0.96)' : 'rgba(255, 255, 255, 0.82)',
+ color: '#46617b',
+ height: '30px',
+ padding: '0 12px',
+ borderRadius: '999px',
+ fontSize: '12px',
+ lineHeight: '30px',
+ cursor: 'pointer',
+ whiteSpace: 'nowrap',
+ boxShadow: '0 6px 16px rgba(37, 64, 97, 0.06)'
+ };
+ },
+ mapToolButtonStyle(active) {
+ return {
+ appearance: 'none',
+ border: '1px solid ' + (active ? 'rgba(255, 136, 93, 0.38)' : 'rgba(160, 180, 205, 0.3)'),
+ background: active ? 'rgba(255, 119, 77, 0.16)' : 'rgba(255, 255, 255, 0.88)',
+ color: active ? '#d85a31' : '#4d647d',
+ height: '30px',
+ padding: '0 12px',
+ borderRadius: '10px',
+ fontSize: '12px',
+ lineHeight: '30px',
+ cursor: 'pointer',
+ transition: 'all 0.2s ease',
+ boxShadow: active ? '0 4px 10px rgba(255, 119, 77, 0.12)' : 'none',
+ whiteSpace: 'nowrap'
+ };
+ },
+ mapToolFloorButtonStyle(active) {
+ return {
+ appearance: 'none',
+ border: '1px solid ' + (active ? 'rgba(96, 132, 170, 0.36)' : 'rgba(160, 180, 205, 0.3)'),
+ background: active ? 'rgba(235, 243, 251, 0.96)' : 'rgba(255, 255, 255, 0.88)',
+ color: active ? '#27425c' : '#4d647d',
+ minWidth: '44px',
+ height: '26px',
+ padding: '0 10px',
+ borderRadius: '8px',
+ fontSize: '11px',
+ lineHeight: '26px',
+ cursor: 'pointer',
+ fontWeight: '700',
+ boxShadow: active ? '0 4px 12px rgba(37, 64, 97, 0.08)' : 'none',
+ whiteSpace: 'nowrap'
+ };
+ },
+ toggleMapToolPanel() {
+ this.showMapToolPanel = !this.showMapToolPanel;
+ },
+ selectFloorFromTool(lev) {
+ if (lev == null || lev === this.currentLev) { return; }
+ this.$emit('switch-lev', lev);
+ },
createMap() {
this.pixiApp = new PIXI.Application({ backgroundColor: 0xF5F7F9, antialias: false, powerPreference: 'high-performance', autoDensity: true, resolution: Math.min(window.devicePixelRatio || 1, 2) });
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.LINEAR;
@@ -175,9 +384,8 @@
this.objectsContainer2 = new PIXI.Container();
this.tracksContainer = new PIXI.ParticleContainer(10000, { scale: true, position: true, rotation: false, uvs: false, alpha: false });
this.tracksGraphics = new PIXI.Graphics();
- this.shelvesContainer = new PIXI.ParticleContainer(10000, { scale: true, position: true, rotation: false, uvs: false, alpha: false });
+ this.shelvesContainer = new PIXI.Container();
this.tracksContainer.autoResize = true;
- this.shelvesContainer.autoResize = true;
this.mapRoot = new PIXI.Container();
this.pixiApp.stage.addChild(this.mapRoot);
this.mapRoot.addChild(this.tracksGraphics);
@@ -225,6 +433,7 @@
const dx = globalPos.x - mouseDownPoint[0];
const dy = globalPos.y - mouseDownPoint[1];
this.pixiApp.stage.position.set(stageOriginalPos[0] + dx, stageOriginalPos[1] + dy);
+ this.scheduleShelfChunkCulling();
}
});
this.pixiApp.renderer.plugins.interaction.on('pointerup', () => { touchBlank = false; });
@@ -250,7 +459,8 @@
const newPosX = sx - worldX * newZoomX;
const newPosY = sy - worldY * newZoomY;
this.pixiApp.stage.setTransform(newPosX, newPosY, newZoomX, newZoomY, 0, 0, 0, 0, 0);
- this.scheduleAdjustLabels();
+ this.scheduleAdjustLabels();
+ this.scheduleShelfChunkCulling();
});
//*******************缂╂斁鐢诲竷*******************
@@ -277,11 +487,94 @@
});
//*******************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 };
+ },
+ getViewportPadding() {
+ return this.normalizeViewportPadding(this.viewportPadding);
+ },
+ normalizeViewportPadding(padding) {
+ const source = padding || {};
+ const normalize = (value) => {
+ const num = Number(value);
+ return isFinite(num) && num > 0 ? num : 0;
+ };
+ return {
+ top: normalize(source.top),
+ right: normalize(source.right),
+ bottom: normalize(source.bottom),
+ left: normalize(source.left)
+ };
+ },
+ getViewportCenter(viewport, padding) {
+ const normalized = this.normalizeViewportPadding(padding);
+ const availableW = Math.max(1, viewport.width - normalized.left - normalized.right);
+ const availableH = Math.max(1, viewport.height - normalized.top - normalized.bottom);
+ return {
+ x: normalized.left + availableW / 2,
+ y: normalized.top + availableH / 2
+ };
+ },
+ adjustStageForViewportPadding(oldPadding, newPadding) {
+ if (!this.pixiApp || !this.pixiApp.stage) { return; }
+ const viewport = this.getViewportSize();
+ if (viewport.width <= 0 || viewport.height <= 0) { return; }
+ const prevCenter = this.getViewportCenter(viewport, oldPadding);
+ const nextCenter = this.getViewportCenter(viewport, newPadding);
+ const deltaX = nextCenter.x - prevCenter.x;
+ const deltaY = nextCenter.y - prevCenter.y;
+ if (Math.abs(deltaX) < 0.5 && Math.abs(deltaY) < 0.5) {
+ return;
+ }
+ const targetX = this.pixiApp.stage.position.x + deltaX;
+ const targetY = this.pixiApp.stage.position.y + deltaY;
+ if (window.gsap) {
+ window.gsap.killTweensOf(this.pixiApp.stage.position);
+ window.gsap.to(this.pixiApp.stage.position, {
+ x: targetX,
+ y: targetY,
+ duration: 0.18,
+ ease: 'power1.out',
+ onUpdate: () => {
+ this.scheduleAdjustLabels();
+ this.scheduleShelfChunkCulling();
+ },
+ onComplete: () => {
+ this.scheduleAdjustLabels();
+ this.scheduleShelfChunkCulling();
+ }
+ });
+ return;
+ }
+ this.pixiApp.stage.position.x = targetX;
+ this.pixiApp.stage.position.y = targetY;
+ this.scheduleAdjustLabels();
+ this.scheduleShelfChunkCulling();
+ },
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() {
@@ -289,6 +582,7 @@
},
changeFloor(lev) {
this.currentLev = lev;
+ this.clearLoopStationHighlight();
this.isSwitchingFloor = true;
this.hideShelfTooltip();
this.hoveredShelfCell = null;
@@ -301,7 +595,7 @@
this.objectsContainer2.removeChildren();
if (this.tracksContainer) { this.tracksContainer.removeChildren(); }
if (this.tracksGraphics) { this.tracksGraphics.clear(); }
- if (this.shelvesContainer) { this.shelvesContainer.removeChildren(); }
+ this.clearShelfChunks();
this.crnList = [];
this.dualCrnList = [];
this.rgvList = [];
@@ -313,6 +607,7 @@
this.getMap();
},
createMapData(map) {
+ this.clearLoopStationHighlight();
this.hideShelfTooltip();
this.hoveredShelfCell = null;
this.mapRowOffsets = [];
@@ -329,7 +624,7 @@
this.objectsContainer2.removeChildren();
if (this.tracksContainer) { this.tracksContainer.removeChildren(); }
if (this.tracksGraphics) { this.tracksGraphics.clear(); }
- if (this.shelvesContainer) { this.shelvesContainer.removeChildren(); }
+ this.clearShelfChunks();
this.crnList = [];
this.dualCrnList = [];
this.rgvList = [];
@@ -430,6 +725,14 @@
}
});
+ map.forEach((row, rowIndex) => {
+ for (let colIndex = 0; colIndex < row.length; colIndex++) {
+ const val = row[colIndex];
+ if (!val || val.type !== 'devp' || val.type === 'merge') { continue; }
+ val.stationDirectionList = this.resolveStationDirectionList(map, rowIndex, colIndex, val);
+ }
+ });
+
this.buildShelfHitGrid(map, rowHeightScaled, yOffsets);
this.drawTracks(map);
@@ -446,15 +749,12 @@
this.collectTrackItem(val);
continue;
}
+ if (val.type === 'shelf') { continue; }
let sprite = this.getSprite(val, (e) => {
//鍥炶皟
});
if (sprite == null) { continue; }
- if (sprite._kind === 'shelf') {
- this.shelvesContainer.addChild(sprite);
- } else {
- this.objectsContainer.addChild(sprite);
- }
+ this.objectsContainer.addChild(sprite);
this.pixiStageList[index][idx] = sprite;
}
});
@@ -571,6 +871,7 @@
}
}
this.mapContentSize = { width: contentW, height: contentH };
+ this.buildShelfChunks(map, contentW, contentH);
this.applyMapTransform(true);
this.map = map;
this.isSwitchingFloor = false;
@@ -616,7 +917,6 @@
if (!sites) { return; }
sites.forEach((item) => {
let id = item.siteId != null ? item.siteId : item.stationId;
- let status = item.siteStatus != null ? item.siteStatus : item.stationStatus;
let workNo = item.workNo != null ? item.workNo : item.taskNo;
if (id == null) { return; }
let sta = this.pixiStaMap.get(parseInt(id));
@@ -627,21 +927,7 @@
sta.statusObj = null;
if (sta.textObj.parent !== sta) { sta.addChild(sta.textObj); sta.textObj.position.set(sta.width / 2, sta.height / 2); }
}
- if (status === "site-auto") {
- this.updateColor(sta, 0x78ff81);
- } else if (status === "site-auto-run" || status === "site-auto-id" || status === "site-auto-run-id") {
- this.updateColor(sta, 0xfa51f6);
- } else if (status === "site-unauto") {
- this.updateColor(sta, 0xb8b8b8);
- } else if (status === "machine-pakin") {
- this.updateColor(sta, 0x30bffc);
- } else if (status === "machine-pakout") {
- this.updateColor(sta, 0x97b400);
- } else if (status === "site-run-block") {
- this.updateColor(sta, 0xe69138);
- } else {
- this.updateColor(sta, 0xb8b8b8);
- }
+ this.setStationBaseColor(sta, this.getStationStatusColor(this.resolveStationStatus(item)));
});
},
getCrnInfo() {
@@ -659,6 +945,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);
@@ -814,6 +1132,7 @@
if (this.wsReconnectTimer) { clearTimeout(this.wsReconnectTimer); this.wsReconnectTimer = null; }
this.wsReconnectAttempts = 0;
this.getMap(this.currentLev);
+ this.getCycleCapacityInfo();
},
webSocketOnError(e) {
this.scheduleReconnect();
@@ -828,6 +1147,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));
}
@@ -1136,6 +1457,49 @@
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
return brightness > 150 ? '#000000' : '#ffffff';
},
+ getStationStatusColor(status) {
+ const colorMap = this.stationStatusColors || this.getDefaultStationStatusColors();
+ if (status && colorMap[status] != null) { return colorMap[status]; }
+ return colorMap['site-unauto'] != null ? colorMap['site-unauto'] : 0xb8b8b8;
+ },
+ resolveStationStatus(item) {
+ const status = item && (item.siteStatus != null ? item.siteStatus : item.stationStatus);
+ const taskNo = this.parseStationTaskNo(item && (item.workNo != null ? item.workNo : item.taskNo));
+ const autoing = !!(item && item.autoing);
+ const loading = !!(item && item.loading);
+ const runBlock = !!(item && item.runBlock);
+ const enableIn = !!(item && item.enableIn);
+ if (taskNo === 9998 || enableIn) { return 'site-enable-in'; }
+ if (autoing && loading && taskNo > 0 && !runBlock) {
+ const taskClass = this.getStationTaskClass(taskNo);
+ if (taskClass) { return taskClass; }
+ }
+ if (status) { return status; }
+ if (autoing && loading && taskNo > 0 && runBlock) { return 'site-run-block'; }
+ if (autoing && loading && taskNo > 0) { return 'site-auto-run-id'; }
+ if (autoing && loading) { return 'site-auto-run'; }
+ if (autoing && taskNo > 0) { return 'site-auto-id'; }
+ if (autoing) { return 'site-auto'; }
+ return 'site-unauto';
+ },
+ parseStationTaskNo(value) {
+ const taskNo = parseInt(value, 10);
+ return isNaN(taskNo) ? 0 : taskNo;
+ },
+ getStationTaskClass(taskNo) {
+ if (!(taskNo > 0)) { return null; }
+ const range = this.stationTaskRange || {};
+ if (this.isTaskNoInRange(taskNo, range.inbound)) { return 'machine-pakin'; }
+ if (this.isTaskNoInRange(taskNo, range.outbound)) { return 'machine-pakout'; }
+ return null;
+ },
+ isTaskNoInRange(taskNo, range) {
+ if (!range) { return false; }
+ const start = parseInt(range.start, 10);
+ const end = parseInt(range.end, 10);
+ if (isNaN(start) || isNaN(end)) { return false; }
+ return taskNo >= start && taskNo <= end;
+ },
getCrnStatusColor(status) {
if (status === "machine-auto") { return 0x21BA45; }
if (status === "machine-un-auto") { return 0xBBBBBB; }
@@ -1167,6 +1531,13 @@
}
sprite = new PIXI.Sprite(texture);
sprite._kind = 'devp';
+ const directionOverlay = this.createStationDirectionOverlay(item.width, item.height, item.stationDirectionList);
+ if (directionOverlay) {
+ directionOverlay.visible = this.showStationDirection;
+ sprite.addChild(directionOverlay);
+ }
+ sprite.directionObj = directionOverlay;
+ sprite._stationDirectionList = Array.isArray(item.stationDirectionList) ? item.stationDirectionList.slice() : [];
let siteId = this.getStationId(value);
if (siteId === -1) { siteId = item.data; }
const style = new PIXI.TextStyle({ fontFamily: 'Arial', fontSize: 10, fill: '#000000', stroke: '#ffffff', strokeThickness: 1 });
@@ -1175,7 +1546,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', () => {
@@ -1377,6 +1752,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; }
},
@@ -1388,6 +1831,132 @@
},
getStationId(obj) {
if (this.isJson(obj)) { let data = JSON.parse(obj); if (data.stationId == null || data.stationId == undefined) { return -1; } return data.stationId; } else { return -1; }
+ },
+ parseMapValue(obj) {
+ if (obj == null) { return null; }
+ if (typeof obj === 'object') { return obj; }
+ if (!this.isJson(obj)) { return null; }
+ try {
+ return JSON.parse(obj);
+ } catch (e) {
+ return null;
+ }
+ },
+ normalizeDirectionList(direction) {
+ const aliasMap = {
+ top: 'top',
+ up: 'top',
+ north: 'top',
+ bottom: 'bottom',
+ down: 'bottom',
+ south: 'bottom',
+ left: 'left',
+ west: 'left',
+ right: 'right',
+ east: 'right'
+ };
+ let rawList = [];
+ if (Array.isArray(direction)) {
+ rawList = direction;
+ } else if (typeof direction === 'string') {
+ rawList = direction.split(/[,\s|/]+/);
+ }
+ const result = [];
+ const seen = new Set();
+ rawList.forEach((item) => {
+ const key = aliasMap[String(item || '').trim().toLowerCase()];
+ if (!key || seen.has(key)) { return; }
+ seen.add(key);
+ result.push(key);
+ });
+ return result;
+ },
+ resolveStationDirectionList(map, rowIndex, colIndex, item) {
+ const valueObj = this.parseMapValue(item && item.value);
+ const fromValue = this.normalizeDirectionList(valueObj && valueObj.direction);
+ if (fromValue.length > 0) { return fromValue; }
+ const rowSpan = item && item.rowSpan ? item.rowSpan : 1;
+ const colSpan = item && item.colSpan ? item.colSpan : 1;
+ const fallback = [];
+ const candidateList = [
+ { key: 'top', cell: this.resolveMergedCell(map, rowIndex - 1, colIndex) },
+ { key: 'right', cell: this.resolveMergedCell(map, rowIndex, colIndex + colSpan) },
+ { key: 'bottom', cell: this.resolveMergedCell(map, rowIndex + rowSpan, colIndex) },
+ { key: 'left', cell: this.resolveMergedCell(map, rowIndex, colIndex - 1) }
+ ];
+ candidateList.forEach((candidate) => {
+ if (this.isStationDirectionNeighbor(candidate.cell)) {
+ fallback.push(candidate.key);
+ }
+ });
+ return fallback;
+ },
+ isStationDirectionNeighbor(cell) {
+ if (!cell) { return false; }
+ if (cell.type === 'devp') { return true; }
+ return this.isTrackType(cell);
+ },
+ createStationDirectionOverlay(width, height, directionList) {
+ if (!Array.isArray(directionList) || directionList.length === 0) { return null; }
+ const container = new PIXI.Container();
+ const arrowSize = Math.max(4, Math.min(width, height) * 0.22);
+ const margin = Math.max(2, Math.min(width, height) * 0.12);
+ directionList.forEach((direction) => {
+ const arrow = new PIXI.Graphics();
+ this.drawStationDirectionArrow(arrow, width, height, direction, arrowSize, margin);
+ container.addChild(arrow);
+ });
+ return container;
+ },
+ drawStationDirectionArrow(graphics, width, height, direction, size, margin) {
+ if (!graphics) { return; }
+ const halfBase = Math.max(2, size * 0.45);
+ const stemLen = Math.max(3, size * 0.7);
+ const centerX = width / 2;
+ const centerY = height / 2;
+ graphics.beginFill(this.stationDirectionColor, 0.95);
+ if (direction === 'top') {
+ const tipY = margin;
+ const baseY = margin + size;
+ const stemY = Math.min(centerY - 2, baseY + stemLen);
+ if (stemY > baseY) { graphics.moveTo(centerX, stemY); graphics.lineTo(centerX, baseY); }
+ graphics.moveTo(centerX, tipY);
+ graphics.lineTo(centerX - halfBase, baseY);
+ graphics.lineTo(centerX + halfBase, baseY);
+ } else if (direction === 'right') {
+ const tipX = width - margin;
+ const baseX = width - margin - size;
+ const stemX = Math.max(centerX + 2, baseX - stemLen);
+ if (stemX < baseX) { graphics.moveTo(stemX, centerY); graphics.lineTo(baseX, centerY); }
+ graphics.moveTo(tipX, centerY);
+ graphics.lineTo(baseX, centerY - halfBase);
+ graphics.lineTo(baseX, centerY + halfBase);
+ } else if (direction === 'bottom') {
+ const tipY = height - margin;
+ const baseY = height - margin - size;
+ const stemY = Math.max(centerY + 2, baseY - stemLen);
+ if (stemY < baseY) { graphics.moveTo(centerX, stemY); graphics.lineTo(centerX, baseY); }
+ graphics.moveTo(centerX, tipY);
+ graphics.lineTo(centerX - halfBase, baseY);
+ graphics.lineTo(centerX + halfBase, baseY);
+ } else if (direction === 'left') {
+ const tipX = margin;
+ const baseX = margin + size;
+ const stemX = Math.min(centerX - 2, baseX + stemLen);
+ if (stemX > baseX) { graphics.moveTo(stemX, centerY); graphics.lineTo(baseX, centerY); }
+ graphics.moveTo(tipX, centerY);
+ graphics.lineTo(baseX, centerY - halfBase);
+ graphics.lineTo(baseX, centerY + halfBase);
+ }
+ graphics.closePath();
+ graphics.endFill();
+ },
+ applyStationDirectionVisibility() {
+ if (!this.pixiStaMap) { return; }
+ this.pixiStaMap.forEach((sprite) => {
+ if (!sprite || !sprite.directionObj) { return; }
+ sprite.directionObj.visible = this.showStationDirection;
+ });
},
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; }
@@ -1472,6 +2041,135 @@
}
}
}
+ },
+ clearShelfChunks() {
+ if (this.shelfCullRaf) {
+ cancelAnimationFrame(this.shelfCullRaf);
+ this.shelfCullRaf = null;
+ }
+ this.shelfChunkList = [];
+ if (!this.shelvesContainer) { return; }
+ const children = this.shelvesContainer.removeChildren();
+ children.forEach((child) => {
+ if (child && typeof child.destroy === 'function') {
+ child.destroy({ children: true, texture: true, baseTexture: true });
+ }
+ });
+ },
+ buildShelfChunks(map, contentW, contentH) {
+ this.clearShelfChunks();
+ if (!this.pixiApp || !this.pixiApp.renderer || !this.shelvesContainer || !Array.isArray(map)) { return; }
+ const chunkSize = Math.max(256, parseInt(this.shelfChunkSize, 10) || 2048);
+ const chunkMap = new Map();
+ 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' || cell.type === 'merge') { continue; }
+ const startChunkX = Math.floor(cell.posX / chunkSize);
+ const endChunkX = Math.floor((cell.posX + Math.max(1, cell.width) - 0.01) / chunkSize);
+ const startChunkY = Math.floor(cell.posY / chunkSize);
+ const endChunkY = Math.floor((cell.posY + Math.max(1, cell.height) - 0.01) / chunkSize);
+ for (let chunkY = startChunkY; chunkY <= endChunkY; chunkY++) {
+ for (let chunkX = startChunkX; chunkX <= endChunkX; chunkX++) {
+ const key = chunkX + ',' + chunkY;
+ let list = chunkMap.get(key);
+ if (!list) {
+ list = [];
+ chunkMap.set(key, list);
+ }
+ list.push(cell);
+ }
+ }
+ }
+ }
+
+ const chunkList = [];
+ chunkMap.forEach((cells, key) => {
+ const keyParts = key.split(',');
+ const chunkX = parseInt(keyParts[0], 10) || 0;
+ const chunkY = parseInt(keyParts[1], 10) || 0;
+ const chunkLeft = chunkX * chunkSize;
+ const chunkTop = chunkY * chunkSize;
+ const chunkWidth = Math.max(1, Math.min(chunkSize, contentW - chunkLeft));
+ const chunkHeight = Math.max(1, Math.min(chunkSize, contentH - chunkTop));
+ const graphics = new PIXI.Graphics();
+ graphics.beginFill(0xb6e2e2);
+ graphics.lineStyle(1, 0xffffff, 1);
+ for (let i = 0; i < cells.length; i++) {
+ const cell = cells[i];
+ graphics.drawRect(cell.posX - chunkLeft, cell.posY - chunkTop, cell.width, cell.height);
+ }
+ graphics.endFill();
+ const texture = this.pixiApp.renderer.generateTexture(
+ graphics,
+ PIXI.SCALE_MODES.LINEAR,
+ 1,
+ new PIXI.Rectangle(0, 0, chunkWidth, chunkHeight)
+ );
+ graphics.destroy(true);
+ const sprite = new PIXI.Sprite(texture);
+ sprite.position.set(chunkLeft, chunkTop);
+ sprite._chunkBounds = {
+ x: chunkLeft,
+ y: chunkTop,
+ width: chunkWidth,
+ height: chunkHeight
+ };
+ this.shelvesContainer.addChild(sprite);
+ chunkList.push(sprite);
+ });
+ this.shelfChunkList = chunkList;
+ this.updateVisibleShelfChunks();
+ },
+ getViewportLocalBounds(padding) {
+ if (!this.mapRoot || !this.pixiApp) { return null; }
+ const viewport = this.getViewportSize();
+ const pad = Math.max(0, Number(padding) || 0);
+ const points = [
+ new PIXI.Point(-pad, -pad),
+ new PIXI.Point(viewport.width + pad, -pad),
+ new PIXI.Point(-pad, viewport.height + pad),
+ new PIXI.Point(viewport.width + pad, viewport.height + pad)
+ ];
+ let minX = Infinity;
+ let minY = Infinity;
+ let maxX = -Infinity;
+ let maxY = -Infinity;
+ points.forEach((point) => {
+ const local = this.mapRoot.toLocal(point);
+ if (local.x < minX) { minX = local.x; }
+ if (local.y < minY) { minY = local.y; }
+ if (local.x > maxX) { maxX = local.x; }
+ if (local.y > maxY) { maxY = local.y; }
+ });
+ if (!isFinite(minX) || !isFinite(minY) || !isFinite(maxX) || !isFinite(maxY)) { return null; }
+ return { minX: minX, minY: minY, maxX: maxX, maxY: maxY };
+ },
+ updateVisibleShelfChunks() {
+ if (!this.shelfChunkList || this.shelfChunkList.length === 0) { return; }
+ const localBounds = this.getViewportLocalBounds(this.shelfCullPadding);
+ if (!localBounds) { return; }
+ for (let i = 0; i < this.shelfChunkList.length; i++) {
+ const sprite = this.shelfChunkList[i];
+ const bounds = sprite && sprite._chunkBounds;
+ if (!bounds) { continue; }
+ const visible = bounds.x < localBounds.maxX &&
+ bounds.x + bounds.width > localBounds.minX &&
+ bounds.y < localBounds.maxY &&
+ bounds.y + bounds.height > localBounds.minY;
+ if (sprite.visible !== visible) {
+ sprite.visible = visible;
+ }
+ }
+ },
+ scheduleShelfChunkCulling() {
+ if (this.shelfCullRaf) { return; }
+ this.shelfCullRaf = requestAnimationFrame(() => {
+ this.shelfCullRaf = null;
+ this.updateVisibleShelfChunks();
+ });
},
findIndexByOffsets(offsets, sizes, value) {
if (!offsets || !sizes || offsets.length === 0) { return -1; }
@@ -1642,8 +2340,9 @@
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);
@@ -1710,10 +2409,36 @@
this.applyMapTransform(true);
this.saveMapTransformConfig();
},
+ resetMapView() {
+ this.fitStageToContent();
+ this.scheduleAdjustLabels();
+ this.scheduleShelfChunkCulling();
+ },
+ toggleStationDirection() {
+ this.showStationDirection = !this.showStationDirection;
+ this.applyStationDirectionVisibility();
+ },
toggleMirror() {
this.mapMirrorX = !this.mapMirrorX;
this.applyMapTransform(true);
this.saveMapTransformConfig();
+ },
+ openStationColorConfigPage() {
+ if (typeof window === 'undefined') { return; }
+ const url = (typeof baseUrl !== 'undefined' ? baseUrl : '') + '/views/watch/stationColorConfig.html';
+ const layerInstance = (window.top && window.top.layer) || window.layer;
+ if (layerInstance && typeof layerInstance.open === 'function') {
+ layerInstance.open({
+ type: 2,
+ title: '绔欑偣棰滆壊閰嶇疆',
+ maxmin: true,
+ area: ['980px', '760px'],
+ shadeClose: false,
+ content: url
+ });
+ return;
+ }
+ window.open(url, '_blank');
},
parseRotation(value) {
const num = parseInt(value, 10);
@@ -1726,6 +2451,98 @@
if (value == null) { return false; }
const str = String(value).toLowerCase();
return str === '1' || str === 'true' || str === 'y';
+ },
+ getDefaultStationStatusColors() {
+ return {
+ 'site-auto': 0x78ff81,
+ 'site-auto-run': 0xfa51f6,
+ 'site-auto-id': 0xc4c400,
+ 'site-auto-run-id': 0x30bffc,
+ 'site-enable-in': 0xA81DEE,
+ 'site-unauto': 0xb8b8b8,
+ 'machine-pakin': 0x30bffc,
+ 'machine-pakout': 0x97b400,
+ 'site-run-block': 0xe69138
+ };
+ },
+ parseColorConfigValue(value, fallback) {
+ if (typeof value === 'number' && isFinite(value)) {
+ return value;
+ }
+ const str = String(value == null ? '' : value).trim();
+ if (!str) { return fallback; }
+ if (/^#[0-9a-fA-F]{6}$/.test(str)) { return parseInt(str.slice(1), 16); }
+ if (/^#[0-9a-fA-F]{3}$/.test(str)) {
+ const expanded = str.charAt(1) + str.charAt(1) + str.charAt(2) + str.charAt(2) + str.charAt(3) + str.charAt(3);
+ return parseInt(expanded, 16);
+ }
+ if (/^0x[0-9a-fA-F]{6}$/i.test(str)) { return parseInt(str.slice(2), 16); }
+ if (/^[0-9]+$/.test(str)) {
+ const num = parseInt(str, 10);
+ return isNaN(num) ? fallback : num;
+ }
+ return fallback;
+ },
+ loadStationColorConfig() {
+ if (!window.$ || typeof baseUrl === 'undefined') { return; }
+ $.ajax({
+ url: baseUrl + "/watch/stationColor/config/auth",
+ headers: { 'token': localStorage.getItem('token') },
+ dataType: 'json',
+ method: 'GET',
+ success: (res) => {
+ if (!res || res.code !== 200 || !res.data) {
+ if (res && res.code === 403) { parent.location.href = baseUrl + "/login"; }
+ return;
+ }
+ this.applyStationColorConfigPayload(res.data);
+ }
+ });
+ },
+ applyStationColorConfigPayload(data) {
+ const defaults = this.getDefaultStationStatusColors();
+ const nextColors = Object.assign({}, defaults);
+ const items = Array.isArray(data.items) ? data.items : [];
+ items.forEach((item) => {
+ if (!item || !item.status || defaults[item.status] == null) { return; }
+ nextColors[item.status] = this.parseColorConfigValue(item.color, defaults[item.status]);
+ });
+ this.stationStatusColors = nextColors;
+ },
+ buildMissingMapConfigList(byCode) {
+ const createList = [];
+ if (!byCode[this.mapConfigCodes.rotate]) {
+ createList.push({
+ name: '鍦板浘鏃嬭浆',
+ code: this.mapConfigCodes.rotate,
+ value: String(this.mapRotation || 0),
+ type: 1,
+ status: 1,
+ selectType: 'map'
+ });
+ }
+ if (!byCode[this.mapConfigCodes.mirror]) {
+ createList.push({
+ name: '鍦板浘闀滃儚',
+ code: this.mapConfigCodes.mirror,
+ value: this.mapMirrorX ? '1' : '0',
+ type: 1,
+ status: 1,
+ selectType: 'map'
+ });
+ }
+ return createList;
+ },
+ createMapConfigs(createList) {
+ if (!window.$ || typeof baseUrl === 'undefined' || !Array.isArray(createList) || createList.length === 0) { return; }
+ createList.forEach((cfg) => {
+ $.ajax({
+ url: baseUrl + "/config/add/auth",
+ headers: { 'token': localStorage.getItem('token') },
+ method: 'POST',
+ data: cfg
+ });
+ });
},
loadMapTransformConfig() {
if (!window.$ || typeof baseUrl === 'undefined') { return; }
@@ -1751,45 +2568,11 @@
if (mirrorCfg && mirrorCfg.value != null) {
this.mapMirrorX = this.parseMirror(mirrorCfg.value);
}
- if (rotateCfg == null || mirrorCfg == null) {
- this.createMapTransformConfigIfMissing(rotateCfg, mirrorCfg);
- }
+ this.createMapConfigs(this.buildMissingMapConfigList(byCode));
if (this.mapContentSize && this.mapContentSize.width > 0) {
this.applyMapTransform(true);
}
}
- });
- },
- createMapTransformConfigIfMissing(rotateCfg, mirrorCfg) {
- if (!window.$ || typeof baseUrl === 'undefined') { return; }
- const createList = [];
- if (!rotateCfg) {
- createList.push({
- name: '鍦板浘鏃嬭浆',
- code: this.mapConfigCodes.rotate,
- value: String(this.mapRotation || 0),
- type: 1,
- status: 1,
- selectType: 'map'
- });
- }
- if (!mirrorCfg) {
- createList.push({
- name: '鍦板浘闀滃儚',
- code: this.mapConfigCodes.mirror,
- value: this.mapMirrorX ? '1' : '0',
- type: 1,
- status: 1,
- selectType: 'map'
- });
- }
- createList.forEach((cfg) => {
- $.ajax({
- url: baseUrl + "/config/add/auth",
- headers: { 'token': localStorage.getItem('token') },
- method: 'POST',
- data: cfg
- });
});
},
saveMapTransformConfig() {
@@ -1821,17 +2604,23 @@
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;
- let scale = Math.min(vw / contentW, vh / contentH) * 0.95;
+ const viewport = this.getViewportSize();
+ const vw = viewport.width;
+ const vh = viewport.height;
+ const padding = this.getViewportPadding();
+ const availableW = Math.max(1, vw - padding.left - padding.right);
+ const availableH = Math.max(1, vh - padding.top - padding.bottom);
+ let scale = Math.min(availableW / contentW, availableH / contentH) * 0.95;
if (!isFinite(scale) || scale <= 0) { scale = 1; }
const baseW = this.mapContentSize.width || contentW;
const baseH = this.mapContentSize.height || contentH;
const mirrorX = this.mapMirrorX ? -1 : 1;
const scaleX = scale * mirrorX;
const scaleY = scale;
- const posX = (vw / 2) - (baseW / 2) * scaleX;
- const posY = (vh / 2) - (baseH / 2) * scaleY;
+ const centerX = padding.left + availableW / 2;
+ const centerY = padding.top + availableH / 2;
+ const posX = centerX - (baseW / 2) * scaleX;
+ const posY = centerY - (baseH / 2) * scaleY;
this.pixiApp.stage.setTransform(posX, posY, scaleX, scaleY, 0, 0, 0, 0, 0);
},
applyMapTransform(fitToView) {
@@ -1845,6 +2634,7 @@
this.mapRoot.scale.set(1, 1);
if (fitToView) { this.fitStageToContent(); }
this.scheduleAdjustLabels();
+ this.scheduleShelfChunkCulling();
},
scheduleAdjustLabels() {
if (this.adjustLabelTimer) { clearTimeout(this.adjustLabelTimer); }
@@ -1856,47 +2646,6 @@
}
}
});
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--
Gitblit v1.9.1