diff --git a/frontend/src/views/dashboard/canvas/CanvasCore.vue b/frontend/src/views/dashboard/canvas/CanvasCore.vue
index 05488ac4..5ed2c796 100644
--- a/frontend/src/views/dashboard/canvas/CanvasCore.vue
+++ b/frontend/src/views/dashboard/canvas/CanvasCore.vue
@@ -8,6 +8,7 @@ import {findComponent} from "@/views/dashboard/components/component-list.ts";
const dashboardStore = dashboardStoreWithOut()
const canvasLocked = ref(false) // Is the canvas movement locked, Default false
+const emits = defineEmits(["parentAddItemBox"]);
// @ts-ignore
let currentInstance
// Props
@@ -400,11 +401,26 @@ function removeItem(index: number) {
canvasComponentData.value.splice(index, 1)
}
+function getNextDragId() {
+ if (!canvasComponentData.value || canvasComponentData.value.length === 0) {
+ return 0;
+ }
+ //@ts-ignore
+ const validIds = canvasComponentData.value.map(item => item._dragId).filter(id => id != null && id !== ''); // 过滤 null、undefined 和空字符串
+
+ if (validIds.length === 0) {
+ return 0;
+ }
+ //@ts-ignore
+ const maxDragId = Math.max(...validIds);
+ return maxDragId + 1;
+}
+
function addItem(item: CanvasItem, index: any) {
if (index < 0) {
index = canvasComponentData.value.length
}
- item._dragId = index
+ item._dragId = getNextDragId()
checkItemPosition(item, {x: item.x, y: item.y})
emptyTargetCell(item)
addItemToPositionBox(item)
@@ -899,15 +915,25 @@ function startMove(e: MouseEvent, item: CanvasItem, index: number) {
if (canvasLocked.value) {
const moveItem = infoBox.value.moveItem
// Get the SQTab currently being moved in
- const curActiveSQTab = canvasComponentData?.value.find(item => item.component === 'SQTab' && item.moveInActive === true);
- if (curActiveSQTab) {
- // @ts-ignore
- const refTabInstance = currentInstance.refs['shape_component_' + curActiveSQTab.id][0]
- refTabInstance.addTabItem(moveItem)
- removeItemById(moveItem.id)
- curActiveSQTab.collisionActive = false
- curActiveSQTab.moveInActive = false
+ const curActiveMoveInSQTab = canvasComponentData?.value.find(item => item.component === 'SQTab' && item.collisionActive === true);
+ if (curActiveMoveInSQTab) {
+ if (curActiveMoveInSQTab.moveInActive) {
+ // @ts-ignore
+ const refTabInstance = currentInstance.refs['shape_component_' + curActiveMoveInSQTab.id][0]
+ refTabInstance.addTabItem(moveItem)
+ removeItemById(moveItem.id)
+ }
+ curActiveMoveInSQTab.collisionActive = false
+ curActiveMoveInSQTab.moveInActive = false
}
+
+ // move out
+ if (props.parentConfigItem && props.parentConfigItem.moveOutActive) {
+ emits('parentAddItemBox', _.cloneDeep(moveItem))
+ removeItemById(moveItem.id)
+ props.parentConfigItem.moveOutActive = false
+ }
+
}
canvasLocked.value = false
}
@@ -1045,6 +1071,7 @@ function tabMoveOutCheckSQ() {
const top = cloneItem.offsetTop
const {tw} = getItemStylePosition(props.parentConfigItem)
props.parentConfigItem.moveOutActive = left < -tabMoveOutXOffset || top < -tabMoveOutYOffset || (left + width - tw) > tabMoveOutXOffset;
+ canvasLocked.value = props.parentConfigItem.moveOutActive
}
}
@@ -1135,7 +1162,8 @@ defineExpose({
+ :config-item="item"
+ @parentAddItemBox=" (subItem:any) => addItemBox(subItem)">
diff --git a/frontend/src/views/dashboard/canvas/CanvasShape.vue b/frontend/src/views/dashboard/canvas/CanvasShape.vue
index dce46a3e..9d811e3c 100644
--- a/frontend/src/views/dashboard/canvas/CanvasShape.vue
+++ b/frontend/src/views/dashboard/canvas/CanvasShape.vue
@@ -42,6 +42,7 @@ const { draggable } = toRefs(props)
+
\ No newline at end of file
diff --git a/frontend/src/views/dashboard/css/CanvasStyle.less b/frontend/src/views/dashboard/css/CanvasStyle.less
index 19007df5..e84ff82c 100644
--- a/frontend/src/views/dashboard/css/CanvasStyle.less
+++ b/frontend/src/views/dashboard/css/CanvasStyle.less
@@ -1,105 +1,104 @@
-.dragAndResize
-{
- position: relative;
- user-select: none;
- width: 100%;
- *
- {
- box-sizing: border-box;
- margin: 0;
- padding: 0;
- }
- .item
- {
- position: absolute;
- width: 100px;
- height: 100px;
- cursor: move;
- border: 1px solid #59c7f9;
- background-color: #fff;
- .resizeHandle
- {
- position: absolute;
- background: #fff;
- border: 1px solid #59c7f9;
- width: 8px;
- height: 8px;
- border-radius: 50%;
- z-index: 5;
- }
- .sql-component {
- width: 100%;
- height: 100%;
- }
- }
- .moveAnimation
- {
- transition: top 80ms ease;
- }
- .canNotDrag
- {
- cursor: default!important;
+.dragAndResize {
+ position: relative;
+ user-select: none;
+ width: 100%;
+
+ * {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ }
+
+ .itemCursorDefault {
+ cursor: default!important;
+ }
+ .item {
+ position: absolute;
+ width: 100px;
+ height: 100px;
+ border: 1px solid #59c7f9;
+ background-color: #fff;
+ cursor: move;
+ .resizeHandle {
+ position: absolute;
+ background: #fff;
+ border: 1px solid #59c7f9;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ z-index: 5;
}
- .cloneNode
- {
- z-index: 100;
+ .sql-component {
+ width: 100%;
+ height: 100%;
+ }
+ }
- transition: none;
+ .moveAnimation {
+ transition: top 80ms ease;
+ }
- opacity: .5;
+ .canNotDrag {
+ cursor: default !important;
+ }
+
+ .cloneNode {
+ z-index: 100;
+
+ transition: none;
+
+ opacity: .5;
+ }
+
+ .movingItem {
+ position: absolute;
+
+ border: none;
+
+ &:before {
+ position: absolute;
+ z-index: 2;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ content: '';
+ background-color: #b8d3f9;
}
- .movingItem
- {
- position: absolute;
-
- border: none;
- &:before
- {
- position: absolute;
- z-index: 2;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- content: '';
- background-color: #b8d3f9;
- }
- .resizeHandle
- {
- display: none;
- }
- .slot-component {
- display: none;
- }
+ .resizeHandle {
+ display: none;
}
- .positionBox
- {
- position: fixed;
- top: 0;
- right: 100px;
-
- overflow: auto;
-
- width: 500px;
- height: 500px;
-
- border: 1px solid;
+ .slot-component {
+ display: none;
}
+ }
- .coords
- {
- position: fixed;
- right: 100px;
- bottom: 200px;
+ .positionBox {
+ position: fixed;
+ top: 0;
+ right: 100px;
- overflow: auto;
+ overflow: auto;
- width: 200px;
- height: 200px;
+ width: 500px;
+ height: 500px;
- border: 1px solid;
- }
+ border: 1px solid;
+ }
+
+ .coords {
+ position: fixed;
+ right: 100px;
+ bottom: 200px;
+
+ overflow: auto;
+
+ width: 200px;
+ height: 200px;
+
+ border: 1px solid;
+ }
}
\ No newline at end of file
diff --git a/frontend/src/views/dashboard/editor/DashboardEditor.vue b/frontend/src/views/dashboard/editor/DashboardEditor.vue
index a06fa3dd..bbddd6be 100644
--- a/frontend/src/views/dashboard/editor/DashboardEditor.vue
+++ b/frontend/src/views/dashboard/editor/DashboardEditor.vue
@@ -83,6 +83,7 @@ onMounted(() => {
}
})
})
+const emits = defineEmits(["parentAddItemBox"]);
@@ -99,6 +100,7 @@ onMounted(() => {
:canvas-component-data="canvasComponentData"
:parent-config-item="parentConfigItem"
:canvas-id="canvasId"
+ @parentAddItemBox=" item => emits('parentAddItemBox',item)"
>
diff --git a/frontend/src/views/dashboard/editor/index.vue b/frontend/src/views/dashboard/editor/index.vue
index 89692c27..250617a6 100644
--- a/frontend/src/views/dashboard/editor/index.vue
+++ b/frontend/src/views/dashboard/editor/index.vue
@@ -3,7 +3,7 @@ import {ref} from 'vue'
import Toolbar from "@/views/dashboard/editor/Toolbar.vue";
import DashboardEditor from "@/views/dashboard/editor/DashboardEditor.vue";
import {findNewComponentFromList} from "@/views/dashboard/components/component-list.ts";
-import {guid} from "@/utils/canvas.ts";
+import {type CanvasItem, guid} from "@/utils/canvas.ts";
import cloneDeep from 'lodash/cloneDeep';
@@ -56,7 +56,10 @@ const componentData = ref([
-
+
+