diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue
index ae11d3d..1d61ced 100644
--- a/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue
+++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue
@@ -5,6 +5,47 @@
:class="{ 'is-maximized': isMaximized, 'is-normal': !isMaximized }"
:style="areaStyle"
>
+
+
@@ -93,6 +134,13 @@ const isDragging = ref(false)
const dragStartPos = ref({ x: 0, y: 0 })
const areaStartPos = ref({ x: 0, y: 0 })
+// 调整大小相关状态
+const isResizing = ref(false)
+const resizeStartPos = ref({ x: 0, y: 0 })
+const resizeDirection = ref(null)
+const resizeStartSize = ref({ width: 0, height: 0 })
+const resizeStartAreaPos = ref({ left: 0, top: 0 })
+
// 父容器引用
const parentContainer = ref(null)
@@ -229,6 +277,135 @@ const onDragEnd = () => {
document.removeEventListener('mouseup', onDragEnd)
}
+// 调整大小开始
+const onResizeStart = (direction, e) => {
+ if (isMaximized.value) return
+
+ isResizing.value = true
+ resizeDirection.value = direction
+ resizeStartPos.value = {
+ x: e.clientX,
+ y: e.clientY
+ }
+ resizeStartSize.value = {
+ width: originalPosition.value.width,
+ height: originalPosition.value.height
+ }
+ resizeStartAreaPos.value = {
+ left: originalPosition.value.left,
+ top: originalPosition.value.top
+ }
+
+ // 添加全局事件监听
+ document.addEventListener('mousemove', onResizeMove)
+ document.addEventListener('mouseup', onResizeEnd)
+ document.addEventListener('mouseleave', onResizeEnd)
+
+ // 防止文本选择
+ e.preventDefault()
+ e.stopPropagation()
+}
+
+// 调整大小移动
+const onResizeMove = (e) => {
+ if (!isResizing.value) return
+
+ const deltaX = e.clientX - resizeStartPos.value.x
+ const deltaY = e.clientY - resizeStartPos.value.y
+
+ let newWidth = resizeStartSize.value.width
+ let newHeight = resizeStartSize.value.height
+ let newLeft = resizeStartAreaPos.value.left
+ let newTop = resizeStartAreaPos.value.top
+
+ // 根据方向调整大小
+ switch (resizeDirection.value) {
+ case 'nw':
+ newWidth = Math.max(200, resizeStartSize.value.width - deltaX)
+ newHeight = Math.max(150, resizeStartSize.value.height - deltaY)
+ newLeft = resizeStartPos.value.left + deltaX
+ newTop = resizeStartPos.value.top + deltaY
+ break
+ case 'ne':
+ newWidth = Math.max(200, resizeStartSize.value.width + deltaX)
+ newHeight = Math.max(150, resizeStartSize.value.height - deltaY)
+ newTop = resizeStartPos.value.top + deltaY
+ break
+ case 'sw':
+ newWidth = Math.max(200, resizeStartSize.value.width - deltaX)
+ newHeight = Math.max(150, resizeStartSize.value.height + deltaY)
+ newLeft = resizeStartPos.value.left + deltaX
+ break
+ case 'se':
+ newWidth = Math.max(200, resizeStartSize.value.width + deltaX)
+ newHeight = Math.max(150, resizeStartSize.value.height + deltaY)
+ break
+ case 'n':
+ newHeight = Math.max(150, resizeStartSize.value.height - deltaY)
+ newTop = resizeStartPos.value.top + deltaY
+ break
+ case 'e':
+ newWidth = Math.max(200, resizeStartSize.value.width + deltaX)
+ break
+ case 's':
+ newHeight = Math.max(150, resizeStartSize.value.height + deltaY)
+ break
+ case 'w':
+ newWidth = Math.max(200, resizeStartSize.value.width - deltaX)
+ newLeft = resizeStartPos.value.left + deltaX
+ break
+ }
+
+ // 确保不超出父容器边界
+ if (parentContainer.value) {
+ const parentRect = parentContainer.value.getBoundingClientRect()
+
+ // 右边界检查
+ if (newLeft + newWidth > parentRect.width) {
+ newWidth = parentRect.width - newLeft
+ }
+ // 下边界检查
+ if (newTop + newHeight > parentRect.height) {
+ newHeight = parentRect.height - newTop
+ }
+ // 左边界检查
+ if (newLeft < 0) {
+ newWidth += newLeft
+ newLeft = 0
+ }
+ // 上边界检查
+ if (newTop < 0) {
+ newHeight += newTop
+ newTop = 0
+ }
+ }
+
+ // 更新位置和大小
+ originalPosition.value.width = newWidth
+ originalPosition.value.height = newHeight
+ originalPosition.value.left = newLeft
+ originalPosition.value.top = newTop
+
+ // 通知父组件位置变化
+ emit('update:position', {
+ left: newLeft,
+ top: newTop
+ })
+
+ // 防止文本选择
+ e.preventDefault()
+}
+
+// 调整大小结束
+const onResizeEnd = () => {
+ isResizing.value = false
+ resizeDirection.value = null
+ // 移除全局事件监听
+ document.removeEventListener('mousemove', onResizeMove)
+ document.removeEventListener('mouseup', onResizeEnd)
+ document.removeEventListener('mouseleave', onResizeEnd)
+}
+
const onToggleMaximize = () => {
const next = isMaximized.value ? '正常' : '最大化'
@@ -402,6 +579,89 @@ onMounted(() => {
min-height: 0;
}
+/* 调整大小的手柄样式 */
+.resize-handle {
+ position: absolute;
+ z-index: 20;
+ background: transparent;
+ pointer-events: auto;
+}
+
+/* 四个角 */
+.resize-handle-nw {
+ width: 12px;
+ height: 12px;
+ top: -6px;
+ left: -6px;
+ cursor: nwse-resize;
+}
+
+.resize-handle-ne {
+ width: 12px;
+ height: 12px;
+ top: -6px;
+ right: -6px;
+ cursor: nesw-resize;
+}
+
+.resize-handle-sw {
+ width: 12px;
+ height: 12px;
+ bottom: -6px;
+ left: -6px;
+ cursor: nesw-resize;
+}
+
+.resize-handle-se {
+ width: 12px;
+ height: 12px;
+ bottom: -6px;
+ right: -6px;
+ cursor: nwse-resize;
+}
+
+/* 四条边 */
+.resize-handle-n {
+ height: 12px;
+ top: -6px;
+ left: 12px;
+ right: 12px;
+ cursor: ns-resize;
+}
+
+.resize-handle-e {
+ width: 12px;
+ right: -6px;
+ top: 12px;
+ bottom: 12px;
+ cursor: ew-resize;
+}
+
+.resize-handle-s {
+ height: 12px;
+ bottom: -6px;
+ left: 12px;
+ right: 12px;
+ cursor: ns-resize;
+}
+
+.resize-handle-w {
+ width: 12px;
+ left: -6px;
+ top: 12px;
+ bottom: 12px;
+ cursor: ew-resize;
+}
+
+/* 鼠标悬停在边框上时的样式提示 */
+.vs-area.is-normal:not(:hover) .resize-handle {
+ opacity: 0;
+}
+
+.vs-area.is-normal:hover .resize-handle {
+ opacity: 0.5;
+}
+
/* 左侧输出 */
.vs-left { flex: 1; background: var(--vs-panel); display: flex; }
.left-blank { flex: 1; background: #eef1f9; border-right: 1px solid var(--vs-border); }