31
This commit is contained in:
@@ -147,5 +147,5 @@
|
||||
"activeTabId": "mxfx11j"
|
||||
}
|
||||
},
|
||||
"lastUpdated": "2025-12-22T15:54:13.388Z"
|
||||
"lastUpdated": "2026-01-20T11:33:21.385Z"
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from 'vue'
|
||||
import { useInteractionStore, useDragStore, generateElementPath } from '../../plugins'
|
||||
import type { ElementType, InteractionTarget } from '../../plugins'
|
||||
import { useVueFileStore } from '../../stores/vueFileStore'
|
||||
import DropZone from './DropZone.vue'
|
||||
import DragPreview from './DragPreview.vue'
|
||||
|
||||
@@ -11,6 +12,7 @@ const props = defineProps<{
|
||||
|
||||
const interactionStore = useInteractionStore()
|
||||
const dragStore = useDragStore()
|
||||
const vueFileStore = useVueFileStore()
|
||||
const containerRef = ref<HTMLElement | null>(null)
|
||||
|
||||
// 存储所有绑定的事件清理函数
|
||||
@@ -222,13 +224,25 @@ const clearDragHighlight = () => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局鼠标移动处理(拖拽时更新方向)
|
||||
*/
|
||||
const handleGlobalMouseMove = (e: MouseEvent) => {
|
||||
if (dragStore.isDragging && dragStore.selectedNode) {
|
||||
dragStore.updateDirectionFromMouse(e.clientX, e.clientY)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局鼠标松开处理
|
||||
*/
|
||||
const handleGlobalMouseUp = () => {
|
||||
const handleGlobalMouseUp = async () => {
|
||||
if (dragStore.isDragging && dragStore.selectedNode && dragStore.hoverDirection) {
|
||||
// 确认拖放
|
||||
dragStore.confirmDrop()
|
||||
// 获取当前页面路径(从vueFileStore)
|
||||
const pagePath = vueFileStore.selectedFilePath
|
||||
|
||||
// 确认拖放,传入页面路径
|
||||
await dragStore.confirmDrop(pagePath || undefined)
|
||||
}
|
||||
|
||||
dragStore.endDrag()
|
||||
@@ -247,6 +261,8 @@ onMounted(() => {
|
||||
|
||||
// 添加键盘事件监听
|
||||
document.addEventListener('keydown', handleKeyDown)
|
||||
// 添加全局鼠标移动事件(用于更新拖放方向)
|
||||
document.addEventListener('mousemove', handleGlobalMouseMove)
|
||||
// 添加全局鼠标松开事件
|
||||
document.addEventListener('mouseup', handleGlobalMouseUp)
|
||||
})
|
||||
@@ -263,6 +279,7 @@ onUnmounted(() => {
|
||||
|
||||
// 移除键盘事件监听
|
||||
document.removeEventListener('keydown', handleKeyDown)
|
||||
document.removeEventListener('mousemove', handleGlobalMouseMove)
|
||||
document.removeEventListener('mouseup', handleGlobalMouseUp)
|
||||
})
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@ import { ref, computed } from 'vue'
|
||||
import type { InteractionTarget, ElementType } from './interactionStore'
|
||||
import { parsePath } from './pathUtils'
|
||||
|
||||
// 后端服务地址
|
||||
const TEMPLATE_SERVICE_URL = 'http://localhost:3001'
|
||||
|
||||
/**
|
||||
* 拖放方向
|
||||
*/
|
||||
@@ -177,16 +180,17 @@ export const useDragStore = defineStore('drag', () => {
|
||||
// 3. 找到最接近的深度
|
||||
if (oldSelectedDepth !== undefined && nodes.length > 0) {
|
||||
let closestIndex = 0
|
||||
let minDiff = Math.abs(nodes[0].depth - oldSelectedDepth)
|
||||
let minDiff = Math.abs((nodes[0]?.depth ?? 0) - oldSelectedDepth)
|
||||
for (let i = 1; i < nodes.length; i++) {
|
||||
const diff = Math.abs(nodes[i].depth - oldSelectedDepth)
|
||||
const nodeDepth = nodes[i]?.depth ?? 0
|
||||
const diff = Math.abs(nodeDepth - oldSelectedDepth)
|
||||
if (diff < minDiff) {
|
||||
minDiff = diff
|
||||
closestIndex = i
|
||||
}
|
||||
}
|
||||
selectedHierarchyIndex.value = closestIndex
|
||||
console.log('[DragStore] 选择最接近深度:', nodes[closestIndex].path)
|
||||
console.log('[DragStore] 选择最接近深度:', nodes[closestIndex]?.path)
|
||||
} else {
|
||||
// 4. 默认选中最深层级
|
||||
selectedHierarchyIndex.value = 0
|
||||
@@ -242,9 +246,32 @@ export const useDragStore = defineStore('drag', () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认拖放
|
||||
* 根据鼠标位置自动计算拖放方向
|
||||
* @param mouseX 鼠标X坐标
|
||||
* @param mouseY 鼠标Y坐标
|
||||
*/
|
||||
const confirmDrop = () => {
|
||||
const updateDirectionFromMouse = (mouseX: number, mouseY: number) => {
|
||||
if (!selectedNode.value?.element) return
|
||||
|
||||
const rect = selectedNode.value.element.getBoundingClientRect()
|
||||
const isRow = selectedNode.value.type === 'er'
|
||||
|
||||
if (isRow) {
|
||||
// Row: 上下方向
|
||||
const centerY = rect.top + rect.height / 2
|
||||
hoverDirection.value = mouseY < centerY ? 'top' : 'bottom'
|
||||
} else {
|
||||
// Col: 左右方向
|
||||
const centerX = rect.left + rect.width / 2
|
||||
hoverDirection.value = mouseX < centerX ? 'left' : 'right'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认拖放
|
||||
* @param pagePath 当前页面路径(相对于views目录)
|
||||
*/
|
||||
const confirmDrop = async (pagePath?: string): Promise<DropRecord | null> => {
|
||||
if (!isDragging.value || !dragSource.value || !selectedNode.value || !hoverDirection.value) {
|
||||
console.log('[DragStore] 拖放条件不满足')
|
||||
return null
|
||||
@@ -263,9 +290,52 @@ export const useDragStore = defineStore('drag', () => {
|
||||
|
||||
console.log('[DragStore] 确认拖放:', record)
|
||||
|
||||
// 如果提供了页面路径,发送API请求到后端
|
||||
if (pagePath && record.source.type === 'canvas-element') {
|
||||
await sendMoveRequest(pagePath, record)
|
||||
}
|
||||
|
||||
return record
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送移动请求到后端服务
|
||||
*/
|
||||
const sendMoveRequest = async (pagePath: string, record: DropRecord) => {
|
||||
try {
|
||||
console.log('[DragStore] 发送移动请求:', { pagePath, record })
|
||||
|
||||
const response = await fetch(`${TEMPLATE_SERVICE_URL}/api/move-element`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
pagePath,
|
||||
source: record.source,
|
||||
targetPath: record.targetPath,
|
||||
targetType: record.targetType,
|
||||
direction: record.direction
|
||||
})
|
||||
})
|
||||
|
||||
const result = await response.json()
|
||||
|
||||
if (result.success) {
|
||||
console.log('[DragStore] 移动成功:', result.message)
|
||||
// 触发页面刷新事件
|
||||
window.dispatchEvent(new CustomEvent('vue-template-updated', { detail: { pagePath } }))
|
||||
} else {
|
||||
console.error('[DragStore] 移动失败:', result.error)
|
||||
}
|
||||
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('[DragStore] API请求失败:', error)
|
||||
return { success: false, error: (error as Error).message }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消拖拽
|
||||
*/
|
||||
@@ -342,6 +412,7 @@ export const useDragStore = defineStore('drag', () => {
|
||||
selectParentLevel,
|
||||
selectChildLevel,
|
||||
setHoverDirection,
|
||||
updateDirectionFromMouse,
|
||||
confirmDrop,
|
||||
cancelDrag,
|
||||
endDrag,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "../../../.."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
Reference in New Issue
Block a user