Apply current workspace changes
This commit is contained in:
@@ -11,6 +11,8 @@ import { normalizePagePayload } from '../utils/appHelpers';
|
||||
import { normalizeTaskStatus } from '../utils/appUiHelpers';
|
||||
import { DEFAULT_LIST_PAGE_SIZE } from '../config/appConstants';
|
||||
|
||||
const NON_BLOCKING_TASK_TYPES = new Set(['UNPACK_ARCHIVES']);
|
||||
|
||||
export default function useDinsarOperations({
|
||||
onCleanupDinsarLayers,
|
||||
fetchRadarImagingDates,
|
||||
@@ -24,7 +26,7 @@ export default function useDinsarOperations({
|
||||
setAiStatus, setActiveAiReport,
|
||||
} = useDinsarStore();
|
||||
const { setHazardPoints } = useHazardStore();
|
||||
const { setPendingTaskIds, setIsGlobalLocked } = useTaskStore();
|
||||
const { setPendingTaskIds, setNonBlockingTaskIds, setIsGlobalLocked } = useTaskStore();
|
||||
const { currentUser } = useAuthStore();
|
||||
const {
|
||||
hasRadarSearched, radarPagination,
|
||||
@@ -120,17 +122,49 @@ export default function useDinsarOperations({
|
||||
}
|
||||
};
|
||||
|
||||
const handleTaskStart = (taskId, message) => {
|
||||
const handleTaskStart = (taskId, message, options = {}) => {
|
||||
const taskType = String(options?.taskType || '').trim().toUpperCase();
|
||||
const isNonBlocking = !!options?.nonBlocking || NON_BLOCKING_TASK_TYPES.has(taskType);
|
||||
if (taskId) {
|
||||
setPendingTaskIds(prev => [...prev, taskId]);
|
||||
if (isNonBlocking) {
|
||||
setNonBlockingTaskIds(prev => [...new Set([...prev, taskId])]);
|
||||
}
|
||||
}
|
||||
if (!isNonBlocking) {
|
||||
setIsGlobalLocked(true);
|
||||
}
|
||||
setIsGlobalLocked(true);
|
||||
if (message) addLog('info', message);
|
||||
};
|
||||
|
||||
const handleTaskCompletion = (taskInfo) => {
|
||||
console.log("收到任务完成通知:", taskInfo);
|
||||
const taskStatus = normalizeTaskStatus(taskInfo?.status);
|
||||
const syncRadarViewsAfterUnpack = async () => {
|
||||
try {
|
||||
await Promise.all([
|
||||
fetchRadarImagingDates(),
|
||||
fetchRadarSearchOptions(),
|
||||
]);
|
||||
if (hasRadarSearched) {
|
||||
const requestId = radarSearchRequestSeqRef.current + 1;
|
||||
radarSearchRequestSeqRef.current = requestId;
|
||||
await fetchAllData({
|
||||
limit: radarPagination.limit,
|
||||
offset: radarPagination.offset,
|
||||
criteria: radarSearchApplied,
|
||||
aoiMode: radarSearchAppliedAoiMode,
|
||||
regionTreeId: radarSearchAppliedRegionTreeId,
|
||||
aoiToken: radarSearchAoiToken,
|
||||
files: null,
|
||||
requestId,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('解包完成后刷新 LT-1 视图失败:', error);
|
||||
addLog('warn', 'LT-1 解包已完成,但刷新数据视图时发生错误,请手动刷新。');
|
||||
}
|
||||
};
|
||||
|
||||
if (taskInfo.task_type === 'AI_ANALYZE') {
|
||||
if (taskInfo.message) {
|
||||
@@ -187,6 +221,14 @@ export default function useDinsarOperations({
|
||||
} else if (taskStatus === 'FAILED') {
|
||||
addLog('error', `灾害点同步失败: ${taskInfo.message || '未知错误'}`);
|
||||
}
|
||||
} else if (taskInfo.task_type === 'UNPACK_ARCHIVES') {
|
||||
if (taskStatus === 'COMPLETED') {
|
||||
addLog('success', taskInfo.message || 'LT-1 解包完成。');
|
||||
addLog('info', '正在同步 LT-1 解包后的数据视图...');
|
||||
void syncRadarViewsAfterUnpack();
|
||||
} else if (taskStatus === 'FAILED') {
|
||||
addLog('error', `LT-1 解包失败: ${taskInfo.message || '未知错误'}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,13 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import apiClient from '../api/client';
|
||||
import { normalizeTaskStatus } from '../utils/appUiHelpers';
|
||||
|
||||
const NON_BLOCKING_TASK_TYPES = new Set(['UNPACK_ARCHIVES']);
|
||||
|
||||
const isTaskNonBlocking = (taskId, taskType, nonBlockingTaskIds = []) => (
|
||||
NON_BLOCKING_TASK_TYPES.has(String(taskType || '').toUpperCase())
|
||||
|| nonBlockingTaskIds.includes(taskId)
|
||||
);
|
||||
|
||||
export default function useGlobalTaskControl({
|
||||
currentUser,
|
||||
licenseOk,
|
||||
@@ -9,6 +16,8 @@ export default function useGlobalTaskControl({
|
||||
setActiveTasks,
|
||||
pendingTaskIds,
|
||||
setPendingTaskIds,
|
||||
nonBlockingTaskIds,
|
||||
setNonBlockingTaskIds,
|
||||
isGlobalLocked,
|
||||
setIsGlobalLocked,
|
||||
setIsCheckingTasks,
|
||||
@@ -31,6 +40,8 @@ export default function useGlobalTaskControl({
|
||||
// Stable refs so SSE handler doesn't need to re-subscribe on every render
|
||||
const pendingTaskIdsRef = useRef(pendingTaskIds);
|
||||
useEffect(() => { pendingTaskIdsRef.current = pendingTaskIds; }, [pendingTaskIds]);
|
||||
const nonBlockingTaskIdsRef = useRef(nonBlockingTaskIds);
|
||||
useEffect(() => { nonBlockingTaskIdsRef.current = nonBlockingTaskIds; }, [nonBlockingTaskIds]);
|
||||
|
||||
const handleTasksUpdate = useCallback(async (tasks) => {
|
||||
setActiveTasks(tasks);
|
||||
@@ -41,14 +52,25 @@ export default function useGlobalTaskControl({
|
||||
|
||||
const currentPending = pendingTaskIdsRef.current;
|
||||
let updatedPending = currentPending;
|
||||
let effectiveNonBlockingTaskIds = Array.from(new Set([
|
||||
...nonBlockingTaskIdsRef.current,
|
||||
...tasks
|
||||
.filter((task) => NON_BLOCKING_TASK_TYPES.has(String(task.task_type || '').toUpperCase()))
|
||||
.map((task) => task.task_id),
|
||||
]));
|
||||
|
||||
// 如果 pendingTaskIds 为空,但 activeTasks 有任务,说明是刷新后的初始化
|
||||
// 需要将 activeTasks 中的任务添加到 pendingTaskIds
|
||||
if (currentPending.length === 0 && hasRunningTasks) {
|
||||
const activeTaskIds = tasks.map((t) => t.task_id);
|
||||
const nextNonBlockingIds = tasks
|
||||
.filter((task) => NON_BLOCKING_TASK_TYPES.has(String(task.task_type || '').toUpperCase()))
|
||||
.map((task) => task.task_id);
|
||||
console.log('初始化:将活跃任务添加到 pending 列表:', activeTaskIds);
|
||||
setPendingTaskIds(activeTaskIds);
|
||||
setNonBlockingTaskIds(nextNonBlockingIds);
|
||||
updatedPending = activeTaskIds;
|
||||
effectiveNonBlockingTaskIds = nextNonBlockingIds;
|
||||
}
|
||||
|
||||
if (currentPending.length > 0) {
|
||||
@@ -104,6 +126,8 @@ export default function useGlobalTaskControl({
|
||||
updatedPending = newPending;
|
||||
return newPending;
|
||||
});
|
||||
setNonBlockingTaskIds((prev) => prev.filter((id) => !reallyFinishedIds.includes(id)));
|
||||
effectiveNonBlockingTaskIds = effectiveNonBlockingTaskIds.filter((id) => !reallyFinishedIds.includes(id));
|
||||
} else {
|
||||
// 没有真正完成的任务,保持 updatedPending 不变
|
||||
updatedPending = currentPending;
|
||||
@@ -112,7 +136,13 @@ export default function useGlobalTaskControl({
|
||||
}
|
||||
|
||||
// 只有当没有运行中的任务且没有待处理的任务时,才解锁
|
||||
const shouldBeLocked = hasRunningTasks || updatedPending.length > 0;
|
||||
const blockingRunningTasks = tasks.filter((task) => (
|
||||
!isTaskNonBlocking(task.task_id, task.task_type, effectiveNonBlockingTaskIds)
|
||||
));
|
||||
const blockingPendingTaskIds = updatedPending.filter((taskId) => (
|
||||
!effectiveNonBlockingTaskIds.includes(taskId)
|
||||
));
|
||||
const shouldBeLocked = blockingRunningTasks.length > 0 || blockingPendingTaskIds.length > 0;
|
||||
|
||||
if (shouldBeLocked !== isGlobalLockedRef.current) {
|
||||
setIsGlobalLocked(shouldBeLocked);
|
||||
@@ -128,6 +158,7 @@ export default function useGlobalTaskControl({
|
||||
setIsCheckingTasks,
|
||||
handleTaskCompletionRef,
|
||||
setPendingTaskIds,
|
||||
setNonBlockingTaskIds,
|
||||
setIsGlobalLocked,
|
||||
addLog,
|
||||
initializeAppDataRef,
|
||||
|
||||
@@ -59,13 +59,13 @@ export default function usePairingLogic({
|
||||
name: `PS_${direction}_${new Date().toISOString().slice(0, 10)}`
|
||||
});
|
||||
const batchId = response.data?.batch_id || '';
|
||||
addLog('success', `已创建 PS 批次: ${batchId || direction}`);
|
||||
addLog('success', `已创建时序批次: ${batchId || direction}`);
|
||||
if (focusAfterCreate && batchId) {
|
||||
await focusBatchAfterCreate('ps', batchId);
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = error.response?.data?.detail || error.message || '未知错误';
|
||||
addLog('error', `PS 批次创建失败: ${errorMessage}`);
|
||||
addLog('error', `时序批次创建失败: ${errorMessage}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -97,7 +97,7 @@ export default function usePairingLogic({
|
||||
setPsResults(null);
|
||||
onClearAoiLayer();
|
||||
setAoiLayer(null);
|
||||
addLog('info', 'PS-InSAR 结果已清空。');
|
||||
addLog('info', '时序InSAR 候选栈结果已清空。');
|
||||
};
|
||||
|
||||
const findPairs = async (e, externalRequireOrbitRef) => {
|
||||
@@ -210,7 +210,7 @@ export default function usePairingLogic({
|
||||
|
||||
setShowPsModal(false);
|
||||
setIsLoading(true);
|
||||
addLog('info', '开始准备PS时序数据栈...');
|
||||
addLog('info', '开始准备时序InSAR候选栈...');
|
||||
|
||||
const formData = new FormData();
|
||||
for (const key in psParams) {
|
||||
@@ -258,7 +258,7 @@ export default function usePairingLogic({
|
||||
setPsResults(processedResults);
|
||||
|
||||
if (Object.keys(processedResults).length > 0) {
|
||||
addLog('success', `成功找到 ${Object.keys(processedResults).length} 个PS时序栈。`);
|
||||
addLog('success', `成功找到 ${Object.keys(processedResults).length} 个时序InSAR候选栈。`);
|
||||
setLeftPanelTab('ps_results');
|
||||
for (const [direction, stack] of Object.entries(processedResults)) {
|
||||
await createPsBatch(direction, stack, { focusAfterCreate: false });
|
||||
@@ -268,9 +268,9 @@ export default function usePairingLogic({
|
||||
setLeftPanelTab('ps_results');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("PS时序准备失败:", error);
|
||||
console.error('时序InSAR候选栈准备失败:', error);
|
||||
const errorMessage = error.response?.data?.detail || error.message || '未知错误';
|
||||
addLog('error', `PS时序准备失败: ${errorMessage}`);
|
||||
addLog('error', `时序InSAR候选栈准备失败: ${errorMessage}`);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
setPsFiles(null);
|
||||
|
||||
Reference in New Issue
Block a user