diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue
new file mode 100644
index 0000000..8b5814c
--- /dev/null
+++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/Area.vue
@@ -0,0 +1,145 @@
+
+
+
+
+
+ ◈
+ {{ title || 'GlobalHook_Test' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/Panel.js b/AutoRobot/Windows/Robot/Web/src/DockLayout/Panel.js
deleted file mode 100644
index afc1af9..0000000
--- a/AutoRobot/Windows/Robot/Web/src/DockLayout/Panel.js
+++ /dev/null
@@ -1,263 +0,0 @@
-import { ref, computed, defineComponent, onMounted, onUnmounted, watch, nextTick } from 'vue';
-
-/**
- * 浮动面板组件
- * 提供可拖拽、最大化、最小化、折叠和工具栏扩展功能的窗口组件
- */
-export default defineComponent({
- name: 'Panel',
- props: {
- panel: {
- type: Object,
- required: true,
- validator: (value) => {
- return value && typeof value === 'object' && 'id' in value && 'title' in value;
- }
- },
- hostRef: {
- type: Object,
- default: null
- }
- },
- emits: ['close', 'toggleCollapse', 'toggleToolbar', 'maximize'],
- setup(props, { emit }) {
- // 响应式状态管理
- const isDragging = ref(false);
- const dragStartPos = ref({ x: 0, y: 0 });
- const panelPosition = ref({
- x: props.panel.x || 100,
- y: props.panel.y || 100
- });
- const panelSize = ref({
- width: props.panel.width || 300,
- height: props.panel.height || 180
- });
-
- // 同步面板属性变化
- const syncPanelProperties = () => {
- if (props.panel.x !== undefined) panelPosition.value.x = props.panel.x;
- if (props.panel.y !== undefined) panelPosition.value.y = props.panel.y;
- if (props.panel.width !== undefined) panelSize.value.width = props.panel.width;
- if (props.panel.height !== undefined) panelSize.value.height = props.panel.height;
- };
-
- // 计算面板样式
- const panelStyle = computed(() => {
- // 直接使用props.panel中的值,确保与父组件状态同步
- const posX = props.panel.x || 100;
- const posY = props.panel.y || 100;
- const width = props.panel.width || 300;
- const height = props.panel.height || 180;
-
- // 始终创建新对象,避免Vue响应式系统无法检测变化
- const style = {
- position: 'absolute',
- top: `${posY}px`,
- left: `${posX}px`,
- width: `${width}px`,
- height: `${height}px`,
- backgroundColor: 'white',
- border: '1px solid #435d9c', // 更深的边框颜色以增强可见性
- borderRadius: '4px',
- boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.15)',
- overflow: 'hidden',
- zIndex: 10,
- display: 'flex',
- flexDirection: 'column'
- };
-
- // 最大化状态
- if (props.panel.maximized) {
- // 获取host元素 - 直接使用hostRef或者hostRef.value(如果是ref)
- const host = props.hostRef && typeof props.hostRef.getBoundingClientRect === 'function'
- ? props.hostRef
- : props.hostRef?.value;
- const rect = host?.getBoundingClientRect();
- if (rect) {
- style.top = '0px';
- style.left = '0px';
- style.width = `${rect.width - 2}px`;
- style.height = `${rect.height - 2}px`;
- }
- }
-
- return style;
- });
-
- // 处理标题栏拖拽
- const handleTitleBarMouseDown = (event) => {
- if (props.panel.maximized) return;
-
- isDragging.value = true;
- dragStartPos.value = {
- x: event.clientX - panelPosition.value.x,
- y: event.clientY - panelPosition.value.y
- };
-
- event.preventDefault();
- };
-
- // 处理窗口关闭
- const handleClose = () => {
- emit('close', props.panel.id);
- };
-
- // 处理折叠/展开
- const handleToggleCollapse = () => {
- emit('toggleCollapse', props.panel.id);
- };
-
- // 处理工具栏展开/收起
- const handleToggleToolbar = () => {
- emit('toggleToolbar', props.panel.id);
- };
-
- // 处理最大化/还原
- const handleMaximize = () => {
- emit('maximize', props.panel.id);
- };
-
- // 鼠标移动事件处理
- const handleMouseMove = (event) => {
- if (isDragging.value && !props.panel.maximized) {
- panelPosition.value = {
- x: event.clientX - dragStartPos.value.x,
- y: event.clientY - dragStartPos.value.y
- };
- }
- };
-
- // 鼠标松开事件处理
- const handleMouseUp = () => {
- isDragging.value = false;
- };
-
- // 监听面板属性变化
- watch(() => props.panel, (newPanel) => {
- if (newPanel) {
- syncPanelProperties();
- }
- }, { deep: true, immediate: true });
-
- // 生命周期钩子
- onMounted(async () => {
- // 确保DOM更新后再同步状态
- await nextTick();
- // 同步外部面板状态
- syncPanelProperties();
-
- // 添加全局事件监听
- document.addEventListener('mousemove', handleMouseMove);
- document.addEventListener('mouseup', handleMouseUp);
- });
-
- onUnmounted(() => {
- // 清理全局事件监听
- document.removeEventListener('mousemove', handleMouseMove);
- document.removeEventListener('mouseup', handleMouseUp);
- });
-
- return {
- isDragging,
- panelStyle,
- handleTitleBarMouseDown,
- handleClose,
- handleToggleCollapse,
- handleToggleToolbar,
- handleMaximize
- };
- },
- template: `
-
-
-
-
-
- {{ panel.title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 工具栏
-
-
-
-
-
-
-
-
-
-
-
- `,
- // 样式应该放在模板外部,作为组件的style选项
- style: `
- /* 向下小三角 */
- .panel-container .icon-triangle-down {
- width: 0; height: 0;
- border-left: 5px solid transparent;
- border-right: 5px solid transparent;
- border-top: 6px solid #cbd6ff;
- }
-
- /* 最大化图标 */
- .panel-container .icon-square {
- position: relative;
- width: 11px; height: 11px;
- background: linear-gradient(180deg, #cbd6ff 0%, #b9c8ff 100%);
- border: 1px solid #b8c6ff;
- box-sizing: border-box;
- }
-
- /* X图标 */
- .panel-container .icon-x {
- position: relative; width: 11px; height: 11px;
- }
- .panel-container .icon-x::before, .panel-container .icon-x::after {
- content: ''; position: absolute; left: 5px; top: 0; width: 1px; height: 11px; background: #e6efff;
- }
- .panel-container .icon-x::before { transform: rotate(45deg); }
- .panel-container .icon-x::after { transform: rotate(-45deg); }
- `
-});
diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/Panel.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/Panel.vue
new file mode 100644
index 0000000..0be7e66
--- /dev/null
+++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/Panel.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
\ No newline at end of file