From 54398271dd26caf3b66b9ef2deff3af0277243d8 Mon Sep 17 00:00:00 2001
From: wuyouming666 <2265557248@qq.com>
Date: 星期三, 26 三月 2025 13:54:59 +0800
Subject: [PATCH] 键盘上下移动成品,余料自适应
---
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue | 306 +++++++++++++++++++++++++++++++++++---------------
1 files changed, 211 insertions(+), 95 deletions(-)
diff --git a/north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue b/north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue
index ea5170a..dd5260b 100644
--- a/north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue
+++ b/north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue
@@ -50,6 +50,7 @@
@mousemove="handleRectDragging"
@mouseup="handleRectDragEnd"
@mouseleave="handleRectDragEnd"
+ @click="handleRectClick(layoutIndex, rectIndex)"
>
<div class="rect-content">
<div class="size">{{ rect.w }}脳{{ rect.h }}</div>
@@ -78,8 +79,7 @@
const { t } = useI18n();
const userStore = useUserInfoStore()
const username = userStore.user.userName
-
-
+let clickEventListener = null;
const props = defineProps({
layoutData: { type: Object, required: true },
gw: { type: Number, default: 1000 },
@@ -100,10 +100,10 @@
const dragging = ref(false);
const dragStartPos = ref({ x: 0, y: 0 });
const dragRect = ref(null);
-const showJiaHao = ref(false); // 鏂板锛氭帶鍒秊ia-hao鐨勬樉绀虹姸鎬�
-const showProcessId= ref(false);
-const themeColor=ref(null)
-// 鎻愪氦甯冨眬鏁版嵁鍒板悗绔�
+const showJiaHao = ref(false);
+const showProcessId = ref(false);
+const themeColor = ref(null);
+
const submitLayouts = async () => {
layouts.value.forEach(layout => {
layout.rects.forEach(rect => {
@@ -129,8 +129,6 @@
});
};
-
-//鑾峰彇浼樺寲璁剧疆
const fetchSettings = async (username) => {
try {
const response = await request.post(`/glassOptimize/selectOptimizeParms/${username}`);
@@ -140,23 +138,15 @@
return;
}
const parsedData = JSON.parse(response.data);
- console.log(parsedData.display.frameNumber)
if (parsedData.display && parsedData.display.frameNumber) {
showJiaHao.value = parsedData.display.frameNumber;
-
}
if (parsedData.display && parsedData.display.orderNumber) {
showProcessId.value = parsedData.display.orderNumber;
-
}
- if (parsedData.display ) {
+ if (parsedData.display) {
themeColor.value = parsedData.display.themeColor;
-
}
-
-
-
- console.log( parsedData);
} else {
console.error('璇锋眰澶辫触锛岀姸鎬佺爜:', response.code);
}
@@ -164,8 +154,6 @@
console.error('璇锋眰鍙戠敓閿欒:', error);
}
};
-
-
const showAddDialog = (layoutIndex, rectIndex) => {
ElMessageBox.prompt('璇疯緭鍏ユ垚鍝佺殑瀹藉害鍜岄珮搴�', '娣诲姞鎴愬搧', {
@@ -186,32 +174,61 @@
},
inputErrorMessage: '杈撳叆鏍煎紡涓嶆纭�'
})
- .then(({ value }) => {
- const values = value.split(',').map(v => parseFloat(v.trim()));
- const newRect = {
- x: 0,
- y: 0,
- w: values[0],
- h: values[1],
- isRemain: false
-
- };
- addNewRect(layoutIndex, newRect);
- })
- .catch(() => {
- // 鐢ㄦ埛鍙栨秷
- });
+ .then(({ value }) => {
+ const values = value.split(',').map(v => parseFloat(v.trim()));
+ const newRect = {
+ x: 0,
+ y: 0,
+ w: values[0],
+ h: values[1],
+ isRemain: false
+ };
+ addNewRect(layoutIndex, newRect);
+ })
+ .catch(() => {
+ // 鐢ㄦ埛鍙栨秷
+ });
};
const addNewRect = (layoutIndex, newRect) => {
const layout = layouts.value[layoutIndex];
- layout.rects.push(newRect);
- adjustGrayRectangles(layoutIndex);
+ const bestFitPosition = findBestFitPosition(layoutIndex, newRect);
+ if (bestFitPosition) {
+ newRect.x = bestFitPosition.x;
+ newRect.y = bestFitPosition.y;
+ layout.rects.push(newRect);
+ adjustGrayRectangles(layoutIndex);
+ } else {
+ ElMessage.warning('鏃犳硶鏀剧疆锛屾病鏈夎冻澶熺殑绌洪棿');
+ }
+};
+
+const findBestFitPosition = (layoutIndex, newRect) => {
+ const layout = layouts.value[layoutIndex];
+ const obstacles = layout.rects.filter(r => !r.isRemain);
+ let bestFit = null;
+ let minAreaDifference = Infinity;
+
+ const remainingAreas = calculateRemainingAreas(layout.width, layout.height, obstacles);
+ remainingAreas.forEach(area => {
+ if (newRect.w <= area.w && newRect.h <= area.h) {
+ const areaDifference = Math.abs(area.w * area.h - newRect.w * newRect.h);
+ if (areaDifference < minAreaDifference) {
+ minAreaDifference = areaDifference;
+ bestFit = {
+ x: area.x,
+ y: area.y,
+ w: newRect.w,
+ h: newRect.h
+ };
+ }
+ }
+ });
+
+ return bestFit;
};
const layoutContainerStyle = (layoutIndex) => {
- const containerWidth = (props.gw - 210) / 2;
- const containerHeight = (props.gh - 100) / 3;
const layout = layouts.value[layoutIndex];
const scale = Math.min(
(props.gw - 100) / layout.width,
@@ -442,22 +459,19 @@
const deltaX = event.clientX - dragStartPos.value.x;
const deltaY = event.clientY - dragStartPos.value.y;
- // 鍙皟鏁翠綅缃紝涓嶈皟鏁村ぇ灏�
const newRect = { ...rect };
newRect.x += deltaX / scale;
newRect.y += deltaY / scale;
- // 妫�鏌ユ槸鍚︿笌鍏朵粬钃濊壊鐭╁舰閲嶅彔
const otherRects = layout.rects.filter(r => !r.isRemain && r !== rect);
let isValidMove = true;
-
+
otherRects.forEach(otherRect => {
if (checkOverlap(newRect, otherRect)) {
isValidMove = false;
}
});
- // 妫�鏌ユ槸鍚﹁秴鍑哄竷灞�杈圭晫
if (newRect.x < 0 || newRect.y < 0 ||
newRect.x + newRect.w > layout.width ||
newRect.y + newRect.h > layout.height) {
@@ -486,14 +500,9 @@
(props.gh - 100) / layout.height
);
- // 鎷栧姩缁撴潫鍚庤嚜鍔ㄥ榻愬埌鏈�杩戠殑鏁存暟浣嶇疆
rect.x = Math.round(rect.x);
rect.y = Math.round(rect.y);
-
- // 鍙皟鏁翠綅缃榻愶紝涓嶈皟鏁村ぇ灏�
- adjustAlignmentPosition(layoutIndex, rectIndex);
-
- // 璋冩暣鐏拌壊鐭╁舰
+ //adjustAlignmentPosition(layoutIndex, rectIndex);
adjustGrayRectangles(layoutIndex);
}
@@ -509,25 +518,39 @@
const threshold = Math.max(rect.w, rect.h) * 0.1;
otherRects.forEach(otherRect => {
+ // 姘村钩瀵归綈
if (Math.abs(rect.x - otherRect.x) < threshold) {
rect.x = Math.round((rect.x + otherRect.x) / 2);
}
+ // 姘村钩瀵归綈鍙充晶杈圭紭
if (Math.abs((rect.x + rect.w) - (otherRect.x + otherRect.w)) < threshold) {
- // 涓嶈皟鏁村搴�
+ rect.x = Math.round((otherRect.x + otherRect.w - rect.w));
}
+ // 鍨傜洿瀵归綈
if (Math.abs(rect.y - otherRect.y) < threshold) {
rect.y = Math.round((rect.y + otherRect.y) / 2);
}
+ // 鍨傜洿瀵归綈涓嬭竟缂�
if (Math.abs((rect.y + rect.h) - (otherRect.y + otherRect.h)) < threshold) {
- // 涓嶈皟鏁撮珮搴�
+ rect.y = Math.round((otherRect.y + otherRect.h - rect.h));
}
});
+
+ // 纭繚鐭╁舰涓嶄細瓒呭嚭甯冨眬杈圭晫
+ rect.x = Math.max(0, rect.x);
+ rect.y = Math.max(0, rect.y);
+ rect.x = Math.min(rect.x, layout.width - rect.w);
+ rect.y = Math.min(rect.y, layout.height - rect.h);
+
+ // 璋冩暣鍚庨噸鏂拌绠楃伆鑹蹭綑鏂�
+ adjustGrayRectangles(layoutIndex);
};
+
const mergeAdjacentGrayRects = (rects) => {
const grayRects = rects.filter(r => r.isRemain);
let merged = [];
-
+
grayRects.sort((a, b) => {
if (a.x !== b.x) return a.x - b.x;
return a.y - b.y;
@@ -541,16 +564,16 @@
const last = merged[merged.length - 1];
const current = grayRects[i];
- if (current.x === last.x + last.w &&
- current.y === last.y &&
+ if (current.x === last.x + last.w &&
+ current.y === last.y &&
current.h === last.h) {
last.w += current.w;
last.x = Math.round(last.x);
last.y = Math.round(last.y);
last.w = Math.round(last.w);
last.h = Math.round(last.h);
- } else if (current.y === last.y + last.h &&
- current.x === last.x &&
+ } else if (current.y === last.y + last.h &&
+ current.x === last.x &&
current.w === last.w) {
last.h += current.h;
last.x = Math.round(last.x);
@@ -558,7 +581,7 @@
last.w = Math.round(last.w);
last.h = Math.round(last.h);
} else {
- merged.push({
+ merged.push({
x: Math.round(current.x),
y: Math.round(current.y),
w: Math.round(current.w),
@@ -611,22 +634,18 @@
const rect = layout.rects[rectIndex];
const originalState = { ...rect };
- // 鏃嬭浆鐭╁舰
const temp = rect.w;
rect.w = rect.h;
rect.h = temp;
- // 妫�鏌ユ棆杞悗鏄惁涓庡叾浠栬摑鑹茬煩褰㈤噸鍙�
const otherRects = layout.rects.filter(r => !r.isRemain && r !== rect);
let isValidRotation = true;
otherRects.forEach(otherRect => {
if (checkOverlap(rect, otherRect)) {
- isValidRotation = false;
- }
+ isValidRotation = false }
});
- // 妫�鏌ユ槸鍚﹁秴鍑哄竷灞�杈圭晫
if (rect.x + rect.w > layout.width || rect.y + rect.h > layout.height) {
isValidRotation = false;
}
@@ -634,7 +653,6 @@
if (isValidRotation) {
adjustGrayRectangles(layoutIndex);
} else {
- // 鎭㈠鍘熺姸
rect.w = originalState.w;
rect.h = originalState.h;
ElMessage.warning('鏃犳硶鏃嬭浆锛屽瓨鍦ㄩ噸鍙犳垨瓒呭嚭杈圭晫');
@@ -646,18 +664,15 @@
const rect = layout.rects[rectIndex];
const grayRects = layout.rects.filter(r => r.isRemain);
- // 鏃嬭浆鐭╁舰
const temp = rect.w;
rect.w = rect.h;
rect.h = temp;
- // 妫�鏌ユ棆杞悗鐨勭煩褰㈡槸鍚﹀彲浠ユ斁缃湪鏌愪釜鐏拌壊鐭╁舰鐨勪綅缃�
const canPlace = grayRects.some(grayRect => {
return grayRect.w >= rect.w && grayRect.h >= rect.h;
});
if (!canPlace) {
- // 濡傛灉涓嶈兘鏀剧疆锛屾仮澶嶅師鐘�
const temp = rect.w;
rect.w = rect.h;
rect.h = temp;
@@ -665,10 +680,7 @@
return;
}
- // 璋冩暣鐏拌壊鐭╁舰
adjustGrayRectangles(layoutIndex);
-
- // 绉诲姩鐭╁舰
moveRect(layoutIndex, rectIndex, direction);
};
@@ -677,47 +689,44 @@
const rect = layout.rects[rectIndex];
const originalState = { ...rect };
- // 璁$畻鍓╀綑绌洪棿
- const remainingAreas = calculateRemainingAreas(layout.width, layout.height, layout.rects.filter(r => !r.isRemain));
-
- // 鏍规嵁鏂瑰悜璁$畻鍙Щ鍔ㄧ殑鏈�澶ф闀�
let maxStep = 0;
+ const obstacles = layout.rects.filter(r => r.isRemain || r !== rect);
+
switch (direction) {
case 'up':
- maxStep = rect.y;
+ maxStep = getAvailableSpaceUp(rect, layout, obstacles);
break;
case 'down':
- maxStep = layout.height - (rect.y + rect.h);
+ maxStep = getAvailableSpaceDown(rect, layout, obstacles);
break;
case 'left':
- maxStep = rect.x;
+ maxStep = getAvailableSpaceLeft(rect, layout, obstacles);
break;
case 'right':
- maxStep = layout.width - (rect.x + rect.w);
+ maxStep = getAvailableSpaceRight(rect, layout, obstacles);
break;
}
- // 绉诲姩姝ラ暱锛屾牴鎹墿浣欑┖闂村姩鎬佽皟鏁�
- const stepSize = maxStep;
- const actualStep = Math.min(maxStep, stepSize);
+ if (maxStep <= 0) {
+ ElMessage.warning('鏃犳硶绉诲姩锛屾病鏈夎冻澶熺殑绌洪棿');
+ return;
+ }
- // 绉诲姩鐭╁舰
switch (direction) {
case 'up':
- rect.y -= actualStep;
+ rect.y -= maxStep;
break;
case 'down':
- rect.y += actualStep;
+ rect.y += maxStep;
break;
case 'left':
- rect.x -= actualStep;
+ rect.x -= maxStep;
break;
case 'right':
- rect.x +=actualStep;
+ rect.x += maxStep;
break;
}
- // 妫�鏌ユ槸鍚︿笌鍏朵粬钃濊壊鐭╁舰閲嶅彔
const otherRects = layout.rects.filter(r => !r.isRemain && r !== rect);
let isValidMove = true;
@@ -727,7 +736,6 @@
}
});
- // 妫�鏌ユ槸鍚﹁秴鍑哄竷灞�杈圭晫
if (rect.x < 0 || rect.y < 0 ||
rect.x + rect.w > layout.width ||
rect.y + rect.h > layout.height) {
@@ -737,7 +745,6 @@
if (isValidMove) {
adjustGrayRectangles(layoutIndex);
} else {
- // 鎭㈠鍘熺姸
rect.x = originalState.x;
rect.y = originalState.y;
ElMessage.warning('鏃犳硶绉诲姩锛屽瓨鍦ㄩ噸鍙犳垨瓒呭嚭杈圭晫');
@@ -829,35 +836,144 @@
layouts.value = props.layoutData.Layouts;
};
+const getAvailableSpaceUp = (rect, layout, obstacles) => {
+ let maxSpace = rect.y;
+ obstacles.forEach(obstacle => {
+ if (obstacle.y + obstacle.h < rect.y &&
+ obstacle.x <= rect.x + rect.w &&
+ obstacle.x + obstacle.w >= rect.x) {
+ maxSpace = Math.min(maxSpace, rect.y - (obstacle.y + obstacle.h));
+ }
+ });
+ return maxSpace;
+};
-let clickEventListener = null;
+const getAvailableSpaceDown = (rect, layout, obstacles) => {
+ let maxSpace = layout.height - (rect.y + rect.h);
+ obstacles.forEach(obstacle => {
+ if (obstacle.y > rect.y + rect.h &&
+ obstacle.x <= rect.x + rect.w &&
+ obstacle.x + obstacle.w >= rect.x) {
+ maxSpace = Math.min(maxSpace, obstacle.y - (rect.y + rect.h));
+ }
+ });
+ return maxSpace;
+};
+
+const getAvailableSpaceLeft = (rect, layout, obstacles) => {
+ let maxSpace = rect.x;
+ obstacles.forEach(obstacle => {
+ if (obstacle.x + obstacle.w < rect.x &&
+ obstacle.y <= rect.y + rect.h &&
+ obstacle.y + obstacle.h >= rect.y) {
+ maxSpace = Math.min(maxSpace, rect.x - (obstacle.x + obstacle.w));
+ }
+ });
+ return maxSpace;
+};
+
+const getAvailableSpaceRight = (rect, layout, obstacles) => {
+ let maxSpace = layout.width - (rect.x + rect.w);
+ obstacles.forEach(obstacle => {
+ if (obstacle.x > rect.x + rect.w &&
+ obstacle.y <= rect.y + rect.h &&
+ obstacle.y + obstacle.h >= rect.y) {
+ maxSpace = Math.min(maxSpace, obstacle.x - (rect.x + rect.w));
+ }
+ });
+ return maxSpace;
+};
+
+let moveInterval = null;
+
+const handleKeyDown = (event) => {
+ if (!focusIndex.value) return;
+
+ const { layoutIndex, rectIndex } = focusIndex.value;
+ const layout = layouts.value[layoutIndex];
+ const rect = layout.rects[rectIndex];
+ const obstacles = layout.rects.filter(r => r.isRemain || r !== rect);
+
+ switch (event.key) {
+ case 'ArrowUp':
+ event.preventDefault();
+ if (!moveInterval) {
+ moveInterval = setInterval(() => {
+ moveRect(layoutIndex, rectIndex, 'up');
+ }, 50);
+ }
+ break;
+ case 'ArrowDown':
+ event.preventDefault();
+ if (!moveInterval) {
+ moveInterval = setInterval(() => {
+ moveRect(layoutIndex, rectIndex, 'down');
+ }, 50);
+ }
+ break;
+ case 'ArrowLeft':
+ event.preventDefault();
+ if (!moveInterval) {
+ moveInterval = setInterval(() => {
+ moveRect(layoutIndex, rectIndex, 'left');
+ }, 50);
+ }
+ break;
+ case 'ArrowRight':
+ event.preventDefault();
+ if (!moveInterval) {
+ moveInterval = setInterval(() => {
+ moveRect(layoutIndex, rectIndex, 'right');
+ }, 50);
+ }
+ break;
+ }
+};
+
+const handleKeyUp = (event) => {
+ if (event.key === 'ArrowUp' || event.key === 'ArrowDown' ||
+ event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
+ if (moveInterval) {
+ clearInterval(moveInterval);
+ moveInterval = null;
+ }
+ }
+};
+
+
+
onMounted(() => {
fetchSettings(username);
setTimeout(updateLayout, 500);
selectedLayoutIndex.value = 0;
- // 娣诲姞鍏ㄥ眬鐐瑰嚮浜嬩欢鐩戝惉鍣�
- clickEventListener = (event) => {
- // 妫�鏌ユ槸鍚﹀瓨鍦ㄥ彸閿彍鍗�
+ clickEventListener = (event) => {
const contextMenus = document.querySelectorAll('.context-menu');
if (contextMenus.length > 0) {
- // 绉婚櫎鎵�鏈夊彸閿彍鍗�
contextMenus.forEach(menu => menu.remove());
}
};
document.addEventListener('click', clickEventListener);
+ document.addEventListener('keydown', handleKeyDown);
+ document.addEventListener('keyup', handleKeyUp);
});
+
+
onUnmounted(() => {
rectsElements.value = {};
- // 绉婚櫎鍏ㄥ眬鐐瑰嚮浜嬩欢鐩戝惉鍣�
- if (clickEventListener) {
+ if (clickEventListener) {
document.removeEventListener('click', clickEventListener);
+ clickEventListener = null;
}
+ document.removeEventListener('keydown', handleKeyDown);
+ document.removeEventListener('keyup', handleKeyUp);
});
+
</script>
+
<style scoped>
.layout-wrapper {
@@ -898,7 +1014,7 @@
font-size: 12px;
}
-.jia-hao .liuchengka {
+.jia-hao, .liuchengka {
grid-row: 2;
grid-column: 1;
margin: auto;
--
Gitblit v1.8.0