---
title: "簽核引擎與應用整合"
category: "operations"
canonical: "https://www.ai-go.app/zh-TW/docs/guide/approval-system"
locale: "zh-TW"
last_updated: "2026-08-10"
source: "AI GO 開發者文件（https://www.ai-go.app）"
---

# 簽核引擎與應用整合

簽核不是一個「審批模組」，而是一層**掛在資料寫入路徑上的攔截器**。這代表：不論資料從 Custom App、REST API 還是 AI 助理寫進來，簽核都會生效——沒有繞過的路徑。

---

## 運作原理

在一般系統中，新增一筆請假單或採購單，資料會立刻寫入生效。AI GO 的差別在於：

1. **寫入攔截**：當管理者為某張表啟用簽核流程後，對該表的寫入會被自動攔截
2. **派單**：系統依流程定義推導出合格審核人並發送通知，產生簽核申請
3. **核准回調**：所有關卡通過後，平台自動執行原本被攔截的操作——包含它連帶觸發的所有業務引擎（開票、扣庫存、產傳票）

若任一關卡駁回，資料會退回草稿狀態，可修改後重新送審。

### 三種寫入的攔截語意不同

| 操作 | 攔截行為 |
|---|---|
| **新增** | 資料以待審核狀態保存，通過後正式生效 |
| **更新** | **不執行**。變更內容暫存，通過後由平台自動套用 |
| **刪除** | **不執行**。通過後由平台自動執行 |

更新與刪除的差別很重要：它們**不會**先寫進去再回滾，而是根本不執行。呼叫端會收到一個帶有申請識別碼的待簽核例外。

**呼叫端不需要也不應該重試**——重試只會產生重複的簽核申請。正確處理是捕捉例外並告知使用者「已送出簽核」。

---

## 設定簽核流程

**入口**：主控台「系統與維運管理 › 簽核流程引擎」，需要 `system.admin` 權限。

### 1. 指定目標

選擇要套用的資料表（銷售訂單、請假單、進項帳單等）。**一張表同時只能啟用一個流程。**

### 2. 觸發條件

可設定只在特定條件下才需要簽核。例如「金額大於 100,000 的採購單才需主管簽核」——低於門檻的直接放行，不製造無謂的審批負擔。

條件也可以依記錄的欄位值路由到不同流程。

### 3. 規劃關卡

按順序建立多個關卡（第一關部門經理、第二關財務總監）。每個關卡可設定：

- 是否為必要關卡
- **簽核類型**：單人核准即可，或多人會簽（全員通過才算過）

### 4. 定義合格審核人

每個關卡指定審核人資格，支援三種規則：

| 規則 | 說明 |
|---|---|
| 指定使用者 | 特定帳號 |
| 指定角色 | 具備該角色的所有成員（如所有財務主管） |
| **動態部門主管** | 依「申請人的部門主管」動態派單，可設定往上追溯的層級 |

動態部門主管是最實用的一種——組織異動時不需要回頭改流程定義。

---

## 在 Custom App 中整合

簽核 SDK 讓您把簽核直接做進應用程式，使用者不需要切換到主控台。

### 伺服器端

```python
def execute(ctx):
    # 觸發者本人的待簽核清單
    pending = ctx.approval.list_pending()

    # 查某筆記錄的簽核狀態（含各關卡明細）
    status = ctx.approval.get_record_status('sale_orders', order_id)

    # 以觸發者身分核准／駁回
    ctx.approval.approve(line_id, comment='確認無誤')
    ctx.approval.reject(line_id, comment='金額與報價不符')

    # 取消申請（限申請人本人、限進行中）
    ctx.approval.cancel(request_id, reason='重新評估')
```

### 前端

`src/approval.ts` 提供對應的前端方法，可以直接組出簽核面板——顯示歷史軌跡、輸入意見、一鍵核准或駁回。

### 身分綁定

簽核 SDK **綁使用者身分**，這是它與其他 SDK 最大的差別：

- `list_pending()` 回的是**觸發者本人**的待辦，不是全組織的
- `approve()` 會驗證觸發者是否為該關卡的合格審核人，不是就拒絕
- 沒有平台使用者身分的呼叫（如排程）會被拒絕

這代表您無法用應用程式的權限「代替別人簽核」。

---

## 透過 API 整合

外部系統可以完整整合簽核機制：

```
GET  /api/v1/approvals/record/{res_model}/{res_id}
POST /api/v1/approvals/{request_line_id}/approve
POST /api/v1/approvals/{request_line_id}/reject
POST /api/v1/approvals/{request_id}/retry
```

**查詢狀態**：回傳每一關卡的狀態、審核人名稱、簽核意見與時間明細。若尚未發起簽核則回傳空。

**核准**：帶入簽核明細行的識別碼與意見。系統會驗證呼叫者資格；最後一關核准時自動執行回調。

**駁回**：原始記錄重設為草稿，可修改後重送。

**回調重試**：簽核全數通過但回調因外部因素失敗時，管理者可手動重試。回調失敗不會讓簽核狀態退回——它是獨立的補救動作。

---

## 常見設計模式

### 讓使用者知道「已送出簽核」而不是「失敗」

```python
def execute(ctx):
    try:
        ctx.db.update('sale_orders', order_id, {'state': 'sale'})
        return ctx.response.json({'status': 'updated'})
    except Exception as e:
        if 'approval' in str(e).lower():
            return ctx.response.json({
                'status': 'pending_approval',
                'message': '變更已送出簽核，通過後自動生效'
            })
        raise
```

### 在列表上顯示簽核狀態

用 `get_record_status` 批次查詢，把「待第 2 關 / 財務總監」這類資訊直接標在列表上，使用者不必逐筆點進去看。

### 主管的待辦面板

用 `list_pending()` 在應用首頁做一個待辦區塊。這是簽核 SDK 最高價值的用法——主管不必為了簽核而登入另一套系統。

---

## 邊界與注意事項

- **一張表一個流程**：需要不同條件走不同路徑時，用條件路由而非多個流程
- **簽核與業務引擎的順序**：回調在簽核通過後才執行，因此開票、扣庫存、產傳票都發生在通過的那一刻，不是送審的當下
- **排程觸發的寫入**：簽核守衛仍會生效，簽核介面上的申請人顯示為 API
- **稽核**：所有簽核決定都留下完整紀錄，包含審核人、時間與意見