|
|
|
@ -36,46 +36,34 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<el-dialog v-model="taskAdjustDialogVisible" title="调整任务" width="420px" append-to-body>
|
|
|
|
<el-dialog v-model="taskAdjustDialogVisible" title="调整任务" width="420px" append-to-body>
|
|
|
|
<el-form label-width="90px">
|
|
|
|
<el-form label-width="110px">
|
|
|
|
<el-form-item label="设备">
|
|
|
|
<el-form-item label="设备">
|
|
|
|
<el-select v-model="taskAdjustForm.deviceTaskId" placeholder="请选择设备" class="!w-full">
|
|
|
|
<el-select v-model="taskAdjustForm.deviceTaskId" placeholder="请选择设备" class="!w-full">
|
|
|
|
<el-option v-for="item in previewDeviceOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
<el-option v-for="item in previewDeviceOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
|
</el-select>
|
|
|
|
</el-select>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="开始日期">
|
|
|
|
<el-form-item label="计划开始日期">
|
|
|
|
<el-date-picker
|
|
|
|
<el-date-picker
|
|
|
|
v-model="taskAdjustForm.startDate"
|
|
|
|
v-model="taskAdjustForm.startDate"
|
|
|
|
type="date"
|
|
|
|
type="datetime"
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
placeholder="请选择开始日期"
|
|
|
|
placeholder="请选择计划开始日期"
|
|
|
|
class="!w-full"
|
|
|
|
class="!w-full"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
<el-form-item label="天数">
|
|
|
|
<el-form-item label="计划结束日期">
|
|
|
|
<el-input-number v-model="taskAdjustForm.duration" :min="1" :max="365" class="!w-full" />
|
|
|
|
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
</el-form>
|
|
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
|
|
<el-button @click="taskAdjustDialogVisible = false">取消</el-button>
|
|
|
|
|
|
|
|
<el-button type="primary" @click="handleTaskAdjustSubmit">确定</el-button>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<el-dialog v-model="startDateEditorVisible" title="修改开始时间" width="360px" append-to-body>
|
|
|
|
|
|
|
|
<el-form label-width="80px">
|
|
|
|
|
|
|
|
<el-form-item label="开始时间">
|
|
|
|
|
|
|
|
<el-date-picker
|
|
|
|
<el-date-picker
|
|
|
|
v-model="startDateEditorValue"
|
|
|
|
v-model="taskAdjustForm.endDate"
|
|
|
|
type="datetime"
|
|
|
|
type="datetime"
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
placeholder="请选择开始时间"
|
|
|
|
placeholder="请选择计划结束日期"
|
|
|
|
class="!w-full"
|
|
|
|
class="!w-full"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</el-form>
|
|
|
|
<template #footer>
|
|
|
|
<template #footer>
|
|
|
|
<el-button @click="startDateEditorVisible = false">取消</el-button>
|
|
|
|
<el-button @click="taskAdjustDialogVisible = false">取消</el-button>
|
|
|
|
<el-button type="primary" @click="handleStartDateEditorSubmit">确定</el-button>
|
|
|
|
<el-button type="primary" @click="handleTaskAdjustSubmit">确定</el-button>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</el-dialog>
|
|
|
|
</el-dialog>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
@ -101,9 +89,6 @@ const message = useMessage()
|
|
|
|
const ganttContainerRef = ref<HTMLDivElement>()
|
|
|
|
const ganttContainerRef = ref<HTMLDivElement>()
|
|
|
|
const activePreviewDevice = ref<any>()
|
|
|
|
const activePreviewDevice = ref<any>()
|
|
|
|
const activePreviewTask = ref<any>()
|
|
|
|
const activePreviewTask = ref<any>()
|
|
|
|
const startDateEditorVisible = ref(false)
|
|
|
|
|
|
|
|
const startDateEditorTaskId = ref<string | number | null>(null)
|
|
|
|
|
|
|
|
const startDateEditorValue = ref('')
|
|
|
|
|
|
|
|
const tooltipCleanupFns = ref<(() => void)[]>([])
|
|
|
|
const tooltipCleanupFns = ref<(() => void)[]>([])
|
|
|
|
const ganttEventIds = ref<string[]>([])
|
|
|
|
const ganttEventIds = ref<string[]>([])
|
|
|
|
const ganttSyncing = ref(false)
|
|
|
|
const ganttSyncing = ref(false)
|
|
|
|
@ -112,7 +97,7 @@ const taskAdjustTaskId = ref<string | number | null>(null)
|
|
|
|
const taskAdjustForm = reactive({
|
|
|
|
const taskAdjustForm = reactive({
|
|
|
|
deviceTaskId: '',
|
|
|
|
deviceTaskId: '',
|
|
|
|
startDate: '',
|
|
|
|
startDate: '',
|
|
|
|
duration: 1
|
|
|
|
endDate: ''
|
|
|
|
})
|
|
|
|
})
|
|
|
|
const taskMoveFromParentMap = ref<Record<string, string | number | undefined>>({})
|
|
|
|
const taskMoveFromParentMap = ref<Record<string, string | number | undefined>>({})
|
|
|
|
const taskDragDurationMap = ref<Record<string, number>>({})
|
|
|
|
const taskDragDurationMap = ref<Record<string, number>>({})
|
|
|
|
@ -549,15 +534,16 @@ const getDeviceInsertIndex = (deviceTaskId: string | number, startDate: dayjs.Da
|
|
|
|
return childTaskIds.length
|
|
|
|
return childTaskIds.length
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const applyTaskAdjust = (task: any, targetDeviceTaskId: string | number, startDate: string, durationValue: number) => {
|
|
|
|
const applyTaskAdjust = (task: any, targetDeviceTaskId: string | number, startDate: string, endDate: string) => {
|
|
|
|
const targetDeviceTask = gantt.getTask(targetDeviceTaskId)
|
|
|
|
const targetDeviceTask = gantt.getTask(targetDeviceTaskId)
|
|
|
|
if (!targetDeviceTask || targetDeviceTask?._planData) return
|
|
|
|
if (!targetDeviceTask || targetDeviceTask?._planData) return
|
|
|
|
const sourceDeviceTaskId = task.parent
|
|
|
|
const sourceDeviceTaskId = task.parent
|
|
|
|
const nextStart = dayjs(startDate).startOf('day')
|
|
|
|
const nextStart = dayjs(startDate)
|
|
|
|
const duration = Math.max(Number(durationValue) || 1, 1)
|
|
|
|
const nextEnd = dayjs(endDate)
|
|
|
|
|
|
|
|
const duration = Math.max(nextEnd.diff(nextStart, 'day') + 1, 1)
|
|
|
|
task.parent = targetDeviceTaskId
|
|
|
|
task.parent = targetDeviceTaskId
|
|
|
|
task.start_date = nextStart.toDate()
|
|
|
|
task.start_date = nextStart.toDate()
|
|
|
|
task.end_date = nextStart.add(duration - 1, 'day').endOf('day').toDate()
|
|
|
|
task.end_date = nextEnd.toDate()
|
|
|
|
task.duration = duration
|
|
|
|
task.duration = duration
|
|
|
|
movePlanDataToDevice(task, targetDeviceTaskId, sourceDeviceTaskId)
|
|
|
|
movePlanDataToDevice(task, targetDeviceTaskId, sourceDeviceTaskId)
|
|
|
|
const targetIndex = getDeviceInsertIndex(targetDeviceTaskId, nextStart)
|
|
|
|
const targetIndex = getDeviceInsertIndex(targetDeviceTaskId, nextStart)
|
|
|
|
@ -576,61 +562,28 @@ const openTaskAdjustDialog = (task: any) => {
|
|
|
|
if (!task?._planData) return
|
|
|
|
if (!task?._planData) return
|
|
|
|
taskAdjustTaskId.value = task.id
|
|
|
|
taskAdjustTaskId.value = task.id
|
|
|
|
taskAdjustForm.deviceTaskId = String(task.parent ?? '')
|
|
|
|
taskAdjustForm.deviceTaskId = String(task.parent ?? '')
|
|
|
|
taskAdjustForm.startDate = dayjs(task.start_date).format('YYYY-MM-DD')
|
|
|
|
taskAdjustForm.startDate = dayjs(task.start_date).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
taskAdjustForm.duration = Math.max(Number(task.duration) || 1, 1)
|
|
|
|
taskAdjustForm.endDate = dayjs(task.end_date).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
taskAdjustDialogVisible.value = true
|
|
|
|
taskAdjustDialogVisible.value = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleTaskAdjustSubmit = () => {
|
|
|
|
const handleTaskAdjustSubmit = () => {
|
|
|
|
if (!taskAdjustTaskId.value) return
|
|
|
|
if (!taskAdjustTaskId.value) return
|
|
|
|
if (!taskAdjustForm.deviceTaskId || !taskAdjustForm.startDate) {
|
|
|
|
if (!taskAdjustForm.deviceTaskId || !taskAdjustForm.startDate || !taskAdjustForm.endDate) {
|
|
|
|
message.warning('请完善设备和开始日期')
|
|
|
|
message.warning('请完善设备、计划开始日期和计划结束日期')
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const task = gantt.getTask(taskAdjustTaskId.value)
|
|
|
|
const task = gantt.getTask(taskAdjustTaskId.value)
|
|
|
|
if (!task?._planData) return
|
|
|
|
if (!task?._planData) return
|
|
|
|
ganttSyncing.value = true
|
|
|
|
ganttSyncing.value = true
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
applyTaskAdjust(task, taskAdjustForm.deviceTaskId, taskAdjustForm.startDate, taskAdjustForm.duration)
|
|
|
|
applyTaskAdjust(task, taskAdjustForm.deviceTaskId, taskAdjustForm.startDate, taskAdjustForm.endDate)
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
ganttSyncing.value = false
|
|
|
|
ganttSyncing.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
taskAdjustDialogVisible.value = false
|
|
|
|
taskAdjustDialogVisible.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleStartDateEditorSubmit = () => {
|
|
|
|
|
|
|
|
if (!startDateEditorTaskId.value || !startDateEditorValue.value) {
|
|
|
|
|
|
|
|
startDateEditorVisible.value = false
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const task = gantt.getTask(startDateEditorTaskId.value)
|
|
|
|
|
|
|
|
if (!task?._planData) {
|
|
|
|
|
|
|
|
startDateEditorVisible.value = false
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const newStart = dayjs(startDateEditorValue.value)
|
|
|
|
|
|
|
|
if (!newStart.isValid()) {
|
|
|
|
|
|
|
|
message.warning('请选择有效的时间')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const duration = Math.max(Number(task.duration) || 1, 1)
|
|
|
|
|
|
|
|
const newEnd = newStart.add(duration - 1, 'day').endOf('day')
|
|
|
|
|
|
|
|
ganttSyncing.value = true
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
task.start_date = newStart.toDate()
|
|
|
|
|
|
|
|
task.end_date = newEnd.toDate()
|
|
|
|
|
|
|
|
task.duration = duration
|
|
|
|
|
|
|
|
syncPlanTimeFromTask(task)
|
|
|
|
|
|
|
|
normalizeDeviceChildren(task.parent)
|
|
|
|
|
|
|
|
refreshPlanLinksByRowOrder()
|
|
|
|
|
|
|
|
refreshTimelineRangeByTasks()
|
|
|
|
|
|
|
|
gantt.updateTask(task.id)
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
ganttSyncing.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
startDateEditorVisible.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const refreshTimelineRangeByTasks = () => {
|
|
|
|
const refreshTimelineRangeByTasks = () => {
|
|
|
|
let minStart = Number.POSITIVE_INFINITY
|
|
|
|
let minStart = Number.POSITIVE_INFINITY
|
|
|
|
let maxEnd = Number.NEGATIVE_INFINITY
|
|
|
|
let maxEnd = Number.NEGATIVE_INFINITY
|
|
|
|
@ -691,28 +644,13 @@ const initGanttPreview = () => {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
name: 'start_date',
|
|
|
|
name: 'start_date',
|
|
|
|
label: '开始时间',
|
|
|
|
label: '计划时间',
|
|
|
|
align: 'center',
|
|
|
|
align: 'center',
|
|
|
|
width: 210,
|
|
|
|
width: 210,
|
|
|
|
template: (task: any) =>
|
|
|
|
template: (task: any) =>
|
|
|
|
task?._planData && String(task?._planData?.sourceType ?? '').toUpperCase() === 'CURRENT'
|
|
|
|
task?._planData && String(task?._planData?.sourceType ?? '').toUpperCase() === 'CURRENT'
|
|
|
|
? `<span class="gantt-inline-editor-trigger" data-field="start_date" data-task-id="${task.id}">${formatGridDateText(task.start_date)}</span>`
|
|
|
|
? `<span class="gantt-inline-editor-trigger" data-field="start_date" data-task-id="${task.id}">${formatGridDateText(task.start_date)}</span>`
|
|
|
|
: formatGridDateText(task.start_date)
|
|
|
|
: formatGridDateText(task.start_date)
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
name: 'duration',
|
|
|
|
|
|
|
|
label: '天数',
|
|
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
|
|
width: 60,
|
|
|
|
|
|
|
|
template: (task: any) =>
|
|
|
|
|
|
|
|
task?._planData && String(task?._planData?.sourceType ?? '').toUpperCase() === 'CURRENT'
|
|
|
|
|
|
|
|
? `<span class="gantt-inline-editor-trigger" data-field="duration">${task.duration ?? 0}</span>`
|
|
|
|
|
|
|
|
: String(task.duration ?? 0),
|
|
|
|
|
|
|
|
editor: {
|
|
|
|
|
|
|
|
type: 'number',
|
|
|
|
|
|
|
|
map_to: 'duration',
|
|
|
|
|
|
|
|
min: 1
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
@ -771,9 +709,7 @@ const initGanttPreview = () => {
|
|
|
|
const field = editableNode?.dataset?.field
|
|
|
|
const field = editableNode?.dataset?.field
|
|
|
|
if (!field || !task?._planData || String(task?._planData?.sourceType ?? '').toUpperCase() !== 'CURRENT') return true
|
|
|
|
if (!field || !task?._planData || String(task?._planData?.sourceType ?? '').toUpperCase() !== 'CURRENT') return true
|
|
|
|
if (field === 'start_date') {
|
|
|
|
if (field === 'start_date') {
|
|
|
|
startDateEditorTaskId.value = id
|
|
|
|
openTaskAdjustDialog(task)
|
|
|
|
startDateEditorValue.value = dayjs(task.start_date).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
|
|
|
startDateEditorVisible.value = true
|
|
|
|
|
|
|
|
return false
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const inlineEditors = (gantt.ext as any)?.inlineEditors
|
|
|
|
const inlineEditors = (gantt.ext as any)?.inlineEditors
|
|
|
|
@ -796,9 +732,7 @@ const initGanttPreview = () => {
|
|
|
|
const task = gantt.getTask(taskId)
|
|
|
|
const task = gantt.getTask(taskId)
|
|
|
|
if (!task?._planData || String(task?._planData?.sourceType ?? '').toUpperCase() !== 'CURRENT') return
|
|
|
|
if (!task?._planData || String(task?._planData?.sourceType ?? '').toUpperCase() !== 'CURRENT') return
|
|
|
|
e.stopPropagation()
|
|
|
|
e.stopPropagation()
|
|
|
|
startDateEditorTaskId.value = taskId
|
|
|
|
openTaskAdjustDialog(task)
|
|
|
|
startDateEditorValue.value = dayjs(task.start_date).format('YYYY-MM-DD HH:mm:ss')
|
|
|
|
|
|
|
|
startDateEditorVisible.value = true
|
|
|
|
|
|
|
|
} catch {}
|
|
|
|
} catch {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ganttContainerRef.value.addEventListener('click', gridClickHandler, true)
|
|
|
|
ganttContainerRef.value.addEventListener('click', gridClickHandler, true)
|
|
|
|
|