Fix D-InSAR task log access after completion
This commit is contained in:
@@ -253,6 +253,20 @@ export default function DinsarProductionPanel({ readOnly = false, onJobQueued })
|
||||
const currentProfiles = currentEngineObj?.profiles || EMPTY_ARRAY;
|
||||
const currentProfileObj = currentProfiles.find(profile => profile.code === selectedProfile) || null;
|
||||
const currentParamSchema = currentProfileObj?.params_schema || EMPTY_OBJECT;
|
||||
const latestRunWithTask = runs.find(run => run?.task_id) || null;
|
||||
const monitoredTask = activeTask || (
|
||||
latestRunWithTask
|
||||
? {
|
||||
task_id: latestRunWithTask.task_id,
|
||||
task_type: latestRunWithTask.engine === 'isce2' ? 'ISCE2_RUN' : 'IDL_RUN_DINSAR',
|
||||
status: latestRunWithTask.raw_status || latestRunWithTask.status,
|
||||
progress: latestRunWithTask.raw_status === 'COMPLETED' || latestRunWithTask.status === 'success' ? 100 : null,
|
||||
message: latestRunWithTask.message || '最近一次任务',
|
||||
}
|
||||
: null
|
||||
);
|
||||
const logTaskId = monitoredTask?.task_id || '';
|
||||
const showingRecentTask = !activeTask && !!monitoredTask;
|
||||
|
||||
const loadEngines = useCallback(async () => {
|
||||
setEnginesLoading(true);
|
||||
@@ -306,7 +320,7 @@ export default function DinsarProductionPanel({ readOnly = false, onJobQueued })
|
||||
}, []);
|
||||
|
||||
const handleDeleteTaskLog = useCallback(async logId => {
|
||||
const taskId = activeTask?.task_id;
|
||||
const taskId = logTaskId;
|
||||
if (!taskId || !logId || taskLogActionLoading) return;
|
||||
if (!window.confirm('确定要删除这条任务日志吗?')) return;
|
||||
|
||||
@@ -322,12 +336,12 @@ export default function DinsarProductionPanel({ readOnly = false, onJobQueued })
|
||||
setTaskLogDeletingId(null);
|
||||
setTaskLogActionLoading(false);
|
||||
}
|
||||
}, [activeTask?.task_id, loadTaskLogs, taskLogActionLoading]);
|
||||
}, [logTaskId, loadTaskLogs, taskLogActionLoading]);
|
||||
|
||||
const handleClearTaskLogs = useCallback(async () => {
|
||||
const taskId = activeTask?.task_id;
|
||||
const taskId = logTaskId;
|
||||
if (!taskId || taskLogActionLoading || taskLogs.length === 0) return;
|
||||
if (!window.confirm('确定要清空当前任务的全部日志吗?')) return;
|
||||
if (!window.confirm(`确定要清空任务 ${taskId} 的全部日志吗?`)) return;
|
||||
|
||||
setTaskLogActionLoading(true);
|
||||
try {
|
||||
@@ -339,7 +353,7 @@ export default function DinsarProductionPanel({ readOnly = false, onJobQueued })
|
||||
} finally {
|
||||
setTaskLogActionLoading(false);
|
||||
}
|
||||
}, [activeTask?.task_id, loadTaskLogs, taskLogActionLoading, taskLogs.length]);
|
||||
}, [logTaskId, loadTaskLogs, taskLogActionLoading, taskLogs.length]);
|
||||
|
||||
useEffect(() => {
|
||||
loadEngines();
|
||||
@@ -348,17 +362,20 @@ export default function DinsarProductionPanel({ readOnly = false, onJobQueued })
|
||||
}, [loadActiveTask, loadEngines, loadRuns]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setInterval(loadActiveTask, 5000);
|
||||
const timer = setInterval(() => {
|
||||
loadRuns();
|
||||
loadActiveTask();
|
||||
}, 5000);
|
||||
return () => clearInterval(timer);
|
||||
}, [loadActiveTask]);
|
||||
}, [loadActiveTask, loadRuns]);
|
||||
|
||||
useEffect(() => {
|
||||
const taskId = activeTask?.task_id || '';
|
||||
const taskId = logTaskId;
|
||||
loadTaskLogs(taskId);
|
||||
if (!taskId) return undefined;
|
||||
const timer = setInterval(() => loadTaskLogs(taskId), 5000);
|
||||
return () => clearInterval(timer);
|
||||
}, [activeTask?.task_id, loadTaskLogs]);
|
||||
}, [logTaskId, loadTaskLogs]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentProfiles.length > 0) {
|
||||
@@ -672,31 +689,65 @@ export default function DinsarProductionPanel({ readOnly = false, onJobQueued })
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{activeTask && (
|
||||
<div style={{ marginBottom: 10, padding: '8px 10px', background: '#fefce8', borderRadius: 6, border: '1px solid #fde68a' }}>
|
||||
<div style={{ fontSize: 12, fontWeight: 600, color: '#92400e', marginBottom: 4 }}>当前任务</div>
|
||||
<div style={{ fontSize: 12, color: '#78350f', wordBreak: 'break-all' }}>
|
||||
{activeTask.task_id} - {formatTaskType(activeTask.task_type)} - {formatStatus(activeTask.status)} - {activeTask.message}
|
||||
{monitoredTask && (
|
||||
<div
|
||||
style={{
|
||||
marginBottom: 10,
|
||||
padding: '8px 10px',
|
||||
background: showingRecentTask ? '#eff6ff' : '#fefce8',
|
||||
borderRadius: 6,
|
||||
border: `1px solid ${showingRecentTask ? '#bfdbfe' : '#fde68a'}`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
color: showingRecentTask ? '#1d4ed8' : '#92400e',
|
||||
marginBottom: 4,
|
||||
}}
|
||||
>
|
||||
{showingRecentTask ? '最近一次任务' : '当前任务'}
|
||||
</div>
|
||||
{activeTask.progress != null && (
|
||||
<div style={{ fontSize: 12, color: showingRecentTask ? '#1e40af' : '#78350f', wordBreak: 'break-all' }}>
|
||||
{monitoredTask.task_id} - {formatTaskType(monitoredTask.task_type)} - {formatStatus(monitoredTask.status)} - {monitoredTask.message}
|
||||
</div>
|
||||
{monitoredTask.progress != null && (
|
||||
<div style={{ marginTop: 6 }}>
|
||||
<div style={{ height: 6, background: '#fde68a', borderRadius: 3, overflow: 'hidden' }}>
|
||||
<div
|
||||
style={{
|
||||
height: 6,
|
||||
background: showingRecentTask ? '#dbeafe' : '#fde68a',
|
||||
borderRadius: 3,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
height: '100%',
|
||||
width: `${activeTask.progress}%`,
|
||||
background: '#f59e0b',
|
||||
width: `${monitoredTask.progress}%`,
|
||||
background: showingRecentTask ? '#3b82f6' : '#f59e0b',
|
||||
transition: 'width 0.3s',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ fontSize: 11, color: '#92400e', marginTop: 2 }}>{activeTask.progress}%</div>
|
||||
<div style={{ fontSize: 11, color: showingRecentTask ? '#1d4ed8' : '#92400e', marginTop: 2 }}>{monitoredTask.progress}%</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div style={{ marginTop: 8, background: '#fff', border: '1px solid #fde68a', borderRadius: 6, padding: '8px 10px' }}>
|
||||
<div
|
||||
style={{
|
||||
marginTop: 8,
|
||||
background: '#fff',
|
||||
border: `1px solid ${showingRecentTask ? '#bfdbfe' : '#fde68a'}`,
|
||||
borderRadius: 6,
|
||||
padding: '8px 10px',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8, marginBottom: 6 }}>
|
||||
<div style={{ fontSize: 11, fontWeight: 600, color: '#92400e' }}>任务日志</div>
|
||||
<div style={{ fontSize: 11, fontWeight: 600, color: showingRecentTask ? '#1d4ed8' : '#92400e' }}>
|
||||
{showingRecentTask ? '最近一次任务日志' : '当前任务日志'}
|
||||
</div>
|
||||
{!readOnly && (
|
||||
<button
|
||||
onClick={handleClearTaskLogs}
|
||||
@@ -716,9 +767,9 @@ export default function DinsarProductionPanel({ readOnly = false, onJobQueued })
|
||||
)}
|
||||
</div>
|
||||
{taskLogsLoading ? (
|
||||
<div style={{ fontSize: 11, color: '#a16207' }}>加载中...</div>
|
||||
<div style={{ fontSize: 11, color: showingRecentTask ? '#1d4ed8' : '#a16207' }}>加载中...</div>
|
||||
) : taskLogs.length === 0 ? (
|
||||
<div style={{ fontSize: 11, color: '#a16207' }}>暂无日志。</div>
|
||||
<div style={{ fontSize: 11, color: showingRecentTask ? '#1d4ed8' : '#a16207' }}>暂无日志。</div>
|
||||
) : (
|
||||
<div style={{ maxHeight: 220, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 6 }}>
|
||||
{taskLogs.map((log, index) => (
|
||||
@@ -731,7 +782,15 @@ export default function DinsarProductionPanel({ readOnly = false, onJobQueued })
|
||||
alignItems: 'flex-start',
|
||||
}}
|
||||
>
|
||||
<div style={{ flex: 1, minWidth: 0, fontSize: 11, lineHeight: 1.45, color: log.level === 'WARNING' ? '#b45309' : '#334155' }}>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
fontSize: 11,
|
||||
lineHeight: 1.45,
|
||||
color: log.level === 'ERROR' ? '#b91c1c' : log.level === 'WARNING' ? '#b45309' : '#334155',
|
||||
}}
|
||||
>
|
||||
<div style={{ color: '#64748b' }}>
|
||||
{(log.timestamp || '').replace('T', ' ').replace('Z', '')} [{log.level}]
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user