v1.3.1 - bugfix; SonarQube Upgrades
This commit is contained in:
@@ -168,7 +168,7 @@ watch(
|
|||||||
selectedTime.value = parsed.timeStr
|
selectedTime.value = parsed.timeStr
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 处理单日期输入变化(预留,当前版本不使用)
|
// 处理单日期输入变化(预留,当前版本不使用)
|
||||||
@@ -297,7 +297,7 @@ const scrollToSelectedTime = () => {
|
|||||||
const containerHeight = 160 // el-time-column-list 的高度
|
const containerHeight = 160 // el-time-column-list 的高度
|
||||||
const scrollTop = Math.max(
|
const scrollTop = Math.max(
|
||||||
0,
|
0,
|
||||||
selectedHourIndex * itemHeight - containerHeight / 2 + itemHeight / 2,
|
selectedHourIndex * itemHeight - containerHeight / 2 + itemHeight / 2
|
||||||
)
|
)
|
||||||
hourListRef.value.scrollTop = scrollTop
|
hourListRef.value.scrollTop = scrollTop
|
||||||
}
|
}
|
||||||
@@ -312,7 +312,7 @@ const scrollToSelectedTime = () => {
|
|||||||
const containerHeight = 160
|
const containerHeight = 160
|
||||||
const scrollTop = Math.max(
|
const scrollTop = Math.max(
|
||||||
0,
|
0,
|
||||||
selectedMinuteIndex * itemHeight - containerHeight / 2 + itemHeight / 2,
|
selectedMinuteIndex * itemHeight - containerHeight / 2 + itemHeight / 2
|
||||||
)
|
)
|
||||||
minuteListRef.value.scrollTop = scrollTop
|
minuteListRef.value.scrollTop = scrollTop
|
||||||
}
|
}
|
||||||
@@ -365,18 +365,16 @@ const confirmDate = () => {
|
|||||||
emit('update:modelValue', newValue)
|
emit('update:modelValue', newValue)
|
||||||
emit('change', newValue)
|
emit('change', newValue)
|
||||||
}
|
}
|
||||||
} else {
|
} else if (singleValue.value) {
|
||||||
if (singleValue.value) {
|
// 格式化日期和时间
|
||||||
// 格式化日期和时间
|
const date = new Date(singleValue.value)
|
||||||
const date = new Date(singleValue.value)
|
const dateFormat = `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')}`
|
||||||
const dateFormat = `${date.getFullYear()}/${String(date.getMonth() + 1).padStart(2, '0')}/${String(date.getDate()).padStart(2, '0')}`
|
const formattedDateTime = selectedTime.value
|
||||||
const formattedDateTime = selectedTime.value
|
? `${dateFormat} ${selectedTime.value}`
|
||||||
? `${dateFormat} ${selectedTime.value}`
|
: dateFormat
|
||||||
: dateFormat
|
|
||||||
|
|
||||||
emit('update:modelValue', formattedDateTime)
|
emit('update:modelValue', formattedDateTime)
|
||||||
emit('change', formattedDateTime)
|
emit('change', formattedDateTime)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确认后关闭面板
|
// 确认后关闭面板
|
||||||
@@ -746,14 +744,6 @@ const handlePickerBlur = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 时间选择器获得焦点时取消关闭
|
|
||||||
const handleTimePickerFocus = () => {
|
|
||||||
if (blurTimer.value) {
|
|
||||||
clearTimeout(blurTimer.value)
|
|
||||||
blurTimer.value = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 时间选择器失去焦点时关闭
|
// 时间选择器失去焦点时关闭
|
||||||
const handleTimePickerBlur = () => {
|
const handleTimePickerBlur = () => {
|
||||||
blurTimer.value = setTimeout(() => {
|
blurTimer.value = setTimeout(() => {
|
||||||
@@ -972,7 +962,7 @@ const timePickerStyle = computed(() => {
|
|||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@click.stop
|
@click.stop
|
||||||
@mousedown.prevent
|
@mousedown.prevent
|
||||||
@focus="handleTimePickerFocus"
|
@focus="handlePickerFocus"
|
||||||
@blur="handleTimePickerBlur"
|
@blur="handleTimePickerBlur"
|
||||||
>
|
>
|
||||||
<div class="el-time-picker-header">
|
<div class="el-time-picker-header">
|
||||||
@@ -1157,8 +1147,9 @@ const timePickerStyle = computed(() => {
|
|||||||
|
|
||||||
<!-- 时间选择器输入框 -->
|
<!-- 时间选择器输入框 -->
|
||||||
<div class="el-time-picker-input">
|
<div class="el-time-picker-input">
|
||||||
<label class="el-time-picker-label">{{ t.time }}:</label>
|
<label class="el-time-picker-label" for="time-input">{{ t.time }}:</label>
|
||||||
<input
|
<input
|
||||||
|
id="time-input"
|
||||||
ref="timeInputRef"
|
ref="timeInputRef"
|
||||||
type="text"
|
type="text"
|
||||||
class="el-time-input"
|
class="el-time-input"
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ const handleMouseMove = (e: MouseEvent) => {
|
|||||||
mouseX: e.clientX,
|
mouseX: e.clientX,
|
||||||
isDragging: isDragging.value,
|
isDragging: isDragging.value,
|
||||||
},
|
},
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const deltaX = e.clientX - dragStartX.value
|
const deltaX = e.clientX - dragStartX.value
|
||||||
@@ -179,7 +179,7 @@ const handleMouseUp = () => {
|
|||||||
mouseX: 0,
|
mouseX: 0,
|
||||||
isDragging: false,
|
isDragging: false,
|
||||||
},
|
},
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// 只有在真正拖拽了(有临时数据)且状态为拖拽中时才触发更新
|
// 只有在真正拖拽了(有临时数据)且状态为拖拽中时才触发更新
|
||||||
@@ -241,7 +241,7 @@ const handleMilestoneClick = (e: MouseEvent) => {
|
|||||||
scrollLeft: targetScrollLeft,
|
scrollLeft: targetScrollLeft,
|
||||||
smooth: true,
|
smooth: true,
|
||||||
},
|
},
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,14 +304,14 @@ const milestoneStyle = computed(() => {
|
|||||||
const centerPosition = calculateMilestonePositionFromTimelineData(
|
const centerPosition = calculateMilestonePositionFromTimelineData(
|
||||||
milestoneDate,
|
milestoneDate,
|
||||||
props.timelineData,
|
props.timelineData,
|
||||||
props.currentTimeScale,
|
props.currentTimeScale
|
||||||
)
|
)
|
||||||
|
|
||||||
left = centerPosition - size / 2 // 从中心位置偏移到图标左上角
|
left = centerPosition - size / 2 // 从中心位置偏移到图标左上角
|
||||||
} else {
|
} else {
|
||||||
// 日视图:保持原有逻辑
|
// 日视图:保持原有逻辑
|
||||||
const startDiff = Math.floor(
|
const startDiff = Math.floor(
|
||||||
(milestoneDate.getTime() - props.startDate.getTime()) / (1000 * 60 * 60 * 24),
|
(milestoneDate.getTime() - props.startDate.getTime()) / (1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
left = startDiff * props.dayWidth + props.dayWidth / 2 - size / 2
|
left = startDiff * props.dayWidth + props.dayWidth / 2 - size / 2
|
||||||
}
|
}
|
||||||
@@ -377,7 +377,7 @@ const milestoneVisibility = computed(() => {
|
|||||||
if (iconRight <= leftBoundary + iconSize / 2) {
|
if (iconRight <= leftBoundary + iconSize / 2) {
|
||||||
// 检查左侧是否有其他停靠的里程碑,需要判断推挤优先级
|
// 检查左侧是否有其他停靠的里程碑,需要判断推挤优先级
|
||||||
const leftStickyMilestones = otherMilestones.filter(
|
const leftStickyMilestones = otherMilestones.filter(
|
||||||
m => m.id !== currentId && m.stickyPosition === 'left' && m.isSticky,
|
m => m.id !== currentId && m.stickyPosition === 'left' && m.isSticky
|
||||||
)
|
)
|
||||||
|
|
||||||
// 如果有其他里程碑已经停靠在左侧,比较优先级决定推挤顺序
|
// 如果有其他里程碑已经停靠在左侧,比较优先级决定推挤顺序
|
||||||
@@ -423,7 +423,7 @@ const milestoneVisibility = computed(() => {
|
|||||||
if (iconLeft >= rightBoundary - iconSize / 2) {
|
if (iconLeft >= rightBoundary - iconSize / 2) {
|
||||||
// 检查右侧是否有其他停靠的里程碑,需要判断推挤优先级
|
// 检查右侧是否有其他停靠的里程碑,需要判断推挤优先级
|
||||||
const rightStickyMilestones = otherMilestones.filter(
|
const rightStickyMilestones = otherMilestones.filter(
|
||||||
m => m.id !== currentId && m.stickyPosition === 'right' && m.isSticky,
|
m => m.id !== currentId && m.stickyPosition === 'right' && m.isSticky
|
||||||
)
|
)
|
||||||
|
|
||||||
// 如果有其他里程碑已经停靠在右侧,比较优先级决定推挤顺序
|
// 如果有其他里程碑已经停靠在右侧,比较优先级决定推挤顺序
|
||||||
@@ -581,13 +581,13 @@ const calculateYearViewMilestonePosition = (targetDate: Date, baseStartDate: Dat
|
|||||||
const daysInHalfYear =
|
const daysInHalfYear =
|
||||||
month <= 6
|
month <= 6
|
||||||
? Math.floor(
|
? Math.floor(
|
||||||
(new Date(targetYear, 6, 1).getTime() - new Date(targetYear, 0, 1).getTime()) /
|
(new Date(targetYear, 6, 1).getTime() - new Date(targetYear, 0, 1).getTime()) /
|
||||||
(1000 * 60 * 60 * 24),
|
(1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
: Math.floor(
|
: Math.floor(
|
||||||
(new Date(targetYear + 1, 0, 1).getTime() - new Date(targetYear, 6, 1).getTime()) /
|
(new Date(targetYear + 1, 0, 1).getTime() - new Date(targetYear, 6, 1).getTime()) /
|
||||||
(1000 * 60 * 60 * 24),
|
(1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
|
|
||||||
const dayPositionInHalfYear = (dayOffset / daysInHalfYear) * halfYearWidth
|
const dayPositionInHalfYear = (dayOffset / daysInHalfYear) * halfYearWidth
|
||||||
position += dayPositionInHalfYear
|
position += dayPositionInHalfYear
|
||||||
@@ -601,12 +601,12 @@ const calculateHourViewMilestonePosition = (targetDate: Date, baseStartDate: Dat
|
|||||||
const targetNormalized = new Date(
|
const targetNormalized = new Date(
|
||||||
targetDate.getFullYear(),
|
targetDate.getFullYear(),
|
||||||
targetDate.getMonth(),
|
targetDate.getMonth(),
|
||||||
targetDate.getDate(),
|
targetDate.getDate()
|
||||||
)
|
)
|
||||||
const baseNormalized = new Date(
|
const baseNormalized = new Date(
|
||||||
baseStartDate.getFullYear(),
|
baseStartDate.getFullYear(),
|
||||||
baseStartDate.getMonth(),
|
baseStartDate.getMonth(),
|
||||||
baseStartDate.getDate(),
|
baseStartDate.getDate()
|
||||||
)
|
)
|
||||||
const timeDiff = targetNormalized.getTime() - baseNormalized.getTime()
|
const timeDiff = targetNormalized.getTime() - baseNormalized.getTime()
|
||||||
const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24))
|
const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24))
|
||||||
@@ -645,7 +645,7 @@ const calculateQuarterViewMilestonePosition = (targetDate: Date, baseStartDate:
|
|||||||
const month = targetDate.getMonth() + 1 // getMonth()返回0-11,需要+1
|
const month = targetDate.getMonth() + 1 // getMonth()返回0-11,需要+1
|
||||||
let quarter = 1
|
let quarter = 1
|
||||||
if (month >= 1 && month <= 3) {
|
if (month >= 1 && month <= 3) {
|
||||||
quarter = 1 // Q1: 1-3月
|
// Q1: 1-3月
|
||||||
} else if (month >= 4 && month <= 6) {
|
} else if (month >= 4 && month <= 6) {
|
||||||
quarter = 2 // Q2: 4-6月
|
quarter = 2 // Q2: 4-6月
|
||||||
} else if (month >= 7 && month <= 9) {
|
} else if (month >= 7 && month <= 9) {
|
||||||
@@ -694,7 +694,7 @@ const calculateQuarterViewMilestonePosition = (targetDate: Date, baseStartDate:
|
|||||||
const calculateMilestonePositionFromTimelineData = (
|
const calculateMilestonePositionFromTimelineData = (
|
||||||
targetDate: Date,
|
targetDate: Date,
|
||||||
timelineData: any,
|
timelineData: any,
|
||||||
timeScale: TimelineScale,
|
timeScale: TimelineScale
|
||||||
) => {
|
) => {
|
||||||
// 回退到原来的逻辑用于其他时间刻度
|
// 回退到原来的逻辑用于其他时间刻度
|
||||||
let cumulativePosition = 0
|
let cumulativePosition = 0
|
||||||
|
|||||||
+22
-23
@@ -198,13 +198,13 @@ const taskBarStyle = computed(() => {
|
|||||||
const startDateOnly = new Date(
|
const startDateOnly = new Date(
|
||||||
startDate.getFullYear(),
|
startDate.getFullYear(),
|
||||||
startDate.getMonth(),
|
startDate.getMonth(),
|
||||||
startDate.getDate(),
|
startDate.getDate()
|
||||||
)
|
)
|
||||||
const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate())
|
const endDateOnly = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate())
|
||||||
const baseStartOnly = new Date(
|
const baseStartOnly = new Date(
|
||||||
baseStart.getFullYear(),
|
baseStart.getFullYear(),
|
||||||
baseStart.getMonth(),
|
baseStart.getMonth(),
|
||||||
baseStart.getDate(),
|
baseStart.getDate()
|
||||||
)
|
)
|
||||||
|
|
||||||
if (props.currentTimeScale === TimelineScale.YEAR) {
|
if (props.currentTimeScale === TimelineScale.YEAR) {
|
||||||
@@ -226,7 +226,7 @@ const taskBarStyle = computed(() => {
|
|||||||
const startPosition = calculatePositionFromTimelineData(
|
const startPosition = calculatePositionFromTimelineData(
|
||||||
startDateOnly,
|
startDateOnly,
|
||||||
props.timelineData,
|
props.timelineData,
|
||||||
props.currentTimeScale,
|
props.currentTimeScale
|
||||||
)
|
)
|
||||||
// 计算结束位置:为结束日期添加一天来获取正确的结束位置
|
// 计算结束位置:为结束日期添加一天来获取正确的结束位置
|
||||||
const nextDay = new Date(endDateOnly)
|
const nextDay = new Date(endDateOnly)
|
||||||
@@ -234,7 +234,7 @@ const taskBarStyle = computed(() => {
|
|||||||
let endPosition = calculatePositionFromTimelineData(
|
let endPosition = calculatePositionFromTimelineData(
|
||||||
nextDay,
|
nextDay,
|
||||||
props.timelineData,
|
props.timelineData,
|
||||||
props.currentTimeScale,
|
props.currentTimeScale
|
||||||
)
|
)
|
||||||
|
|
||||||
// 如果结束日期+1天超出范围,使用结束日期的位置+一天的宽度
|
// 如果结束日期+1天超出范围,使用结束日期的位置+一天的宽度
|
||||||
@@ -249,7 +249,7 @@ const taskBarStyle = computed(() => {
|
|||||||
calculatePositionFromTimelineData(
|
calculatePositionFromTimelineData(
|
||||||
endDateOnly,
|
endDateOnly,
|
||||||
props.timelineData,
|
props.timelineData,
|
||||||
props.currentTimeScale,
|
props.currentTimeScale
|
||||||
) + dayWidth
|
) + dayWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +258,7 @@ const taskBarStyle = computed(() => {
|
|||||||
} else {
|
} else {
|
||||||
// 日视图:基于日期的简单计算
|
// 日视图:基于日期的简单计算
|
||||||
const startDiff = Math.floor(
|
const startDiff = Math.floor(
|
||||||
(startDateOnly.getTime() - baseStartOnly.getTime()) / (1000 * 60 * 60 * 24),
|
(startDateOnly.getTime() - baseStartOnly.getTime()) / (1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
|
|
||||||
// 计算持续天数(基于日期,忽略时间)
|
// 计算持续天数(基于日期,忽略时间)
|
||||||
@@ -437,7 +437,7 @@ const handleMouseMove = (e: MouseEvent) => {
|
|||||||
mouseX: e.clientX,
|
mouseX: e.clientX,
|
||||||
isDragging: isDragging.value || isResizingLeft.value || isResizingRight.value,
|
isDragging: isDragging.value || isResizingLeft.value || isResizingRight.value,
|
||||||
},
|
},
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isDragging.value) {
|
if (isDragging.value) {
|
||||||
@@ -560,7 +560,7 @@ const handleMouseMove = (e: MouseEvent) => {
|
|||||||
const newDurationDays = newWidth / props.dayWidth
|
const newDurationDays = newWidth / props.dayWidth
|
||||||
const newEndDate = addDaysToLocalDate(
|
const newEndDate = addDaysToLocalDate(
|
||||||
props.startDate,
|
props.startDate,
|
||||||
resizeStartLeft.value / props.dayWidth + newDurationDays - 1,
|
resizeStartLeft.value / props.dayWidth + newDurationDays - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
// 只更新临时数据,不触发事件
|
// 只更新临时数据,不触发事件
|
||||||
@@ -580,7 +580,7 @@ const handleMouseUp = () => {
|
|||||||
mouseX: 0,
|
mouseX: 0,
|
||||||
isDragging: false,
|
isDragging: false,
|
||||||
},
|
},
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// 如果有临时数据,说明发生了拖拽或拉伸,提交数据更新
|
// 如果有临时数据,说明发生了拖拽或拉伸,提交数据更新
|
||||||
@@ -661,7 +661,7 @@ watch(
|
|||||||
reportBarPosition()
|
reportBarPosition()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 处理TaskBar双击事件
|
// 处理TaskBar双击事件
|
||||||
@@ -951,7 +951,7 @@ watch(
|
|||||||
}
|
}
|
||||||
}, 200)
|
}, 200)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// 监听外部hideBubbles属性变化,确保Timeline的容器变化能及时反应
|
// 监听外部hideBubbles属性变化,确保Timeline的容器变化能及时反应
|
||||||
@@ -964,7 +964,7 @@ watch(
|
|||||||
// 强制重新计算bubbleIndicator,确保容器宽度变化后正确显示半圆
|
// 强制重新计算bubbleIndicator,确保容器宽度变化后正确显示半圆
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// 监听TaskBar可见性变化,只在滚动时实现重新出现动画
|
// 监听TaskBar可见性变化,只在滚动时实现重新出现动画
|
||||||
@@ -973,7 +973,7 @@ watch(
|
|||||||
() => {
|
() => {
|
||||||
// TaskBar重新出现时,不需要动画效果
|
// TaskBar重新出现时,不需要动画效果
|
||||||
// 半圆会自然消失,TaskBar会立即显示
|
// 半圆会自然消失,TaskBar会立即显示
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// 监听页面缩放和大小变化,重新计算气泡位置
|
// 监听页面缩放和大小变化,重新计算气泡位置
|
||||||
@@ -1133,13 +1133,13 @@ const calculateYearViewPosition = (targetDate: Date, baseStartDate: Date): numbe
|
|||||||
const daysInHalfYear =
|
const daysInHalfYear =
|
||||||
month <= 6
|
month <= 6
|
||||||
? Math.floor(
|
? Math.floor(
|
||||||
(new Date(targetYear, 6, 1).getTime() - new Date(targetYear, 0, 1).getTime()) /
|
(new Date(targetYear, 6, 1).getTime() - new Date(targetYear, 0, 1).getTime()) /
|
||||||
(1000 * 60 * 60 * 24),
|
(1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
: Math.floor(
|
: Math.floor(
|
||||||
(new Date(targetYear + 1, 0, 1).getTime() - new Date(targetYear, 6, 1).getTime()) /
|
(new Date(targetYear + 1, 0, 1).getTime() - new Date(targetYear, 6, 1).getTime()) /
|
||||||
(1000 * 60 * 60 * 24),
|
(1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
|
|
||||||
const dayPositionInHalfYear = (dayOffset / daysInHalfYear) * halfYearWidth
|
const dayPositionInHalfYear = (dayOffset / daysInHalfYear) * halfYearWidth
|
||||||
position += dayPositionInHalfYear
|
position += dayPositionInHalfYear
|
||||||
@@ -1163,7 +1163,7 @@ const calculatePositionFromTimelineData = (
|
|||||||
subDays: Array<{ date: Date; dayOfWeek?: number }>
|
subDays: Array<{ date: Date; dayOfWeek?: number }>
|
||||||
}>
|
}>
|
||||||
}>,
|
}>,
|
||||||
timeScale: TimelineScale,
|
timeScale: TimelineScale
|
||||||
) => {
|
) => {
|
||||||
let cumulativePosition = 0
|
let cumulativePosition = 0
|
||||||
|
|
||||||
@@ -1181,11 +1181,11 @@ const calculatePositionFromTimelineData = (
|
|||||||
// 找到目标日期所在的季度
|
// 找到目标日期所在的季度
|
||||||
const quarterWidth = 60
|
const quarterWidth = 60
|
||||||
const daysInQuarter = Math.ceil(
|
const daysInQuarter = Math.ceil(
|
||||||
(quarterEnd.getTime() - quarterStart.getTime()) / (1000 * 60 * 60 * 24),
|
(quarterEnd.getTime() - quarterStart.getTime()) / (1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
const dayWidth = quarterWidth / daysInQuarter
|
const dayWidth = quarterWidth / daysInQuarter
|
||||||
const dayInQuarter = Math.ceil(
|
const dayInQuarter = Math.ceil(
|
||||||
(targetDate.getTime() - quarterStart.getTime()) / (1000 * 60 * 60 * 24),
|
(targetDate.getTime() - quarterStart.getTime()) / (1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
return cumulativePosition + dayInQuarter * dayWidth
|
return cumulativePosition + dayInQuarter * dayWidth
|
||||||
}
|
}
|
||||||
@@ -1434,7 +1434,6 @@ onUnmounted(() => {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
transition: box-shadow 0.2s;
|
transition: box-shadow 0.2s;
|
||||||
/*min-width: 60px;*/
|
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
border: 2px solid;
|
border: 2px solid;
|
||||||
overflow: visible; /* 允许内容超出 TaskBar */
|
overflow: visible; /* 允许内容超出 TaskBar */
|
||||||
|
|||||||
+15
-15
@@ -61,7 +61,7 @@ const handleTaskRowHover = (taskId: number | null) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('task-list-hover', {
|
new CustomEvent('task-list-hover', {
|
||||||
detail: taskId,
|
detail: taskId,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,14 +85,14 @@ const handleTaskRowDoubleClick = (task: Task) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('task-row-double-click', {
|
new CustomEvent('task-row-double-click', {
|
||||||
detail: task,
|
detail: task,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算父级任务的进度和日期范围
|
// 计算父级任务的进度和日期范围
|
||||||
const calculateParentTaskData = (
|
const calculateParentTaskData = (
|
||||||
task: Task,
|
task: Task
|
||||||
): { progress: number; startDate: string; endDate: string } => {
|
): { progress: number; startDate: string; endDate: string } => {
|
||||||
if (!task.children || task.children.length === 0) {
|
if (!task.children || task.children.length === 0) {
|
||||||
return {
|
return {
|
||||||
@@ -198,7 +198,7 @@ watch(
|
|||||||
// 更新父级任务数据
|
// 更新父级任务数据
|
||||||
updateParentTasksData()
|
updateParentTasksData()
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true },
|
{ immediate: true, deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
function toggleCollapse(task: Task) {
|
function toggleCollapse(task: Task) {
|
||||||
@@ -258,7 +258,7 @@ const handleRequestTaskList = () => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('task-list-updated', {
|
new CustomEvent('task-list-updated', {
|
||||||
detail: allTasks,
|
detail: allTasks,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ const handleTaskListScroll = (event: Event) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('task-list-vertical-scroll', {
|
new CustomEvent('task-list-vertical-scroll', {
|
||||||
detail: { scrollTop },
|
detail: { scrollTop },
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ const handleTaskRowContextMenu = (event: { task: Task; position: { x: number; y:
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('context-menu', {
|
new CustomEvent('context-menu', {
|
||||||
detail: event,
|
detail: event,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('TaskList - Failed to dispatch context-menu event', error)
|
console.error('TaskList - Failed to dispatch context-menu event', error)
|
||||||
@@ -371,7 +371,7 @@ onUnmounted(() => {
|
|||||||
window.removeEventListener('timeline-task-hover', handleTimelineHover as EventListener)
|
window.removeEventListener('timeline-task-hover', handleTimelineHover as EventListener)
|
||||||
window.removeEventListener(
|
window.removeEventListener(
|
||||||
'timeline-vertical-scroll',
|
'timeline-vertical-scroll',
|
||||||
handleTimelineVerticalScroll as EventListener,
|
handleTimelineVerticalScroll as EventListener
|
||||||
)
|
)
|
||||||
window.removeEventListener('milestone-icon-changed', handleMilestoneIconChange as EventListener)
|
window.removeEventListener('milestone-icon-changed', handleMilestoneIconChange as EventListener)
|
||||||
window.removeEventListener('splitter-drag-start', handleSplitterDragStart as EventListener)
|
window.removeEventListener('splitter-drag-start', handleSplitterDragStart as EventListener)
|
||||||
@@ -473,33 +473,33 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
.col-name {
|
.col-name {
|
||||||
flex: 2 0 300px;
|
flex: 2 0 300px;
|
||||||
min-width: 300px;
|
max-width: 300px;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-pre {
|
.col-pre {
|
||||||
flex: 1 0 120px;
|
flex: 1 0 120px;
|
||||||
min-width: 120px;
|
max-width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-assignee {
|
.col-assignee {
|
||||||
flex: 1 0 120px;
|
flex: 1 0 200px;
|
||||||
min-width: 120px;
|
max-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-date {
|
.col-date {
|
||||||
flex: 1.2 0 140px;
|
flex: 1.2 0 140px;
|
||||||
min-width: 140px;
|
max-width: 140px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-hours {
|
.col-hours {
|
||||||
flex: 1 0 100px;
|
flex: 1 0 100px;
|
||||||
min-width: 100px;
|
max-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-progress {
|
.col-progress {
|
||||||
flex: 1 0 100px;
|
flex: 1 0 100px;
|
||||||
min-width: 100px;
|
max-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-list-body {
|
.task-list-body {
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ watch(
|
|||||||
updateTimer()
|
updateTimer()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 右键菜单相关状态
|
// 右键菜单相关状态
|
||||||
@@ -596,33 +596,33 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
.col-name {
|
.col-name {
|
||||||
flex: 2 0 300px;
|
flex: 2 0 300px;
|
||||||
min-width: 300px;
|
max-width: 300px;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-pre {
|
.col-pre {
|
||||||
flex: 1 0 120px;
|
flex: 1 0 120px;
|
||||||
min-width: 120px;
|
max-width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-assignee {
|
.col-assignee {
|
||||||
flex: 1 0 120px;
|
flex: 1 0 200px;
|
||||||
min-width: 120px;
|
max-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-date {
|
.col-date {
|
||||||
flex: 1.2 0 140px;
|
flex: 1.2 0 140px;
|
||||||
min-width: 140px;
|
max-width: 140px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-hours {
|
.col-hours {
|
||||||
flex: 1 0 100px;
|
flex: 1 0 100px;
|
||||||
min-width: 100px;
|
max-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-progress {
|
.col-progress {
|
||||||
flex: 1 0 100px;
|
flex: 1 0 100px;
|
||||||
min-width: 100px;
|
max-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-name-text {
|
.task-name-text {
|
||||||
|
|||||||
+115
-223
@@ -354,7 +354,7 @@ const optimizedTimelineData = computed(() => {
|
|||||||
const currentDay = new Date(day.year, day.month - 1, day.day)
|
const currentDay = new Date(day.year, day.month - 1, day.day)
|
||||||
currentDay.setHours(0, 0, 0, 0)
|
currentDay.setHours(0, 0, 0, 0)
|
||||||
const daysDiff = Math.floor(
|
const daysDiff = Math.floor(
|
||||||
(currentDay.getTime() - dayStart.getTime()) / (1000 * 60 * 60 * 24),
|
(currentDay.getTime() - dayStart.getTime()) / (1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
const totalHourOffset = daysDiff * 24
|
const totalHourOffset = daysDiff * 24
|
||||||
|
|
||||||
@@ -455,7 +455,7 @@ const computeAllMilestonesPositions = () => {
|
|||||||
if (!isNaN(milestoneDate.getTime())) {
|
if (!isNaN(milestoneDate.getTime())) {
|
||||||
const startDiff = Math.floor(
|
const startDiff = Math.floor(
|
||||||
(milestoneDate.getTime() - timelineConfig.value.startDate.getTime()) /
|
(milestoneDate.getTime() - timelineConfig.value.startDate.getTime()) /
|
||||||
(1000 * 60 * 60 * 24),
|
(1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
const left = startDiff * 30 + 30 / 2 - 12 // 30是dayWidth,12是图标半径
|
const left = startDiff * 30 + 30 / 2 - 12 // 30是dayWidth,12是图标半径
|
||||||
|
|
||||||
@@ -489,7 +489,7 @@ const computeAllMilestonesPositions = () => {
|
|||||||
if (!isNaN(milestoneDate.getTime())) {
|
if (!isNaN(milestoneDate.getTime())) {
|
||||||
const startDiff = Math.floor(
|
const startDiff = Math.floor(
|
||||||
(milestoneDate.getTime() - timelineConfig.value.startDate.getTime()) /
|
(milestoneDate.getTime() - timelineConfig.value.startDate.getTime()) /
|
||||||
(1000 * 60 * 60 * 24),
|
(1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
const left = startDiff * 30 + 30 / 2 - 12
|
const left = startDiff * 30 + 30 / 2 - 12
|
||||||
|
|
||||||
@@ -592,7 +592,7 @@ const handleTaskRowHover = (taskId: number | null) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('timeline-task-hover', {
|
new CustomEvent('timeline-task-hover', {
|
||||||
detail: taskId,
|
detail: taskId,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,7 +644,7 @@ const handleMilestoneIconChange = (milestoneId: number, icon: string) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('milestone-icon-changed', {
|
new CustomEvent('milestone-icon-changed', {
|
||||||
detail: { milestoneId, icon },
|
detail: { milestoneId, icon },
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,7 +662,7 @@ const handleMilestoneSave = (updatedMilestone: Milestone) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('milestone-data-updated', {
|
new CustomEvent('milestone-data-updated', {
|
||||||
detail: { milestone: updatedMilestone },
|
detail: { milestone: updatedMilestone },
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,14 +675,14 @@ const handleMilestoneDelete = (milestoneId: number) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('milestone-deleted', {
|
new CustomEvent('milestone-deleted', {
|
||||||
detail: { milestoneId },
|
detail: { milestoneId },
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
// 广播里程碑数据变化事件,确保Timeline重新渲染
|
// 广播里程碑数据变化事件,确保Timeline重新渲染
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('milestone-data-changed', {
|
new CustomEvent('milestone-data-changed', {
|
||||||
detail: { milestoneId },
|
detail: { milestoneId },
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -697,7 +697,7 @@ const handleMilestoneUpdate = (updatedMilestone: Milestone) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('milestone-data-updated', {
|
new CustomEvent('milestone-data-updated', {
|
||||||
detail: { milestone: updatedMilestone },
|
detail: { milestone: updatedMilestone },
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,7 +997,7 @@ watch(
|
|||||||
clearTimelineCache()
|
clearTimelineCache()
|
||||||
timelineData.value = generateTimelineData()
|
timelineData.value = generateTimelineData()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// 保证每次时间轴数据变化后都自动居中今日(仅初始化和外部props变更时触发,不因任务/里程碑变更触发)
|
// 保证每次时间轴数据变化后都自动居中今日(仅初始化和外部props变更时触发,不因任务/里程碑变更触发)
|
||||||
@@ -1012,7 +1012,7 @@ watch(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 将今日定位到时间线中间位置
|
// 将今日定位到时间线中间位置
|
||||||
@@ -1029,26 +1029,21 @@ const scrollToTodayCenter = (retry = 0) => {
|
|||||||
|
|
||||||
// 年度视图和季度视图需要使用实际的timeline绘制起始日期
|
// 年度视图和季度视图需要使用实际的timeline绘制起始日期
|
||||||
let startNormalized: Date
|
let startNormalized: Date
|
||||||
if (currentTimeScale.value === TimelineScale.YEAR) {
|
if (
|
||||||
|
currentTimeScale.value === TimelineScale.YEAR ||
|
||||||
|
currentTimeScale.value === TimelineScale.QUARTER
|
||||||
|
) {
|
||||||
const yearRange = getYearTimelineRange()
|
const yearRange = getYearTimelineRange()
|
||||||
startNormalized = new Date(
|
startNormalized = new Date(
|
||||||
yearRange.startDate.getFullYear(),
|
yearRange.startDate.getFullYear(),
|
||||||
yearRange.startDate.getMonth(),
|
yearRange.startDate.getMonth(),
|
||||||
yearRange.startDate.getDate(),
|
yearRange.startDate.getDate()
|
||||||
)
|
|
||||||
} else if (currentTimeScale.value === TimelineScale.QUARTER) {
|
|
||||||
// 季度视图使用与年度视图相同的基准日期,确保坐标系统一致
|
|
||||||
const yearRange = getYearTimelineRange()
|
|
||||||
startNormalized = new Date(
|
|
||||||
yearRange.startDate.getFullYear(),
|
|
||||||
yearRange.startDate.getMonth(),
|
|
||||||
yearRange.startDate.getDate(),
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
startNormalized = new Date(
|
startNormalized = new Date(
|
||||||
timelineStart.getFullYear(),
|
timelineStart.getFullYear(),
|
||||||
timelineStart.getMonth(),
|
timelineStart.getMonth(),
|
||||||
timelineStart.getDate(),
|
timelineStart.getDate()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1091,7 +1086,7 @@ const scrollToTodayCenter = (retry = 0) => {
|
|||||||
const month = todayNormalized.getMonth() + 1
|
const month = todayNormalized.getMonth() + 1
|
||||||
let quarter = 1
|
let quarter = 1
|
||||||
if (month >= 1 && month <= 3) {
|
if (month >= 1 && month <= 3) {
|
||||||
quarter = 1 // Q1: 1-3月
|
// Q1: 1-3月
|
||||||
} else if (month >= 4 && month <= 6) {
|
} else if (month >= 4 && month <= 6) {
|
||||||
quarter = 2 // Q2: 4-6月
|
quarter = 2 // Q2: 4-6月
|
||||||
} else if (month >= 7 && month <= 9) {
|
} else if (month >= 7 && month <= 9) {
|
||||||
@@ -1121,7 +1116,7 @@ const scrollToTodayCenter = (retry = 0) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const dayOffset = Math.floor(
|
const dayOffset = Math.floor(
|
||||||
(todayNormalized.getTime() - startOfQuarter.getTime()) / (1000 * 60 * 60 * 24),
|
(todayNormalized.getTime() - startOfQuarter.getTime()) / (1000 * 60 * 60 * 24)
|
||||||
)
|
)
|
||||||
const daysInQuarter =
|
const daysInQuarter =
|
||||||
Math.floor((endOfQuarter.getTime() - startOfQuarter.getTime()) / (1000 * 60 * 60 * 24)) + 1
|
Math.floor((endOfQuarter.getTime() - startOfQuarter.getTime()) / (1000 * 60 * 60 * 24)) + 1
|
||||||
@@ -1178,7 +1173,7 @@ const getTodayLinePositionInYearView = computed(() => {
|
|||||||
const startNormalized = new Date(
|
const startNormalized = new Date(
|
||||||
yearRange.startDate.getFullYear(),
|
yearRange.startDate.getFullYear(),
|
||||||
yearRange.startDate.getMonth(),
|
yearRange.startDate.getMonth(),
|
||||||
yearRange.startDate.getDate(),
|
yearRange.startDate.getDate()
|
||||||
)
|
)
|
||||||
|
|
||||||
const startYear = startNormalized.getFullYear()
|
const startYear = startNormalized.getFullYear()
|
||||||
@@ -1272,7 +1267,7 @@ const scrollToToday = () => {
|
|||||||
const startNormalized = new Date(
|
const startNormalized = new Date(
|
||||||
timelineStart.getFullYear(),
|
timelineStart.getFullYear(),
|
||||||
timelineStart.getMonth(),
|
timelineStart.getMonth(),
|
||||||
timelineStart.getDate(),
|
timelineStart.getDate()
|
||||||
)
|
)
|
||||||
|
|
||||||
// 计算今天距离时间线开始日期的天数
|
// 计算今天距离时间线开始日期的天数
|
||||||
@@ -1323,7 +1318,7 @@ const updateTask = (updatedTask: Task) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('task-updated', {
|
new CustomEvent('task-updated', {
|
||||||
detail: updatedTask,
|
detail: updatedTask,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1383,7 +1378,7 @@ const handleTaskBarContextMenu = (event: { task: Task; position: { x: number; y:
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('context-menu', {
|
new CustomEvent('context-menu', {
|
||||||
detail: event,
|
detail: event,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1466,7 +1461,7 @@ onMounted(() => {
|
|||||||
// 监听TaskList的垂直滚动事件
|
// 监听TaskList的垂直滚动事件
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
'task-list-vertical-scroll',
|
'task-list-vertical-scroll',
|
||||||
handleTaskListVerticalScroll as EventListener,
|
handleTaskListVerticalScroll as EventListener
|
||||||
)
|
)
|
||||||
// 监听语言变化
|
// 监听语言变化
|
||||||
window.addEventListener('locale-changed', handleLocaleChange as EventListener)
|
window.addEventListener('locale-changed', handleLocaleChange as EventListener)
|
||||||
@@ -1476,7 +1471,7 @@ onMounted(() => {
|
|||||||
// 监听Timeline容器resize事件(TaskList切换等)
|
// 监听Timeline容器resize事件(TaskList切换等)
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
'timeline-container-resized',
|
'timeline-container-resized',
|
||||||
handleTimelineContainerResized as EventListener,
|
handleTimelineContainerResized as EventListener
|
||||||
)
|
)
|
||||||
|
|
||||||
// 监听里程碑点击定位事件
|
// 监听里程碑点击定位事件
|
||||||
@@ -1566,7 +1561,7 @@ const handleTimelineBodyScroll = (event: Event) => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('timeline-vertical-scroll', {
|
new CustomEvent('timeline-vertical-scroll', {
|
||||||
detail: { scrollTop },
|
detail: { scrollTop },
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1579,7 +1574,7 @@ watch(
|
|||||||
updateSvgSize()
|
updateSvgSize()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 拖拽滑动相关状态
|
// 拖拽滑动相关状态
|
||||||
@@ -1763,7 +1758,7 @@ const startAutoScroll = (direction: 'left' | 'right') => {
|
|||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent('timeline-auto-scroll', {
|
new CustomEvent('timeline-auto-scroll', {
|
||||||
detail: { scrollDelta: newScrollLeft - currentScrollLeft },
|
detail: { scrollDelta: newScrollLeft - currentScrollLeft },
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
autoScrollTimer = window.setTimeout(scroll, 16) // 约60fps
|
autoScrollTimer = window.setTimeout(scroll, 16) // 约60fps
|
||||||
@@ -1817,14 +1812,14 @@ onUnmounted(() => {
|
|||||||
window.removeEventListener('task-list-hover', handleTaskListHover as EventListener)
|
window.removeEventListener('task-list-hover', handleTaskListHover as EventListener)
|
||||||
window.removeEventListener(
|
window.removeEventListener(
|
||||||
'task-list-vertical-scroll',
|
'task-list-vertical-scroll',
|
||||||
handleTaskListVerticalScroll as EventListener,
|
handleTaskListVerticalScroll as EventListener
|
||||||
)
|
)
|
||||||
window.removeEventListener('locale-changed', handleLocaleChange as EventListener)
|
window.removeEventListener('locale-changed', handleLocaleChange as EventListener)
|
||||||
window.removeEventListener('splitter-drag-start', handleSplitterDragStart as EventListener)
|
window.removeEventListener('splitter-drag-start', handleSplitterDragStart as EventListener)
|
||||||
window.removeEventListener('splitter-drag-end', handleSplitterDragEnd as EventListener)
|
window.removeEventListener('splitter-drag-end', handleSplitterDragEnd as EventListener)
|
||||||
window.removeEventListener(
|
window.removeEventListener(
|
||||||
'timeline-container-resized',
|
'timeline-container-resized',
|
||||||
handleTimelineContainerResized as EventListener,
|
handleTimelineContainerResized as EventListener
|
||||||
)
|
)
|
||||||
window.removeEventListener('milestone-click-locate', handleMilestoneClickLocate as EventListener)
|
window.removeEventListener('milestone-click-locate', handleMilestoneClickLocate as EventListener)
|
||||||
window.removeEventListener('drag-boundary-check', handleDragBoundaryCheck as EventListener)
|
window.removeEventListener('drag-boundary-check', handleDragBoundaryCheck as EventListener)
|
||||||
@@ -1935,7 +1930,7 @@ watch(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 处理里程碑点击定位事件
|
// 处理里程碑点击定位事件
|
||||||
@@ -3471,152 +3466,6 @@ const handleAddSuccessor = (task: Task) => {
|
|||||||
opacity: 0.15;
|
opacity: 0.15;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 小时视图专用样式 */
|
|
||||||
.date-row {
|
|
||||||
min-height: 40px;
|
|
||||||
border-bottom: 1px solid var(--gantt-border-medium, #e1e4e8);
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hours-row {
|
|
||||||
min-height: 40px;
|
|
||||||
border-bottom: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-day-item {
|
|
||||||
border-right: 1px solid var(--gantt-border-medium, #e1e4e8);
|
|
||||||
background-color: var(--gantt-bg-secondary, #f6f8fa);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-height: 40px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 小时视图日期项专用样式 */
|
|
||||||
.timeline-day-item.hour-view-day {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
height: 100%;
|
|
||||||
border-right: 1px solid var(--gantt-border-medium, #e1e4e8);
|
|
||||||
background-color: var(--gantt-bg-secondary, #f6f8fa);
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-hour-item {
|
|
||||||
height: 100%;
|
|
||||||
border-right: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-height: 40px;
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
box-sizing: border-box;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-column {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
border-right: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-label {
|
|
||||||
color: var(--gantt-text-header, #24292e);
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.5;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hours-row {
|
|
||||||
min-height: 40px;
|
|
||||||
border-bottom: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-hour-item {
|
|
||||||
height: 100%;
|
|
||||||
border-right: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-height: 40px;
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
box-sizing: border-box;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-hour-item.today {
|
|
||||||
background-color: var(--gantt-primary);
|
|
||||||
color: var(--gantt-text-white);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-label {
|
|
||||||
color: var(--gantt-text-primary, #24292e);
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.3;
|
|
||||||
text-align: center;
|
|
||||||
letter-spacing: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-hour-item.today .hour-label {
|
|
||||||
color: var(--gantt-text-white);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-column {
|
|
||||||
border-right: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
position: relative;
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-column.weekend {
|
|
||||||
background-color: var(--gantt-bg-secondary, #f5f7fa);
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-column.rest-hour {
|
|
||||||
background-color: var(--gantt-bg-secondary, #f5f7fa);
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-column.working-hour {
|
|
||||||
background-color: var(--gantt-bg-primary, #ffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-column.today {
|
|
||||||
background-color: var(--gantt-primary-color, #409eff);
|
|
||||||
opacity: 0.2;
|
|
||||||
border-left: 2px solid var(--gantt-primary-color, #409eff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 15分钟刻度线样式 */
|
|
||||||
.quarter-hour-lines {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quarter-line {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 1px;
|
|
||||||
background-color: var(--gantt-border-light, #d1d5da);
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 年度视图样式 */
|
/* 年度视图样式 */
|
||||||
.half-years-row {
|
.half-years-row {
|
||||||
min-height: 36px;
|
min-height: 36px;
|
||||||
@@ -3781,13 +3630,7 @@ const handleAddSuccessor = (task: Task) => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hours-row {
|
/*---------------*/
|
||||||
min-height: 40px;
|
|
||||||
border-bottom: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-day-item {
|
.timeline-day-item {
|
||||||
top: 0;
|
top: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -3800,6 +3643,60 @@ const handleAddSuccessor = (task: Task) => {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 小时视图日期项专用样式 */
|
||||||
|
.timeline-day-item.hour-view-day {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
border-right: 1px solid var(--gantt-border-medium, #e1e4e8);
|
||||||
|
background-color: var(--gantt-bg-secondary, #f6f8fa);
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-label {
|
||||||
|
color: var(--gantt-text-header, #24292e);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hours-row {
|
||||||
|
min-height: 40px;
|
||||||
|
border-bottom: 1px solid var(--gantt-border-light, #d1d5da);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hour-label {
|
||||||
|
color: var(--gantt-text-primary, #24292e);
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.3;
|
||||||
|
text-align: center;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 15分钟刻度线样式 */
|
||||||
|
.quarter-hour-lines {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarter-line {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 1px;
|
||||||
|
background-color: var(--gantt-border-light, #d1d5da);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
/**------------------------ */
|
||||||
|
|
||||||
.timeline-hour-item {
|
.timeline-hour-item {
|
||||||
top: 0;
|
top: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -3810,6 +3707,16 @@ const handleAddSuccessor = (task: Task) => {
|
|||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-hour-item.today {
|
||||||
|
background-color: var(--gantt-primary);
|
||||||
|
color: var(--gantt-text-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-hour-item.today .hour-label {
|
||||||
|
color: var(--gantt-text-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 小时视图非工作时间样式 - 参考日视图周末样式 */
|
/* 小时视图非工作时间样式 - 参考日视图周末样式 */
|
||||||
@@ -3826,61 +3733,46 @@ const handleAddSuccessor = (task: Task) => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hour-column {
|
.hour-column {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
border-right: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
pointer-events: none;
|
|
||||||
background-color: transparent;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-column:hover {
|
|
||||||
background-color: var(--gantt-hover-bg, rgba(0, 123, 255, 0.1));
|
|
||||||
}
|
|
||||||
.hour-columns-container {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
min-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 小时视图header容器 */
|
|
||||||
.hour-header-container {
|
|
||||||
position: relative;
|
|
||||||
min-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-row {
|
|
||||||
min-height: 40px;
|
|
||||||
border-bottom: 1px solid var(--gantt-border-light, #d1d5da);
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hour-column {
|
|
||||||
border-right: 1px solid var(--gantt-border-light, #e0e6ed);
|
border-right: 1px solid var(--gantt-border-light, #e0e6ed);
|
||||||
background-color: var(--gantt-bg-primary, #ffffff);
|
background-color: var(--gantt-bg-primary, #ffffff);
|
||||||
transition: background-color 0.2s ease;
|
transition: background-color 0.2s ease;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hour-column:hover {
|
.hour-column.weekend {
|
||||||
background-color: var(--gantt-bg-hover, rgba(64, 158, 255, 0.05));
|
background-color: var(--gantt-bg-secondary, #f5f7fa);
|
||||||
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hour-column.today {
|
.hour-column.rest-hour {
|
||||||
background-color: var(--gantt-primary-color, #f0f9ff);
|
background-color: var(--gantt-bg-secondary, #f5f7fa);
|
||||||
border-left: 2px solid var(--gantt-primary-color, #409eff);
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hour-column.working-hour {
|
.hour-column.working-hour {
|
||||||
background-color: var(--gantt-bg-primary, #ffffff);
|
background-color: var(--gantt-bg-primary, #ffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hour-column.today {
|
||||||
|
background-color: var(--gantt-primary-color, #409eff);
|
||||||
|
opacity: 0.2;
|
||||||
|
border-left: 2px solid var(--gantt-primary-color, #409eff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hour-column:hover {
|
||||||
|
background-color: var(--gantt-bg-hover, rgba(64, 158, 255, 0.05));
|
||||||
|
}
|
||||||
|
|
||||||
/* 小时视图暗色主题样式 */
|
/* 小时视图暗色主题样式 */
|
||||||
:global(html[data-theme='dark']) .date-row {
|
:global(html[data-theme='dark']) .date-row {
|
||||||
background: var(--gantt-bg-secondary, #1a1a1a) !important;
|
background: var(--gantt-bg-secondary, #1a1a1a) !important;
|
||||||
|
|||||||
Reference in New Issue
Block a user