From 33dbc6a161554f3a897f9e9273feb4f2c1b47381 Mon Sep 17 00:00:00 2001
From: chenlu <1320612696@qq.com>
Date: 星期一, 15 十二月 2025 17:04:27 +0800
Subject: [PATCH] Merge branch 'master' of http://10.153.19.25:10105/r/ERP_override
---
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue | 1096 +++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 719 insertions(+), 377 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 9860384..5a9490e 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
@@ -1,16 +1,80 @@
<template>
<div style="display: flex; height: 90vh;">
<!-- Sidebar -->
- <div class="sidebar" style="width: 200px; background: #f4f4f4; padding: 10px;">
- <div
- v-for="(layout, layoutIndex) in layouts"
- :key="layoutIndex"
- class="sidebar-item"
- @click="selectLayout(layoutIndex)"
- :class="{ 'selected': selectedLayoutIndex === layoutIndex }"
- >
- {{ layout.width }} 脳 {{ layout.height }} 脳 {{ layout.SameCount }}
+ <div class="sidebar" style="width: 200px; background: #f4f4f4; padding: 10px; height: 93%; overflow-y: auto; max-height: 90vh; border-radius: 8px;">
+ <div class="folder">
+ <div
+ class="folder-header" style="padding: 8px; background: #e0e0e0; margin-bottom: 5px; border-radius: 4px; user-select: none; display: flex; justify-content: space-between; align-items: center;"
+ >
+ <span @click="toggleFolder('pending')" style="flex: 1; cursor: pointer;">寰呭垏鍓插師鐗�</span>
+ <button
+ @click="toggleFolder('pending')" style="background: none; border: none; cursor: pointer; font-size: 14px; padding: 2px 5px; border-radius: 3px;"
+ :title="openFolders.pending ? '鏀惰捣' : '灞曞紑'"
+ >
+ <el-icon v-if="openFolders.pending"><ArrowUp /></el-icon>
+ <el-icon v-else><ArrowDown /></el-icon>
+ </button>
+ </div>
+ <div v-show="openFolders.pending" class="folder-content" style="padding-left: 15px;">
+ <div
+ v-for="(layout, layoutIndex) in layouts"
+ :key="layoutIndex"
+ class="sidebar-item"
+ @click="selectLayout(layoutIndex)"
+ :class="{ 'selected': selectedLayoutIndex === layoutIndex }" style="margin-bottom: 5px;"
+ >
+ {{ layout.realWidth }} 脳 {{ layout.realHeight }} 脳 {{ layout.quantity }}
+ </div>
+ </div>
</div>
+
+<!-- 寰呰ˉ鐗囬槦鍒楁枃浠跺す -->
+ <div class="folder">
+ <div
+ class="folder-header" style="padding: 8px; background: #e0e0e0; margin-bottom: 5px; border-radius: 4px; user-select: none; display: flex; justify-content: space-between; align-items: center;"
+ >
+ <span @click="toggleFolder('patchQueue')" style="flex: 1; cursor: pointer;">寰呰ˉ鐗囬槦鍒�</span>
+ <button
+ @click="toggleFolder('patchQueue')" style="background: none; border: none; cursor: pointer; font-size: 14px; padding: 2px 5px; border-radius: 3px;"
+ :title="openFolders.patchQueue ? '鏀惰捣' : '灞曞紑'"
+ >
+ <el-icon v-if="openFolders.patchQueue"><ArrowUp /></el-icon>
+ <el-icon v-else><ArrowDown /></el-icon>
+ </button>
+ </div>
+ <div v-show="openFolders.patchQueue" class="folder-content" style="padding-left: 15px;">
+ <div style="padding: 10px; color: #666; font-style: italic;">
+ 鏆傛棤琛ョ墖浠诲姟
+ </div>
+ </div>
+ </div>
+
+ <!-- 娣诲姞鑷畾涔夊昂瀵告枃浠跺す -->
+ <div class="folder">
+ <div
+ class="folder-header" style="padding: 8px; background: #e0e0e0; margin-bottom: 5px; border-radius: 4px; user-select: none; display: flex; justify-content: space-between; align-items: center;"
+ >
+ <span @click="toggleFolder('customSize')" style="flex: 1; cursor: pointer;">娣诲姞鑷畾涔夊昂瀵�</span>
+ <button
+ @click="toggleFolder('customSize')" style="background: none; border: none; cursor: pointer; font-size: 14px; padding: 2px 5px; border-radius: 3px;"
+ :title="openFolders.customSize ? '鏀惰捣' : '灞曞紑'"
+ >
+ <el-icon v-if="openFolders.customSize"><ArrowUp /></el-icon>
+ <el-icon v-else><ArrowDown /></el-icon>
+ </button>
+ </div>
+ <div v-show="openFolders.customSize" class="folder-content" style="padding-left: 15px;">
+ <div style="padding: 10px;">
+ <button
+ @click="showAddCustomSizeDialog" style="width: 100%; padding: 8px; background: #409eff; color: white; border: none; border-radius: 4px; cursor: pointer;"
+ >
+ + 娣诲姞鑷畾涔夊昂瀵�
+ </button>
+ </div>
+ </div>
+ </div>
+
+
</div>
<!-- Main Layout Panel -->
@@ -27,50 +91,47 @@
</div>
<!-- Layout Container -->
+ <div class="layout-container" :style="layoutContainerStyle1(layoutIndex)">
<div class="layout-container" :style="layoutContainerStyle(layoutIndex)">
<!-- 鐏拌壊鐭╁舰 -->
<div
- v-for="(rect, rectIndex) in layout.rects.filter(r => r.isRemain)"
+ v-for="(glassDetail, rectIndex) in layout.glassDetails.filter(r => r.isRemain)"
:key="`gray-${rectIndex}`"
:ref="(el) => { if (el) rectsElements[layoutIndex + '-' + rectIndex] = el }"
- class="layout-rect"
- :style="rectStyle(rect, layoutIndex)"
- @contextmenu.prevent="handleGrayRectRightClick(layoutIndex, rectIndex,rect)"
+ class="layout-glassDetail"
+ :style="rectStyle1(glassDetail, layoutIndex)"
+ @contextmenu.prevent="handleGrayRectRightClick(layoutIndex, rectIndex,glassDetail)"
>
-<!-- <div class="rect-content">
- <div class="size">{{ rect.w }}脳{{ rect.h }}</div>
- <div v-if="showJiaHao" class="jia-hao">{{ rect.JiaHao }}</div>
- <div v-if="showProcessId" class="liuchengka">{{ rect.liuchengka }}</div>
+<!-- <div class="glassDetail-content">
+ <div class="size">{{ glassDetail.width }}脳{{ glassDetail.height }}</div>
+ <div v-if="showJiaHao" class="jia-hao">{{ glassDetail.JiaHao }}</div>
+ <div v-if="showProcessId" class="liuchengka">{{ glassDetail.liuchengka }}</div>
</div>-->
</div>
<!-- 钃濊壊鐭╁舰 -->
<div
- v-for="(rect, rectIndex) in layout.rects.filter(r => !r.isRemain)"
+ v-for="(glassDetail, rectIndex) in layout.glassDetails.filter(r => !r.isRemain)"
:key="`blue-${rectIndex}`"
:ref="(el) => { if (el) rectsElements[layoutIndex + '-' + rectIndex] = el }"
- class="layout-rect"
- :style="rectStyle(rect, layoutIndex)"
+ class="layout-glassDetail"
+ :style="rectStyle(glassDetail, layoutIndex)"
@contextmenu.prevent="handleRectRightClick(layoutIndex, rectIndex)"
- @mousedown="handleRectDragStart(layoutIndex, rectIndex)"
- @mousemove="handleRectDragging"
- @mouseup="handleRectDragEnd"
- @mouseleave="handleRectDragEnd"
@click="handleRectClick(layoutIndex, rectIndex)"
>
- <div class="rect-content">
- <div class="size">{{ rect.w }}脳{{ rect.h }}</div>
- <div>{{rectIndex }}</div>
- <div v-if="showJiaHao" class="jia-hao">{{ rect.JiaHao }}</div>
- <div v-if="showProcessId" class="liuchengka">{{ rect.liuchengka }}</div>
+ <div class="glassDetail-content">
+ <div class="size">{{ glassDetail.realWidth }}脳{{ glassDetail.realHeight }}</div>
+ <div>{{glassDetail.polySort }}</div>
+ <div v-if="showJiaHao" class="jia-hao">{{ glassDetail.rackNo }}</div>
+ <div v-if="showProcessId" class="liuchengka">{{ glassDetail.processId }}</div>
</div>
</div>
+ </div>
</div>
</div>
</div>
- <!-- 鎻愪氦鎸夐挳 -->
- <button @click="submitLayouts" style="position: fixed; bottom: 20px; right: 20px; padding: 10px; background: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer;">
+ <button @click="submitLayouts" style="position: fixed; top: 90px; right: 20px; padding: 10px; background: #409eff; color: white; border: none; border-radius: 5px; cursor: pointer;">
淇濆瓨璋冩暣
</button>
</div>
@@ -78,7 +139,10 @@
<script setup>
import { ref, reactive, onMounted, onUnmounted } from 'vue';
+import { useRouter } from 'vue-router';
+import { ArrowUp, ArrowDown } from '@element-plus/icons-vue'
import request from "@/utils/request";
+const router = useRouter();
import { useI18n } from "vue-i18n";
import { ElMessage, ElMessageBox } from "element-plus";
import useUserInfoStore from "@/stores/userInfo";
@@ -99,14 +163,15 @@
const rectsElements = ref({});
const focusIndex = ref(null);
const layouts = ref([]);
+const layoutsHead = ref();
const panelClass = ref('');
const panelStyle = ref(props.style);
-const rectClass = ref('layout-rect');
+const rectClass = ref('layout-glassDetail');
const selectedLayoutIndex = ref(0);
const currentRect = ref(null);
-const dragging = ref(false);
-const dragStartPos = ref({ x: 0, y: 0 });
-const dragRect = ref(null);
+// const dragging = ref(false);
+// const dragStartPos = ref({ x: 0, y: 0 });
+// const dragRect = ref(null);
const showJiaHao = ref(false);
const showProcessId = ref(false);
const themeColor = ref(null);
@@ -114,27 +179,64 @@
//淇濆瓨璋冩暣
const submitLayouts = async () => {
layouts.value.forEach(layout => {
- layout.rects.forEach(rect => {
- rect.x = Math.round(rect.x);
- rect.y = Math.round(rect.y);
- rect.w = Math.round(rect.w);
- rect.h = Math.round(rect.h);
+ layout.glassDetails.forEach(glassDetail => {
+ glassDetail.x = parseFloat(glassDetail.x.toFixed(2));
+ glassDetail.y = parseFloat(glassDetail.y.toFixed(2));
+ glassDetail.width = parseFloat(glassDetail.width.toFixed(2));
+ glassDetail.height = parseFloat(glassDetail.height.toFixed(2));
});
});
const savedProjectNo = localStorage.getItem('projectNo');
const processId = savedProjectNo;
- const Layouts = layouts.value;
- request.post(`/glassOptimize/updateOptimizeResult/${processId}`, JSON.stringify({ Layouts }), {
+ // 鏋勯�犱笌鍘熷鏁版嵁缁撴瀯涓�鑷寸殑瀵硅薄
+ const saveData = {
+ projectNo: processId,
+ layouts: layouts.value,
+ // 澶嶅埗鍘熷鏁版嵁涓殑鍏朵粬蹇呰瀛楁
+ ...layoutsHead.value
+ };
+
+ // 纭繚 Layouts 瀛楁鏄簭鍒楀寲鐨勫瓧绗︿覆
+ const requestData = {
+ Layouts: JSON.stringify(saveData)
+ };
+ request.post(`/glassOptimize/updateOptimizeResult/${processId}`, layoutsHead.value, {
headers: {
'Content-Type': 'application/json'
}
}).then((res) => {
if (res.code == 200 && res.data === true) {
ElMessage.success(t('basicData.msg.saveSuccess'));
+ // // 淇濆瓨鎴愬姛鍚庤烦杞埌鏁版帶鐣岄潰
+ // router.push({ path: '/main/glassOptimize/OptimizeControl' });
} else {
ElMessage.warning(res.msg);
}
});
+};
+
+const openFolders = ref({
+ pending: true, // 榛樿灞曞紑"寰呭垏鍓插師鐗�"鏂囦欢澶�
+ patchQueue: false, // 榛樿鏀惰捣"寰呰ˉ鐗囬槦鍒�"鏂囦欢澶�
+ customSize: false // 榛樿鏀惰捣"娣诲姞鑷畾涔夊昂瀵�"鏂囦欢澶�
+});
+
+// 鍒囨崲鏂囦欢澶瑰睍寮�/鏀惰捣鐘舵��
+const toggleFolder = (folderName) => {
+ openFolders.value[folderName] = !openFolders.value[folderName];
+};
+
+
+
+const showAddCustomSizeDialog = () => {
+ // 妫�鏌ユ槸鍚﹂�夋嫨浜嗙増鍥�
+ if (selectedLayoutIndex.value === null || layouts.value.length === 0) {
+ ElMessage.warning('璇峰厛閫夋嫨涓�涓増鍥�');
+ return;
+ }
+
+ // 浣跨敤鐜版湁鐨勬坊鍔犳垚鍝侀�昏緫锛屼紶鍏ュ綋鍓嶉�変腑鐨勭増鍥剧储寮�
+ showAddDialog(selectedLayoutIndex.value);
};
//鏌ヨ璁剧疆鐨勫熀纭�淇℃伅鏋跺彿锛岀煩褰㈤鑹诧紝璁㈠崟搴忓彿绛�
@@ -189,8 +291,8 @@
const newRect = {
x: 0,
y: 0,
- w: values[0],
- h: values[1],
+ width: values[0],
+ height: values[1],
isRemain: false
};
addNewRect(layoutIndex, newRect);
@@ -207,7 +309,7 @@
if (bestFitPosition) {
newRect.x = bestFitPosition.x;
newRect.y = bestFitPosition.y;
- layout.rects.push(newRect);
+ layout.glassDetails.push(newRect);
adjustGrayRectangles(layoutIndex);
} else {
ElMessage.warning('鏃犳硶鏀剧疆锛屾病鏈夎冻澶熺殑绌洪棿');
@@ -217,21 +319,21 @@
//娣诲姞鎴愬搧鍒ゆ柇鏄惁鍙互鏀句笅
const findBestFitPosition = (layoutIndex, newRect) => {
const layout = layouts.value[layoutIndex];
- const obstacles = layout.rects.filter(r => !r.isRemain);
+ const obstacles = layout.glassDetails.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 (newRect.width <= area.width && newRect.height <= area.height) {
+ const areaDifference = Math.abs(area.width * area.height - newRect.width * newRect.height);
if (areaDifference < minAreaDifference) {
minAreaDifference = areaDifference;
bestFit = {
x: area.x,
y: area.y,
- w: newRect.w,
- h: newRect.h
+ width: newRect.width,
+ height: newRect.height
};
}
}
@@ -240,21 +342,41 @@
return bestFit;
};
+const isSelected = (layoutIndex, rectIndex) => {
+ return focusIndex.value &&
+ focusIndex.value.layoutIndex === layoutIndex &&
+ focusIndex.value.rectIndex === rectIndex;
+};
+
//鐗堝浘鍐呭鏍峰紡鍔犺浇
const layoutContainerStyle = (layoutIndex) => {
const layout = layouts.value[layoutIndex];
- const scale = Math.min(
- (props.gw - 100) / layout.width,
- (props.gh - 100) / layout.height
+ const scale = Math.min(0.25
);
return {
position: 'absolute',
- left: `${(props.gw - layout.width * scale) / 2}px`,
- top: `${(props.gh - layout.height * scale) / 2}px`,
+ left: `${layout.leftTrim * scale}px`,
+ bottom: `${layout.upTrim * scale}px`,
width: `${layout.width * scale}px`,
height: `${layout.height * scale}px`,
overflow: 'visible',
- border: '1px solid #ccc',
+ //border: '1px solid #ccc',
+ background: '#fff'
+ };
+};
+
+const layoutContainerStyle1 = (layoutIndex) => {
+ const layout = layouts.value[layoutIndex];
+ const scale = Math.min(0.25
+ );
+ return {
+ position: 'absolute',
+ left: `20px`,
+ top: `140px`,
+ width: `${layout.realWidth * scale}px`,
+ height: `${layout.realHeight * scale}px`,
+ overflow: 'visible',
+ //border: '1px solid #ccc',
background: '#fff'
};
};
@@ -262,14 +384,12 @@
//鐗堝浘鍐呭澶撮儴鏍峰紡鍔犺浇
const layoutInfoStyle = (layoutIndex) => {
const layout = layouts.value[layoutIndex];
- const scale = Math.min(
- (props.gw - 100) / layout.width,
- (props.gh - 100) / layout.height
+ const scale = Math.min(0.25
);
return {
position: 'absolute',
- left: `${(props.gw - layout.width * scale) / 2}px`,
- top: `${(props.gh - layout.height * scale) / 2 - 45}px`,
+ left: `20px`,
+ top: `100px`,
background: 'none',
textAlign: 'center',
zIndex: 1000
@@ -277,42 +397,79 @@
};
//鐗堝浘鍐呭灏忕墖鏍峰紡鍔犺浇
-const rectStyle = (rect, layoutIndex) => {
+const rectStyle = (glassDetail, layoutIndex) => {
const layout = layouts.value[layoutIndex];
- const scale = Math.min(
- (props.gw - 100) / layout.width,
- (props.gh - 100) / layout.height
- );
- return {
+ const scale = Math.min(0.25);
+ const isSelectedRect = isSelected(layoutIndex, layout.glassDetails.indexOf(glassDetail));
+
+ let style = {
position: 'absolute',
- left: `${rect.x * scale}px`,
- bottom: `${rect.y * scale}px`,
- width: `${rect.w * scale}px`,
- height: `${rect.h * scale}px`,
- backgroundColor: rect.isRemain ? '#f0f0f0' : themeColor.value,
+ left: `${glassDetail.x * scale}px`,
+ top: `${glassDetail.y * scale}px`,
+ width: `${glassDetail.width * scale}px`,
+ height: `${glassDetail.height * scale}px`,
+ backgroundColor: glassDetail.isRemain ? '#f0f0f0' : themeColor.value,
border: '1px solid #000',
cursor: 'pointer',
- draggable: !rect.isRemain,
- zIndex: rect.isRemain ? 1 : 2
+ draggable: !glassDetail.isRemain,
+ zIndex: glassDetail.isRemain ? 1 : 2
};
+
+ // 濡傛灉琚�変腑锛屽垯娣诲姞鍐呬晶绾㈡
+ if (isSelectedRect) {
+ style.boxShadow = 'inset 0 0 0 2px red';
+ }
+
+ return style;
+};
+
+const rectStyle1 = (glassDetail, layoutIndex) => {
+ const layout = layouts.value[layoutIndex];
+ const scale = Math.min(0.25);
+ const isSelectedRect = isSelected(layoutIndex, layout.glassDetails.indexOf(glassDetail));
+
+ let style = {
+ position: 'absolute',
+ left: `${glassDetail.x * scale}px`,
+ top: `${glassDetail.y * scale}px`,
+ width: `${glassDetail.width * scale}px`,
+ height: `${glassDetail.height * scale}px`,
+ backgroundColor: glassDetail.isRemain ? '#f0f0f0' : themeColor.value,
+ border: '1px solid #000',
+ cursor: 'pointer',
+ draggable: !glassDetail.isRemain,
+ zIndex: glassDetail.isRemain ? 1 : 2
+ };
+
+ // 濡傛灉琚�変腑锛屽垯娣诲姞鍐呬晶绾㈡
+ if (isSelectedRect) {
+ style.boxShadow = 'inset 0 0 0 2px red';
+ }
+
+ return style;
};
//鐐瑰嚮灏忕墖
const handleRectClick = (layoutIndex, rectIndex) => {
+ // if (dragging.value) {
+ // return;
+ // }
+
focusIndex.value = { layoutIndex, rectIndex };
emit('rectClicked', layoutIndex, rectIndex);
};
//灏忕墖鍙抽敭鑿滃崟鍔熻兘
const handleRectRightClick = (layoutIndex, rectIndex) => {
- const rect = layouts.value[layoutIndex].rects[rectIndex];
- if (rect.isRemain) return;
+ const glassDetail = layouts.value[layoutIndex].glassDetails[rectIndex];
+ if (glassDetail.isRemain) return;
+ document.querySelectorAll('.context-menu').forEach(el => el.remove());
const contextMenu = document.createElement('div');
contextMenu.className = 'context-menu';
contextMenu.style.position = 'absolute';
contextMenu.style.left = `${event.clientX}px`;
- contextMenu.style.bottom = `${event.clientY}px`;
+ contextMenu.style.top = `${event.clientY}px`;
contextMenu.style.backgroundColor = '#fff';
contextMenu.style.border = '1px solid #ccc';
contextMenu.style.padding = '5px';
@@ -330,7 +487,7 @@
moveUpAndRotateItem.textContent = '鍚戜笂绉诲姩骞舵棆杞�';
moveUpAndRotateItem.style.cursor = 'pointer';
moveUpAndRotateItem.addEventListener('click', () => {
- moveRectAndRotate(layoutIndex, rectIndex, 'up');
+ moveRectAndRotate(layoutIndex, rectIndex, 'down');
document.body.removeChild(contextMenu);
});
@@ -338,7 +495,7 @@
moveDownAndRotateItem.textContent = '鍚戜笅绉诲姩骞舵棆杞�';
moveDownAndRotateItem.style.cursor = 'pointer';
moveDownAndRotateItem.addEventListener('click', () => {
- moveRectAndRotate(layoutIndex, rectIndex, 'down');
+ moveRectAndRotate(layoutIndex, rectIndex, 'up');
document.body.removeChild(contextMenu);
});
@@ -362,7 +519,7 @@
moveUpItem.textContent = '鍚戜笂绉诲姩';
moveUpItem.style.cursor = 'pointer';
moveUpItem.addEventListener('click', () => {
- moveRect(layoutIndex, rectIndex, 'up');
+ moveRect(layoutIndex, rectIndex, 'down');
document.body.removeChild(contextMenu);
});
@@ -370,7 +527,7 @@
moveDownItem.textContent = '鍚戜笅绉诲姩';
moveDownItem.style.cursor = 'pointer';
moveDownItem.addEventListener('click', () => {
- moveRect(layoutIndex, rectIndex, 'down');
+ moveRect(layoutIndex, rectIndex, 'up');
document.body.removeChild(contextMenu);
});
@@ -440,15 +597,16 @@
};
//浣欐枡鍙抽敭鑿滃崟鍔熻兘
-const handleGrayRectRightClick = (layoutIndex, rectIndex,rects) => {
- //const rect = rects[rectIndex];
- if (!rects.isRemain) return;
+const handleGrayRectRightClick = (layoutIndex, rectIndex,glassDetails) => {
+ //const glassDetail = glassDetails[rectIndex];
+ if (!glassDetails.isRemain) return;
+ document.querySelectorAll('.context-menu').forEach(el => el.remove());
const contextMenu = document.createElement('div');
contextMenu.className = 'context-menu';
contextMenu.style.position = 'absolute';
contextMenu.style.left = `${event.clientX}px`;
- contextMenu.style.bottom = `${event.clientY}px`;
+ contextMenu.style.top = `${event.clientY}px`;
contextMenu.style.backgroundColor = '#fff';
contextMenu.style.border = '1px solid #ccc';
contextMenu.style.padding = '5px';
@@ -486,242 +644,353 @@
};
//灏忕墖榧犳爣鎸変笅浜嬩欢
-const handleRectDragStart = (layoutIndex, rectIndex) => {
- const layout = layouts.value[layoutIndex];
- const rect = layout.rects[rectIndex];
- if (rect.isRemain) return;
+// const handleRectDragStart = (layoutIndex, rectIndex) => {
+// const layout = layouts.value[layoutIndex];
+// const glassDetail = layout.glassDetails[rectIndex];
+// if (glassDetail.isRemain) return;
+//
+// dragRect.value = { layoutIndex, rectIndex };
+// dragStartPos.value = {
+// x: event.clientX,
+// y: event.clientY
+// };
+// };
- dragging.value = true;
- dragRect.value = { layoutIndex, rectIndex };
- dragStartPos.value = {
- x: event.clientX,
- y: event.clientY
- };
-};
+// //灏忕墖榧犳爣绉诲姩浜嬩欢
+// const handleRectDragging = (event) => {
+// if (!dragRect.value) return;
+//
+// // 濡傛灉杩樻病纭鏄嫋鎷斤紝鍒欏厛鍒ゆ柇鏄惁杈惧埌鎷栨嫿闃堝��(渚嬪5鍍忕礌)
+// if (!dragging.value) {
+// const deltaX = event.clientX - dragStartPos.value.x;
+// const deltaY = event.clientY - dragStartPos.value.y;
+// const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+//
+// // 濡傛灉绉诲姩璺濈灏忎簬闃堝�硷紝鍒欒涓烘槸鐐瑰嚮鑰岄潪鎷栨嫿
+// if (distance < 5) {
+// return;
+// }
+//
+// // 杈惧埌闃堝�硷紝纭鏄嫋鎷芥搷浣�
+// dragging.value = true;
+// }
+//
+// const layoutIndex = dragRect.value.layoutIndex;
+// const rectIndex = dragRect.value.rectIndex;
+// const layout = layouts.value[layoutIndex];
+// const glassDetail = layout.glassDetails[rectIndex];
+//
+// // 淇濆瓨鍘熷鍧愭爣鐢ㄤ簬璁$畻鍋忕Щ閲�
+// const originalX = glassDetail.x;
+// const originalY = glassDetail.y;
+//
+// const scale = Math.min(
+// (props.gw - 100) / layout.width,
+// (props.gh - 100) / layout.height
+// );
+//
+// const deltaX = event.clientX - dragStartPos.value.x;
+// const deltaY = event.clientY - dragStartPos.value.y;
+//
+// const newRect = { ...glassDetail };
+// newRect.x += deltaX / scale;
+// newRect.y += deltaY / scale;
+//
+// const otherRects = layout.glassDetails.filter(r => !r.isRemain && r !== glassDetail);
+// let isValidMove = true;
+//
+// otherRects.forEach(otherRect => {
+// if (checkOverlap(newRect, otherRect)) {
+// isValidMove = false;
+// }
+// });
+//
+// if (newRect.x < 0 || newRect.y < 0 ||
+// newRect.x + newRect.width > layout.width ||
+// newRect.y + newRect.height > layout.height) {
+// isValidMove = false;
+// }
+//
+// if (isValidMove) {
+// glassDetail.x = newRect.x;
+// glassDetail.y = newRect.y;
+//
+// // 鏇存柊glassPoint鍧愭爣
+// if (glassDetail.glassPoint && Array.isArray(glassDetail.glassPoint)) {
+// const offsetX = glassDetail.x - originalX;
+// const offsetY = glassDetail.y - originalY;
+//
+// glassDetail.glassPoint.forEach(point => {
+// point.X += offsetX;
+// point.Y += offsetY;
+// // 娣诲姞绮惧害鎺у埗
+// point.X = parseFloat(point.X.toFixed(2));
+// point.Y = parseFloat(point.Y.toFixed(2));
+// });
+// }
+//
+// dragStartPos.value = {
+// x: event.clientX,
+// y: event.clientY
+// };
+// adjustGrayRectangles(layoutIndex);
+// }
+// };
-//灏忕墖榧犳爣绉诲姩浜嬩欢
-const handleRectDragging = (event) => {
- if (!dragging.value || !dragRect.value) return;
-
- const layoutIndex = dragRect.value.layoutIndex;
- const rectIndex = dragRect.value.rectIndex;
- const layout = layouts.value[layoutIndex];
- const rect = layout.rects[rectIndex];
- const scale = Math.min(
- (props.gw - 100) / layout.width,
- (props.gh - 100) / layout.height
- );
-
- 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) {
- isValidMove = false;
- }
-
- if (isValidMove) {
- rect.x = newRect.x;
- rect.y = newRect.y;
- dragStartPos.value = {
- x: event.clientX,
- y: event.clientY
- };
- adjustGrayRectangles(layoutIndex);
- }
-};
-
-//灏忕墖榧犳爣鏉惧紑浜嬩欢
-const handleRectDragEnd = () => {
- if (dragRect.value) {
- const layoutIndex = dragRect.value.layoutIndex;
- const rectIndex = dragRect.value.rectIndex;
- const rect = layouts.value[layoutIndex].rects[rectIndex];
- const layout = layouts.value[layoutIndex];
- const scale = Math.min(
- (props.gw - 100) / layout.width,
- (props.gh - 100) / layout.height
- );
-
- rect.x = Math.round(rect.x);
- rect.y = Math.round(rect.y);
- adjustAlignmentPosition(layoutIndex, rectIndex);
- }
-
- dragging.value = false;
- dragRect.value = null;
-};
+// //灏忕墖榧犳爣鏉惧紑浜嬩欢
+// const handleRectDragEnd = () => {
+// dragging.value = false;
+// dragRect.value = null;
+// dragStartPos.value = { x: 0, y: 0 };
+// if (dragRect.value) {
+// const layoutIndex = dragRect.value.layoutIndex;
+// const rectIndex = dragRect.value.rectIndex;
+// const glassDetail = layouts.value[layoutIndex].glassDetails[rectIndex];
+// const layout = layouts.value[layoutIndex];
+// const scale = Math.min(
+// (props.gw - 100) / layout.width,
+// (props.gh - 100) / layout.height
+// );
+//
+// glassDetail.x = parseFloat(glassDetail.x.toFixed(2));
+// glassDetail.y = parseFloat(glassDetail.y.toFixed(2));
+// adjustAlignmentPosition(layoutIndex, rectIndex);
+// }
+//
+// dragging.value = false;
+// dragRect.value = null;
+// };
const adjustAlignmentPosition = (layoutIndex, rectIndex) => {
const layout = layouts.value[layoutIndex];
- const rect = layout.rects[rectIndex];
- const otherRects = layout.rects.filter((r, i) => i !== rectIndex);
+ const glassDetail = layout.glassDetails[rectIndex];
+ const otherRects = layout.glassDetails.filter((r, i) => i !== rectIndex);
- const threshold = Math.max(rect.w, rect.h) * 0.1;
+ const threshold = Math.max(glassDetail.width, glassDetail.height) * 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(glassDetail.x - otherRect.x) < threshold) {
+ glassDetail.x = Math.round((glassDetail.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((glassDetail.x + glassDetail.width) - (otherRect.x + otherRect.width)) < threshold) {
+ glassDetail.x = Math.round((otherRect.x + otherRect.width - glassDetail.width));
}
// 鍨傜洿瀵归綈
- if (Math.abs(rect.y - otherRect.y) < threshold) {
- rect.y = Math.round((rect.y + otherRect.y) / 2);
+ if (Math.abs(glassDetail.y - otherRect.y) < threshold) {
+ glassDetail.y = Math.round((glassDetail.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));
+ // 鍨傜洿瀵归綈涓婅竟缂�
+ if (Math.abs((glassDetail.y + glassDetail.height) - (otherRect.y + otherRect.height)) < threshold) {
+ glassDetail.y = Math.round((otherRect.y + otherRect.height - glassDetail.height));
}
});
// 纭繚鐭╁舰涓嶄細瓒呭嚭甯冨眬杈圭晫
- 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);
+ glassDetail.x = Math.max(0, glassDetail.x);
+ glassDetail.y = Math.max(0, glassDetail.y);
+ glassDetail.x = Math.min(glassDetail.x, layout.width - glassDetail.width);
+ glassDetail.y = Math.min(glassDetail.y, layout.height - glassDetail.height);
// 璋冩暣鍚庨噸鏂拌绠楃伆鑹蹭綑鏂�
adjustGrayRectangles(layoutIndex);
};
-const mergeAdjacentGrayRects = (rects,totalWidth,totalHeight) => {
- const grayRects = rects.filter(r => r.isRemain);
- const grayRects2 = rects.filter(r => r.isRemain);
- let merged = [];
+const mergeAdjacentGrayRects = (glassDetails, totalWidth, totalHeight) => {
+ const grayRects = glassDetails.filter(r => r.isRemain);
+ const nonGrayRects = glassDetails.filter(r => !r.isRemain);
+ // 鎸夊潗鏍囨帓搴忥紝浼樺厛鎸墆鍧愭爣锛屽叾娆℃寜x鍧愭爣锛堣繖鏍锋洿绗﹀悎浠庝笂鍒颁笅銆佷粠宸﹀埌鍙崇殑闃呰涔犳儻锛�
grayRects.sort((a, b) => {
- if (a.x !== b.x) return a.x - b.x;
- return a.y - b.y;
+ if (a.y !== b.y) return a.y - b.y;
+ return a.x - b.x;
});
if (grayRects.length === 0) return;
- merged.push({ ...grayRects[0] });
+ const merged = [];
+ let current = { ...grayRects[0] };
+ // 閬嶅巻鎵�鏈変綑鏂欑煩褰㈣繘琛屽悎骞�
for (let i = 1; i < grayRects.length; i++) {
- const last = merged[merged.length-1];
- const current = grayRects[i];
+ const next = grayRects[i];
-
- 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 &&
- current.w === last.w) {
- last.h += current.h;
- 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 === next.y &&
+ current.height === next.height &&
+ current.x + current.width === next.x) {
+ // 姘村钩鍚堝苟
+ current.width += next.width;
+ }
+ // 妫�鏌ユ槸鍚﹀彲浠ュ瀭鐩村悎骞讹紙鍚屼竴鍒楋紝瀹藉害鐩稿悓锛岀浉閭伙級
+ else if (current.x === next.x &&
+ current.width === next.width &&
+ current.y + current.height === next.y) {
+ // 鍨傜洿鍚堝苟
+ current.height += next.height;
+ }
+ else {
+ // 鏃犳硶鍚堝苟锛屼繚瀛樺綋鍓嶇煩褰紝寮�濮嬫柊鐨勫悎骞�
merged.push({
- x: Math.round(current.x),
- y: Math.round(current.y),
- w: Math.round(current.w),
- h: Math.round(current.h),
+ x: current.x,
+ y: current.y,
+ width: current.width,
+ height: current.height,
isRemain: true
});
+ current = { ...next };
}
}
- const nonGray = rects.filter(r => !r.isRemain);
- //鍒犻櫎鍘熸暟缁勬嫾鎺ユ柊鐨勫皬鐗囪窡浣欐枡
- rects.splice(0, rects.length, ...nonGray, ...merged);
+ // 娣诲姞鏈�鍚庝竴涓煩褰�
+ merged.push({
+ x: current.x,
+ y: current.y,
+ width: current.width,
+ height: current.height,
+ isRemain: true
+ });
+
+ // 閲嶆柊鏋勫缓鏁扮粍锛氶潪浣欐枡 + 鍚堝苟鍚庣殑浣欐枡
+ glassDetails.splice(0, glassDetails.length, ...nonGrayRects, ...merged);
};
+
+// 纭繚杩斿洖鐨勫尯鍩熶笉閲嶅彔
+const calculateRemainingAreas = (totalWidth, totalHeight, obstacles) => {
+ // 浠庢暣涓師鐗囧紑濮�
+ let remaining = [{ x: 0, y: 0, width: totalWidth, height: totalHeight }];
+
+ // 閫愪釜澶勭悊闅滅鐗╋紙宸叉斁缃殑鐜荤拑鐗囷級
+ obstacles.forEach(obstacle => {
+ remaining = cutRemainingAreas(remaining, obstacle, totalWidth, totalHeight);
+ });
+
+ // 瀵圭粨鏋滆繘琛屾帓搴忥紝纭繚涓�鑷存��
+ remaining.sort((a, b) => {
+ if (a.x !== b.x) return a.x - b.x;
+ return a.y - b.y;
+ });
+
+ return remaining;
+};
+
// 璋冩暣鍚庨噸鏂拌绠楃伆鑹蹭綑鏂�
const adjustGrayRectangles = (layoutIndex) => {
const layout = layouts.value[layoutIndex];
- const rects = layout.rects;
- //灏忕墖鐨勬暟鎹�
- const nonGrayRects = rects.filter(rect => !rect.isRemain);
+ const glassDetails = layout.glassDetails;
- //鎵�鏈夌殑灏忕墖浣欐枡鍧愭爣璺熷昂瀵�
+ // 1. 绛涢�夊嚭闈炰綑鏂欑殑鐜荤拑鐗囷紙鍗冲疄闄呰鍒囧壊鐨勭幓鐠冪墖锛�
+ const nonGrayRects = glassDetails.filter(glassDetail => !glassDetail.isRemain);
+
+ // 2. 璁$畻鍓╀綑鍙敤鍖哄煙
let remainingAreas = calculateRemainingAreas(layout.width, layout.height, nonGrayRects);
- const uniqueArr = Array.from(
- new Set(remainingAreas.map(item => JSON.stringify(item)))
- ).map(item => JSON.parse(item));
- //浣欐枡鐨勬暟鎹�
- const currentGrayRects = rects.filter(r => r.isRemain);
- //寰幆浣欐枡鏁版嵁璺熷叏閮ㄧ殑瀵规瘮
- currentGrayRects.forEach((_, index) => {
- if (index >= remainingAreas.length) {
- rects.splice(index, 1);
- }
+
+ // 3. 鍘婚噸澶勭悊 - 鏇翠弗鏍肩殑鍘婚噸閫昏緫
+ const uniqueArr = removeDuplicateAreas(remainingAreas);
+
+ // 4. 鑾峰彇褰撳墠宸插瓨鍦ㄧ殑浣欐枡鐭╁舰锛堥渶瑕佷繚鐣欏紩鐢ㄤ互渚挎洿鏂帮級
+ const currentGrayRects = glassDetails.filter(r => r.isRemain);
+
+ // 5. 娓呴櫎鎵�鏈夌幇鏈夌殑浣欐枡鐭╁舰
+ // 鍏堟敹闆嗛潪浣欐枡鐭╁舰
+ const nonRemainRects = glassDetails.filter(r => !r.isRemain);
+
+ // 6. 閲嶆柊鏋勫缓鐜荤拑璇︽儏鏁扮粍
+ // 淇濈暀闈炰綑鏂欑煩褰�
+ const newGlassDetails = [...nonRemainRects];
+
+ // 娣诲姞鏂扮殑浣欐枡鐭╁舰
+ uniqueArr.forEach((area) => {
+ newGlassDetails.push({
+ x: area.x,
+ y: area.y,
+ width: area.width,
+ height: area.height,
+ isRemain: true
+ });
});
- uniqueArr.forEach((area, index) => {
- if (index < currentGrayRects.length) {
- currentGrayRects[index].x = Math.round(area.x);
- currentGrayRects[index].y = Math.round(area.y);
- currentGrayRects[index].w = Math.round(area.w);
- currentGrayRects[index].h = Math.round(area.h);
- } else {
- rects.push({
- x: Math.round(area.x),
- y: Math.round(area.y),
- w: Math.round(area.w),
- h: Math.round(area.h),
- isRemain: true
- });
- }
- });
+ // 7. 鏇存柊甯冨眬鐨勭幓鐠冭鎯�
+ layout.glassDetails = newGlassDetails;
- mergeAdjacentGrayRects(rects,layout.width, layout.height);
+ // 8. 鍚堝苟鐩搁偦鐨勪綑鏂欑煩褰�
+ mergeAdjacentGrayRects(layout.glassDetails, layout.width, layout.height);
};
+
+
+const removeDuplicateAreas = (areas) => {
+ const result = [];
+
+ areas.forEach(area => {
+ // 妫�鏌ユ槸鍚︿笌宸插瓨鍦ㄧ殑鍖哄煙閲嶅彔鎴栫浉绛�
+ const isDuplicate = result.some(existingArea => {
+ return (
+ existingArea.x === area.x &&
+ existingArea.y === area.y &&
+ existingArea.width === area.width &&
+ existingArea.height === area.height
+ );
+ });
+
+ if (!isDuplicate) {
+ result.push(area);
+ }
+ });
+
+ return result;
+};
+
+
//鏃嬭浆鏂规硶
const rotateRect = (layoutIndex, rectIndex) => {
const layout = layouts.value[layoutIndex];
- const rect = layout.rects[rectIndex];
- const originalState = { ...rect };
+ const glassDetail = layout.glassDetails[rectIndex];
+ const originalState = { ...glassDetail };
- const temp = rect.w;
- rect.w = rect.h;
- rect.h = temp;
+ const temp = glassDetail.width;
+ glassDetail.width = glassDetail.height;
+ glassDetail.height = temp;
- const otherRects = layout.rects.filter(r => !r.isRemain && r !== rect);
+ const otherRects = layout.glassDetails.filter(r => !r.isRemain && r !== glassDetail);
let isValidRotation = true;
otherRects.forEach(otherRect => {
- if (checkOverlap(rect, otherRect)) {
+ if (checkOverlap(glassDetail, otherRect)) {
isValidRotation = false;
}
});
- if (rect.x + rect.w > layout.width || rect.y + rect.h > layout.height) {
+ if (glassDetail.x + glassDetail.width > layout.width || glassDetail.y + glassDetail.height > layout.height) {
isValidRotation = false;
}
if (isValidRotation) {
+ // 鏇存柊glassPoint鍧愭爣锛堝鏋滃瓨鍦級
+ if (glassDetail.glassPoint && Array.isArray(glassDetail.glassPoint)) {
+ // 淇濆瓨鍘熷鐐瑰潗鏍�
+ const originalPoints = JSON.parse(JSON.stringify(glassDetail.glassPoint));
+
+ // 鏃嬭浆鐐瑰潗鏍囷紙浠ョ煩褰㈠乏涓婅涓哄師鐐圭殑鏃嬭浆锛�
+ glassDetail.glassPoint.forEach((point, index) => {
+ // 璁$畻鐩稿浜庣煩褰㈠乏涓婅鐨勫潗鏍�
+ const relX = originalPoints[index].X - originalState.x;
+ const relY = originalPoints[index].Y - originalState.y;
+
+ // 鏃嬭浆90搴﹀悗鐨勫潗鏍囷紙椤烘椂閽堬級
+ point.X = originalState.x + relY;
+ point.Y = originalState.y + (originalState.width - relX);
+ // 娣诲姞绮惧害鎺у埗
+ point.X = parseFloat(point.X.toFixed(2));
+ point.Y = parseFloat(point.Y.toFixed(2));
+ });
+ }
adjustGrayRectangles(layoutIndex);
} else {
- rect.w = originalState.w;
- rect.h = originalState.h;
+ glassDetail.width = originalState.width;
+ glassDetail.height = originalState.height;
ElMessage.warning('鏃犳硶鏃嬭浆锛屽瓨鍦ㄩ噸鍙犳垨瓒呭嚭杈圭晫');
}
};
@@ -729,21 +998,21 @@
//绉诲姩鏃嬭浆鏂规硶
const moveRectAndRotate = (layoutIndex, rectIndex, direction) => {
const layout = layouts.value[layoutIndex];
- const rect = layout.rects[rectIndex];
- const grayRects = layout.rects.filter(r => r.isRemain);
+ const glassDetail = layout.glassDetails[rectIndex];
+ const grayRects = layout.glassDetails.filter(r => r.isRemain);
- const temp = rect.w;
- rect.w = rect.h;
- rect.h = temp;
+ const temp = glassDetail.width;
+ glassDetail.width = glassDetail.height;
+ glassDetail.height = temp;
const canPlace = grayRects.some(grayRect => {
- return grayRect.w >= rect.w && grayRect.h >= rect.h;
+ return grayRect.width >= glassDetail.width && grayRect.height >= glassDetail.height;
});
if (!canPlace) {
- const temp = rect.w;
- rect.w = rect.h;
- rect.h = temp;
+ const temp = glassDetail.width;
+ glassDetail.width = glassDetail.height;
+ glassDetail.height = temp;
ElMessage.warning('鏃犳硶鏃嬭浆锛屾病鏈夎冻澶熺殑绌洪棿');
return;
}
@@ -755,24 +1024,24 @@
//绉诲姩鏂规硶
const moveRect = (layoutIndex, rectIndex, direction) => {
const layout = layouts.value[layoutIndex];
- const rect = layout.rects[rectIndex];
- const originalState = { ...rect };
+ const glassDetail = layout.glassDetails[rectIndex];
+ const originalState = { ...glassDetail };
let maxStep = 0;
- const obstacles = layout.rects.filter(r => r.isRemain || r !== rect);
+ const obstacles = layout.glassDetails.filter(r => r.isRemain || r !== glassDetail);
switch (direction) {
case 'up':
- maxStep = getAvailableSpaceUp(rect, layout, obstacles);
+ maxStep = getAvailableSpaceUp(glassDetail, layout, obstacles);
break;
case 'down':
- maxStep = getAvailableSpaceDown(rect, layout, obstacles);
+ maxStep = getAvailableSpaceDown(glassDetail, layout, obstacles);
break;
case 'left':
- maxStep = getAvailableSpaceLeft(rect, layout, obstacles);
+ maxStep = getAvailableSpaceLeft(glassDetail, layout, obstacles);
break;
case 'right':
- maxStep = getAvailableSpaceRight(rect, layout, obstacles);
+ maxStep = getAvailableSpaceRight(glassDetail, layout, obstacles);
break;
}
@@ -781,41 +1050,59 @@
return;
}
+
+ // 淇濆瓨鍘熷鍧愭爣
+ const originalX = glassDetail.x;
+ const originalY = glassDetail.y;
+
switch (direction) {
case 'up':
- rect.y += maxStep;
+ glassDetail.y += maxStep;
break;
case 'down':
- rect.y -= maxStep;
+ glassDetail.y -= maxStep;
break;
case 'left':
- rect.x -= maxStep;
+ glassDetail.x -= maxStep;
break;
case 'right':
- rect.x += maxStep;
+ glassDetail.x += maxStep;
break;
}
- const otherRects = layout.rects.filter(r => !r.isRemain && r !== rect);
+ const otherRects = layout.glassDetails.filter(r => !r.isRemain && r !== glassDetail);
let isValidMove = true;
otherRects.forEach(otherRect => {
- if (checkOverlap(rect, otherRect)) {
+ if (checkOverlap(glassDetail, otherRect)) {
isValidMove = false;
}
});
- if (rect.x < 0 || rect.y < 0 ||
- rect.x + rect.w > layout.width ||
- rect.y + rect.h > layout.height) {
+ if (glassDetail.x < 0 || glassDetail.y < 0 ||
+ glassDetail.x + glassDetail.width > layout.width ||
+ glassDetail.y + glassDetail.height > layout.height) {
isValidMove = false;
}
if (isValidMove) {
+ // 鏇存柊glassPoint鍧愭爣
+ if (glassDetail.glassPoint && Array.isArray(glassDetail.glassPoint)) {
+ const offsetX = glassDetail.x - originalX;
+ const offsetY = glassDetail.y - originalY;
+
+ glassDetail.glassPoint.forEach(point => {
+ point.X += offsetX;
+ point.Y += offsetY;
+ // 娣诲姞绮惧害鎺у埗
+ point.X = parseFloat(point.X.toFixed(2));
+ point.Y = parseFloat(point.Y.toFixed(2));
+ });
+ }
adjustGrayRectangles(layoutIndex);
} else {
- rect.x = originalState.x;
- rect.y = originalState.y;
+ glassDetail.x = originalState.x;
+ glassDetail.y = originalState.y;
ElMessage.warning('鏃犳硶绉诲姩锛屽瓨鍦ㄩ噸鍙犳垨瓒呭嚭杈圭晫');
}
};
@@ -823,82 +1110,104 @@
//鍒犻櫎灏忕墖
const deleteRect = (layoutIndex, rectIndex) => {
const layout = layouts.value[layoutIndex];
- layout.rects.splice(rectIndex, 1);
+ layout.glassDetails.splice(rectIndex, 1);
adjustGrayRectangles(layoutIndex);
};
//鍒ゆ柇鍘熺墖璺熷皬鐗囩Щ鍔ㄦ槸鍚﹁秴鍑�
const checkOverlap = (rect1, rect2) => {
- return !(rect1.x + rect1.w <= rect2.x ||
- rect1.x >= rect2.x + rect2.w ||
- rect1.y + rect1.h <= rect2.y ||
- rect1.y >= rect2.y + rect2.h);
+ return !(rect1.x + rect1.width <= rect2.x ||
+ rect1.x >= rect2.x + rect2.width ||
+ rect1.y + rect1.height <= rect2.y ||
+ rect1.y >= rect2.y + rect2.height);
};
//閲嶆柊璁$畻浣欐枡鍧愭爣浠ュ強灏哄1
-const calculateRemainingAreas = (totalWidth, totalHeight, obstacles) => {
- let remaining = [{ x: 0, y: 0, w: totalWidth, h: totalHeight }];
- obstacles.forEach(rect => {
- remaining = cutRemainingAreas(remaining, rect,totalWidth,totalHeight);
- });
- return remaining;
-};
+// const calculateRemainingAreas = (totalWidth, totalHeight, obstacles) => {
+// let remaining = [{ x: 0, y: 0, width: totalWidth, height: totalHeight }];
+// obstacles.forEach(glassDetail => {
+// remaining = cutRemainingAreas(remaining, glassDetail,totalWidth,totalHeight);
+// });
+// return remaining;
+// };
//閲嶆柊璁$畻浣欐枡鍧愭爣浠ュ強灏哄2
-const cutRemainingAreas = (remainingAreas, obstacle,totalWidth,totalHeight) => {
+const cutRemainingAreas = (remainingAreas, obstacle, totalWidth, totalHeight) => {
const newRemaining = [];
- remainingAreas.forEach(area => {
- if (checkOverlap(area, obstacle)) {
- if (obstacle.x > area.x) {
- newRemaining.push({
- x: area.x,
- y: area.y,
- w: obstacle.x - area.x,
- h: area.h
- });
- }
- if (obstacle.x + obstacle.w < area.x + area.w) {
- newRemaining.push({
- x: obstacle.x + obstacle.w,
- y: area.y,
- w: area.w - (obstacle.x + obstacle.w - area.x),
- h: area.h
- });
- }
- if (obstacle.y > area.y) {
- newRemaining.push({
- x: area.x,
- y: area.y,
- w: area.w,
- h: obstacle.y - area.y
- });
- }
- if (obstacle.y + obstacle.h < area.y + area.h ) {
- newRemaining.push({
- x: area.x,
- y: obstacle.y + obstacle.h,
- w: area.w,
- h: area.h - (obstacle.y + obstacle.h - area.y)
- });
- }
- } else {
+ remainingAreas.forEach(area => {
+ // 濡傛灉闅滅鐗╀笌褰撳墠鍖哄煙娌℃湁閲嶅彔锛屼繚鐣欏師鍖哄煙
+ if (!checkOverlap(area, obstacle)) {
newRemaining.push(area);
+ return;
+ }
+
+ // 璁$畻閲嶅彔鍖哄煙鐨勮竟鐣�
+ const overlapLeft = Math.max(area.x, obstacle.x);
+ const overlapRight = Math.min(area.x + area.width, obstacle.x + obstacle.width);
+ const overlapTop = Math.max(area.y, obstacle.y);
+ const overlapBottom = Math.min(area.y + area.height, obstacle.y + obstacle.height);
+
+ // 鐢熸垚鍥涗釜鍙兘鐨勬柊鍖哄煙锛堜笂銆佷笅銆佸乏銆佸彸锛�
+
+ // 涓婃柟鍖哄煙
+ if (overlapTop > area.y) {
+ newRemaining.push({
+ x: area.x,
+ y: area.y,
+ width: area.width,
+ height: overlapTop - area.y
+ });
+ }
+
+ // 涓嬫柟鍖哄煙
+ if (overlapBottom < area.y + area.height) {
+ newRemaining.push({
+ x: area.x,
+ y: overlapBottom,
+ width: area.width,
+ height: area.y + area.height - overlapBottom
+ });
+ }
+
+ // 宸︽柟鍖哄煙锛堜粎鍦ㄩ噸鍙犲尯鍩熺殑鍨傜洿鑼冨洿鍐咃級
+ if (overlapLeft > area.x) {
+ const regionTop = overlapTop;
+ const regionBottom = overlapBottom;
+ newRemaining.push({
+ x: area.x,
+ y: regionTop,
+ width: overlapLeft - area.x,
+ height: regionBottom - regionTop
+ });
+ }
+
+ // 鍙虫柟鍖哄煙锛堜粎鍦ㄩ噸鍙犲尯鍩熺殑鍨傜洿鑼冨洿鍐咃級
+ if (overlapRight < area.x + area.width) {
+ const regionTop = overlapTop;
+ const regionBottom = overlapBottom;
+ newRemaining.push({
+ x: overlapRight,
+ y: regionTop,
+ width: area.x + area.width - overlapRight,
+ height: regionBottom - regionTop
+ });
}
});
+
return newRemaining;
};
//瀹氫箟姣忎釜鐗堝浘鐨勭患鍚堝唴瀹�
const getCurrentRectInfo = (layoutIndex) => {
const layout = layouts.value[layoutIndex];
- const rect = layout.rects[focusIndex.value?.rectIndex || 0];
- if (!rect) return '';
+/* const glassDetail = layout.glassDetails[focusIndex.value?.rectIndex || 0];
+ if (!glassDetail) return '';*/
const totalRects = layouts.value.length;
const currentRectIndex = layoutIndex + 1;
- const width = layout.width;
- const height = layout.height;
- const percentage = ((rect.w / layout.width) * 100).toFixed(1) + '%';
+ const width = layout.realWidth;
+ const height = layout.realHeight;
+ const percentage = (layout.usageRate * 100).toFixed(2) + '%';
return `${currentRectIndex}/${totalRects} ${width}脳${height} 脳1 ${percentage}`;
};
@@ -910,56 +1219,57 @@
//鎶婁紶杈撶殑鏁版嵁璧嬪��
const updateLayout = () => {
if (!layoutPanel.value) return;
- layouts.value = props.layoutData.Layouts;
+ layoutsHead.value = props.layoutData;
+ layouts.value = props.layoutData.layouts;
};
//鍚戜笂绉诲姩璁$畻鍧愭爣
-const getAvailableSpaceUp = (rect, layout, obstacles) => {
- let maxSpace = layout.height - (rect.y + rect.h);
+const getAvailableSpaceUp = (glassDetail, layout, obstacles) => {
+ let maxSpace = layout.height - glassDetail.y - glassDetail.height;
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));
+ if (obstacle.y > glassDetail.y + glassDetail.height &&
+ obstacle.x <= glassDetail.x + glassDetail.width &&
+ obstacle.x + obstacle.width >= glassDetail.x) {
+ maxSpace = Math.min(maxSpace, obstacle.y - (glassDetail.y + glassDetail.height));
}
});
return maxSpace;
};
//鍚戜笅绉诲姩璁$畻鍧愭爣
-const getAvailableSpaceDown = (rect, layout, obstacles) => {
- let maxSpace = rect.y;
+const getAvailableSpaceDown = (glassDetail, layout, obstacles) => {
+ let maxSpace = glassDetail.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));
+ if (obstacle.y + obstacle.height < glassDetail.y &&
+ obstacle.x <= glassDetail.x + glassDetail.width &&
+ obstacle.x + obstacle.width >= glassDetail.x) {
+ maxSpace = Math.min(maxSpace, glassDetail.y - (obstacle.y + obstacle.height));
}
});
return maxSpace;
};
//鍚戝乏绉诲姩璁$畻鍧愭爣
-const getAvailableSpaceLeft = (rect, layout, obstacles) => {
- let maxSpace = rect.x;
+const getAvailableSpaceLeft = (glassDetail, layout, obstacles) => {
+ let maxSpace = glassDetail.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));
+ if (obstacle.x + obstacle.width < glassDetail.x &&
+ obstacle.y <= glassDetail.y + glassDetail.height &&
+ obstacle.y + obstacle.height >= glassDetail.y) {
+ maxSpace = Math.min(maxSpace, glassDetail.x - (obstacle.x + obstacle.width));
}
});
return maxSpace;
};
//鍚戝彸绉诲姩璁$畻鍧愭爣
-const getAvailableSpaceRight = (rect, layout, obstacles) => {
- let maxSpace = layout.width - (rect.x + rect.w);
+const getAvailableSpaceRight = (glassDetail, layout, obstacles) => {
+ let maxSpace = layout.width - (glassDetail.x + glassDetail.width);
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));
+ if (obstacle.x > glassDetail.x + glassDetail.width &&
+ obstacle.y <= glassDetail.y + glassDetail.height &&
+ obstacle.y + obstacle.height >= glassDetail.y) {
+ maxSpace = Math.min(maxSpace, obstacle.x - (glassDetail.x + glassDetail.width));
}
});
return maxSpace;
@@ -973,15 +1283,15 @@
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);
+ const glassDetail = layout.glassDetails[rectIndex];
+ const obstacles = layout.glassDetails.filter(r => r.isRemain || r !== glassDetail);
switch (event.key) {
case 'ArrowUp':
event.preventDefault();
if (!moveInterval) {
moveInterval = setInterval(() => {
- moveRect(layoutIndex, rectIndex, 'up');
+ moveRect(layoutIndex, rectIndex, 'down');
}, 50);
}
break;
@@ -989,7 +1299,7 @@
event.preventDefault();
if (!moveInterval) {
moveInterval = setInterval(() => {
- moveRect(layoutIndex, rectIndex, 'down');
+ moveRect(layoutIndex, rectIndex, 'up');
}, 50);
}
break;
@@ -1027,20 +1337,29 @@
const mirrorLayoutX = (layoutIndex) => {
const layout = layouts.value[layoutIndex];
const width = layout.width;
- const rects = [...layout.rects]; // 鍒涘缓鍓湰閬垮厤鐩存帴淇敼
+ const glassDetails = [...layout.glassDetails]; // 鍒涘缓鍓湰閬垮厤鐩存帴淇敼
- rects.forEach(rect => {
+ glassDetails.forEach(glassDetail => {
// 璁$畻X闀滃儚鍚庣殑鍧愭爣
- const newX = width - rect.x - rect.w;
- const newY = rect.y;
+ const newX = width - glassDetail.x - glassDetail.width;
+ const newY = glassDetail.y;
// 鏇存柊鐭╁舰浣嶇疆
- rect.x = newX;
- rect.y = newY;
+ glassDetail.x = newX;
+ glassDetail.y = newY;
+
+ // 鏇存柊glassPoint鍧愭爣
+ if (glassDetail.glassPoint && Array.isArray(glassDetail.glassPoint)) {
+ glassDetail.glassPoint.forEach(point => {
+ point.X = width - point.X;
+ point.X = parseFloat(point.X.toFixed(2));
+ point.Y = parseFloat(point.Y.toFixed(2));
+ });
+ }
});
// 鏇存柊甯冨眬
- layout.rects = rects;
+ layout.glassDetails = glassDetails;
adjustGrayRectangles(layoutIndex);
};
@@ -1048,19 +1367,29 @@
const mirrorLayoutY = (layoutIndex) => {
const layout = layouts.value[layoutIndex];
const height = layout.height;
- const rects = [...layout.rects]; // 鍒涘缓鍓湰閬垮厤鐩存帴淇敼
+ const glassDetails = [...layout.glassDetails]; // 鍒涘缓鍓湰閬垮厤鐩存帴淇敼
- rects.forEach(rect => {
+ glassDetails.forEach(glassDetail => {
// 璁$畻Y闀滃儚鍚庣殑鍧愭爣
- const newX = rect.x;
- const newY = height - rect.y - rect.h;
+ const newX = glassDetail.x;
+ const newY = height - glassDetail.y - glassDetail.height;
// 鏇存柊鐭╁舰浣嶇疆
- rect.y = newY;
+ glassDetail.y = newY;
+
+ // 鏇存柊glassPoint鍧愭爣
+ if (glassDetail.glassPoint && Array.isArray(glassDetail.glassPoint)) {
+ glassDetail.glassPoint.forEach(point => {
+ point.Y = height - point.Y;
+ // 娣诲姞绮惧害鎺у埗
+ point.X = parseFloat(point.X.toFixed(2));
+ point.Y = parseFloat(point.Y.toFixed(2));
+ });
+ }
});
// 鏇存柊甯冨眬
- layout.rects = rects;
+ layout.glassDetails = glassDetails;
adjustGrayRectangles(layoutIndex);
};
@@ -1099,7 +1428,7 @@
margin-top: 50px;
}
-.layout-rect {
+.layout-glassDetail {
user-select: none;
}
@@ -1118,7 +1447,7 @@
font-weight: bold;
}
-.rect-content {
+.glassDetail-content {
display: flex;
flex-direction: column;
align-items: flex-start;
@@ -1168,4 +1497,17 @@
.context-menu div:hover {
background-color: #f0f0f0;
}
+
+.folder-header {
+ font-weight: bold;
+}
+
+.folder-header:hover {
+ background-color: #d0d0d0 !important;
+}
+
+.folder-content {
+ border-left: 2px solid #ccc;
+ margin-left: 5px;
+}
</style>
--
Gitblit v1.8.0