跳轉到正文
開發者文檔/開放 API

審批開放 API

透過 Muse Open 轉發地址建立審批、查詢狀態並接收回調事件。

最近更新

審批開放接口

  • POST https://muse-open.test.tezign.com/api/muse/approval-api

調用約定

  • 請求方法:POST
  • Content-Type:application/json
  • 請求體必須是合法 JSON
  • 使用 service 區分具體能力

可用 service:

  • subscriptionQuery
  • subscriptionChange
  • listTemplates
  • createApproval
  • taskStatusQuery

統一響應

json
{
"code": "0",
"message": "成功",
"result": {},
"traceId": "trace_xxx"
}

常見錯誤碼:

  • 400:參數錯誤
  • 401:鑑權失敗
  • 403:權限不足
  • 404:資源不存在
  • 500:服務內部錯誤

listTemplates

請求示例:

json
{
"service": "listTemplates"
}

result 為模板陣列,常見字段: id、name、description、enabled、usageCount、autoImportEnabled、targetFolder、workflow。

createApproval

必填字段:

  • templateId
  • createdBy
  • assets(至少 1 條)
  • assets[].url 必須為可公開訪問的 http/https 地址

請求示例:

json
{
"service": "createApproval",
"templateId": "101",
"createdBy": "10086",
"assets": [
{
"name": "demo.mp4",
"url": "https://cdn.example.com/m/asset_1.mp4"
}
]
}

成功示例:

json
{
"code": "0",
"message": "成功",
"result": {
"taskId": "9527"
}
}

taskStatusQuery

請求示例:

json
{
"service": "taskStatusQuery",
"taskId": "9527"
}

result.status 取值: PENDING | PROCESSING | APPROVED | REJECTED | CANCELED。

訂閱與回調

查詢訂閱:

json
{
"service": "subscriptionQuery"
}

新增訂閱:

json
{
"service": "subscriptionChange",
"operation": "ADD",
"callbackUrl": "https://example.com/webhook/approval"
}

取消訂閱:

json
{
"service": "subscriptionChange",
"operation": "DELETE"
}

訂閱回調 payload 說明

當呼叫 subscriptionChange 且 operation = ADD 成功後,審批狀態變化會回調到你傳入的 callbackUrl。

回調請求基礎約定

  • 請求方法:POST
  • Content-Type:application/json

回調體結構:

json
{
"eventId": "evt_xxx",
"eventType": "APPROVAL",
"eventTime": "1760258885000",
"payload": {
"eventName": "TASK_APPROVED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "APPROVED"
}
}

字段說明:

  • eventId:事件唯一 ID(接收方建議按此做冪等)
  • eventType:固定為 APPROVAL
  • eventTime:毫秒時間戳字串
  • payload:業務資料體

payload 公共字段

每個回調事件的 payload 至少包含:

  • eventName:事件名
  • orgId:組織 ID(由系統填充)
  • taskId:審批任務 ID
  • taskStatus:任務狀態(PROCESSING / APPROVED / TIMEOUT)

事件全集(觸發條件)

  • NODE_STARTED:節點開始處理時觸發(建立任務首節點、節點流轉到下一節點、流轉到重提節點都會觸發)
  • APPROVER_SUBMITTED:審批人在節點提交審批意見時觸發(同一節點可多次觸發,不同審批人各觸發一次)
  • NODE_COMPLETED:某節點辦結時觸發(通過 / 拒絕)
  • NODE_TRANSFERRED:節點辦結後流轉到下一處理節點時觸發(正常流轉、重提流轉、超時轉交流轉)
  • SUBMITTER_RESUBMITTED:發起人在「待重新提交」節點提交新素材時觸發
  • TASK_APPROVED:任務終態通過時觸發
  • NODE_TIMEOUT:節點超時時觸發(超時轉交或超時待重新分配)

字段定義(完整)

payload.node(節點物件)
  • nodeId(string):節點 ID(必有)
  • nodeOrder(number):節點順序(部分事件存在)
  • nodeRole(string):節點角色(normal / resubmit_submitter / resubmit_approver,部分事件存在)
  • nodeStatus(string):節點狀態
    • 常見值:pending / processing / approved / rejected / timeout_transferred / re_assigned
  • signMode(string):簽審模式(and / or,按場景出現)
  • approverCount(number):審批人數(按場景出現)
  • approvers(array):節點辦結時審批人結果(NODE_COMPLETED)
    • 子項:id、name、status
  • startedAt(string):節點開始時間(ISO)
  • completedAt(string):節點完成時間(ISO)
  • timeoutHours(number):節點超時閾值小時數(超時事件出現)
payload.approver(審批人提交物件,APPROVER_SUBMITTED)
  • id(string):審批人用戶 ID
  • name(string):審批人名稱
  • decision(approved | rejected):審批決定
  • comment(string):審批意見
  • submittedAt(string):提交時間(ISO)
