|
|
|
@ -62,7 +62,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
<el-table
|
|
|
|
<el-table
|
|
|
|
ref="taskTableRef"
|
|
|
|
ref="taskTableRef"
|
|
|
|
v-loading="taskLoading"
|
|
|
|
v-loading="taskTableBusy"
|
|
|
|
:data="taskList"
|
|
|
|
:data="taskList"
|
|
|
|
border
|
|
|
|
border
|
|
|
|
:stripe="true"
|
|
|
|
:stripe="true"
|
|
|
|
@ -74,7 +74,7 @@
|
|
|
|
@select="handleTaskSelect"
|
|
|
|
@select="handleTaskSelect"
|
|
|
|
@select-all="handleTaskSelectAll"
|
|
|
|
@select-all="handleTaskSelectAll"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<el-table-column type="selection" width="55" :reserve-selection="true" align="center" />
|
|
|
|
<el-table-column type="selection" width="55" :reserve-selection="true" align="center" :selectable="isTaskRowSelectable" />
|
|
|
|
<el-table-column :label="t('ProductionPlan.TaskSummary.tableTaskCodeColumn')" align="center" prop="code" width="200px" sortable />
|
|
|
|
<el-table-column :label="t('ProductionPlan.TaskSummary.tableTaskCodeColumn')" align="center" prop="code" width="200px" sortable />
|
|
|
|
<el-table-column :label="t('ProductionPlan.TaskSummary.tableOrderDateColumn')" align="center" prop="orderDate" :formatter="dateFormatter2" sortable />
|
|
|
|
<el-table-column :label="t('ProductionPlan.TaskSummary.tableOrderDateColumn')" align="center" prop="orderDate" :formatter="dateFormatter2" sortable />
|
|
|
|
<el-table-column :label="t('ProductionPlan.TaskSummary.tableDeliveryDateColumn')" align="center" prop="deliveryDate" :formatter="dateFormatter2" sortable />
|
|
|
|
<el-table-column :label="t('ProductionPlan.TaskSummary.tableDeliveryDateColumn')" align="center" prop="deliveryDate" :formatter="dateFormatter2" sortable />
|
|
|
|
@ -184,6 +184,7 @@ const emit = defineEmits(['success'])
|
|
|
|
const dialogVisible = ref(false)
|
|
|
|
const dialogVisible = ref(false)
|
|
|
|
const taskLoading = ref(false)
|
|
|
|
const taskLoading = ref(false)
|
|
|
|
const detailLoading = ref(false)
|
|
|
|
const detailLoading = ref(false)
|
|
|
|
|
|
|
|
const taskSelectionLoading = ref(false)
|
|
|
|
const submitLoading = ref(false)
|
|
|
|
const submitLoading = ref(false)
|
|
|
|
const previewVisible = ref(false)
|
|
|
|
const previewVisible = ref(false)
|
|
|
|
const itemNeedRef = ref()
|
|
|
|
const itemNeedRef = ref()
|
|
|
|
@ -222,6 +223,9 @@ const taskList = ref<any[]>([])
|
|
|
|
const detailList = ref<any[]>([])
|
|
|
|
const detailList = ref<any[]>([])
|
|
|
|
const currentTask = ref<any>()
|
|
|
|
const currentTask = ref<any>()
|
|
|
|
const allDetailsMap = ref<Record<number, any[]>>({}) // store details per taskId
|
|
|
|
const allDetailsMap = ref<Record<number, any[]>>({}) // store details per taskId
|
|
|
|
|
|
|
|
const taskDetailRequestMap = new Map<number, Promise<any[]>>()
|
|
|
|
|
|
|
|
const currentDetailRequestId = ref(0)
|
|
|
|
|
|
|
|
const taskTableBusy = computed(() => taskLoading.value || taskSelectionLoading.value)
|
|
|
|
|
|
|
|
|
|
|
|
const loadTaskList = async () => {
|
|
|
|
const loadTaskList = async () => {
|
|
|
|
taskLoading.value = true
|
|
|
|
taskLoading.value = true
|
|
|
|
@ -250,121 +254,127 @@ const loadTaskList = async () => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const loadDetailList = async (taskId?: number) => {
|
|
|
|
const getTaskDetailList = async (taskRow?: any) => {
|
|
|
|
if (!taskId) {
|
|
|
|
const taskId = taskRow?.id
|
|
|
|
detailList.value = []
|
|
|
|
if (!taskId) return []
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Use cached list if exists
|
|
|
|
|
|
|
|
if (allDetailsMap.value[taskId]) {
|
|
|
|
if (allDetailsMap.value[taskId]) {
|
|
|
|
detailList.value = allDetailsMap.value[taskId]
|
|
|
|
return allDetailsMap.value[taskId]
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
detailLoading.value = true
|
|
|
|
const pendingRequest = taskDetailRequestMap.get(taskId)
|
|
|
|
try {
|
|
|
|
if (pendingRequest) {
|
|
|
|
const data = await TaskApi.getTaskDetailPage({
|
|
|
|
return pendingRequest
|
|
|
|
pageNo: 1,
|
|
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
|
|
taskId
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
console.log('currentTask.value',currentTask.value)
|
|
|
|
|
|
|
|
const list = (data?.list ?? []).map((item: any) => ({
|
|
|
|
|
|
|
|
...item,
|
|
|
|
|
|
|
|
_parentTaskOrderPriority: currentTask.value?.isUrgent,
|
|
|
|
|
|
|
|
_parentTaskDeliveryDate: currentTask.value?.deliveryDate
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Cache the loaded list
|
|
|
|
|
|
|
|
allDetailsMap.value[taskId] = list
|
|
|
|
|
|
|
|
detailList.value = list
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
detailLoading.value = false
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const requestPromise = TaskApi.getTaskDetailPage({
|
|
|
|
|
|
|
|
pageNo: 1,
|
|
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
|
|
taskId
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.then((data: any) => {
|
|
|
|
|
|
|
|
const list = (data?.list ?? []).map((item: any) => ({
|
|
|
|
|
|
|
|
...item,
|
|
|
|
|
|
|
|
_parentTaskOrderPriority: taskRow?.isUrgent,
|
|
|
|
|
|
|
|
_parentTaskDeliveryDate: taskRow?.deliveryDate
|
|
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
allDetailsMap.value[taskId] = list
|
|
|
|
|
|
|
|
return list
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
.finally(() => {
|
|
|
|
|
|
|
|
taskDetailRequestMap.delete(taskId)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
taskDetailRequestMap.set(taskId, requestPromise)
|
|
|
|
|
|
|
|
return requestPromise
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleCurrentTaskChange = async (row: any) => {
|
|
|
|
const handleCurrentTaskChange = async (row: any) => {
|
|
|
|
if (!row) return
|
|
|
|
if (!row) return
|
|
|
|
currentTask.value = row
|
|
|
|
currentTask.value = row
|
|
|
|
await loadDetailList(row?.id)
|
|
|
|
const requestId = ++currentDetailRequestId.value
|
|
|
|
|
|
|
|
detailLoading.value = true
|
|
|
|
// Re-apply selection state for children when view changes
|
|
|
|
try {
|
|
|
|
nextTick(() => {
|
|
|
|
const list = await getTaskDetailList(row)
|
|
|
|
const parentIsSelected = taskTableRef.value?.getSelectionRows()?.some((t: any) => t.id === row.id)
|
|
|
|
if (requestId !== currentDetailRequestId.value || currentTask.value?.id !== row.id) return
|
|
|
|
if (parentIsSelected) {
|
|
|
|
detailList.value = list
|
|
|
|
detailList.value.forEach(child => {
|
|
|
|
nextTick(() => {
|
|
|
|
detailTableRef.value?.toggleRowSelection(child, true)
|
|
|
|
const parentIsSelected = taskTableRef.value?.getSelectionRows()?.some((t: any) => t.id === row.id)
|
|
|
|
})
|
|
|
|
if (parentIsSelected) {
|
|
|
|
|
|
|
|
detailList.value.forEach(child => {
|
|
|
|
|
|
|
|
detailTableRef.value?.toggleRowSelection(child, true)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
if (requestId === currentDetailRequestId.value) {
|
|
|
|
|
|
|
|
detailLoading.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleTaskSelect = async (selection: any[], row: any) => {
|
|
|
|
const handleTaskSelect = async (selection: any[], row: any) => {
|
|
|
|
const isSelected = selection.some((item) => item.id === row.id)
|
|
|
|
if (taskSelectionLoading.value) return
|
|
|
|
|
|
|
|
taskSelectionLoading.value = true
|
|
|
|
// load detail list to cache if not exists
|
|
|
|
try {
|
|
|
|
if (!allDetailsMap.value[row.id]) {
|
|
|
|
const isSelected = selection.some((item) => item.id === row.id)
|
|
|
|
currentTask.value = row
|
|
|
|
if (isSelected) {
|
|
|
|
await loadDetailList(row.id)
|
|
|
|
await handleCurrentTaskChange(row)
|
|
|
|
}
|
|
|
|
const childList = allDetailsMap.value[row.id] || []
|
|
|
|
|
|
|
|
if (childList.length === 0) {
|
|
|
|
const childList = allDetailsMap.value[row.id] || []
|
|
|
|
message.warning(`任务单 ${row.code} 无任务明细数据,无法勾选`)
|
|
|
|
|
|
|
|
taskTableRef.value?.toggleRowSelection(row, false)
|
|
|
|
if (isSelected && childList.length === 0) {
|
|
|
|
return
|
|
|
|
message.warning(`任务单 ${row.code} 无任务明细数据,无法勾选`)
|
|
|
|
|
|
|
|
taskTableRef.value?.toggleRowSelection(row, false)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (childList.length) {
|
|
|
|
|
|
|
|
childList.forEach((child) => {
|
|
|
|
|
|
|
|
// Find the row in detailList if currently displayed, or just use the child object
|
|
|
|
|
|
|
|
// `toggleRowSelection` needs the exact object reference that is in `data`
|
|
|
|
|
|
|
|
const rowInView = detailList.value.find(d => d.id === child.id)
|
|
|
|
|
|
|
|
if (rowInView) {
|
|
|
|
|
|
|
|
detailTableRef.value?.toggleRowSelection(rowInView, isSelected)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// If not in view but we want to select it, we can push it to selection or wait until viewed
|
|
|
|
|
|
|
|
// In Element Plus, toggleRowSelection works best with displayed data.
|
|
|
|
|
|
|
|
// We'll rely on handleCurrentTaskChange to re-apply selection if needed when viewed.
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
detailList.value.forEach((child) => {
|
|
|
|
|
|
|
|
detailTableRef.value?.toggleRowSelection(child, true)
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const childList = allDetailsMap.value[row.id] || []
|
|
|
|
|
|
|
|
if (currentTask.value?.id === row.id) {
|
|
|
|
|
|
|
|
childList.forEach((child) => {
|
|
|
|
|
|
|
|
const rowInView = detailList.value.find(d => d.id === child.id)
|
|
|
|
|
|
|
|
if (rowInView) {
|
|
|
|
|
|
|
|
detailTableRef.value?.toggleRowSelection(rowInView, false)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
taskSelectionLoading.value = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleTaskSelectAll = async (selection: any[]) => {
|
|
|
|
const handleTaskSelectAll = async (selection: any[]) => {
|
|
|
|
const isAllSelected = selection.length > 0
|
|
|
|
if (taskSelectionLoading.value) return
|
|
|
|
|
|
|
|
taskSelectionLoading.value = true
|
|
|
|
if (isAllSelected) {
|
|
|
|
try {
|
|
|
|
const validRows = []
|
|
|
|
const isAllSelected = selection.length > 0
|
|
|
|
let hasEmptyChild = false
|
|
|
|
if (isAllSelected) {
|
|
|
|
|
|
|
|
let hasEmptyChild = false
|
|
|
|
for (const row of selection) {
|
|
|
|
for (const row of selection) {
|
|
|
|
if (!allDetailsMap.value[row.id]) {
|
|
|
|
const childList = await getTaskDetailList(row)
|
|
|
|
currentTask.value = row
|
|
|
|
if (childList.length === 0) {
|
|
|
|
await loadDetailList(row.id)
|
|
|
|
hasEmptyChild = true
|
|
|
|
|
|
|
|
taskTableRef.value?.toggleRowSelection(row, false)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
childList.forEach((child) => {
|
|
|
|
|
|
|
|
const rowInView = detailList.value.find(d => d.id === child.id)
|
|
|
|
|
|
|
|
if (rowInView) {
|
|
|
|
|
|
|
|
detailTableRef.value?.toggleRowSelection(rowInView, true)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const childList = allDetailsMap.value[row.id] || []
|
|
|
|
if (hasEmptyChild) {
|
|
|
|
|
|
|
|
message.warning('部分任务单无明细数据,已自动取消勾选')
|
|
|
|
if (childList.length === 0) {
|
|
|
|
|
|
|
|
hasEmptyChild = true
|
|
|
|
|
|
|
|
taskTableRef.value?.toggleRowSelection(row, false)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
validRows.push(row)
|
|
|
|
|
|
|
|
childList.forEach((child) => {
|
|
|
|
|
|
|
|
const rowInView = detailList.value.find(d => d.id === child.id)
|
|
|
|
|
|
|
|
if (rowInView) {
|
|
|
|
|
|
|
|
detailTableRef.value?.toggleRowSelection(rowInView, true)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
detailTableRef.value?.clearSelection()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (hasEmptyChild) {
|
|
|
|
} finally {
|
|
|
|
message.warning('部分任务单无明细数据,已自动取消勾选')
|
|
|
|
taskSelectionLoading.value = false
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
detailTableRef.value?.clearSelection()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -406,6 +416,8 @@ const handleDetailSelectAll = (selection: any[]) => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isTaskRowSelectable = () => !taskTableBusy.value && !detailLoading.value
|
|
|
|
|
|
|
|
|
|
|
|
const handleSearch = async () => {
|
|
|
|
const handleSearch = async () => {
|
|
|
|
queryParams.pageNo = 1
|
|
|
|
queryParams.pageNo = 1
|
|
|
|
await loadTaskList()
|
|
|
|
await loadTaskList()
|
|
|
|
|