## ADDED Requirements ### Requirement: 02010067 支持可选异步受理模式 系统 SHALL 为接口服务 `02010067`(`HisDataService.GetInpatientData`)提供可选的异步受理模式,由入参 `params[0].asyncFlag` 控制。当 `asyncFlag` 未显式传入时,SHALL 依次回退取 `BS_HISSyncConfig.AsyncFlag`、再回退取 `'N'`。 当 `asyncFlag = 'N'` 时,系统 SHALL 完全保持现有同步执行语义与返回结构,`result` 仍为 HIS 原始数组,不得做任何裁剪。 当 `asyncFlag = 'Y'` 时,系统 SHALL 在毫秒级返回受理回执,不得等待同步完成。 #### Scenario: 显式传入 asyncFlag='Y' 时立即返回受理回执 - **WHEN** 调用 `02010067` 且 `params[0].asyncFlag = 'Y'` - **THEN** 系统应创建一条 `BS_HISSyncTask` 任务记录(`Status='pending'`) - **AND** 应启动后台进程执行同步,并立即返回 `{errorCode:'0', result:{taskId:<任务号>, status:'pending'}}` - **AND** 从接收到返回响应耗时应与数据量无关(不随费用明细行数增长) #### Scenario: 未传 asyncFlag 且配置为 N 时保持同步语义 - **WHEN** 调用 `02010067` 且未传 `asyncFlag`,且 `BS_HISSyncConfig.AsyncFlag = 'N'` - **THEN** 系统应沿用现有同步执行路径 - **AND** 返回结构应与改造前完全一致(`result` 为 HIS 原始数组) #### Scenario: 未传 asyncFlag 且配置缺失时回退为同步 - **WHEN** 调用 `02010067` 且未传 `asyncFlag`,且 `BS_HISSyncConfig` 无对应配置记录 - **THEN** 系统应将 `asyncFlag` 回退为 `'N'` 并同步执行 ### Requirement: 异步任务状态机与进度回写 系统 SHALL 维护 `BS_HISSyncTask` 任务表,任务状态在 `pending` / `running` / `success` / `partial` / `failed` 之间流转,并在执行过程中持续回写进度计数(`admTotal`、`admProcessed`、`feeTotal`、`feeProcessed`、`successCount`、`failedCount`、`skippedCount`)与阶段(`phase`:`fetch` / `saveAdm` / `saveFee` / `done`)。 #### Scenario: 任务正常启动并流转到 running - **WHEN** 后台进程开始执行任务 - **THEN** 系统应将任务 `Status` 置为 `running`、`Phase` 置为 `fetch`、写入 `StartTime` #### Scenario: 执行过程中回写进度 - **WHEN** 后台进程每处理完一个就诊或每处理完 500 行费用明细 - **THEN** 系统应更新对应 `admProcessed` / `feeProcessed` 与 `successCount` / `failedCount` - **AND** 不得在每一行费用明细处理后回写(避免进度回写本身成为性能瓶颈) #### Scenario: 全部成功时置为 success - **WHEN** 任务执行完成且 `failedCount = 0` 且无异常 - **THEN** 系统应将 `Status` 置为 `success`、`Phase` 置为 `done`、写入 `EndTime` #### Scenario: 部分失败时置为 partial - **WHEN** 任务执行完成但存在 `failedCount > 0` 或 `skippedCount > 0` - **THEN** 系统应将 `Status` 置为 `partial` 并写入 `ErrorMessage` 摘要 #### Scenario: 执行异常时置为 failed - **WHEN** 后台进程抛出未捕获异常 - **THEN** 系统应将 `Status` 置为 `failed`、`ErrorMessage` 记录异常摘要 - **AND** 异常不得导致已成功落库的数据被回滚 ### Requirement: 同参数任务并发去重 系统 SHALL 对相同的 `(HospCode, StDate, EndDate, AdmID)` 组合做并发去重:当已存在 `pending` 或 `running` 状态的任务时,SHALL 直接复用并返回既有 `taskId`,不得重复启动后台进程。 #### Scenario: 重复提交同一范围的同步请求 - **WHEN** 用户在前一个任务仍处于 `running` 时再次提交相同机构与日期范围的同步请求 - **THEN** 系统应返回既有任务的 `taskId` - **AND** 不得创建新的任务记录或启动新的后台进程 #### Scenario: 前一任务已终态时允许新建 - **WHEN** 相同参数的前序任务已处于 `success` / `partial` / `failed` - **THEN** 系统应创建新任务并正常启动后台进程 ### Requirement: 提供任务进度查询接口 02010089 系统 SHALL 提供接口服务 `02010089`(`src.DRG.HISData.Interface.GetSyncTaskProgress` → `HisDataService.GetSyncTaskProgress`),按 `taskId` 返回任务状态与进度。该接口 SHALL 为只读查询,不得触发任何同步动作。 #### Scenario: 查询进行中任务的进度 - **WHEN** 调用 `02010089` 传入一个 `running` 任务的 `taskId` - **THEN** 系统应返回 `{status, phase, admTotal, admProcessed, feeTotal, feeProcessed, successCount, failedCount, skippedCount, percent, startTime, errorMessage}` - **AND** `percent` 应为 0–100 的整数 #### Scenario: 查询不存在的任务 - **WHEN** 调用 `02010089` 传入不存在的 `taskId` - **THEN** 系统应返回 `errorCode` 非 `'0'` 及对应错误提示,不得抛出异常 ### Requirement: 僵死任务回收 系统 SHALL 识别并回收因后台进程异常退出而长期停留在 `running` 状态的任务,避免任务永久悬挂。 #### Scenario: running 任务超时无进度更新 - **WHEN** 查询一个 `running` 任务且其进度超过设定阈值(默认 30 分钟)无任何更新 - **THEN** 系统应将该任务 `Status` 置为 `failed` 并写入超时相关 `ErrorMessage` - **AND** 后续查询应返回该终态