payload.submitter(提交人物件,SUBMITTER_RESUBMITTED)
  • id(string):提交人用戶 ID
  • name(string):提交人名稱
  • comment(string):重提備註
  • submittedAt(string):提交時間(ISO)
payload.timeout(超時物件)
  • transferTo(object | null):超時轉交目標
    • 有轉交人時:{ "id": "...", "name": "..." }
    • 無轉交人時:null
payload.latestAssets(重提素材快照,SUBMITTER_RESUBMITTED)
  • assetId(string)
  • filePathId(string)
  • version(number)
  • oldStorePath(string):舊版本儲存路徑
  • newStorePath(string):新版本儲存路徑
  • updatedAt(string):更新時間(ISO)
payload.transferReason(NODE_TRANSFERRED)
  • NEXT_NODE:正常流轉到下一審批節點
  • RESUBMIT_SUBMITTER:流轉到待重新提交節點
  • RESUBMIT_APPROVER:重提後流轉到重審節點
  • TIMEOUT_TRANSFER:超時後轉交

回調示例(全事件)

TASK_APPROVED 示例:

json
{
"eventId": "evt_2a93f5f5f4d64907a2f3b73cb8f0f201",
"eventType": "APPROVAL",
"eventTime": "1760258885000",
"payload": {
"eventName": "TASK_APPROVED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "APPROVED",
"operator": {
"id": "10086",
"name": "张三"
},
"finishedAt": "2026-10-12T08:08:05.000Z"
}
}

NODE_STARTED 示例:

json
{
"eventId": "evt_d3a39140643a4d73afedf0a47c0a601d",
"eventType": "APPROVAL",
"eventTime": "1760258700000",
"payload": {
"eventName": "NODE_STARTED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "PROCESSING",
"node": {
"nodeId": "12001",
"nodeOrder": 1,
"nodeRole": "normal",
"nodeStatus": "processing",
"signMode": "and",
"approverCount": 2,
"startedAt": "2026-10-12T08:05:00.000Z"
}
}
}

APPROVER_SUBMITTED 示例:

json
{
"eventId": "evt_8bc9f92f83564f10adf8270b598f95d2",
"eventType": "APPROVAL",
"eventTime": "1760258820000",
"payload": {
"eventName": "APPROVER_SUBMITTED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "PROCESSING",
"node": {
"nodeId": "12001",
"nodeOrder": 1,
"nodeStatus": "processing",
"signMode": "and"
},
"approver": {
"id": "10086",
"name": "张三",
"decision": "approved",
"comment": "同意",
"submittedAt": "2026-10-12T08:07:00.000Z"
},
"approverCount": 2
}
}

NODE_COMPLETED 示例:

json
{
"eventId": "evt_652d4d8c09d24477af9fdb21624fd070",
"eventType": "APPROVAL",
"eventTime": "1760258855000",
"payload": {
"eventName": "NODE_COMPLETED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "PROCESSING",
"node": {
"nodeId": "12001",
"nodeOrder": 1,
"nodeStatus": "approved",
"signMode": "and",
"approvers": [
{
"id": "10086",
"name": "张三",
"status": "approved"
},
{
"id": "10087",
"name": "李四",
"status": "approved"
}
],
"completedAt": "2026-10-12T08:07:35.000Z"
}
}
}

NODE_TRANSFERRED 示例(正常流轉):

json
{
"eventId": "evt_21881077723e4a17aa4e2e58ee78ce79",
"eventType": "APPROVAL",
"eventTime": "1760258856000",
"payload": {
"eventName": "NODE_TRANSFERRED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "PROCESSING",
"transferReason": "NEXT_NODE",
"fromNode": {
"nodeId": "12001",
"nodeOrder": 1,
"nodeStatus": "approved"
},
"node": {
"nodeId": "12002",
"nodeOrder": 2,
"nodeRole": "normal",
"nodeStatus": "pending"
}
}
}

NODE_TRANSFERRED 示例(拒絕後流轉到待重提):

json
{
"eventId": "evt_e612f8b5e1de4960bb712d3df18e2617",
"eventType": "APPROVAL",
"eventTime": "1760258900000",
"payload": {
"eventName": "NODE_TRANSFERRED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "PROCESSING",
"transferReason": "RESUBMIT_SUBMITTER",
"fromNode": {
"nodeId": "12001",
"nodeOrder": 1,
"nodeStatus": "rejected"
},
"node": {
"nodeId": "13001",
"nodeOrder": 2,
"nodeRole": "resubmit_submitter",
"nodeStatus": "pending"
}
}
}

NODE_TRANSFERRED 示例(重提後流轉到重審):

