昨天從流程的開始(Start node),今天講結束(End node),這就是一個最基本的流程。
是的,還真沒錯,如果只想單純的先用表單集中資料,有開始有結束,這是一個完整的流程設計,因為 BeakPlatform 將Form.io 表單系統與Cytoscape.js 流程系統刻意設計成透過[配對]統一一套技術方便維護,所以人-機四模都是同一套技術。
原生的 Form.io 是用JSON格式儲存表單內容, BeakPlatform 善用對PostgreSQL的JSONB把表單儲存到資料表的欄位內,好處是表單設計隨時可改,麻煩的是改太多次較難統計,不統計倒也不麻煩。所以 BeakPlatform 設計[SQL同步]讓JSON+SQL都儲存限制: a. 同步:並非即時同步,要等表單正常透過End Node結束之後,系統才會把JSONB轉SQL插入一筆。 b. 版本:每修改過一次必須[發行],發行一個版本自動產生一個SQL資料表用於儲存表單內容。 所以把同一表單的不同版本的資料表串一起得自己來,所以別因為太方便就常改。 
現在開始說明結束(End node)
| 顯示名稱 | 結束 |
|---|---|
| node_type | End |
| 一句話用途 | 結束整個流程實例,由結束模式決定其他未完成節點與案件終態怎麼處理 |
| 會讓流程等待 | 嚴格等待模式(strict)會反覆等待;其餘兩種模式最多只等設定的秒數,不進入長時間等待 |
| 出線 | 沒有出線——它是終點,就算畫面上接了線,引擎也不會使用 |
| 可用範圍 | 所有企業 |
結束(End)是流程的終點:只要流程實例裡任何一條分支走到 End 並成功執行, 整個流程實例就會被引擎判定結束——不是只有 End 所在的那條分支結束,是「整個流程」結束。 它真正決定的不是「這條分支怎麼收尾」,而是「結束當下,流程裡其他還沒跑完的節點該怎麼處理、案件最終要 記成什麼終態」,這由「結束模式」(finish_mode)決定,三種模式的行為差異很大。
任何流程模板都至少需要一個 End 才能真正結束;沒有它,流程會一直停留在 RUNNING。並行分支如果只是想讓某一條「安靜地停下,但不影響其他分支,也不結束整個流程」, 不要把它接到 End——改指向一個沒有設定任何出線的節點即可(見下方 4. 出線行為)。
| 面板欄位 | config key | 必填 | 預設值 | 說明 |
|---|---|---|---|---|
| 等待……秒後結束流程 | wait_seconds | 選填 | 3(主流程;子流程內的 End 沒有面板可設,程式預設 1) | 執行到 End 後先等待這麼多秒,才真正進入結束模式的判斷,給還在跑的並行分支一點 收尾時間。面板輸入上限 300 秒,設定超過會被系統自動夾限為 300 秒並在節點執行紀錄留一行警告, 不會顯示在畫面上、也不會報錯;可以填 0 代表不等待。 |
| 分離執行模式/取消終止模式/嚴格等待模式(三選一) | finish_mode | 選填(有預設) | detach | 決定其他未完成節點與案件終態,三種模式的精確差異見下方「4. 出線行為」。 |
End 可以讀取的變數前綴與其他節點相同(${f.} ${fi.} ${v.} ${wi.} ${n.} ${t.}),但它目前沒有任何 設定欄位會用到變數替換。它寫出的東西:
End 沒有出線——它是流程的終點。就算在畫布上真的替它接了一條出線,引擎判定流程結束的 邏輯裡也不會呼叫任何「推進到下一個節點」的動作,那條線會被完全忽略。

分離執行模式(detach,預設)
等待 wait_seconds 後直接判定流程 COMPLETED,不主動處理其他未完成節點。還在 WAITING 的暫停節點或簽核任務 不會被作廢;只有等到它們自己的到期時間到了,被執行器排程撿到時,才會發現「流程已是 終態」而直接取消——不會再往下推進,也不會報錯或觸發任何催辦動作。
取消/終止模式(cancel)
等待 wait_seconds 後判定流程 CANCELLED(不是 COMPLETED),同時主動取消所有還在 PENDING/RUNNING/WAITING 的節點,包含強制終止正在執行中的 作業系統子行程。放在子流程裡時,只收「自己與所有下層」(不含上一層與其他支線),不會影響上一層流程或 同一子流程模板的其他執行中支線。
嚴格等待模式(strict)
等待 wait_seconds 後檢查流程裡是否還有未完成節點:有的話回到 等待狀態,固定 30 秒後(寫死,不可設定)再檢查一次,如此反覆,直到全部完成才判定 結束。過程中若發現有節點狀態是 FAILED,流程會被標記為 FAILED 而不是 COMPLETED。
子流程裡的 End 行為多一層:它結束的不是「主流程」,而是完成「這個子流程實例」,並喚醒 上一層呼叫它的子流程節點——依該節點的結果路由設定決定父流程接下來走哪些出線(沒有設定就走全部出線), 同時把子流程的結束方式(完成/中止)寫進父流程的流程變數,讓上一層的判斷邏輯可以引用。


用 cancel 當作「正常結束、順便清乾淨」的手段
症狀:案件明明是正常處置完成,但表單中心顯示「已取消」,不是「已核准」。
原因:finish_mode=cancel 從設計上就是「中止」語意,流程與表單一律記成 CANCELLED,不是「完工並順便清掉分支」。
正確做法:正常完工的流程一律用 detach;detach 不會讓還在等待的節點 造成任何副作用——到期時執行器自己會發現流程已結束並取消,不需要主動用 cancel 去清乾淨。
以為 detach 會自動作廢還沒簽的任務
症狀:流程實例已經是 COMPLETED,但表單中心的待簽核清單裡還看得到一張「活的」 任務,點開仍然可以正常簽核。
原因:detach 不會主動處理其他節點,只有那個節點自己的到期時間到了、被執行器排程 撿到時,才會發現流程已結束並直接取消——在那之前它是真的還活著、可操作,不是殘影。
正確做法:如果不希望還有游離的任務留著,改用 cancel;如果任務最終有沒有被簽根本 不影響案件結果,detach 本來就是為這種情境設計的。
把 End 接了出線,以為它會照著走
症狀:End 後面明明接了一條線到別的節點,但那個節點從來不會被執行。
原因:End 是終點,判定流程結束的邏輯裡沒有任何「推進到下一個節點」的呼叫, 出線會被完全忽略。
正確做法:拿掉那條多餘的線;如果目的是「流程結束後再做點什麼」,那段邏輯要放在 End 之前執行。
等待秒數設超過 300
症狀:設定的等待秒數被自動改小,實際等待時間不如預期。
原因:300 秒是寫死的上限,超過會被系統自動夾限,只在節點執行紀錄留一行警告,畫面上看不出來。
正確做法:需要更長的收尾等待,應該改用 Delay 節點串接,不要把 End 的等待秒數當成通用的延遲機制——它的用途只是給並行分支一點收尾時間。
對應「NT-02 End 示範」,同一份骨架各佈建了三份,分別固定 finish_mode 為 detach/cancel/strict: Start 分出快慢兩條並行分支,快分支約 8 秒後抵達 End;慢分支是等待 10 秒後進入 一個指定簽核人=發起人自己、但示範故意不主動簽的簽核任務。三個示範各自到表單中心送出後,查 fw_workflow_instances.status 看流程實例最終狀態,再查 fw_node_execution_queue(依 node_type/status)比對慢分支的 簽核任務下場:
建議三個示範都跑一次,直接比對三次查詢結果的差異,比只看單一個流程更容易看懂三種模式的分別。