# Job 批次完成任務 — 前端整合規格

## 功能概述

在待辦任務頁面（`/project/task-manage`）新增批次完成功能，讓使用者勾選多個處理中的任務，填寫統一的 comment，一次送出完成。

---

## API 規格

### 批次完成任務

```
POST /api/1.0/grc/project/<project_uid>/jobs/batch-complete
Authorization: Bearer <token>
Content-Type: application/json
```

**Request：**

```json
{
  "comment": "已完成相關佐證文件上傳",
  "job_uids": [
    "job-uid-1",
    "job-uid-2",
    "job-uid-3"
  ]
}
```

| 欄位 | 必填 | 說明 |
|------|------|------|
| `comment` | 選填 | 完成說明，套用到所有被選的任務 |
| `job_uids` | 必填 | 要完成的 job UID 陣列，從任務列表的 `id` 欄位取得 |

**Response：**

```json
{
  "status": true,
  "data": {
    "total": 3,
    "completed_count": 2,
    "failed_count": 1,
    "results": [
      {"job_uid": "job-uid-1", "success": true, "error": null},
      {"job_uid": "job-uid-2", "success": true, "error": null},
      {"job_uid": "job-uid-3", "success": false, "error": "任務不在處理中狀態"}
    ]
  }
}
```

| 欄位 | 說明 |
|------|------|
| `total` | 送出的總筆數 |
| `completed_count` | 成功完成的筆數 |
| `failed_count` | 失敗的筆數 |
| `results` | 每筆的結果明細 |
| `results[].job_uid` | Job UID |
| `results[].success` | 是否成功 |
| `results[].error` | 失敗原因（成功時為 null） |

---

## 前端 UI 設計建議

### 任務列表頁面調整

1. **新增勾選欄**
   - 任務列表表格最左方新增 checkbox 欄位
   - 只有 **PROCESSING** 狀態的任務才能勾選（其他狀態 checkbox disabled）
   - 表頭有全選 checkbox（只全選 PROCESSING 狀態的）

2. **批次操作工具列**
   - 當有任務被勾選時，顯示工具列：`已選 N 筆` + 「批次完成」按鈕
   - 無勾選時隱藏工具列

3. **批次完成 Dialog**

   **Step 1 — 確認與填寫 comment**

   ```
   ┌─────────────────────────────────────┐
   │  批次完成任務                         │
   │                                     │
   │  即將完成 3 筆任務：                  │
   │  ┌─────────────────────────────┐    │
   │  │ ☑ [AC.L1-3.1.1] 佐證上傳    │    │
   │  │ ☑ [AC.L1-3.1.1] 問卷填答    │    │
   │  │ ☑ [IA.L1-3.5.1] 佐證上傳    │    │
   │  └─────────────────────────────┘    │
   │                                     │
   │  完成說明（選填）                     │
   │  ┌─────────────────────────────┐    │
   │  │                             │    │
   │  └─────────────────────────────┘    │
   │                                     │
   │           [取消]  [確認完成]          │
   └─────────────────────────────────────┘
   ```

   - 列出被勾選的任務清單（顯示控制項代碼 + 任務名稱）
   - 提供 comment 輸入框（textarea，選填）
   - 「確認完成」→ 送 API

   **Step 2 — 結果顯示**

   ```
   ┌─────────────────────────────────────┐
   │  批次完成結果                         │
   │                                     │
   │  ✓ 成功完成 2 筆                     │
   │  ✗ 失敗 1 筆                         │
   │                                     │
   │  ┌──────────┬────────┬─────────┐    │
   │  │ 任務名稱  │ 結果   │ 原因    │    │
   │  ├──────────┼────────┼─────────┤    │
   │  │ 佐證上傳  │  ✓    │         │    │
   │  │ 問卷填答  │  ✓    │         │    │
   │  │ 佐證上傳  │  ✗    │ 不在... │    │
   │  └──────────┴────────┴─────────┘    │
   │                                     │
   │                    [關閉]            │
   └─────────────────────────────────────┘
   ```

   - 顯示成功/失敗筆數
   - 表格列出每筆結果
   - 失敗的任務顯示原因（`results[].error`）
   - 關閉後刷新任務列表

---

## 前端實作重點

### 1. 勾選邏輯

```javascript
// 只允許勾選 PROCESSING 狀態的任務
const isSelectable = (job) => job.status === 'PROCESSING'

// 取得被勾選的 job_uids
const selectedJobUids = selectedJobs.map(job => job.id)
```

### 2. 送出批次完成

```javascript
const response = await api.post(
  `/grc/project/${projectUid}/jobs/batch-complete`,
  {
    comment: commentText,
    job_uids: selectedJobUids
  }
)

// 解析結果
const { completed_count, failed_count, results } = response.data
```

### 3. 結果處理

```javascript
// 全部成功
if (failed_count === 0) {
  message.success(`已完成 ${completed_count} 筆任務`)
}
// 部分失敗
else {
  message.warning(`完成 ${completed_count} 筆，失敗 ${failed_count} 筆`)
  // 顯示失敗明細
}

// 刷新列表
refreshJobList()
```

---

## 限制條件

| 條件 | 說明 |
|------|------|
| 只能完成 PROCESSING 狀態 | 前端 checkbox 應 disable 非 PROCESSING 任務，後端也會驗證 |
| 部分成功 | 不會因為單筆失敗而回滾其他任務，每筆獨立處理 |
| Comment 共用 | 所有被選任務套用同一個 comment |
| 無需 workflow_execution_uid | 前端只需送 `job_uid`（即任務列表的 `id` 欄位），後端自動查詢 |

---

## 相關現有 API

| API | 用途 |
|-----|------|
| `POST /grc/jobs/my/list` | 取得使用者的任務列表（含 status、id 等） |
| `POST /flow-engine/task/complete/<job_id>` | 單筆完成任務（現有，批次完成基於此） |
