diff --git a/.gitignore b/.gitignore index f4a55f8..e1b61bf 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ Desktop.ini yarn.lock .ai/ +demo/data-custome.json diff --git a/demo/App.vue b/demo/App.vue index 6fa81d7..e4ccafc 100644 --- a/demo/App.vue +++ b/demo/App.vue @@ -1,9 +1,10 @@ @@ -3371,7 +3425,7 @@ defineExpose({ -
+
+ + diff --git a/src/components/GanttToolbar.vue b/src/components/GanttToolbar.vue index 2e38d2e..62b63bb 100644 --- a/src/components/GanttToolbar.vue +++ b/src/components/GanttToolbar.vue @@ -551,7 +551,7 @@ onUnmounted(() => {
-
+
('positionCache', null) -// 注入 TaskList 宽度(用于 tooltip 定位边界检测) -const taskListWidth = inject>('gantt-task-list-width', ref(0)) - // 注入右键菜单配置 const enableTaskBarContextMenu = inject>('enable-task-bar-context-menu', computed(() => true)) const hasTaskBarContextMenuSlot = inject>('task-bar-context-menu-slot', computed(() => false)) @@ -2396,10 +2396,7 @@ const bubbleIndicator = computed(() => { const showTooltip = ref(false) const tooltipPosition = ref({ x: 0, y: 0 }) -// TaskBar 悬停 tooltip 状态 -const showHoverTooltip = ref(false) -const hoverTooltipPosition = ref({ x: 0, y: 0 }) -const isTooltipBelow = ref(false) // v1.9.0 标记tooltip是否显示在TaskBar下方 +// TaskBar 悬停 tooltip 延迟定时器(状态已上移至 Timeline) let hoverTooltipTimer: number | null = null // 跟踪滚动状态,避免非滚动时的动画 @@ -2568,7 +2565,7 @@ const handleBubbleMouseEnter = (event: MouseEvent) => { event.stopPropagation() // v1.9.1 隐藏TaskBar的hover tooltip,只显示bubble tooltip - showHoverTooltip.value = false + emit('tooltip-hide') // 清除可能正在等待的tooltip定时器 if (hoverTooltipTimer) { window.clearTimeout(hoverTooltipTimer) @@ -2668,67 +2665,16 @@ const handleTaskBarMouseEnter = (event: MouseEvent) => { const mouseY = event.clientY // 延迟显示tooltip,避免快速滑过时显示 + // Singleton Tooltip:Timer后 emit tooltip-show,由 Timeline 统一计算位置和渲染 hoverTooltipTimer = window.setTimeout(() => { - showHoverTooltip.value = true const rect = targetElement.getBoundingClientRect() - - // 计算tooltip的预估宽高(根据实际CSS设置) - const tooltipWidth = 250 // 预估宽度 - const margin = 10 // 边距 - - // 视口尺寸 - const viewportWidth = window.innerWidth - const viewportHeight = window.innerHeight - - // v1.9.0 改为基于TaskBar边界定位 - // 水平位置:TaskBar中心对齐 - let x = rect.left + rect.width / 2 - // 默认显示在TaskBar上方边缘外(CSS transform: translateY(-100%)会向上偏移tooltip高度) - let y = rect.top - 10 - - // 获取TaskList的右边界(用于防止tooltip进入TaskList区域) - const taskListRightBoundary = taskListWidth.value + margin - - // 水平边界检测:左侧超出或进入TaskList区域 - if (x - tooltipWidth / 2 < taskListRightBoundary) { - x = taskListRightBoundary + tooltipWidth / 2 - } - // 水平边界检测:右侧超出 - if (x + tooltipWidth / 2 > viewportWidth - margin) { - x = viewportWidth - margin - tooltipWidth / 2 - } - - // 垂直边界检测:计算上下方可用空间,选择空间更大的方向 - const spaceAbove = rect.top - margin - const spaceBelow = viewportHeight - rect.bottom - margin - - // 动态计算tooltip高度(基础高度 + 每行内容) - const baseHeight = 80 // 基础高度(标题 + padding) - const rowHeight = 24 // 每行内容高度 - let contentRows = 4 // 默认4行(开始日期、结束日期、预估工时、实际工时、进度) - - // 资源视图且利用率<100%时,多1行 - if (viewMode.value === 'resource' && resourcePercent.value < 100) { - contentRows += 1 - } - // 有资源冲突警告时,多1行 - if (props.hasResourceConflict) { - contentRows += 1 - } - - const estimatedTooltipHeight = baseHeight + (contentRows * rowHeight) - - // 如果上方空间不足,显示在下方 - if (spaceAbove < estimatedTooltipHeight && spaceBelow > spaceAbove) { - // 显示在TaskBar下方 - y = rect.bottom + 10 - isTooltipBelow.value = true - } else { - // 显示在TaskBar上方 - isTooltipBelow.value = false - } - - hoverTooltipPosition.value = { x, y } + emit('tooltip-show', { + task: props.task, + taskStatus: taskStatus.value, + resourcePercent: resourcePercent.value, + hasResourceConflict: props.hasResourceConflict ?? false, + targetRect: rect, + }) }, 300) // 300ms延迟 } } @@ -2736,19 +2682,19 @@ const handleTaskBarMouseEnter = (event: MouseEvent) => { const handleTaskBarMouseLeave = () => { isTaskBarHovered.value = false - // 清除定时器并隐藏tooltip + // 清除定时器并通知 Timeline 隐藏 tooltip if (hoverTooltipTimer) { clearTimeout(hoverTooltipTimer) hoverTooltipTimer = null } - showHoverTooltip.value = false + emit('tooltip-hide') } // 监听拖拽/拉伸状态,如果开始拖拽/拉伸,立即隐藏tooltip // v1.9.7 使用 flush: 'sync' 确保状态变化时立即同步执行,避免在资源视图拖拽时因组件更新导致watch延迟执行 watch([isDragging, isResizingLeft, isResizingRight], ([dragging, resizingL, resizingR]) => { if (dragging || resizingL || resizingR) { - showHoverTooltip.value = false + emit('tooltip-hide') if (hoverTooltipTimer) { clearTimeout(hoverTooltipTimer) hoverTooltipTimer = null @@ -2767,18 +2713,14 @@ watch([isDragging, isResizingLeft, isResizingRight], ([dragging, resizingL, resi // v1.9.2 监听 Tab 悬停状态,当 Tab 悬停时立即隐藏 TaskBar 的 tooltip watch(isTabHovered, (tabHovered) => { if (tabHovered) { - // Tab 悬停:隐藏 TaskBar 的 tooltip - showHoverTooltip.value = false + // Tab 悬停:隐藏 TaskBar 的 tooltip(通知 Timeline) + emit('tooltip-hide') if (hoverTooltipTimer) { clearTimeout(hoverTooltipTimer) hoverTooltipTimer = null } - } else { - // Tab 离开:如果鼠标还在 TaskBar 上,重新显示 tooltip - if (isTaskBarHovered.value && props.enableTaskBarTooltip !== false) { - showHoverTooltip.value = true - } } + // Tab 离开后不主动重显 tooltip,等待用户下次 mouseenter 触发 }) // 格式化日期显示 @@ -3726,44 +3668,7 @@ const handleAnchorDragEnd = (anchorEvent: { taskId: number; type: 'predecessor'
- - -
-
-
-
{{ task.name }}
-
- {{ t('plannedStartDate') }}: - {{ formatDisplayDate(task.startDate) }} -
-
- {{ t('plannedEndDate') }}: - {{ formatDisplayDate(task.endDate) }} -
-
- {{ t('actualStartDate') }}: - {{ task.actualStartDate ? formatDisplayDate(task.actualStartDate) : '-' }} -
-
- {{ t('actualEndDate') }}: - {{ task.actualEndDate ? formatDisplayDate(task.actualEndDate) : '-' }} -
-
-
-
+