| 顯示名稱 | 分支 |
|---|---|
| node_type | Branch |
| 一句話用途 | 依規則比對流程變數或表單欄位目前的值,決定接下來要走哪一條、哪幾條出線,或完全不走任何出線。 |
| 會讓流程等待 | 否。比對是同步進行的,評估完規則立刻決定去向,不會進入等待狀態,也不佔用任何人的待辦。 |
| 出線 | 不限制條數。每條規則可以同時勾選多條出線(代表命中後同時並行走這幾條);也可以完全不勾(該分支安靜結束)。命中多條規則時,這些規則各自勾選的出線會全部一起被推進。 |
| 可用範圍 | 所有企業,不需要平台管理者另外授權。 |
分支(Branch)是流程裡負責「路由」的節點:它讀取目前的表單欄位或流程變數,依你設定的一組規則逐條比對, 命中某條規則就把流程往那條規則指定的出線推進。它本身不呼叫任何外部服務、不寫回表單、也不會停下來等任何人, 純粹是「看一眼目前的值、決定往哪走」的判斷點。
適合用在:依金額分段走不同的簽核路徑、依事件嚴重度決定要不要交給人處理、檢查某個流程變數是否已經被填過(例如 是否已經有人簽核、是否已經有處置結果)。不適合用在:需要等待某個條件「之後才成立」的情境——分支只評估「當下」的值, 不會反覆檢查,要做這種等待要靠暫停(Delay)配合分支輪流檢查;也不適合直接拿來做需要 人判斷的決策,那是簽核(FormAdapter)的工作,分支通常接在簽核之後,依簽核結果 再往下分流。
設計器面板把設定分成兩個區塊:「分支規則」與「無匹配時(Fallback)」。
| 面板欄位 | config key | 必填 | 預設值 | 說明 |
|---|---|---|---|---|
| (規則清單,按「新增規則」新增) | rules | 選填 | 空陣列 | 規則陣列,逐條獨立評估。完全沒有規則時,等於每次都直接走 fallback。 |
| 規則名稱 | rules[].name | 選填 | 「規則 N」 | 純顯示用,只影響畫面與節點日誌上看到的名稱,不影響比對邏輯。 |
| 條件(一條規則內可加多個,按「+條件」新增) | rules[].conditions | 必填 | — | 至少要有一個條件;沒有條件的規則視為驗證失敗,無法儲存。 |
| 條件的變數(輸入框,placeholder 為 ${v.name}) | conditions[].variable | 必填 | — | 要拿來比較的值,見下方「3. 可用的變數與輸出」。務必整段包在 ${...} 內,例如 ${f.amount};沒有包起來的文字會被當成常數字串,不會被解析成變數。 |
| 運算符(下拉選單) | conditions[].operator | 必填 | == | 15 種,見下方「運算符一覽」。 |
| 值(empty/not_empty 時面板會隱藏此欄) | conditions[].value | 依運算符而定 | — | 可以是固定文字,也可以包含 ${...} 變數表達式(例如拿另一個流程變數當比較基準); 字串裡只要出現 ${ 就會先做一次變數替換再比較。 |
| 條件之間的關係(每個條件後面的下拉選單,最後一個條件不顯示) | conditions[].logic | 選填 | AND | 不是「這個條件」的標記,而是分組的切分符,見下方「規則內條件怎麼組合」。 |
| 目標路徑(可多選的核取方塊,列出此節點目前的出線) | rules[].target_edges | 必填(或 target_nodes) | 空陣列 | 這條規則成立時要推進的出線,可多選;多選代表同時並行推進多條路徑。 |
handler 的驗證邏輯同時接受 rules[].target_nodes(陣列,直接指定目標節點 ID 而非出線 ID)作為 target_edges 的替代寫法,但設計器面板完全沒有提供設定它的介面。不建議使用 target_nodes——原因見下方「6. 注意事項」,它並不會如字面意思限定路徑。
| 運算符 | 面板顯示 | 語意 | 需要「值」欄位 |
|---|---|---|---|
| == | == | 相等(一律轉成字串比較,不是數值比較) | 是 |
| != | != | 不相等(同上,字串比較) | 是 |
|>|數值大於|是
=|>=|數值大於等於|是
<|<|數值小於|是
<=|<=|數值小於等於|是
contains|包含|變數值是否包含指定子字串|是
not_contains|不含|變數值是否不包含指定子字串|是
startswith|開頭|變數值是否以指定字串開頭|是
endswith|結尾|變數值是否以指定字串結尾|是
in|在|變數值是否等於清單中的某一項|是
not_in|不在|變數值是否不等於清單中任何一項|是
empty|空|變數值是否為空|否
not_empty|非空|變數值是否非空|否
matches|正則|變數值是否符合正則表達式(「值」欄位放正則本身)|是
in/not_in 的「值」欄位如果不是陣列(面板輸入的一定是文字),會以逗號切開、 去除頭尾空白後再逐一比對——例如填 approved, confirmed 等同 ['approved','confirmed']。
logic 不是「這個條件是 AND 還是 OR」,而是「這個條件與下一個條件之間」的分組切分符: 依序掃描條件,遇到標 OR 的條件、或掃到最後一個條件時,就把目前累積的條件收成一組;組內全部 成立(AND)才算這組成立,只要有任一組成立,整條規則就成立(組間是 OR)。例如三個條件依序標 AND、OR、AND,會被拆成「條件1 且 條件2」與「條件3」兩組,整條規則 等於「(條件1 且 條件2)或 條件3」。
| 面板欄位 | config key | 必填 | 預設值 | 說明 |
|---|---|---|---|---|
| 下拉選單:不走任何出線(終止此分支)/路由至節點 | fallback.action | 選填 | log | log=這個分支到此為止,不推進任何出邊(安靜結束,不算錯誤);route=依 target_edge 導向指定的單一出線。 |
| Log 訊息(action=log 時顯示) | fallback.log_message | 選填 | 「無匹配規則」 | 只寫進節點日誌,方便事後追查為什麼落到 fallback,不影響流程走向。 |
| 選擇目標出線(action=route 時顯示的下拉選單) | fallback.target_edge | route 時必填 | — | 只能從這個 Branch 節點目前已有的出線中挑一條,不能指向不相連的節點。 |
「變數」與「值」兩個欄位都吃同一套解析規則,支援的前綴:
| 前綴 | 意義 | 範例 |
|---|---|---|
| ${f.欄位} | 表單欄位(目前這次流程實例送出的表單資料) | ${f.amount} |
| ${v.變數} | 流程變數(NODE > FLOW > TREE 優先序) | ${v.soc_decision} |
| ${fi.xxx} | 表單實例資訊:applicant/applicant_dept/applicant_email/applicant_code/serial/name/subject/code/status | ${fi.applicant} |
| ${wi.xxx} | 流程實例資訊,只有五個:code/exec_code/name/status/depth | ${wi.status} |
| ${n.xxx} | 節點上下文:name/id/type | ${n.type} |
| ${t.xxx} | 時間:now/date/time(皆為 UTC) | ${t.date} |
不加 ${}、只寫裸名稱(例如直接填 status)會被當成流程變數名稱查詢(等同 ${v.status}),但這是過渡期相容寫法,一律用完整的 ${...} 前綴寫法比較不會混淆。
分支本身不會寫出任何流程變數,也不會動表單資料——它純粹決定出線。如果想留下「這次走了 哪一段」的紀錄,慣例是在每條出線後面各接一個設定變數(OpSet)節點,寫入一個 記錄用的流程變數。
執行順序:
單一條件的比較如果因為缺值或型別不符而拋出例外(例如用數值運算符比較一個非數字字串),該條件視為不成立, 只記一條警告日誌,不會讓整個節點失敗。
分支本身是同步節點,不會進入等待狀態;它產生的下游節點(例如各出線接的簽核、暫停)才各自可能等待。
最常見、也是設計時該優先追求的用法:把規則設計成彼此互斥的區間,讓每次評估只會有一條規則命中, 流程只走一條路徑。
一條規則的 target_edges 不是只能填一個。資安事件處置流程(SOC 團隊版)的「嚴重度分流」用 這個特性讓高危事件同時走兩條路:一條交給值班人員簽核,另一條純粹計時,用來在遲遲沒人處理時自動催辦—— 計時分支只負責提醒,不會代替人做出封鎖或放行的決定。
下面兩段 config 效果不同,容易搞混:
// 寫法 A:真的有指定路由目標
"fallback": {
"action": "route",
"target_edge": "edge-med",
"log_message": "嚴重度缺值,走中危標準簽核"
}
// 效果:無匹配時只推進 edge-med 這一條出線
// 寫法 B:選了「路由至節點」但沒有選目標(面板下拉維持空白)
"fallback": {
"action": "route"
}
// 效果:等同 action=log——不推進任何出線,分支安靜結束
// 因為 handler 只有在 target_edge 或 target_node 真的有值時才會路由,
// 否則會落到與 action=log 完全相同的「不推進任何出線」處理路徑
規則條件重疊,案件會同時走多條路
症狀:設計時以為每次只會命中一條規則,結果同一批案件裡,落在某個金額或某個值域的案件,兩條規則 下游的節點都真的被執行了(例如兩個 OpSet 都各自寫入了自己的流程變數)。
原因:分支對「同時命中多條 規則」的處理方式是全部展開、取聯集推進,不是先到先贏,也不會因為某條規則已命中就跳過其餘規則不評估。 兩條規則的判斷區間只要有重疊(例如一條是「>=50000」、另一條是「<=200000」),中間的區間就會同時 命中兩條。
正確做法:設計規則時明確畫出彼此互斥的邊界(例如用 < 而非 <= 錯開兩段的分界),或者本來就是要並行(像圖 2 的高危雙軌),那就不是問題,但要在規則 名稱與節點描述裡寫清楚這是刻意設計。
用 target_nodes 指定目標,不會真的限定路徑
症狀:直接編輯流程 graph(例如用腳本產生流程),用 rules[].target_nodes 取代 target_edges 指定某條規則命中後要去的節點,結果命中時流程不是只往那個節點走, 而是把這個分支節點所有的出線全部一起推進了。
原因:handler 確實會把 target_nodes 的內容整理進執行結果的 data.selected_nodes,但實際負責推進流程的 程式只讀取 data.selected_edges(陣列)或 data.selected_edge(單一字串),完全不會 讀 selected_nodes。當一條規則只填了 target_nodes、沒有填 target_edges 時,selected_edges 會是空陣列,於是被判定成「沒有指定出線」, 依通用規則退回「取所有出邊」——不會有任何錯誤或警告訊息。
正確做法:一律使用 target_edges(也就是面板上「目標路徑」的核取方塊),不要使用 target_nodes;設計器面板本身也沒有提供設定 target_nodes 的介面,只有直接編輯 流程 graph 才會踩到這個坑。
fallback 選了「路由至節點」卻忘了選目標
症狀:面板上把 fallback 動作切成「路由至節點」,但下拉選單裡沒有選任何出線就直接按套用並發行, 結果無匹配時的行為跟原本「不走任何出線」一模一樣。
原因:只有在確實選了目標出線、 fallback.target_edge 真的有值時,才會產生路由效果;action 設成 route 但目標是空的, 會落到與 action=log 完全相同的處理路徑。
正確做法:選了「路由至節點」之後,務必確認下拉 選單裡已經選到一條出線;這個節點至少要先拉出你想要的那條出線,下拉選單才選得到。
AND/OR 分組容易拆錯
症狀:同一條規則裡有兩個條件,本來想表達「兩個都要成立」,結果只要其中一個條件成立,規則就命中了。
原因:logic 是「這個條件跟下一個條件之間」的分組切分符,不是「這個條件本身」的性質。 只要中間有任何一個條件被誤標成 OR,就會被拆成兩個獨立的群組(組間是 OR 關係)。
正確做法:要表達「全部條件都要成立」,每個條件(除了最後一個)都要標 AND(或留預設值); 只有真正想要「任一群組成立即可」時才用 OR 斷開分組。
== 是字串比較,empty 把數字 0 也當成空
==/!= 一律把兩邊轉成字串再比較,所以字串 "100" 與 "100.0" 不相等;金額類比較建議一律用 >/>=/</ <= 等數值運算符。另外,empty 運算子的判定是 Python 的真假值判定,數字 0、空字串、未設定的變數(預設回傳空字串)都會被視為「空」——如果拿它去判斷一個合法值可能是 0 的欄位(例如某個計數),要注意 0 會被誤判成空。
比較失敗一律視為不成立,不會報錯
缺值、型別不符(例如拿一個文字字串做數值比較)都會讓該條件判定為不成立,只記一條警告到節點日誌, 不會讓節點失敗、也不會中斷流程。這個特性可以刻意拿來當安全閥(缺資料時自動落到 fallback),但也代表 「變數欄位打錯字」這種設定錯誤不會有任何提示——案件會一路落到 fallback,畫面上看不出原因,要靠節點日誌 才查得到。
node展覽館裡有兩支分支的示範流程,都在同一個批次(B2):
在平台安裝目錄下執行(需要系統管理權限):
venv/bin/python scripts/seed_node_showcase.py --apply --only B2
寫入後到表單中心(例如 http://192.168.0.112:8000/beakplatform/forms/center)的「填寫表單」 分類「node展覽館」下找到對應表單送出;兩個示範表單送出後都會產生一張待簽核任務(示範用設計成發起人自己簽核), 簽核完流程才會走到結束。