json
{
"eventId": "evt_f0c43dd5ca5d4fca9e4adbe536fbb8f5",
"eventType": "APPROVAL",
"eventTime": "1760259005000",
"payload": {
"eventName": "NODE_TRANSFERRED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "PROCESSING",
"transferReason": "RESUBMIT_APPROVER",
"fromNode": {
"nodeId": "13001",
"nodeOrder": 2,
"nodeStatus": "approved"
},
"node": {
"nodeId": "13002",
"nodeOrder": 3,
"nodeRole": "resubmit_approver",
"nodeStatus": "pending"
}
}
}

NODE_TIMEOUT 示例(超時轉交):

json
{
"eventId": "evt_b0d67fb6f3de42e79a60b8f9df6ad20d",
"eventType": "APPROVAL",
"eventTime": "1760260000000",
"payload": {
"eventName": "NODE_TIMEOUT",
"orgId": "233",
"taskId": "9527",
"taskStatus": "TIMEOUT",
"node": {
"nodeId": "12002",
"nodeStatus": "timeout_transferred",
"timeoutHours": 24
},
"timeout": {
"transferTo": {
"id": "10100",
"name": "王五"
}
}
}
}

NODE_TIMEOUT 示例(超時未轉交):

json
{
"eventId": "evt_2e4372871f0c4a7eb95a9d7c638de8a0",
"eventType": "APPROVAL",
"eventTime": "1760260100000",
"payload": {
"eventName": "NODE_TIMEOUT",
"orgId": "233",
"taskId": "9527",
"taskStatus": "TIMEOUT",
"node": {
"nodeId": "12002",
"nodeStatus": "re_assigned",
"timeoutHours": 24
},
"timeout": {
"transferTo": null
}
}
}

SUBMITTER_RESUBMITTED 示例:

json
{
"eventId": "evt_5d017db5b458443697f6c10d5f6370df",
"eventType": "APPROVAL",
"eventTime": "1760259000000",
"payload": {
"eventName": "SUBMITTER_RESUBMITTED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "PROCESSING",
"node": {
"nodeId": "12002",
"nodeOrder": 3,
"nodeStatus": "approved",
"signMode": "and"
},
"submitter": {
"id": "10010",
"name": "李四",
"comment": "已更新素材,重新提交",
"submittedAt": "2026-10-12T08:10:00.000Z"
},
"latestAssets": [
{
"assetId": "asset_1",
"filePathId": "30001",
"version": 3,
"oldStorePath": "assets/old/asset_1_v2.mp4",
"newStorePath": "assets/new/asset_1_v3.mp4",
"updatedAt": "2026-10-12T08:10:00.000Z"
}
],
"latestAssetCount": 1
}
}

NODE_TRANSFERRED 示例(超時轉交後):

json
{
"eventId": "evt_15f4348dd4f34a4b9d51ec93313f4dff",
"eventType": "APPROVAL",
"eventTime": "1760260001000",
"payload": {
"eventName": "NODE_TRANSFERRED",
"orgId": "233",
"taskId": "9527",
"taskStatus": "PROCESSING",
"transferReason": "TIMEOUT_TRANSFER",
"node": {
"nodeId": "12002",
"nodeStatus": "timeout_transferred"
},
"timeout": {
"transferTo": {
"id": "10100",
"name": "王五"
}
}
}
}

事件時序(關鍵流程)

說明:回調為「至少一次投遞」,消費方應按 eventId 做冪等去重,不要假設不會重複投遞。

正常通過(多節點)
  1. NODE_STARTED(首節點開始)
  2. APPROVER_SUBMITTED(每位審批人提交時觸發,可能多次)
  3. NODE_COMPLETED(當前節點完成)
  4. 若有下一節點:NODE_TRANSFERRED -> NODE_STARTED
  5. 重複 2~4,直到最後一個節點完成
  6. TASK_APPROVED(任務終態通過)
拒絕後重提
  1. APPROVER_SUBMITTED(decision = rejected)
  2. NODE_COMPLETED(nodeStatus = rejected)
  3. NODE_TRANSFERRED(transferReason = RESUBMIT_SUBMITTER)
  4. NODE_STARTED(nodeRole = resubmit_submitter)
  5. SUBMITTER_RESUBMITTED(提交人重提)
  6. NODE_COMPLETED(重提節點完成)
  7. NODE_TRANSFERRED(transferReason = RESUBMIT_APPROVER)
  8. NODE_STARTED(重審節點開始)
  9. 後續再次進入正常審批鏈路(APPROVER_SUBMITTED ...)
超時轉交 / 超時未轉交
  1. 節點超時觸發 NODE_TIMEOUT(taskStatus = TIMEOUT)
  2. 若配置了超時轉交人:緊接著觸發 NODE_TRANSFERRED(transferReason = TIMEOUT_TRANSFER),任務回到 PROCESSING
  3. 若無可轉交人:僅有 NODE_TIMEOUT(常見 nodeStatus = re_assigned),等待人工處理後再推進
MuseDAM Developer PlatformAPI · Integrations · MCP
    審批開放 API | MuseDAM Developers