执行部门回报完成,任务进入 Review 待尚书省汇总审查。
(task_id, output_path='', summary='')
| 438 | |
| 439 | |
| 440 | def cmd_done(task_id, output_path='', summary=''): |
| 441 | """执行部门回报完成,任务进入 Review 待尚书省汇总审查。""" |
| 442 | rejected = [False] |
| 443 | reject_reason = [''] |
| 444 | def modifier(tasks): |
| 445 | t = find_task(tasks, task_id) |
| 446 | if not t: |
| 447 | log.error(f'任务 {task_id} 不存在') |
| 448 | return tasks |
| 449 | old_state = t.get('state') |
| 450 | if old_state not in ('Doing', 'Next'): |
| 451 | rejected[0] = True |
| 452 | reject_reason[0] = f'当前状态 {old_state} 不允许直接上报完成' |
| 453 | return tasks |
| 454 | completed, total = _todo_counts(t) |
| 455 | if total > 0 and completed < total: |
| 456 | rejected[0] = True |
| 457 | reject_reason[0] = f'todos 未完成({completed}/{total}),禁止直接收口' |
| 458 | return tasks |
| 459 | |
| 460 | from_org = t.get('org', '执行部门') |
| 461 | t['state'] = 'Review' |
| 462 | t['org'] = STATE_ORG_MAP.get('Review', t.get('org', '')) |
| 463 | t['output'] = output_path |
| 464 | t['now'] = summary or '执行已完成,提交尚书省汇总审查' |
| 465 | t.setdefault('flow_log', []).append({ |
| 466 | "at": now_iso(), "from": from_org, |
| 467 | "to": "尚书省", "remark": f"✅ 执行完成,提交审查:{summary or '待尚书省汇总'}" |
| 468 | }) |
| 469 | # 同步设置 outputMeta,避免依赖 refresh_live_data.py 异步补充 |
| 470 | if output_path: |
| 471 | p = pathlib.Path(output_path) |
| 472 | if p.exists(): |
| 473 | ts = datetime.datetime.fromtimestamp(p.stat().st_mtime).strftime('%Y-%m-%d %H:%M:%S') |
| 474 | t['outputMeta'] = {"exists": True, "lastModified": ts} |
| 475 | else: |
| 476 | t['outputMeta'] = {"exists": False, "lastModified": None} |
| 477 | t['updatedAt'] = now_iso() |
| 478 | return tasks |
| 479 | atomic_json_update(TASKS_FILE, modifier, []) |
| 480 | _trigger_refresh() |
| 481 | if rejected[0]: |
| 482 | log.warning(f'⚠️ {task_id} done 被拒绝:{reject_reason[0]}') |
| 483 | _append_audit(task_id, _infer_agent_id_from_runtime(), 'done_rejected', None, 'Review', reject_reason[0]) |
| 484 | return |
| 485 | log.info(f'✅ {task_id} 执行完成,已提交尚书省审查') |
| 486 | _append_audit(task_id, _infer_agent_id_from_runtime(), 'done', None, 'Review', summary or '') |
| 487 | |
| 488 | |
| 489 | def cmd_block(task_id, reason): |