|
|
|
@ -110,6 +110,12 @@ const previewDeviceOptions = computed(() =>
|
|
|
|
}))
|
|
|
|
}))
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const hasCurrentPlan = (device: any) =>
|
|
|
|
|
|
|
|
(device?.plans ?? []).some((plan: any) => String(plan.sourceType ?? '').toUpperCase() === 'CURRENT')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getGanttScheduleList = () =>
|
|
|
|
|
|
|
|
previewScheduleList.value.filter((device: any) => hasCurrentPlan(device))
|
|
|
|
|
|
|
|
|
|
|
|
const getGlobalDateRange = (scheduleList: any[]) => {
|
|
|
|
const getGlobalDateRange = (scheduleList: any[]) => {
|
|
|
|
const allPlans = scheduleList.flatMap((item: any) => item?.plans ?? [])
|
|
|
|
const allPlans = scheduleList.flatMap((item: any) => item?.plans ?? [])
|
|
|
|
const starts = allPlans.map((item: any) => dayjs(item?.planStartTimeStr).valueOf()).filter((item: number) => Number.isFinite(item))
|
|
|
|
const starts = allPlans.map((item: any) => dayjs(item?.planStartTimeStr).valueOf()).filter((item: number) => Number.isFinite(item))
|
|
|
|
@ -240,10 +246,20 @@ const cleanupTaskTooltips = () => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const destroyGantt = () => {
|
|
|
|
const destroyGantt = () => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
cleanupTaskTooltips()
|
|
|
|
cleanupTaskTooltips()
|
|
|
|
ganttEventIds.value.forEach((eventId) => gantt.detachEvent(eventId))
|
|
|
|
} catch {}
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
ganttEventIds.value.forEach((eventId) => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
gantt.detachEvent(eventId)
|
|
|
|
|
|
|
|
} catch {}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} catch {}
|
|
|
|
ganttEventIds.value = []
|
|
|
|
ganttEventIds.value = []
|
|
|
|
|
|
|
|
try {
|
|
|
|
gantt.clearAll()
|
|
|
|
gantt.clearAll()
|
|
|
|
|
|
|
|
} catch {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const formatGridDateText = (value: unknown) => {
|
|
|
|
const formatGridDateText = (value: unknown) => {
|
|
|
|
@ -534,18 +550,122 @@ const getDeviceInsertIndex = (deviceTaskId: string | number, startDate: dayjs.Da
|
|
|
|
return childTaskIds.length
|
|
|
|
return childTaskIds.length
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const addDeviceToGantt = (device: any, excludePlanIdentity?: string) => {
|
|
|
|
|
|
|
|
const deviceId = `device-${device.deviceId}`
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
gantt.getTask(deviceId)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
} catch {}
|
|
|
|
|
|
|
|
const plans = (device?.plans ?? []).map((plan: any) => ({
|
|
|
|
|
|
|
|
...plan,
|
|
|
|
|
|
|
|
_start: dayjs(plan?.planStartTimeStr),
|
|
|
|
|
|
|
|
_end: dayjs(plan?.planEndTimeStr)
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
const validPlans = plans
|
|
|
|
|
|
|
|
.filter((plan: any) => plan._start.isValid() && plan._end.isValid())
|
|
|
|
|
|
|
|
.sort((a: any, b: any) => a._start.valueOf() - b._start.valueOf())
|
|
|
|
|
|
|
|
const firstPlan = validPlans[0]
|
|
|
|
|
|
|
|
const deviceRange = getDeviceTaskRangeByChildren(
|
|
|
|
|
|
|
|
validPlans.map((item: any) => ({ start_date: item?._start, end_date: item?._end }))
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
gantt.addTask({
|
|
|
|
|
|
|
|
id: deviceId,
|
|
|
|
|
|
|
|
text: `${device.deviceName ?? '-'}`,
|
|
|
|
|
|
|
|
start_date: formatGanttDate(deviceRange?.start_date ?? firstPlan?._start),
|
|
|
|
|
|
|
|
end_date: formatGanttDate(deviceRange?.end_date ?? firstPlan?._end),
|
|
|
|
|
|
|
|
duration: deviceRange?.duration ?? 1,
|
|
|
|
|
|
|
|
parent: 0,
|
|
|
|
|
|
|
|
progress: 0,
|
|
|
|
|
|
|
|
open: true,
|
|
|
|
|
|
|
|
readonly: true,
|
|
|
|
|
|
|
|
deviceName: device.deviceName ?? '-',
|
|
|
|
|
|
|
|
_deviceData: device
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
validPlans.forEach((plan: any, index: number) => {
|
|
|
|
|
|
|
|
const planIdentity = `${plan?.taskId ?? ''}-${plan?.taskDetailId ?? ''}`
|
|
|
|
|
|
|
|
if (excludePlanIdentity && planIdentity === excludePlanIdentity) return
|
|
|
|
|
|
|
|
const startDate = formatGanttDate(plan.planStartTimeStr)
|
|
|
|
|
|
|
|
const endDate = formatGanttDate(plan.planEndTimeStr)
|
|
|
|
|
|
|
|
if (!startDate || !endDate) return
|
|
|
|
|
|
|
|
const duration = Number(plan.scheduleDays) > 0 ? Number(plan.scheduleDays) : Math.max(plan._end.diff(plan._start, 'day') + 1, 1)
|
|
|
|
|
|
|
|
const isHistory = String(plan.sourceType ?? '').toUpperCase() === 'HISTORY'
|
|
|
|
|
|
|
|
const planTaskId = `plan-${device.deviceId}-${plan.taskDetailId ?? index}-${index}`
|
|
|
|
|
|
|
|
gantt.addTask({
|
|
|
|
|
|
|
|
id: planTaskId,
|
|
|
|
|
|
|
|
text: `${plan.productCode ?? '-'} / ${plan.productName ?? '-'} / ${plan.taskCode ?? '-'}`,
|
|
|
|
|
|
|
|
start_date: startDate,
|
|
|
|
|
|
|
|
end_date: endDate,
|
|
|
|
|
|
|
|
duration,
|
|
|
|
|
|
|
|
parent: deviceId,
|
|
|
|
|
|
|
|
progress: 0,
|
|
|
|
|
|
|
|
readonly: isHistory,
|
|
|
|
|
|
|
|
_planData: plan,
|
|
|
|
|
|
|
|
_deviceData: device
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const removeDeviceFromGanttIfNoCurrent = (deviceTaskId: string | number) => {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const deviceTask = gantt.getTask(deviceTaskId)
|
|
|
|
|
|
|
|
if (!deviceTask || deviceTask?._planData) return
|
|
|
|
|
|
|
|
const childTaskIds = gantt.getChildren(deviceTaskId)
|
|
|
|
|
|
|
|
const hasCurrent = (Array.isArray(childTaskIds) ? childTaskIds : []).some((childId: string | number) => {
|
|
|
|
|
|
|
|
const childTask = gantt.getTask(childId)
|
|
|
|
|
|
|
|
return childTask?._planData && String(childTask._planData.sourceType ?? '').toUpperCase() === 'CURRENT'
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
if (!hasCurrent) {
|
|
|
|
|
|
|
|
gantt.deleteTask(String(deviceTaskId))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch {}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const applyTaskAdjust = (task: any, targetDeviceTaskId: string | number, startDate: string, endDate: string) => {
|
|
|
|
const applyTaskAdjust = (task: any, targetDeviceTaskId: string | number, startDate: string, endDate: string) => {
|
|
|
|
const targetDeviceTask = gantt.getTask(targetDeviceTaskId)
|
|
|
|
|
|
|
|
if (!targetDeviceTask || targetDeviceTask?._planData) return
|
|
|
|
|
|
|
|
const sourceDeviceTaskId = task.parent
|
|
|
|
const sourceDeviceTaskId = task.parent
|
|
|
|
const nextStart = dayjs(startDate)
|
|
|
|
const nextStart = dayjs(startDate)
|
|
|
|
const nextEnd = dayjs(endDate)
|
|
|
|
const nextEnd = dayjs(endDate)
|
|
|
|
const duration = Math.max(nextEnd.diff(nextStart, 'day') + 1, 1)
|
|
|
|
const duration = Math.max(nextEnd.diff(nextStart, 'day') + 1, 1)
|
|
|
|
|
|
|
|
const planIdentity = `${task?._planData?.taskId ?? ''}-${task?._planData?.taskDetailId ?? ''}`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const targetDeviceData = previewScheduleList.value.find((d: any) => `device-${d.deviceId}` === targetDeviceTaskId)
|
|
|
|
|
|
|
|
if (!targetDeviceData) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const sourceDeviceData = task._deviceData
|
|
|
|
|
|
|
|
if (sourceDeviceData?.plans && Array.isArray(sourceDeviceData.plans)) {
|
|
|
|
|
|
|
|
sourceDeviceData.plans = sourceDeviceData.plans.filter((item: any) => {
|
|
|
|
|
|
|
|
const itemId = `${item?.taskId ?? ''}-${item?.taskDetailId ?? ''}`
|
|
|
|
|
|
|
|
return itemId !== planIdentity
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Array.isArray(targetDeviceData.plans)) {
|
|
|
|
|
|
|
|
targetDeviceData.plans = []
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const targetExists = targetDeviceData.plans.some((item: any) => {
|
|
|
|
|
|
|
|
const itemId = `${item?.taskId ?? ''}-${item?.taskDetailId ?? ''}`
|
|
|
|
|
|
|
|
return itemId === planIdentity
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
if (!targetExists) {
|
|
|
|
|
|
|
|
targetDeviceData.plans.push(task._planData)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
task._planData.deviceId = targetDeviceData.deviceId
|
|
|
|
|
|
|
|
task._planData.feedingPipeline = targetDeviceData.deviceId
|
|
|
|
|
|
|
|
task._deviceData = targetDeviceData
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let targetDeviceInGantt = true
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
gantt.getTask(targetDeviceTaskId)
|
|
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
targetDeviceInGantt = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!targetDeviceInGantt) {
|
|
|
|
|
|
|
|
addDeviceToGantt(targetDeviceData, planIdentity)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
task.parent = targetDeviceTaskId
|
|
|
|
task.parent = targetDeviceTaskId
|
|
|
|
task.start_date = nextStart.toDate()
|
|
|
|
task.start_date = nextStart.toDate()
|
|
|
|
task.end_date = nextEnd.toDate()
|
|
|
|
task.end_date = nextEnd.toDate()
|
|
|
|
task.duration = duration
|
|
|
|
task.duration = duration
|
|
|
|
movePlanDataToDevice(task, targetDeviceTaskId, sourceDeviceTaskId)
|
|
|
|
|
|
|
|
const targetIndex = getDeviceInsertIndex(targetDeviceTaskId, nextStart)
|
|
|
|
const targetIndex = getDeviceInsertIndex(targetDeviceTaskId, nextStart)
|
|
|
|
gantt.moveTask(task.id, targetIndex, targetDeviceTaskId)
|
|
|
|
gantt.moveTask(task.id, targetIndex, targetDeviceTaskId)
|
|
|
|
gantt.updateTask(task.id)
|
|
|
|
gantt.updateTask(task.id)
|
|
|
|
@ -553,9 +673,11 @@ const applyTaskAdjust = (task: any, targetDeviceTaskId: string | number, startDa
|
|
|
|
normalizeDeviceChildren(targetDeviceTaskId, task.id)
|
|
|
|
normalizeDeviceChildren(targetDeviceTaskId, task.id)
|
|
|
|
if (sourceDeviceTaskId && sourceDeviceTaskId !== targetDeviceTaskId) {
|
|
|
|
if (sourceDeviceTaskId && sourceDeviceTaskId !== targetDeviceTaskId) {
|
|
|
|
normalizeDeviceChildren(sourceDeviceTaskId)
|
|
|
|
normalizeDeviceChildren(sourceDeviceTaskId)
|
|
|
|
|
|
|
|
removeDeviceFromGanttIfNoCurrent(sourceDeviceTaskId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
refreshPlanLinksByRowOrder()
|
|
|
|
refreshPlanLinksByRowOrder()
|
|
|
|
refreshTimelineRangeByTasks()
|
|
|
|
refreshTimelineRangeByTasks()
|
|
|
|
|
|
|
|
gantt.render()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const openTaskAdjustDialog = (task: any) => {
|
|
|
|
const openTaskAdjustDialog = (task: any) => {
|
|
|
|
@ -666,13 +788,14 @@ const initGanttPreview = () => {
|
|
|
|
return sourceType === 'HISTORY' ? 'schedule-plan-task-history' : 'schedule-plan-task'
|
|
|
|
return sourceType === 'HISTORY' ? 'schedule-plan-task-history' : 'schedule-plan-task'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const globalRange = getGlobalDateRange(previewScheduleList.value)
|
|
|
|
const ganttScheduleData = getGanttScheduleList()
|
|
|
|
|
|
|
|
const globalRange = getGlobalDateRange(ganttScheduleData)
|
|
|
|
gantt.config.start_date = dayjs(globalRange.start).startOf('day').toDate()
|
|
|
|
gantt.config.start_date = dayjs(globalRange.start).startOf('day').toDate()
|
|
|
|
gantt.config.end_date = dayjs(globalRange.end).endOf('day').toDate()
|
|
|
|
gantt.config.end_date = dayjs(globalRange.end).endOf('day').toDate()
|
|
|
|
|
|
|
|
|
|
|
|
gantt.init(ganttContainerRef.value)
|
|
|
|
gantt.init(ganttContainerRef.value)
|
|
|
|
|
|
|
|
|
|
|
|
const ganttData = buildPreviewGanttData(previewScheduleList.value)
|
|
|
|
const ganttData = buildPreviewGanttData(ganttScheduleData)
|
|
|
|
gantt.parse(ganttData)
|
|
|
|
gantt.parse(ganttData)
|
|
|
|
|
|
|
|
|
|
|
|
// 强制刷新所有任务的样式,确保颜色正确应用
|
|
|
|
// 强制刷新所有任务的样式,确保颜色正确应用
|
|
|
|
@ -775,6 +898,7 @@ const initGanttPreview = () => {
|
|
|
|
syncPlanTimeFromTask(task)
|
|
|
|
syncPlanTimeFromTask(task)
|
|
|
|
normalizeDeviceChildren(parent)
|
|
|
|
normalizeDeviceChildren(parent)
|
|
|
|
normalizeDeviceChildren(sourceParent)
|
|
|
|
normalizeDeviceChildren(sourceParent)
|
|
|
|
|
|
|
|
removeDeviceFromGanttIfNoCurrent(sourceParent)
|
|
|
|
refreshPlanLinksByRowOrder()
|
|
|
|
refreshPlanLinksByRowOrder()
|
|
|
|
refreshTimelineRangeByTasks()
|
|
|
|
refreshTimelineRangeByTasks()
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
@ -838,7 +962,9 @@ onMounted(async () => {
|
|
|
|
watch(
|
|
|
|
watch(
|
|
|
|
() => props.scheduleList,
|
|
|
|
() => props.scheduleList,
|
|
|
|
async () => {
|
|
|
|
async () => {
|
|
|
|
|
|
|
|
if (ganttSyncing.value) return
|
|
|
|
await nextTick()
|
|
|
|
await nextTick()
|
|
|
|
|
|
|
|
if (ganttSyncing.value) return
|
|
|
|
initGanttPreview()
|
|
|
|
initGanttPreview()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{ deep: true }
|
|
|
|
{ deep: true }
|
|
|
|
|