697 lines
18 KiB
Markdown
697 lines
18 KiB
Markdown
# 全局任务状态与界面锁重构设计
|
||
|
||
最后更新:2026-06-12
|
||
|
||
## 1. 背景
|
||
|
||
当前前端存在一个“全局界面锁”机制:只要系统检测到仍有活跃任务,并且该任务不在前端非阻塞白名单内,就会把整个系统切到全局锁定状态,并弹出 `ActiveTasksOverlay` 全屏遮罩。
|
||
|
||
这个设计在早期可以避免用户在 ENVI / SARscape / IDL 长任务执行期间重复点击、切换入口或提交冲突任务。但随着系统扩展到 D-InSAR、多引擎生产、SBAS-InSAR、数据接入、资产扫描、洪涝分析、AI 诊断等多个相对独立的任务域,全局锁已经过粗:
|
||
|
||
- SBAS Gamma / LandSAR SBAS 已经证明长任务可以不锁全局界面,只在模块内展示状态。
|
||
- 后端 `task_service.create_task()` 已经按 `task_type` 做同类型 `PENDING/RUNNING` 互斥。
|
||
- 很多任务只是扫描、解包、目录重建或产物刷新,不应阻断其他业务操作。
|
||
- 全屏遮罩会遮住当前功能页,用户看不到任务详情,也无法继续浏览结果或管理其他独立任务。
|
||
|
||
因此,本设计将“全局界面锁”降级为“全局任务状态中心”,并要求每个功能模块设计自己的任务状态面板和局部操作约束。
|
||
|
||
## 2. 当前实现审计
|
||
|
||
### 2.1 前端锁入口
|
||
|
||
核心文件:
|
||
|
||
- `frontend/src/hooks/useGlobalTaskControl.js`
|
||
- `frontend/src/hooks/useDinsarOperations.js`
|
||
- `frontend/src/components/ActiveTasksOverlay.jsx`
|
||
- `frontend/src/components/app/AppOverlays.jsx`
|
||
- `frontend/src/ProductionWorkspace.jsx`
|
||
|
||
当前逻辑:
|
||
|
||
1. `useGlobalTaskControl` 订阅 `/tasks/active` 或 SSE `/tasks/active/stream`。
|
||
2. 前端维护 `pendingTaskIds` 和 `nonBlockingTaskIds`。
|
||
3. 活跃任务中只要存在不属于 `NON_BLOCKING_TASK_TYPES` 的任务,就设置 `isGlobalLocked=true`。
|
||
4. `AppOverlays` 根据 `isGlobalLocked` 渲染 `ActiveTasksOverlay`。
|
||
5. `App.ensureCanOperate()` 会因为 `isGlobalLocked` 拒绝写操作。
|
||
|
||
### 2.2 当前非阻塞任务
|
||
|
||
当前白名单包括:
|
||
|
||
- `UNPACK_ARCHIVES`
|
||
- `UNPACK_SENTINEL1`
|
||
- `GF3_UNPACK`
|
||
- `GF3_SARSCAPE_PRODUCE`
|
||
- `GF3_SARSCAPE_SYNC`
|
||
- `GF3_SARSCAPE_CLEAN`
|
||
- `SCAN_ASSET_INVENTORY`
|
||
- `COPY_DATA`
|
||
- `SBAS_GAMMA_WORKFLOW`
|
||
- `SBAS_LANDSAR_WORKFLOW`
|
||
- `SBAS_COREGISTRATION`
|
||
- `SBAS_RDC_DEM`
|
||
- `SBAS_INTERFEROGRAMS`
|
||
- `SBAS_IPTA_TIMESERIES`
|
||
- `REBUILD_SBAS_INSAR_CATALOG`
|
||
|
||
这些任务已经以“不锁全局界面”的方式运行。
|
||
|
||
### 2.3 当前仍会锁全局界面的任务
|
||
|
||
主要原因通常不是任务本身必须锁,而是提交时没有传 `taskType` 或 `nonBlocking: true`。
|
||
|
||
已审计到的典型入口:
|
||
|
||
- D-InSAR 生产任务
|
||
- `ProductionWorkspace.handleDinsarRunQueued()`
|
||
- `DinsarProductionPanel.handleSubmit()`
|
||
- D-InSAR 结果扫描
|
||
- `ProductionWorkspace.handleDinsarProductQueued()`
|
||
- `DinsarProductsPanel.handleScan()`
|
||
- IDL Import / IDL DInSAR
|
||
- `IDLAutomationPanel`
|
||
- AI 训练、全量预测、AI 诊断
|
||
- `useDinsarOperations.handleTrainAi()`
|
||
- `useDinsarOperations.handlePredictAll()`
|
||
- `useDinsarOperations.handleAnalyzeResult()`
|
||
- 灾害点同步
|
||
- `HazardPointPanel`
|
||
- 水体 / 洪涝检测任务
|
||
- `WaterMonitorPanel`
|
||
- 部分数据监控任务
|
||
- `GF3_BATCH_PROCESS`
|
||
- `SCAN_DATA`
|
||
- 手动 LT-1 / 精轨 / GF3 扫描
|
||
- 预览缓存重建
|
||
- `App.rebuildRadarPreviewCache()` 通过 `handleTaskStart(null, ...)` 触发临时全局锁
|
||
|
||
### 2.4 后端已有保护
|
||
|
||
后端 `backend/app/services/task_service.py` 在 `create_task()` 中已做同类型任务互斥:
|
||
|
||
- 查询相同 `task_type` 且状态为 `PENDING` / `RUNNING` 的任务。
|
||
- 如果存在,直接返回任务冲突错误。
|
||
|
||
这说明前端全局锁不是唯一安全机制。真正的任务并发保护应继续下沉到后端,并从 `task_type` 扩展到更精确的资源锁。
|
||
|
||
## 3. 设计目标
|
||
|
||
1. 取消“任意阻塞任务遮住整个系统”的交互模式。
|
||
2. 全局层只负责展示所有活跃任务、最近任务、失败任务和快捷入口。
|
||
3. 每个功能模块拥有自己的任务状态面板,只展示和本功能相关的任务。
|
||
4. 默认任务不锁全局界面。
|
||
5. 需要互斥的场景由后端资源锁保证,而不是靠前端遮罩保证。
|
||
6. 前端只做局部禁用:禁用同一个功能里会造成重复提交或破坏状态的按钮。
|
||
7. 保留管理员取消任务能力,但从“强制解锁”改为“取消/中止任务”。
|
||
|
||
## 4. 非目标
|
||
|
||
本设计不要求一次性重写所有任务系统。
|
||
|
||
不在本阶段处理:
|
||
|
||
- 重做后端任务表结构。
|
||
- 重写 job worker。
|
||
- 改变现有任务 API 的基本返回格式。
|
||
- 一次性把所有历史任务类型改名。
|
||
- 删除所有旧 overlay 代码。
|
||
|
||
本设计优先保证渐进迁移。
|
||
|
||
## 5. 新架构概览
|
||
|
||
```text
|
||
后端任务系统
|
||
├─ SystemTaskORM / TaskLogORM
|
||
├─ SystemJobORM
|
||
├─ task_type 同类型互斥
|
||
└─ 后续扩展:resource_lock_key / resource_scope
|
||
|
||
前端任务状态层
|
||
├─ 全局任务状态中心
|
||
│ ├─ 展示所有活跃任务
|
||
│ ├─ 展示最近失败 / 完成任务
|
||
│ ├─ 支持跳转到所属功能
|
||
│ └─ 不遮住全系统
|
||
├─ 功能级任务面板
|
||
│ ├─ D-InSAR 生产任务面板
|
||
│ ├─ SBAS-InSAR 生产任务面板
|
||
│ ├─ 数据接入任务面板
|
||
│ ├─ 资产库存任务面板
|
||
│ ├─ 洪涝分析任务面板
|
||
│ └─ AI / 灾害点任务面板
|
||
└─ 局部操作约束
|
||
├─ 同类任务运行中,禁用同类提交按钮
|
||
├─ 目录重建中,禁用同一目录重建按钮
|
||
└─ 其他功能仍可浏览和操作
|
||
```
|
||
|
||
## 6. 全局任务状态中心
|
||
|
||
### 6.1 职责
|
||
|
||
全局任务状态中心只做观察和导航,不做全局阻断。
|
||
|
||
职责:
|
||
|
||
- 汇总 `/tasks/active`。
|
||
- 汇总最近任务 `/tasks/recent`。
|
||
- 显示任务类型、状态、进度、开始时间、最近消息。
|
||
- 支持按功能域筛选:
|
||
- 数据接入
|
||
- D-InSAR
|
||
- SBAS-InSAR
|
||
- 洪涝
|
||
- AI
|
||
- 运维
|
||
- 支持点击任务跳转到所属功能页。
|
||
- 支持查看任务日志。
|
||
- 支持管理员取消任务。
|
||
|
||
### 6.2 交互形态
|
||
|
||
建议替换现有 `ActiveTasksOverlay`:
|
||
|
||
- 不再使用全屏遮罩。
|
||
- 使用顶部状态入口或右下角任务抽屉。
|
||
- 有活跃任务时显示小型状态指示。
|
||
- 点击后打开任务中心抽屉或弹层。
|
||
- 弹层不阻止用户关闭和继续使用系统。
|
||
|
||
### 6.3 状态文案
|
||
|
||
旧文案:
|
||
|
||
```text
|
||
为了保证数据一致性,耗时任务执行期间 UI 已锁定。
|
||
```
|
||
|
||
应替换为:
|
||
|
||
```text
|
||
后台任务正在执行。你可以继续使用其他功能;同类任务的重复提交会由系统自动限制。
|
||
```
|
||
|
||
## 7. 功能级任务面板
|
||
|
||
每个功能页应自行展示本功能任务状态。这样用户在当前业务上下文里能直接看到“我刚提交的任务跑到哪一步”,而不是被全局遮罩挡住。
|
||
|
||
### 7.1 通用组件建议
|
||
|
||
新增通用组件:
|
||
|
||
- `TaskStatusPanel`
|
||
- `TaskLogPanel`
|
||
- `TaskProgressRow`
|
||
- `TaskStatusBadge`
|
||
- `useTaskMonitor`
|
||
|
||
建议参数:
|
||
|
||
```ts
|
||
type TaskStatusPanelProps = {
|
||
title: string;
|
||
taskTypes?: string[];
|
||
taskTypePrefixes?: string[];
|
||
taskIds?: string[];
|
||
showRecent?: boolean;
|
||
compact?: boolean;
|
||
onTaskClick?: (task) => void;
|
||
};
|
||
```
|
||
|
||
`useTaskMonitor` 负责:
|
||
|
||
- 按 `taskTypes` / `taskTypePrefixes` 查询活跃任务。
|
||
- 轮询或复用全局 SSE 数据。
|
||
- 拉取指定任务日志。
|
||
- 返回 `activeTasks`、`recentTasks`、`latestTask`、`isBusy`。
|
||
|
||
### 7.2 D-InSAR 生产
|
||
|
||
任务类型:
|
||
|
||
- `IDL_RUN_DINSAR`
|
||
- `ISCE2_RUN`
|
||
- `PYINT_RUN`
|
||
- `LANDSAR_RUN`
|
||
|
||
面板位置:
|
||
|
||
- `DinsarProductionPanel` 右侧或提交区下方。
|
||
|
||
局部约束:
|
||
|
||
- 如果同一 engine 的任务正在运行,禁用同 engine 再提交。
|
||
- 其他 engine 是否允许并行应由后端资源锁决定。
|
||
- 用户仍可查看历史 run、日志、结果列表。
|
||
|
||
### 7.3 D-InSAR 产物
|
||
|
||
任务类型:
|
||
|
||
- `SCAN_DINSAR`
|
||
- `DINSAR_RESULT_SCAN`
|
||
- `DINSAR_RESULT_PACKAGE`
|
||
- 以当前后端实际 task_type 为准。
|
||
|
||
面板位置:
|
||
|
||
- `DinsarProductsPanel` 扫描按钮旁或结果列表顶部。
|
||
|
||
局部约束:
|
||
|
||
- 同一 catalog 重建任务运行中,禁用重复重建按钮。
|
||
- 不影响 SBAS 生产、D-InSAR 生产、结果浏览。
|
||
|
||
### 7.4 SBAS-InSAR 生产
|
||
|
||
任务类型:
|
||
|
||
- `SBAS_GAMMA_WORKFLOW`
|
||
- `SBAS_LANDSAR_WORKFLOW`
|
||
- `SBAS_COREGISTRATION`
|
||
- `SBAS_RDC_DEM`
|
||
- `SBAS_INTERFEROGRAMS`
|
||
- `SBAS_IPTA_TIMESERIES`
|
||
|
||
当前状态:
|
||
|
||
- 已基本符合新设计。
|
||
- 已在模块内展示 Runtime Status。
|
||
- 已显式设置 `nonBlocking: true`。
|
||
|
||
后续调整:
|
||
|
||
- 将 Runtime Status 抽成 `TaskStatusPanel` 风格组件。
|
||
- 支持按 `run_id` 过滤关联任务。
|
||
- 全局任务中心只显示摘要和跳转入口。
|
||
|
||
### 7.5 SBAS-InSAR 结果
|
||
|
||
任务类型:
|
||
|
||
- `REBUILD_SBAS_INSAR_CATALOG`
|
||
|
||
局部约束:
|
||
|
||
- 重建中只禁用“重建目录”按钮。
|
||
- 结果列表仍可浏览。
|
||
|
||
当前已接近目标。
|
||
|
||
### 7.6 数据接入与资产扫描
|
||
|
||
任务类型:
|
||
|
||
- `UNPACK_ARCHIVES`
|
||
- `UNPACK_SENTINEL1`
|
||
- `GF3_UNPACK`
|
||
- `GF3_BATCH_PROCESS`
|
||
- `GF3_SARSCAPE_PRODUCE`
|
||
- `GF3_SARSCAPE_SYNC`
|
||
- `GF3_SARSCAPE_CLEAN`
|
||
- `SCAN_DATA`
|
||
- `SCAN_ASSET_INVENTORY`
|
||
|
||
建议:
|
||
|
||
- 数据接入页按卫星/流程展示独立状态卡。
|
||
- `SCAN_DATA` 不应锁全局界面。
|
||
- `GF3_BATCH_PROCESS` 是否需要局部锁取决于是否写共享目录;默认只锁 GF3 预处理按钮。
|
||
|
||
### 7.7 洪涝 / 水体分析
|
||
|
||
任务类型:
|
||
|
||
- `WATER_GEOCODE_*`
|
||
- `WATER_DETECT_*`
|
||
- `WATER_FLOOD_*`
|
||
- `FLOOD_SCENE_PREPROCESS_*`
|
||
- `FLOOD_WATER_EXTRACTION_*`
|
||
- `FLOOD_DETECTION_*`
|
||
- `GF3_PROCESS_*`
|
||
|
||
建议:
|
||
|
||
- 洪涝工作台显示场景级任务状态。
|
||
- 使用 task type prefix 匹配。
|
||
- 不再触发全局锁。
|
||
- 单个场景处理时,只禁用该场景相关按钮。
|
||
|
||
### 7.8 AI 与灾害点
|
||
|
||
任务类型:
|
||
|
||
- `AI_TRAIN`
|
||
- `AI_PREDICT`
|
||
- `AI_ANALYZE`
|
||
- `AI_WARMUP`
|
||
- `SCAN_HAZARD`
|
||
|
||
建议:
|
||
|
||
- AI 质量页显示 AI 训练/预测任务状态。
|
||
- AI 诊断页显示诊断任务状态。
|
||
- `AI_TRAIN` 运行中禁用再次训练;不阻止浏览结果。
|
||
- `AI_ANALYZE` 运行中只禁用同一结果的重复诊断。
|
||
- `SCAN_HAZARD` 只影响灾害点同步按钮。
|
||
|
||
## 8. 任务分类模型
|
||
|
||
建议引入统一任务元数据配置,前端和后端可逐步共享。
|
||
|
||
```ts
|
||
type TaskUiPolicy = {
|
||
taskType: string;
|
||
featureScope: string;
|
||
label: string;
|
||
globalVisible: boolean;
|
||
globalBlocking: boolean;
|
||
localBlocking: boolean;
|
||
resourceScope?: string;
|
||
routeTarget?: string;
|
||
};
|
||
```
|
||
|
||
默认策略:
|
||
|
||
- `globalVisible=true`
|
||
- `globalBlocking=false`
|
||
- `localBlocking=true`
|
||
|
||
也就是说,任务默认显示在全局任务中心,但不锁整个系统。
|
||
|
||
只有极少数任务可设置:
|
||
|
||
```ts
|
||
globalBlocking=true
|
||
```
|
||
|
||
但这应作为过渡兼容,不作为长期设计。
|
||
|
||
## 9. 后端资源锁设计
|
||
|
||
后端当前只有 `task_type` 级互斥。这不足以表达以下场景:
|
||
|
||
- 同一个 run 不能同时执行两个会修改同一状态文件的步骤。
|
||
- 同一个 catalog 不能并发重建。
|
||
- 同一个输出目录不能被两个生产任务同时写入。
|
||
- 同一个 ENVI / SARscape 单实例资源不能并行调用。
|
||
|
||
建议新增资源锁概念。
|
||
|
||
### 9.1 资源锁 key
|
||
|
||
示例:
|
||
|
||
```text
|
||
sbas-run:{run_id}
|
||
sbas-catalog:{catalog_root}
|
||
dinsar-engine:{engine_code}
|
||
dinsar-root:{root_dir}
|
||
envi-runtime:{host_or_profile}
|
||
gf3-sarscape-root:{root_dir}
|
||
water-scene:{scene_id}
|
||
ai-model:{model_id}
|
||
```
|
||
|
||
### 9.2 后端行为
|
||
|
||
创建任务时检查:
|
||
|
||
- 同 `task_type` 是否已有活跃任务。
|
||
- 同 `resource_lock_key` 是否已有活跃任务。
|
||
|
||
如果冲突:
|
||
|
||
- 返回 `409 Conflict`。
|
||
- 返回冲突任务 ID、任务类型、状态、消息。
|
||
|
||
前端收到后:
|
||
|
||
- 不弹全局锁。
|
||
- 在当前功能面板提示“已有同资源任务运行中”。
|
||
- 提供跳转到任务日志。
|
||
|
||
### 9.3 迁移方式
|
||
|
||
第一阶段不必改数据库结构,可把资源锁写入 `SystemTaskORM.params`:
|
||
|
||
```json
|
||
{
|
||
"resource_lock_key": "sbas-run:sbas_e21648e52bd4",
|
||
"feature_scope": "sbas_insar"
|
||
}
|
||
```
|
||
|
||
后续再考虑独立列或资源锁表。
|
||
|
||
## 10. 前端状态管理重构
|
||
|
||
### 10.1 保留内容
|
||
|
||
保留:
|
||
|
||
- `/tasks/active` SSE / fallback polling。
|
||
- `activeTasks` 全局缓存。
|
||
- 任务完成后刷新相关数据的能力。
|
||
|
||
### 10.2 移除或降级内容
|
||
|
||
降级:
|
||
|
||
- `isGlobalLocked`
|
||
- `pendingTaskIds`
|
||
- `nonBlockingTaskIds`
|
||
- `NON_BLOCKING_TASK_TYPES`
|
||
- `ActiveTasksOverlay`
|
||
|
||
迁移后:
|
||
|
||
- `isGlobalLocked` 不再驱动全屏遮罩。
|
||
- `pendingTaskIds` 不再用于判断系统锁定。
|
||
- `nonBlockingTaskIds` 不再需要。
|
||
- `NON_BLOCKING_TASK_TYPES` 变成 `TASK_UI_POLICIES`。
|
||
- `ActiveTasksOverlay` 替换为 `GlobalTaskCenter`。
|
||
|
||
### 10.3 新 hook
|
||
|
||
建议新增:
|
||
|
||
```text
|
||
frontend/src/hooks/useTaskCenter.js
|
||
frontend/src/hooks/useTaskMonitor.js
|
||
frontend/src/config/taskUiPolicies.js
|
||
```
|
||
|
||
`useTaskCenter`:
|
||
|
||
- 订阅 active tasks。
|
||
- 维护全局任务状态。
|
||
- 提供任务完成事件分发。
|
||
|
||
`useTaskMonitor`:
|
||
|
||
- 从全局任务状态中过滤当前功能相关任务。
|
||
- 提供 `isBusy`、`latestTask`、`activeTasks`、`recentTasks`。
|
||
|
||
## 11. 任务完成后的刷新策略
|
||
|
||
当前全局锁解除时会调用 `initializeAppData({ refreshRadarSearch: true })`,这也过粗。
|
||
|
||
应改成按任务类型刷新:
|
||
|
||
| 任务类型 | 刷新目标 |
|
||
|---|---|
|
||
| `UNPACK_ARCHIVES` | LT-1 数据检索选项、当前检索页 |
|
||
| `UNPACK_SENTINEL1` | Sentinel-1 资产状态 |
|
||
| `SCAN_ASSET_INVENTORY` | 资产库存状态 |
|
||
| `SBAS_*` | 对应 SBAS run detail 或产品 catalog |
|
||
| `REBUILD_SBAS_INSAR_CATALOG` | SBAS 产品列表 |
|
||
| `SCAN_DINSAR` | D-InSAR 产品列表 |
|
||
| `AI_TRAIN` / `AI_PREDICT` | AI 状态与结果质量 |
|
||
| `SCAN_HAZARD` | 灾害点列表 |
|
||
| `WATER_*` / `FLOOD_*` | 洪涝工作台当前场景/事件 |
|
||
|
||
实现上可维护:
|
||
|
||
```ts
|
||
TASK_COMPLETION_REFRESH_POLICIES
|
||
```
|
||
|
||
每个功能页也可以订阅自己的任务完成事件。
|
||
|
||
## 12. 迁移计划
|
||
|
||
### 阶段 1:文档与审计
|
||
|
||
状态:本设计文档。
|
||
|
||
输出:
|
||
|
||
- 当前锁机制审计。
|
||
- 新交互原则。
|
||
- 迁移边界。
|
||
|
||
### 阶段 2:抽象任务 UI policy
|
||
|
||
新增:
|
||
|
||
- `frontend/src/config/taskUiPolicies.js`
|
||
|
||
内容:
|
||
|
||
- task type -> label
|
||
- task type -> feature scope
|
||
- task type -> route target
|
||
- task type -> local/global blocking policy
|
||
|
||
替换:
|
||
|
||
- `useGlobalTaskControl.NON_BLOCKING_TASK_TYPES`
|
||
- `useDinsarOperations.NON_BLOCKING_TASK_TYPES`
|
||
- `ActiveTasksOverlay.getTaskTypeLabel`
|
||
|
||
验收:
|
||
|
||
- 所有任务类型 label 来自同一配置。
|
||
- 新任务默认不锁全局。
|
||
|
||
### 阶段 3:全局遮罩改为任务中心
|
||
|
||
新增:
|
||
|
||
- `GlobalTaskCenter`
|
||
- `TaskCenterButton` 或顶部状态入口
|
||
|
||
替换:
|
||
|
||
- `ActiveTasksOverlay`
|
||
|
||
验收:
|
||
|
||
- 有活跃任务时不再遮住全系统。
|
||
- 用户可继续切换页面和浏览结果。
|
||
- 管理员仍可取消任务。
|
||
|
||
### 阶段 4:功能级任务面板
|
||
|
||
优先级:
|
||
|
||
1. D-InSAR 生产
|
||
2. D-InSAR 产物
|
||
3. 数据接入
|
||
4. 洪涝分析
|
||
5. AI / 灾害点
|
||
6. SBAS 组件收敛到通用面板
|
||
|
||
验收:
|
||
|
||
- 每个功能页能看到本功能任务状态。
|
||
- 同类任务运行中,只禁用同类提交按钮。
|
||
|
||
### 阶段 5:后端资源锁
|
||
|
||
新增:
|
||
|
||
- 任务 params 中写入 `feature_scope`、`resource_lock_key`。
|
||
- `task_service.create_task()` 支持资源锁冲突检查。
|
||
|
||
验收:
|
||
|
||
- 同 run、同目录、同 catalog 的冲突任务由后端返回 `409`。
|
||
- 前端不靠全局遮罩防冲突。
|
||
|
||
### 阶段 6:删除旧全局锁状态
|
||
|
||
删除或废弃:
|
||
|
||
- `isGlobalLocked`
|
||
- `pendingTaskIds`
|
||
- `nonBlockingTaskIds`
|
||
- `handleTaskStart(null, ...)` 触发全局锁的路径
|
||
|
||
验收:
|
||
|
||
- 代码中不存在“无 taskId 触发全局锁”的逻辑。
|
||
- 全局任务中心只展示状态,不控制系统可用性。
|
||
|
||
## 13. 风险与处理
|
||
|
||
### 13.1 后端资源冲突未覆盖
|
||
|
||
风险:
|
||
|
||
- 去掉前端全局锁后,某些共享目录或单实例程序可能被并发调用。
|
||
|
||
处理:
|
||
|
||
- 迁移初期保留少量 `globalBlocking=true` 兼容策略。
|
||
- 优先给 ENVI / SARscape / 同目录生产补资源锁。
|
||
- 对不确定任务先做局部锁,不做全局遮罩。
|
||
|
||
### 13.2 用户忽略后台任务
|
||
|
||
风险:
|
||
|
||
- 没有全屏遮罩后,用户可能不知道任务仍在跑。
|
||
|
||
处理:
|
||
|
||
- 顶部或右下角常驻任务指示。
|
||
- 功能页内明确显示任务状态。
|
||
- 失败任务有醒目提示。
|
||
|
||
### 13.3 任务完成刷新过少
|
||
|
||
风险:
|
||
|
||
- 以前全局刷新掩盖了局部刷新缺失。
|
||
|
||
处理:
|
||
|
||
- 建立 `TASK_COMPLETION_REFRESH_POLICIES`。
|
||
- 逐功能补刷新策略。
|
||
- 保留手动刷新入口。
|
||
|
||
## 14. 验收标准
|
||
|
||
完成重构后应满足:
|
||
|
||
1. 任意 SBAS 任务运行时,系统其他功能可正常浏览和操作。
|
||
2. D-InSAR 任务运行时,不再弹全屏锁;D-InSAR 面板显示任务进度。
|
||
3. 同一个 D-InSAR engine 或同一输出目录的冲突提交由后端拒绝。
|
||
4. 数据接入扫描/解包任务运行时,不影响生产管理和结果浏览。
|
||
5. 洪涝场景级任务运行时,只影响对应场景按钮。
|
||
6. AI 训练/预测运行时,不阻断地图、结果浏览和 SBAS/DInSAR 生产。
|
||
7. 所有活跃任务都能在全局任务中心找到。
|
||
8. 每个功能页能看到与本功能相关的任务。
|
||
9. 管理员取消任务能力仍可用,但语义是“取消任务”,不是“强制解锁界面”。
|
||
10. 代码中不再通过 `handleTaskStart(null, ...)` 触发全局锁。
|
||
|
||
## 15. 推荐首批改动清单
|
||
|
||
建议第一批代码改动只做前端交互,不动后端任务模型:
|
||
|
||
1. 新建 `taskUiPolicies.js`,统一任务 label、scope、blocking 策略。
|
||
2. 将 D-InSAR 生产、D-InSAR 产物、IDL、AI、灾害点、水体任务全部标为 `globalBlocking=false`。
|
||
3. `ActiveTasksOverlay` 改为可关闭的 `GlobalTaskCenter`。
|
||
4. `ensureCanOperate()` 不再读取 `isGlobalLocked`,只检查用户权限。
|
||
5. `rebuildRadarPreviewCache()` 删除 `handleTaskStart(null, ...)`,改用局部 loading。
|
||
6. D-InSAR 生产面板增加任务状态卡。
|
||
7. D-InSAR 产物面板增加目录扫描任务状态卡。
|
||
|
||
第二批再做后端资源锁。
|
||
|
||
## 16. 结论
|
||
|
||
全局界面锁应退出核心设计。任务系统的正确边界应是:
|
||
|
||
- 全局:看见所有任务。
|
||
- 功能页:管理本功能任务。
|
||
- 后端:保证资源互斥和并发安全。
|
||
|
||
前端全屏锁只应作为临时兼容手段,不应继续扩展。
|