FormatPlan 格式化执行计划为可读文本
(plan *ExecutionPlan)
| 348 | |
| 349 | // FormatPlan 格式化执行计划为可读文本 |
| 350 | func FormatPlan(plan *ExecutionPlan) string { |
| 351 | var sb strings.Builder |
| 352 | |
| 353 | sb.WriteString(fmt.Sprintf("# 执行计划: %s\n\n", plan.Description)) |
| 354 | sb.WriteString(fmt.Sprintf("计划 ID: %s\n", plan.ID)) |
| 355 | sb.WriteString(fmt.Sprintf("状态: %s\n", plan.Status)) |
| 356 | |
| 357 | if plan.Options != nil && plan.Options.RequireApproval { |
| 358 | if plan.UserApproved { |
| 359 | sb.WriteString("审批状态: ✅ 已审批\n") |
| 360 | } else { |
| 361 | sb.WriteString("审批状态: ⏳ 待审批\n") |
| 362 | } |
| 363 | } |
| 364 | sb.WriteString("\n") |
| 365 | |
| 366 | sb.WriteString("## 执行步骤\n\n") |
| 367 | for i, step := range plan.Steps { |
| 368 | statusIcon := getStatusIcon(step.Status) |
| 369 | sb.WriteString(fmt.Sprintf("### 步骤 %d: %s %s\n", i+1, step.Description, statusIcon)) |
| 370 | sb.WriteString(fmt.Sprintf("- 工具: `%s`\n", step.ToolName)) |
| 371 | |
| 372 | if step.Input != "" { |
| 373 | sb.WriteString(fmt.Sprintf("- 输入: %s\n", step.Input)) |
| 374 | } |
| 375 | |
| 376 | if len(step.Parameters) > 0 { |
| 377 | sb.WriteString("- 参数:\n") |
| 378 | for name, value := range step.Parameters { |
| 379 | sb.WriteString(fmt.Sprintf(" - %s: %v\n", name, value)) |
| 380 | } |
| 381 | } |
| 382 | |
| 383 | if len(step.DependsOn) > 0 { |
| 384 | sb.WriteString(fmt.Sprintf("- 依赖: %v\n", step.DependsOn)) |
| 385 | } |
| 386 | |
| 387 | if step.Error != "" { |
| 388 | sb.WriteString(fmt.Sprintf("- 错误: %s\n", step.Error)) |
| 389 | } |
| 390 | |
| 391 | sb.WriteString("\n") |
| 392 | } |
| 393 | |
| 394 | return sb.String() |
| 395 | } |
| 396 | |
| 397 | // getStatusIcon 获取状态图标 |
| 398 | func getStatusIcon(status StepStatus) string { |
no test coverage detected