sy-form-components 0.2.12 → 0.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -107,6 +107,7 @@ __export(index_exports, {
107
107
  getProcessBasic: () => getProcessBasic,
108
108
  getProcessDefinition: () => getProcessDefinition,
109
109
  getProcessProgress: () => getProcessProgress,
110
+ getReturnableNodeResult: () => getReturnableNodeResult,
110
111
  getReturnableNodes: () => getReturnableNodes,
111
112
  getSystemFieldsForFormType: () => getSystemFieldsForFormType,
112
113
  getViewPermission: () => getViewPermission,
@@ -6712,12 +6713,13 @@ var normalizeProcessBasic = (value) => {
6712
6713
  processStatus: raw.processStatus ?? raw.status ?? instance.processStatus ?? instance.status,
6713
6714
  formUuid: raw.formUuid ?? instance.formUuid ?? instance.definition?.formUuid,
6714
6715
  appType: raw.appType ?? instance.appType ?? instance.definition?.appType,
6715
- title: raw.title ?? instance.title,
6716
+ title: raw.title ?? instance.title ?? instance.instanceTitle,
6716
6717
  originatorId: raw.originatorId ?? instance.originatorId ?? instance.startedBy,
6717
6718
  originatorName: raw.originatorName ?? instance.originatorName ?? instance.startedByName,
6718
6719
  originatorDepartment: raw.originatorDepartment ?? instance.originatorDepartment ?? instance.startedDepartmentName,
6719
6720
  createdAt: raw.createdAt ?? instance.createdAt ?? instance.startedAt,
6720
- currentTask
6721
+ currentTask,
6722
+ isExecuting: raw.isExecuting ?? instance.isExecuting
6721
6723
  };
6722
6724
  };
6723
6725
  var normalizeApprovalPermission = (value) => {
@@ -6741,6 +6743,13 @@ var normalizeReturnableNodes = (value) => {
6741
6743
  nodeName: node?.nodeName || node?.name || node?.title || node?.id || ""
6742
6744
  }));
6743
6745
  };
6746
+ var normalizeReturnableNodeResult = (value) => {
6747
+ const raw = value?.data || value || {};
6748
+ return {
6749
+ nodes: normalizeReturnableNodes(raw),
6750
+ policy: raw?.policy || null
6751
+ };
6752
+ };
6744
6753
  var normalizeProcessDefinition = (value) => {
6745
6754
  const raw = value?.definitionJson || value?.viewJson || value || {};
6746
6755
  const nodes = Array.isArray(raw.nodes) ? raw.nodes : [];
@@ -6827,11 +6836,15 @@ async function saveTask(request, params) {
6827
6836
  return response.data || response.result;
6828
6837
  }
6829
6838
  async function getReturnableNodes(request, taskId) {
6839
+ const result = await getReturnableNodeResult(request, taskId);
6840
+ return result.nodes;
6841
+ }
6842
+ async function getReturnableNodeResult(request, taskId) {
6830
6843
  const response = await request({
6831
6844
  url: `/workflow/task/${taskId}/returnable-nodes`,
6832
6845
  method: "get"
6833
6846
  });
6834
- return normalizeReturnableNodes(response.data || response.result);
6847
+ return normalizeReturnableNodeResult(response.data || response.result);
6835
6848
  }
6836
6849
  async function previewProcess(request, params) {
6837
6850
  const response = await request({
@@ -8009,6 +8022,13 @@ var DEFAULT_APPROVAL_ACTIONS = [
8009
8022
  { action: "rejected", name: { zh_CN: "\u62D2\u7EDD" } }
8010
8023
  ];
8011
8024
  var WITHDRAW_ACTION = { action: "withdraw", name: { zh_CN: "\u64A4\u9500" } };
8025
+ var FINAL_PROCESS_STATUSES = /* @__PURE__ */ new Set([
8026
+ "completed",
8027
+ "terminated",
8028
+ "withdrawn",
8029
+ "cancelled"
8030
+ ]);
8031
+ var EDITABLE_COMPLETED_STATUSES = /* @__PURE__ */ new Set(["completed", "terminated"]);
8012
8032
  function mergeCurrentTask(processTask, approvalTask) {
8013
8033
  if (!approvalTask) return processTask ?? null;
8014
8034
  if (!processTask) return approvalTask;
@@ -8030,11 +8050,14 @@ function useProcessDetail(options) {
8030
8050
  const [progressList, setProgressList] = (0, import_react50.useState)([]);
8031
8051
  const [formData, setFormData] = (0, import_react50.useState)(null);
8032
8052
  const [instanceInfo, setInstanceInfo] = (0, import_react50.useState)(null);
8053
+ const [accessDenied, setAccessDenied] = (0, import_react50.useState)(false);
8054
+ const [loadError, setLoadError] = (0, import_react50.useState)(null);
8033
8055
  const [isApprover, setIsApprover] = (0, import_react50.useState)(false);
8034
8056
  const [canWithdraw, setCanWithdraw] = (0, import_react50.useState)(false);
8035
8057
  const [approvalTasks, setApprovalTasks] = (0, import_react50.useState)([]);
8036
8058
  const [permissions, setPermissions] = (0, import_react50.useState)(null);
8037
8059
  const [processDefinition, setProcessDefinition] = (0, import_react50.useState)(null);
8060
+ const [dataVersion, setDataVersion] = (0, import_react50.useState)(0);
8038
8061
  const mountedRef = (0, import_react50.useRef)(true);
8039
8062
  const fieldIdsKey = fieldIds?.join("") ?? "";
8040
8063
  (0, import_react50.useEffect)(() => {
@@ -8048,26 +8071,34 @@ function useProcessDetail(options) {
8048
8071
  [processInfo?.currentTask, approvalTasks]
8049
8072
  );
8050
8073
  const processStatus = processInfo?.processStatus ?? null;
8051
- const isOriginatorReturn = currentTask?.nodeType === "originator_return";
8052
- const isProcessCompleted = processStatus === "completed" || processStatus === "terminated";
8074
+ const isProcessFinal = processStatus ? FINAL_PROCESS_STATUSES.has(processStatus) : false;
8075
+ const isOriginatorReturn = !isProcessFinal && currentTask?.nodeType === "originator_return";
8076
+ const isProcessCompleted = processStatus ? EDITABLE_COMPLETED_STATUSES.has(processStatus) : false;
8077
+ const canEdit = hasViewOperation(permissions?.operations, "edit");
8078
+ const canDelete = hasViewOperation(permissions?.operations, "delete");
8079
+ const canViewWorkflow = hasViewOperation(permissions?.operations, "workflow");
8080
+ const canViewChangeRecords = hasViewOperation(permissions?.operations, "change_records");
8081
+ const fieldPermissionTask = isProcessFinal ? void 0 : currentTask ?? void 0;
8053
8082
  const { fieldBehaviors } = useFieldPermission({
8054
8083
  viewPermissions: permissions ?? void 0,
8055
8084
  processDefinition: processDefinition ?? void 0,
8056
- currentTask: currentTask ?? void 0,
8057
- isApprover,
8085
+ currentTask: fieldPermissionTask,
8086
+ isApprover: isProcessFinal ? false : isApprover,
8058
8087
  mode
8059
8088
  });
8060
8089
  const activeActions = (0, import_react50.useMemo)(() => {
8061
- if (!isApprover) return [];
8090
+ if (!isApprover || isProcessFinal) return [];
8062
8091
  const actions = currentTask?.actions && currentTask.actions.length > 0 ? [...currentTask.actions] : [...DEFAULT_APPROVAL_ACTIONS];
8063
8092
  if (canWithdraw && !actions.some((action) => action.action === "withdraw")) {
8064
8093
  actions.push(WITHDRAW_ACTION);
8065
8094
  }
8066
8095
  return actions;
8067
- }, [isApprover, currentTask?.actions, canWithdraw]);
8096
+ }, [isApprover, isProcessFinal, currentTask?.actions, canWithdraw]);
8068
8097
  const loadData = (0, import_react50.useCallback)(async () => {
8069
8098
  if (!mountedRef.current) return;
8070
8099
  setLoading(true);
8100
+ setAccessDenied(false);
8101
+ setLoadError(null);
8071
8102
  try {
8072
8103
  const [basicResult, approvalResult, permResult, formResult] = await Promise.all([
8073
8104
  getProcessBasic(request, formInstanceId),
@@ -8076,16 +8107,35 @@ function useProcessDetail(options) {
8076
8107
  getFormData(request, { formInstanceId, appType, formUuid })
8077
8108
  ]);
8078
8109
  if (!mountedRef.current) return;
8110
+ if (!hasViewPermission(permResult)) {
8111
+ setAccessDenied(true);
8112
+ setProcessInfo(null);
8113
+ setIsApprover(false);
8114
+ setCanWithdraw(false);
8115
+ setApprovalTasks([]);
8116
+ setPermissions(permResult);
8117
+ setInstanceInfo(null);
8118
+ setFormData(null);
8119
+ setProgressList([]);
8120
+ setProcessDefinition(null);
8121
+ return;
8122
+ }
8079
8123
  setProcessInfo(basicResult);
8080
- setIsApprover(approvalResult?.isApprover ?? false);
8081
- setCanWithdraw(approvalResult?.canUndo ?? false);
8082
- setApprovalTasks(approvalResult?.currentTasks ?? []);
8124
+ const nextProcessStatus = basicResult?.processStatus ?? null;
8125
+ const nextIsProcessFinal = nextProcessStatus ? FINAL_PROCESS_STATUSES.has(nextProcessStatus) : false;
8126
+ const nextCanWithdraw = Boolean(
8127
+ approvalResult?.canUndo && nextProcessStatus === "running" && basicResult?.isExecuting !== true
8128
+ );
8129
+ setIsApprover(nextIsProcessFinal ? false : approvalResult?.isApprover ?? false);
8130
+ setCanWithdraw(nextCanWithdraw);
8131
+ setApprovalTasks(nextIsProcessFinal ? [] : approvalResult?.currentTasks ?? []);
8083
8132
  setPermissions(permResult);
8084
8133
  setInstanceInfo(formResult);
8085
8134
  setFormData(
8086
8135
  extractFormValues(formResult, fieldIdsKey ? fieldIdsKey.split("") : void 0)
8087
8136
  );
8088
- if (permResult?.operations?.includes("VIEW_PROCESS") || permResult?.operations?.length > 0) {
8137
+ setDataVersion((version) => version + 1);
8138
+ if (hasViewOperation(permResult?.operations, "workflow")) {
8089
8139
  try {
8090
8140
  const progress = await getProcessProgress(request, formInstanceId);
8091
8141
  if (mountedRef.current) {
@@ -8095,8 +8145,8 @@ function useProcessDetail(options) {
8095
8145
  console.error("[useProcessDetail] Failed to load progress:", error);
8096
8146
  }
8097
8147
  }
8098
- const task = basicResult?.currentTask;
8099
- if (approvalResult?.isApprover && task && (task.nodeType === "originator_return" || task.nodeType === "approval")) {
8148
+ const task = mergeCurrentTask(basicResult?.currentTask, approvalResult?.currentTasks?.[0]);
8149
+ if (!nextIsProcessFinal && approvalResult?.isApprover && task && (task.nodeType === "originator_return" || task.nodeType === "approval")) {
8100
8150
  try {
8101
8151
  const definition = await getProcessDefinition(request, formUuid);
8102
8152
  if (mountedRef.current) {
@@ -8105,14 +8155,20 @@ function useProcessDetail(options) {
8105
8155
  } catch (error) {
8106
8156
  console.error("[useProcessDetail] Failed to load process definition:", error);
8107
8157
  }
8158
+ } else if (mountedRef.current) {
8159
+ setProcessDefinition(null);
8108
8160
  }
8109
8161
  } catch (error) {
8110
8162
  console.error("[useProcessDetail] Failed to load data:", error);
8111
8163
  if (mountedRef.current) {
8164
+ setLoadError(error instanceof Error ? error.message : "\u9875\u9762\u52A0\u8F7D\u5931\u8D25");
8165
+ setAccessDenied(false);
8112
8166
  setProcessInfo(null);
8113
8167
  setFormData(null);
8114
8168
  setInstanceInfo(null);
8115
8169
  setApprovalTasks([]);
8170
+ setProgressList([]);
8171
+ setProcessDefinition(null);
8116
8172
  }
8117
8173
  } finally {
8118
8174
  if (mountedRef.current) {
@@ -8125,24 +8181,46 @@ function useProcessDetail(options) {
8125
8181
  }, [loadData]);
8126
8182
  const switchToEdit = (0, import_react50.useCallback)(() => {
8127
8183
  setMode("edit");
8128
- }, []);
8184
+ void loadData();
8185
+ }, [loadData]);
8129
8186
  const switchToReadonly = (0, import_react50.useCallback)(() => {
8130
8187
  setMode("readonly");
8131
8188
  }, []);
8189
+ const refreshDetail = (0, import_react50.useCallback)(async () => {
8190
+ setMode("readonly");
8191
+ await loadData();
8192
+ }, [loadData]);
8132
8193
  const refreshProgress = (0, import_react50.useCallback)(async () => {
8133
- try {
8134
- const [progress, basicResult] = await Promise.all([
8135
- getProcessProgress(request, formInstanceId),
8136
- getProcessBasic(request, formInstanceId)
8137
- ]);
8138
- if (mountedRef.current) {
8139
- setProgressList(progress);
8140
- setProcessInfo(basicResult);
8194
+ await refreshDetail();
8195
+ }, [refreshDetail]);
8196
+ const saveChanges = (0, import_react50.useCallback)(
8197
+ async (values) => {
8198
+ try {
8199
+ await api.updateFormData({
8200
+ formInstanceId,
8201
+ formUuid,
8202
+ appType,
8203
+ updateFormDataJson: JSON.stringify(values)
8204
+ });
8205
+ setMode("readonly");
8206
+ await loadData();
8207
+ return true;
8208
+ } catch (error) {
8209
+ console.error("[useProcessDetail] Failed to save changes:", error);
8210
+ return false;
8141
8211
  }
8212
+ },
8213
+ [api, formInstanceId, formUuid, appType, loadData]
8214
+ );
8215
+ const deleteInstance = (0, import_react50.useCallback)(async () => {
8216
+ try {
8217
+ await deleteFormData(request, { formInstanceId, appType, formUuid });
8218
+ return true;
8142
8219
  } catch (error) {
8143
- console.error("[useProcessDetail] Failed to refresh progress:", error);
8220
+ console.error("[useProcessDetail] Failed to delete instance:", error);
8221
+ return false;
8144
8222
  }
8145
- }, [request, formInstanceId]);
8223
+ }, [request, formInstanceId, appType, formUuid]);
8146
8224
  return {
8147
8225
  loading,
8148
8226
  processInfo,
@@ -8151,6 +8229,8 @@ function useProcessDetail(options) {
8151
8229
  progressList,
8152
8230
  formData,
8153
8231
  instanceInfo,
8232
+ accessDenied,
8233
+ loadError,
8154
8234
  isApprover,
8155
8235
  activeActions,
8156
8236
  fieldBehaviors,
@@ -8158,8 +8238,16 @@ function useProcessDetail(options) {
8158
8238
  isOriginatorReturn,
8159
8239
  isProcessCompleted,
8160
8240
  canWithdraw,
8241
+ canEdit,
8242
+ canDelete,
8243
+ canViewWorkflow,
8244
+ canViewChangeRecords,
8245
+ dataVersion,
8161
8246
  switchToEdit,
8162
8247
  switchToReadonly,
8248
+ saveChanges,
8249
+ deleteInstance,
8250
+ refreshDetail,
8163
8251
  refreshProgress
8164
8252
  };
8165
8253
  }
@@ -8173,6 +8261,7 @@ function useApprovalActions(options) {
8173
8261
  const [isLoading, setIsLoading] = (0, import_react51.useState)(false);
8174
8262
  const [currentAction, setCurrentAction] = (0, import_react51.useState)(null);
8175
8263
  const [returnableNodes, setReturnableNodes] = (0, import_react51.useState)([]);
8264
+ const [returnPolicy, setReturnPolicy] = (0, import_react51.useState)(null);
8176
8265
  const mountedRef = (0, import_react51.useRef)(true);
8177
8266
  (0, import_react51.useEffect)(() => {
8178
8267
  mountedRef.current = true;
@@ -8200,8 +8289,8 @@ function useApprovalActions(options) {
8200
8289
  formUuid,
8201
8290
  updateFormDataJson: formValues ? JSON.stringify(formValues) : void 0
8202
8291
  });
8292
+ await onActionComplete?.("approve");
8203
8293
  resetLoading();
8204
- onActionComplete?.("approve");
8205
8294
  return true;
8206
8295
  } catch (error) {
8207
8296
  console.error("[useApprovalActions] approve failed:", error);
@@ -8216,17 +8305,13 @@ function useApprovalActions(options) {
8216
8305
  setIsLoading(true);
8217
8306
  setCurrentAction("reject");
8218
8307
  try {
8219
- const formValues = getFormValues?.();
8220
8308
  await handleApproval(request, {
8221
8309
  instanceId: formInstanceId,
8222
8310
  action: "rejected",
8223
- comments,
8224
- appType,
8225
- formUuid,
8226
- updateFormDataJson: formValues ? JSON.stringify(formValues) : void 0
8311
+ comments
8227
8312
  });
8313
+ await onActionComplete?.("reject");
8228
8314
  resetLoading();
8229
- onActionComplete?.("reject");
8230
8315
  return true;
8231
8316
  } catch (error) {
8232
8317
  console.error("[useApprovalActions] reject failed:", error);
@@ -8234,7 +8319,7 @@ function useApprovalActions(options) {
8234
8319
  return false;
8235
8320
  }
8236
8321
  },
8237
- [request, formInstanceId, appType, formUuid, getFormValues, onActionComplete, resetLoading]
8322
+ [request, formInstanceId, onActionComplete, resetLoading]
8238
8323
  );
8239
8324
  const transfer = (0, import_react51.useCallback)(
8240
8325
  async (userId, reason) => {
@@ -8250,8 +8335,8 @@ function useApprovalActions(options) {
8250
8335
  newAssignee: userId,
8251
8336
  reason
8252
8337
  });
8338
+ await onActionComplete?.("transfer");
8253
8339
  resetLoading();
8254
- onActionComplete?.("transfer");
8255
8340
  return true;
8256
8341
  } catch (error) {
8257
8342
  console.error("[useApprovalActions] transfer failed:", error);
@@ -8275,8 +8360,8 @@ function useApprovalActions(options) {
8275
8360
  targetNodeId: nodeId,
8276
8361
  reason
8277
8362
  });
8363
+ await onActionComplete?.("return");
8278
8364
  resetLoading();
8279
- onActionComplete?.("return");
8280
8365
  return true;
8281
8366
  } catch (error) {
8282
8367
  console.error("[useApprovalActions] returnTo failed:", error);
@@ -8295,8 +8380,8 @@ function useApprovalActions(options) {
8295
8380
  instanceId: formInstanceId,
8296
8381
  reason
8297
8382
  });
8383
+ await onActionComplete?.("withdraw");
8298
8384
  resetLoading();
8299
- onActionComplete?.("withdraw");
8300
8385
  return true;
8301
8386
  } catch (error) {
8302
8387
  console.error("[useApprovalActions] withdraw failed:", error);
@@ -8317,8 +8402,8 @@ function useApprovalActions(options) {
8317
8402
  appType,
8318
8403
  updateFormDataJson: JSON.stringify(formValues)
8319
8404
  });
8405
+ await onActionComplete?.("save");
8320
8406
  resetLoading();
8321
- onActionComplete?.("save");
8322
8407
  return true;
8323
8408
  } catch (error) {
8324
8409
  console.error("[useApprovalActions] save failed:", error);
@@ -8343,8 +8428,8 @@ function useApprovalActions(options) {
8343
8428
  updateFormDataJson: JSON.stringify(formValues),
8344
8429
  comments
8345
8430
  });
8431
+ await onActionComplete?.("resubmit");
8346
8432
  resetLoading();
8347
- onActionComplete?.("resubmit");
8348
8433
  return true;
8349
8434
  } catch (error) {
8350
8435
  console.error("[useApprovalActions] resubmit failed:", error);
@@ -8367,8 +8452,8 @@ function useApprovalActions(options) {
8367
8452
  taskId: currentTaskId,
8368
8453
  payload
8369
8454
  });
8455
+ await onActionComplete?.("callback");
8370
8456
  resetLoading();
8371
- onActionComplete?.("callback");
8372
8457
  return true;
8373
8458
  } catch (error) {
8374
8459
  console.error("[useApprovalActions] callbackTask failed:", error);
@@ -8379,14 +8464,21 @@ function useApprovalActions(options) {
8379
8464
  [request, currentTaskId, onActionComplete, resetLoading]
8380
8465
  );
8381
8466
  const loadReturnableNodes = (0, import_react51.useCallback)(async () => {
8382
- if (!currentTaskId) return;
8467
+ if (!currentTaskId) return [];
8383
8468
  try {
8384
- const nodes = await getReturnableNodes(request, currentTaskId);
8469
+ const result = await getReturnableNodeResult(request, currentTaskId);
8385
8470
  if (mountedRef.current) {
8386
- setReturnableNodes(nodes);
8471
+ setReturnableNodes(result.nodes);
8472
+ setReturnPolicy(result.policy || null);
8387
8473
  }
8474
+ return result.nodes;
8388
8475
  } catch (error) {
8389
8476
  console.error("[useApprovalActions] loadReturnableNodes failed:", error);
8477
+ if (mountedRef.current) {
8478
+ setReturnableNodes([]);
8479
+ setReturnPolicy(null);
8480
+ }
8481
+ return [];
8390
8482
  }
8391
8483
  }, [request, currentTaskId]);
8392
8484
  return {
@@ -8401,6 +8493,7 @@ function useApprovalActions(options) {
8401
8493
  isLoading,
8402
8494
  currentAction,
8403
8495
  returnableNodes,
8496
+ returnPolicy,
8404
8497
  loadReturnableNodes
8405
8498
  };
8406
8499
  }
@@ -8408,13 +8501,13 @@ function useApprovalActions(options) {
8408
8501
  // src/hooks/useChangeRecords.ts
8409
8502
  var import_react52 = require("react");
8410
8503
  var normalizeChangeRecordList = (value) => {
8411
- const body = value?.data ?? value?.result ?? value ?? {};
8412
- const records = body.records ?? body.data ?? body.list ?? body.items ?? [];
8504
+ const body = value && typeof value === "object" && !Array.isArray(value) ? Array.isArray(value.data) || Array.isArray(value.records) || Array.isArray(value.list) || Array.isArray(value.items) ? value : value.data ?? value.result ?? value : value;
8505
+ const records = Array.isArray(body) ? body : body?.records ?? body?.data ?? body?.list ?? body?.items ?? [];
8413
8506
  return {
8414
8507
  records: Array.isArray(records) ? records : [],
8415
- total: Number(body.total ?? body.totalCount ?? body.count ?? records.length) || 0,
8416
- page: Number(body.page ?? body.currentPage ?? 1) || 1,
8417
- pageSize: Number(body.pageSize ?? body.limit ?? 20) || 20
8508
+ total: Number(body?.total ?? body?.totalCount ?? body?.count ?? records.length) || 0,
8509
+ page: Number(body?.page ?? body?.currentPage ?? 1) || 1,
8510
+ pageSize: Number(body?.pageSize ?? body?.limit ?? 20) || 20
8418
8511
  };
8419
8512
  };
8420
8513
  function useChangeRecords(options) {
@@ -9239,7 +9332,7 @@ var ApprovalTimeline = ({
9239
9332
  };
9240
9333
 
9241
9334
  // src/modules/ApprovalActionBar.tsx
9242
- var import_react58 = require("react");
9335
+ var import_react58 = __toESM(require("react"));
9243
9336
  var import_antd25 = require("antd");
9244
9337
  var import_icons6 = require("@ant-design/icons");
9245
9338
 
@@ -9270,7 +9363,6 @@ var getActionPriority = (action) => {
9270
9363
  if (action.type === "danger") return 90;
9271
9364
  return 50;
9272
9365
  };
9273
- var getPlacement = (action) => action.placement;
9274
9366
  var StickyActionBar = ({
9275
9367
  actions,
9276
9368
  className = "",
@@ -9294,8 +9386,6 @@ var StickyActionBar = ({
9294
9386
  const maxWidthStyle = typeof maxWidth === "number" ? `${maxWidth}px` : maxWidth;
9295
9387
  const primaryMobile = visibleActions.slice(0, maxMobileButtons);
9296
9388
  const moreMobile = visibleActions.slice(maxMobileButtons);
9297
- const leftActions = visibleActions.filter((action) => getPlacement(action) === "left");
9298
- const rightActions = visibleActions.filter((action) => getPlacement(action) !== "left");
9299
9389
  const positionClass = position === "fixed" ? "fixed bottom-0 left-0 right-0" : position === "inline" ? "relative" : "sticky bottom-0";
9300
9390
  const runAction = (action) => {
9301
9391
  if (action.confirm) {
@@ -9325,7 +9415,7 @@ var StickyActionBar = ({
9325
9415
  children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
9326
9416
  "div",
9327
9417
  {
9328
- className: `mx-auto flex w-full items-center gap-3 ${layoutMode === "approval" && !isMobile ? "justify-between" : "justify-end"}`,
9418
+ className: `mx-auto flex w-full items-center gap-3 ${layoutMode === "approval" && !isMobile ? "justify-center" : "justify-end"}`,
9329
9419
  style: { maxWidth: maxWidthStyle },
9330
9420
  children: isMobile ? /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_jsx_runtime81.Fragment, { children: [
9331
9421
  /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "flex flex-1 gap-2", children: primaryMobile.map((action) => renderButton(action, true)) }),
@@ -9347,10 +9437,7 @@ var StickyActionBar = ({
9347
9437
  children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_antd24.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_icons5.MoreOutlined, {}), className: "rounded-md", children: "\u66F4\u591A" })
9348
9438
  }
9349
9439
  )
9350
- ] }) : layoutMode === "approval" && leftActions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(import_jsx_runtime81.Fragment, { children: [
9351
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "flex flex-wrap items-center gap-3", children: leftActions.map((action) => renderButton(action)) }),
9352
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: rightActions.map((action) => renderButton(action)) })
9353
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: visibleActions.map((action) => renderButton(action)) })
9440
+ ] }) : layoutMode === "approval" ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "flex flex-wrap items-center justify-center gap-3", children: visibleActions.map((action) => renderButton(action)) }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: visibleActions.map((action) => renderButton(action)) })
9354
9441
  }
9355
9442
  )
9356
9443
  }
@@ -9400,6 +9487,50 @@ function getModalTitle(action) {
9400
9487
  return "\u786E\u8BA4\u64CD\u4F5C";
9401
9488
  }
9402
9489
  }
9490
+ function formatReturnPolicy(policy) {
9491
+ if (!policy?.resubmitMode) return null;
9492
+ return policy.resubmitMode === "resume_current" ? "\u4ECE\u5F53\u524D\u8282\u70B9\u5BA1\u6279" : "\u91CD\u65B0\u4F9D\u6B21\u5BA1\u6279";
9493
+ }
9494
+ function DefaultTransferSelector({
9495
+ value,
9496
+ onChange
9497
+ }) {
9498
+ const formContext = import_react58.default.useContext(FormContext);
9499
+ const [open, setOpen] = (0, import_react58.useState)(false);
9500
+ const [selectedUsers, setSelectedUsers] = (0, import_react58.useState)([]);
9501
+ if (!formContext) {
9502
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_antd25.Input, { value, onChange: (event) => onChange(event.target.value) });
9503
+ }
9504
+ const selectedLabel = selectedUsers[0] ? getUserName(selectedUsers[0]) : value;
9505
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
9506
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9507
+ import_antd25.Input,
9508
+ {
9509
+ readOnly: true,
9510
+ value: selectedLabel,
9511
+ placeholder: "\u8BF7\u9009\u62E9\u8F6C\u4EA4\u7528\u6237",
9512
+ addonAfter: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "cursor-pointer text-blue-600", onClick: () => setOpen(true), children: "\u9009\u62E9" })
9513
+ }
9514
+ ),
9515
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9516
+ UserPicker,
9517
+ {
9518
+ api: formContext.api,
9519
+ open,
9520
+ onOpenChange: setOpen,
9521
+ multiple: false,
9522
+ value: selectedUsers,
9523
+ onCancel: () => setOpen(false),
9524
+ onConfirm: (items) => {
9525
+ const next = items.slice(0, 1);
9526
+ setSelectedUsers(next);
9527
+ const userId = next[0] ? getUserId(next[0]) : "";
9528
+ onChange(userId);
9529
+ }
9530
+ }
9531
+ )
9532
+ ] });
9533
+ }
9403
9534
  var ApprovalActionBar = ({
9404
9535
  actions,
9405
9536
  onApprove,
@@ -9411,6 +9542,7 @@ var ApprovalActionBar = ({
9411
9542
  onResubmit,
9412
9543
  onCallback,
9413
9544
  returnableNodes = [],
9545
+ returnPolicy,
9414
9546
  onLoadReturnableNodes,
9415
9547
  renderTransferSelector,
9416
9548
  renderReturnNodeLabel,
@@ -9436,7 +9568,12 @@ var ApprovalActionBar = ({
9436
9568
  userId: void 0,
9437
9569
  nodeId: void 0
9438
9570
  });
9439
- if (target === "return") await onLoadReturnableNodes?.();
9571
+ if (target === "return") {
9572
+ const loadedNodes = await onLoadReturnableNodes?.() || returnableNodes;
9573
+ if (loadedNodes.length === 1) {
9574
+ form.setFieldsValue({ nodeId: loadedNodes[0].nodeId || loadedNodes[0].id || "" });
9575
+ }
9576
+ }
9440
9577
  setModalAction(target);
9441
9578
  };
9442
9579
  const executeDirect = async (action) => {
@@ -9451,6 +9588,14 @@ var ApprovalActionBar = ({
9451
9588
  }
9452
9589
  if (normalized === "agree") {
9453
9590
  await onApprove?.();
9591
+ return;
9592
+ }
9593
+ if (normalized === "rejected") {
9594
+ await onReject?.();
9595
+ return;
9596
+ }
9597
+ if (normalized === "resubmit") {
9598
+ await onResubmit?.();
9454
9599
  }
9455
9600
  };
9456
9601
  const handleActionClick = async (action) => {
@@ -9459,6 +9604,10 @@ var ApprovalActionBar = ({
9459
9604
  await executeDirect(action);
9460
9605
  return;
9461
9606
  }
9607
+ if ((normalized === "agree" || normalized === "rejected" || normalized === "resubmit") && !action.remark?.popUp) {
9608
+ await executeDirect(action);
9609
+ return;
9610
+ }
9462
9611
  await openModal(action, normalized);
9463
9612
  };
9464
9613
  const handleOk = async () => {
@@ -9520,7 +9669,7 @@ var ApprovalActionBar = ({
9520
9669
  setActiveAction(null);
9521
9670
  form.resetFields();
9522
9671
  },
9523
- destroyOnClose: true,
9672
+ destroyOnHidden: true,
9524
9673
  children: /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_antd25.Form, { form, layout: "vertical", children: [
9525
9674
  modalAction === "transfer" && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9526
9675
  import_antd25.Form.Item,
@@ -9531,28 +9680,40 @@ var ApprovalActionBar = ({
9531
9680
  children: renderTransferSelector ? renderTransferSelector({
9532
9681
  value: form.getFieldValue("userId"),
9533
9682
  onChange: (userId) => form.setFieldsValue({ userId })
9534
- }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_antd25.Input, { placeholder: "\u8BF7\u8F93\u5165\u7528\u6237 ID" })
9535
- }
9536
- ),
9537
- modalAction === "return" && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9538
- import_antd25.Form.Item,
9539
- {
9540
- name: "nodeId",
9541
- label: "\u9000\u56DE\u5230\u8282\u70B9",
9542
- rules: [{ required: true, message: "\u8BF7\u9009\u62E9\u9000\u56DE\u8282\u70B9" }],
9543
- children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9544
- import_antd25.Select,
9683
+ }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9684
+ DefaultTransferSelector,
9545
9685
  {
9546
- placeholder: "\u8BF7\u9009\u62E9\u9000\u56DE\u8282\u70B9",
9547
- getPopupContainer: (triggerNode) => triggerNode.parentElement || document.body,
9548
- options: returnableNodes.map((node) => ({
9549
- value: node.nodeId || node.id || "",
9550
- label: renderReturnNodeLabel ? renderReturnNodeLabel(node) : node.nodeName || node.name || node.nodeId || node.id
9551
- }))
9686
+ value: form.getFieldValue("userId"),
9687
+ onChange: (userId) => form.setFieldsValue({ userId })
9552
9688
  }
9553
9689
  )
9554
9690
  }
9555
9691
  ),
9692
+ modalAction === "return" && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(import_jsx_runtime82.Fragment, { children: [
9693
+ formatReturnPolicy(returnPolicy) && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "mb-3 text-sm text-gray-500", children: [
9694
+ "\u9000\u56DE\u540E\u5BA1\u6279\u903B\u8F91\uFF1A",
9695
+ formatReturnPolicy(returnPolicy)
9696
+ ] }),
9697
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9698
+ import_antd25.Form.Item,
9699
+ {
9700
+ name: "nodeId",
9701
+ label: "\u9000\u56DE\u5230\u8282\u70B9",
9702
+ rules: [{ required: true, message: "\u8BF7\u9009\u62E9\u9000\u56DE\u8282\u70B9" }],
9703
+ children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9704
+ import_antd25.Select,
9705
+ {
9706
+ placeholder: "\u8BF7\u9009\u62E9\u9000\u56DE\u8282\u70B9",
9707
+ getPopupContainer: (triggerNode) => triggerNode.parentElement || document.body,
9708
+ options: returnableNodes.map((node) => ({
9709
+ value: node.nodeId || node.id || "",
9710
+ label: renderReturnNodeLabel ? renderReturnNodeLabel(node) : node.nodeName || node.name || node.nodeId || node.id
9711
+ }))
9712
+ }
9713
+ )
9714
+ }
9715
+ )
9716
+ ] }),
9556
9717
  /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
9557
9718
  import_antd25.Form.Item,
9558
9719
  {
@@ -9602,6 +9763,7 @@ var ApprovalActions = ({
9602
9763
  const [activeAction, setActiveAction] = (0, import_react59.useState)(null);
9603
9764
  const [loading, setLoading] = (0, import_react59.useState)(false);
9604
9765
  const [saveLoading, setSaveLoading] = (0, import_react59.useState)(false);
9766
+ const [directLoading, setDirectLoading] = (0, import_react59.useState)(null);
9605
9767
  const renderableActions = (0, import_react59.useMemo)(
9606
9768
  () => actions.filter((action) => !action.hidden).sort((a, b) => (priority[a.action] ?? 50) - (priority[b.action] ?? 50)),
9607
9769
  [actions]
@@ -9619,6 +9781,14 @@ var ApprovalActions = ({
9619
9781
  setSaveLoading(false);
9620
9782
  }
9621
9783
  };
9784
+ const executeDirect = async (action, fn) => {
9785
+ setDirectLoading(action.action);
9786
+ try {
9787
+ await fn?.();
9788
+ } finally {
9789
+ setDirectLoading(null);
9790
+ }
9791
+ };
9622
9792
  const handleAction = (action) => {
9623
9793
  if (action.action === "transfer") {
9624
9794
  onTransfer?.();
@@ -9637,9 +9807,17 @@ var ApprovalActions = ({
9637
9807
  return;
9638
9808
  }
9639
9809
  if (action.action === "rejected" || action.action === "reject") {
9810
+ if (!action.remark?.popUp) {
9811
+ void executeDirect(action, onReject);
9812
+ return;
9813
+ }
9640
9814
  openModal("reject", action);
9641
9815
  return;
9642
9816
  }
9817
+ if (!action.remark?.popUp) {
9818
+ void executeDirect(action, onApprove);
9819
+ return;
9820
+ }
9643
9821
  openModal("approve", action);
9644
9822
  };
9645
9823
  const handleConfirm = async () => {
@@ -9665,7 +9843,7 @@ var ApprovalActions = ({
9665
9843
  type: action.action === "agree" || action.action === "approved" ? "primary" : "default",
9666
9844
  danger: action.action === "rejected" || action.action === "reject" || action.action === "withdraw",
9667
9845
  onClick: () => handleAction(action),
9668
- loading: action.action === "save" && saveLoading,
9846
+ loading: action.action === "save" && saveLoading || directLoading === action.action,
9669
9847
  children: getLabel(action)
9670
9848
  },
9671
9849
  action.action
@@ -9674,7 +9852,7 @@ var ApprovalActions = ({
9674
9852
  /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
9675
9853
  "div",
9676
9854
  {
9677
- className: `${layout === "horizontal" ? "flex items-center gap-3" : "flex flex-col gap-2"} ${className}`,
9855
+ className: `${layout === "horizontal" ? "flex items-center justify-center gap-3" : "flex flex-col items-center gap-2"} ${className}`,
9678
9856
  children: [
9679
9857
  visibleButtons.map(button),
9680
9858
  moreButtons.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
@@ -9711,7 +9889,7 @@ var ApprovalActions = ({
9711
9889
  setActiveAction(null);
9712
9890
  form.resetFields();
9713
9891
  },
9714
- destroyOnClose: true,
9892
+ destroyOnHidden: true,
9715
9893
  children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd26.Form, { form, layout: "vertical", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
9716
9894
  import_antd26.Form.Item,
9717
9895
  {
@@ -11876,6 +12054,8 @@ var InnerDetailContent = ({
11876
12054
  const {
11877
12055
  records,
11878
12056
  loading: recordsLoading,
12057
+ total: recordsTotal,
12058
+ page: recordsPage,
11879
12059
  hasMore,
11880
12060
  loadMore,
11881
12061
  refresh: refreshRecords
@@ -11987,7 +12167,8 @@ var InnerDetailContent = ({
11987
12167
  {
11988
12168
  records,
11989
12169
  loading: recordsLoading,
11990
- total: records.length,
12170
+ total: recordsTotal,
12171
+ page: recordsPage,
11991
12172
  hasMore,
11992
12173
  onLoadMore: loadMore,
11993
12174
  onRefresh: refreshRecords,
@@ -12010,12 +12191,15 @@ var FormDetailTemplate = (props) => {
12010
12191
 
12011
12192
  // src/templates/ProcessDetailTemplate.tsx
12012
12193
  var import_react64 = require("react");
12194
+ var import_antd35 = require("antd");
12013
12195
  var import_jsx_runtime93 = require("react/jsx-runtime");
12014
12196
  function FormDataBridge2({
12015
- formDataRef
12197
+ formDataRef,
12198
+ validateRef
12016
12199
  }) {
12017
- const { getFormData: getFormData2 } = useFormContext();
12200
+ const { getFormData: getFormData2, validateAll } = useFormContext();
12018
12201
  formDataRef.current = getFormData2;
12202
+ validateRef.current = validateAll;
12019
12203
  return null;
12020
12204
  }
12021
12205
  var InnerProcessContent = ({
@@ -12023,18 +12207,31 @@ var InnerProcessContent = ({
12023
12207
  formUuid,
12024
12208
  appType,
12025
12209
  formInstanceId,
12210
+ enableEdit = true,
12211
+ enableDelete = true,
12212
+ enableChangeRecords = true,
12213
+ showApproverInfo = true,
12026
12214
  header,
12027
12215
  renderTimeline,
12028
12216
  renderActions,
12217
+ renderFooterActions,
12029
12218
  renderTransferSelector,
12030
12219
  renderReturnNodeLabel,
12031
12220
  renderActionModalExtra,
12032
12221
  beforeForm,
12033
12222
  afterForm,
12034
12223
  onActionComplete,
12224
+ onSave,
12225
+ onDelete,
12035
12226
  inDrawer = false
12036
12227
  }) => {
12037
12228
  const formDataRef = (0, import_react64.useRef)(void 0);
12229
+ const validateRef = (0, import_react64.useRef)(void 0);
12230
+ const [withdrawForm] = import_antd35.Form.useForm();
12231
+ const [withdrawOpen, setWithdrawOpen] = (0, import_react64.useState)(false);
12232
+ const [withdrawLoading, setWithdrawLoading] = (0, import_react64.useState)(false);
12233
+ const [saveLoading, setSaveLoading] = (0, import_react64.useState)(false);
12234
+ const [deleteLoading, setDeleteLoading] = (0, import_react64.useState)(false);
12038
12235
  const fieldIds = (0, import_react64.useMemo)(() => schema.fields.map((field) => field.fieldId), [schema.fields]);
12039
12236
  const {
12040
12237
  loading,
@@ -12044,15 +12241,25 @@ var InnerProcessContent = ({
12044
12241
  progressList,
12045
12242
  formData,
12046
12243
  instanceInfo,
12244
+ accessDenied,
12245
+ loadError,
12047
12246
  isApprover,
12048
12247
  activeActions,
12049
12248
  fieldBehaviors,
12050
12249
  mode,
12051
12250
  isOriginatorReturn,
12251
+ isProcessCompleted,
12052
12252
  canWithdraw,
12253
+ canEdit,
12254
+ canDelete,
12255
+ canViewWorkflow,
12256
+ canViewChangeRecords,
12257
+ dataVersion,
12053
12258
  switchToEdit,
12054
12259
  switchToReadonly,
12055
- refreshProgress
12260
+ saveChanges,
12261
+ deleteInstance,
12262
+ refreshDetail
12056
12263
  } = useProcessDetail({ formUuid, appType, formInstanceId, fieldIds });
12057
12264
  const {
12058
12265
  approve,
@@ -12064,6 +12271,7 @@ var InnerProcessContent = ({
12064
12271
  resubmit,
12065
12272
  callbackTask,
12066
12273
  returnableNodes,
12274
+ returnPolicy,
12067
12275
  loadReturnableNodes
12068
12276
  } = useApprovalActions({
12069
12277
  formInstanceId,
@@ -12071,16 +12279,34 @@ var InnerProcessContent = ({
12071
12279
  appType,
12072
12280
  currentTaskId: currentTask?.taskId ?? currentTask?.id,
12073
12281
  onActionComplete: async (action) => {
12074
- onActionComplete?.(action);
12075
- await refreshProgress();
12282
+ await onActionComplete?.(action);
12283
+ await refreshDetail();
12076
12284
  },
12077
12285
  getFormValues: () => formDataRef.current?.() ?? formData ?? {}
12078
12286
  });
12287
+ const {
12288
+ records,
12289
+ loading: recordsLoading,
12290
+ total: recordsTotal,
12291
+ page: recordsPage,
12292
+ hasMore,
12293
+ loadMore,
12294
+ refresh: refreshRecords
12295
+ } = useChangeRecords({
12296
+ formUuid,
12297
+ appType,
12298
+ formInstanceId,
12299
+ autoLoad: enableChangeRecords && canViewChangeRecords
12300
+ });
12301
+ const validateForm = (0, import_react64.useCallback)(async () => {
12302
+ return validateRef.current ? validateRef.current() : true;
12303
+ }, []);
12079
12304
  const handleApprove = (0, import_react64.useCallback)(
12080
12305
  async (comments) => {
12306
+ if (!await validateForm()) return;
12081
12307
  await approve(comments);
12082
12308
  },
12083
- [approve]
12309
+ [approve, validateForm]
12084
12310
  );
12085
12311
  const handleReject = (0, import_react64.useCallback)(
12086
12312
  async (comments) => {
@@ -12107,22 +12333,104 @@ var InnerProcessContent = ({
12107
12333
  [withdraw]
12108
12334
  );
12109
12335
  const handleSave = (0, import_react64.useCallback)(async () => {
12336
+ if (!await validateForm()) return;
12110
12337
  await save();
12111
- }, [save]);
12338
+ }, [save, validateForm]);
12112
12339
  const handleResubmit = (0, import_react64.useCallback)(
12113
12340
  async (comments) => {
12341
+ if (!await validateForm()) return;
12114
12342
  await resubmit(comments);
12115
12343
  },
12116
- [resubmit]
12344
+ [resubmit, validateForm]
12117
12345
  );
12118
12346
  const handleCallback = (0, import_react64.useCallback)(async () => {
12119
12347
  await callbackTask();
12120
12348
  }, [callbackTask]);
12349
+ const handleCompletedSave = (0, import_react64.useCallback)(async () => {
12350
+ if (!await validateForm()) return;
12351
+ const values = formDataRef.current?.() ?? formData;
12352
+ if (!values) return;
12353
+ setSaveLoading(true);
12354
+ try {
12355
+ const success = await saveChanges(values);
12356
+ if (success) {
12357
+ await onSave?.(values);
12358
+ }
12359
+ } finally {
12360
+ setSaveLoading(false);
12361
+ }
12362
+ }, [formData, onSave, saveChanges, validateForm]);
12363
+ const handleCompletedDelete = (0, import_react64.useCallback)(async () => {
12364
+ setDeleteLoading(true);
12365
+ try {
12366
+ const success = await deleteInstance();
12367
+ if (success) {
12368
+ await onDelete?.();
12369
+ }
12370
+ } finally {
12371
+ setDeleteLoading(false);
12372
+ }
12373
+ }, [deleteInstance, onDelete]);
12374
+ const handleFooterWithdraw = (0, import_react64.useCallback)(async () => {
12375
+ const values = await withdrawForm.validateFields();
12376
+ setWithdrawLoading(true);
12377
+ try {
12378
+ await handleWithdraw(values.reason || void 0);
12379
+ setWithdrawOpen(false);
12380
+ withdrawForm.resetFields();
12381
+ } finally {
12382
+ setWithdrawLoading(false);
12383
+ }
12384
+ }, [handleWithdraw, withdrawForm]);
12385
+ const handleFooterWithdrawCancel = (0, import_react64.useCallback)(() => {
12386
+ setWithdrawOpen(false);
12387
+ withdrawForm.resetFields();
12388
+ }, [withdrawForm]);
12121
12389
  const bottomActions = (0, import_react64.useMemo)(() => {
12122
- if (isApprover && activeActions.length > 0) return [];
12390
+ if (isApprover && !isOriginatorReturn && activeActions.length > 0) return [];
12391
+ if (isProcessCompleted) {
12392
+ if (mode === "readonly") {
12393
+ const actions = [];
12394
+ if (enableEdit && canEdit) {
12395
+ actions.push({
12396
+ key: "edit",
12397
+ label: "\u7F16\u8F91",
12398
+ type: "primary",
12399
+ onClick: switchToEdit
12400
+ });
12401
+ }
12402
+ if (enableDelete && canDelete) {
12403
+ actions.push({
12404
+ key: "delete",
12405
+ label: "\u5220\u9664",
12406
+ type: "danger",
12407
+ loading: deleteLoading,
12408
+ onClick: handleCompletedDelete,
12409
+ confirm: { title: "\u786E\u8BA4\u5220\u9664", content: "\u5220\u9664\u540E\u5C06\u65E0\u6CD5\u6062\u590D\uFF0C\u786E\u8BA4\u8981\u5220\u9664\u5417\uFF1F" }
12410
+ });
12411
+ }
12412
+ return actions;
12413
+ }
12414
+ return [
12415
+ {
12416
+ key: "cancel",
12417
+ label: "\u53D6\u6D88",
12418
+ type: "default",
12419
+ onClick: switchToReadonly,
12420
+ placement: "left"
12421
+ },
12422
+ {
12423
+ key: "save",
12424
+ label: "\u4FDD\u5B58",
12425
+ type: "primary",
12426
+ loading: saveLoading,
12427
+ onClick: handleCompletedSave
12428
+ }
12429
+ ];
12430
+ }
12123
12431
  if (isOriginatorReturn) {
12124
12432
  if (mode === "readonly") {
12125
- return [
12433
+ const actions2 = [
12126
12434
  {
12127
12435
  key: "edit",
12128
12436
  label: "\u7F16\u8F91",
@@ -12130,8 +12438,23 @@ var InnerProcessContent = ({
12130
12438
  onClick: switchToEdit
12131
12439
  }
12132
12440
  ];
12441
+ actions2.push({
12442
+ key: "resubmit",
12443
+ label: "\u91CD\u65B0\u63D0\u4EA4",
12444
+ type: "default",
12445
+ onClick: () => handleResubmit()
12446
+ });
12447
+ if (canWithdraw) {
12448
+ actions2.push({
12449
+ key: "withdraw",
12450
+ label: "\u64A4\u9500",
12451
+ type: "danger",
12452
+ onClick: () => setWithdrawOpen(true)
12453
+ });
12454
+ }
12455
+ return actions2;
12133
12456
  }
12134
- return [
12457
+ const actions = [
12135
12458
  {
12136
12459
  key: "cancel",
12137
12460
  label: "\u53D6\u6D88",
@@ -12146,6 +12469,15 @@ var InnerProcessContent = ({
12146
12469
  onClick: () => handleResubmit()
12147
12470
  }
12148
12471
  ];
12472
+ if (canWithdraw) {
12473
+ actions.push({
12474
+ key: "withdraw",
12475
+ label: "\u64A4\u9500",
12476
+ type: "danger",
12477
+ onClick: () => setWithdrawOpen(true)
12478
+ });
12479
+ }
12480
+ return actions;
12149
12481
  }
12150
12482
  if (canWithdraw) {
12151
12483
  return [
@@ -12153,22 +12485,31 @@ var InnerProcessContent = ({
12153
12485
  key: "withdraw",
12154
12486
  label: "\u64A4\u9500",
12155
12487
  type: "danger",
12156
- onClick: () => handleWithdraw(),
12157
- confirm: { title: "\u786E\u8BA4\u64A4\u9500", content: "\u64A4\u9500\u540E\u6D41\u7A0B\u5C06\u7EC8\u6B62\uFF0C\u786E\u8BA4\u7EE7\u7EED\u5417\uFF1F" }
12488
+ loading: withdrawLoading,
12489
+ onClick: () => setWithdrawOpen(true)
12158
12490
  }
12159
12491
  ];
12160
12492
  }
12161
12493
  return [];
12162
12494
  }, [
12163
12495
  activeActions.length,
12496
+ canDelete,
12497
+ canEdit,
12164
12498
  canWithdraw,
12499
+ deleteLoading,
12500
+ enableDelete,
12501
+ enableEdit,
12502
+ handleCompletedDelete,
12503
+ handleCompletedSave,
12165
12504
  handleResubmit,
12166
- handleWithdraw,
12167
12505
  isApprover,
12168
12506
  isOriginatorReturn,
12507
+ isProcessCompleted,
12169
12508
  mode,
12509
+ saveLoading,
12170
12510
  switchToEdit,
12171
- switchToReadonly
12511
+ switchToReadonly,
12512
+ withdrawLoading
12172
12513
  ]);
12173
12514
  const formConfig = {
12174
12515
  mode: mode === "edit" ? "edit" : "readonly",
@@ -12183,7 +12524,10 @@ var InnerProcessContent = ({
12183
12524
  if (loading) {
12184
12525
  return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "min-h-screen bg-ant-bg-layout", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "mx-auto max-w-4xl px-6 py-8 pb-24", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(PageSkeleton, { type: "process" }) }) });
12185
12526
  }
12186
- const showApprovalActions = isApprover && activeActions.length > 0;
12527
+ if (accessDenied || loadError) {
12528
+ return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(RuntimePageShell, { accessDenied, error: loadError, inDrawer, children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", {}) });
12529
+ }
12530
+ const showApprovalActions = isApprover && !isOriginatorReturn && activeActions.length > 0;
12187
12531
  const actionsNode = showApprovalActions ? renderActions ? renderActions(activeActions) : /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
12188
12532
  ApprovalActionBar,
12189
12533
  {
@@ -12197,52 +12541,108 @@ var InnerProcessContent = ({
12197
12541
  onResubmit: handleResubmit,
12198
12542
  onCallback: handleCallback,
12199
12543
  returnableNodes,
12544
+ returnPolicy,
12200
12545
  onLoadReturnableNodes: loadReturnableNodes,
12201
12546
  renderTransferSelector,
12202
12547
  renderReturnNodeLabel,
12203
12548
  renderActionModalExtra,
12204
12549
  inDrawer
12205
12550
  }
12206
- ) : bottomActions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(StickyActionBar, { actions: bottomActions, inDrawer }) : null;
12551
+ ) : bottomActions.length > 0 ? renderFooterActions ? renderFooterActions(bottomActions) : /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(StickyActionBar, { actions: bottomActions, inDrawer }) : null;
12207
12552
  const statusMeta = processStatus ? PROCESS_STATUS_META[processStatus] : void 0;
12208
- return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(RuntimePageShell, { actions: actionsNode, inDrawer, children: /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "space-y-6", children: [
12209
- header,
12553
+ return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(RuntimePageShell, { actions: actionsNode, inDrawer, children: [
12554
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "space-y-6", children: [
12555
+ header,
12556
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
12557
+ SummaryPanel,
12558
+ {
12559
+ title: processInfo?.title || instanceInfo?.title || schema.formMeta.title,
12560
+ eyebrow: `\u6D41\u7A0B\u5B9E\u4F8B ${formInstanceId?.slice(0, 8) || "-"}`,
12561
+ creator: processInfo?.originatorName ? {
12562
+ name: processInfo.originatorName,
12563
+ department: processInfo.originatorDepartment
12564
+ } : void 0,
12565
+ createdAt: processInfo?.createdAt,
12566
+ status: statusMeta,
12567
+ metaItems: [
12568
+ { key: "currentTask", label: "\u5F53\u524D\u8282\u70B9", value: currentTask?.nodeName || "\u65E0" },
12569
+ {
12570
+ key: "processStatus",
12571
+ label: "\u5B9E\u4F8B\u72B6\u6001",
12572
+ value: statusMeta?.label || processStatus || "-"
12573
+ }
12574
+ ]
12575
+ }
12576
+ ),
12577
+ beforeForm,
12578
+ mode === "edit" && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "rounded-lg border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-700 transition-all duration-150", children: isProcessCompleted ? "\u6B63\u5728\u7F16\u8F91\uFF0C\u4FEE\u6539\u540E\u8BF7\u4FDD\u5B58" : "\u6B63\u5728\u7F16\u8F91\u8868\u5355\uFF0C\u4FEE\u6539\u540E\u8BF7\u91CD\u65B0\u63D0\u4EA4" }),
12579
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
12580
+ FormProvider,
12581
+ {
12582
+ schema,
12583
+ config: formConfig,
12584
+ initialValues: formData ?? void 0,
12585
+ children: [
12586
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(FormDataBridge2, { formDataRef, validateRef }),
12587
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(FormRenderer, { columns: 2 })
12588
+ ]
12589
+ },
12590
+ `${mode}-${dataVersion}`
12591
+ ) }),
12592
+ afterForm,
12593
+ canViewWorkflow && /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: [
12594
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "mb-4 flex items-center justify-between gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { children: [
12595
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("h3", { className: "text-base font-semibold text-ant-color-text", children: "\u5BA1\u6279\u8FDB\u5EA6" }),
12596
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { className: "mt-1 text-xs text-ant-color-text-tertiary", children: "\u8282\u70B9\u3001\u5BA1\u6279\u4EBA\u3001\u5904\u7406\u610F\u89C1\u548C\u7B49\u5F85\u72B6\u6001" })
12597
+ ] }) }),
12598
+ renderTimeline ? renderTimeline(progressList) : /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
12599
+ ApprovalTimeline,
12600
+ {
12601
+ tasks: progressList,
12602
+ showRemarks: true,
12603
+ showApproverInfo
12604
+ }
12605
+ )
12606
+ ] }),
12607
+ enableChangeRecords && canViewChangeRecords && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
12608
+ RecordChangePanel,
12609
+ {
12610
+ records,
12611
+ loading: recordsLoading,
12612
+ total: recordsTotal,
12613
+ page: recordsPage,
12614
+ hasMore,
12615
+ onLoadMore: loadMore,
12616
+ onRefresh: refreshRecords,
12617
+ onExpand: refreshRecords
12618
+ }
12619
+ )
12620
+ ] }),
12210
12621
  /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
12211
- SummaryPanel,
12622
+ import_antd35.Modal,
12212
12623
  {
12213
- title: processInfo?.title || instanceInfo?.title || schema.formMeta.title,
12214
- eyebrow: `\u6D41\u7A0B\u5B9E\u4F8B ${formInstanceId?.slice(0, 8) || "-"}`,
12215
- creator: processInfo?.originatorName ? {
12216
- name: processInfo.originatorName,
12217
- department: processInfo.originatorDepartment
12218
- } : void 0,
12219
- createdAt: processInfo?.createdAt,
12220
- status: statusMeta,
12221
- metaItems: [
12222
- { key: "currentTask", label: "\u5F53\u524D\u8282\u70B9", value: currentTask?.nodeName || "\u65E0" },
12624
+ getContainer: false,
12625
+ title: "\u64A4\u9500\u6D41\u7A0B",
12626
+ open: withdrawOpen,
12627
+ okText: "\u786E\u8BA4\u64A4\u9500",
12628
+ cancelText: "\u53D6\u6D88",
12629
+ confirmLoading: withdrawLoading,
12630
+ okButtonProps: { danger: true },
12631
+ onOk: handleFooterWithdraw,
12632
+ onCancel: handleFooterWithdrawCancel,
12633
+ destroyOnHidden: true,
12634
+ children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(import_antd35.Form, { form: withdrawForm, layout: "vertical", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
12635
+ import_antd35.Form.Item,
12223
12636
  {
12224
- key: "processStatus",
12225
- label: "\u5B9E\u4F8B\u72B6\u6001",
12226
- value: statusMeta?.label || processStatus || "-"
12637
+ name: "reason",
12638
+ label: "\u64A4\u9500\u539F\u56E0",
12639
+ rules: [{ required: true, message: "\u8BF7\u586B\u5199\u64A4\u9500\u539F\u56E0" }],
12640
+ children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(import_antd35.Input.TextArea, { rows: 4, maxLength: 500, showCount: true, placeholder: "\u8BF7\u8F93\u5165\u64A4\u9500\u539F\u56E0" })
12227
12641
  }
12228
- ]
12642
+ ) })
12229
12643
  }
12230
- ),
12231
- beforeForm,
12232
- mode === "edit" && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "rounded-lg border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-700 transition-all duration-150", children: "\u6B63\u5728\u7F16\u8F91\u8868\u5355\uFF0C\u4FEE\u6539\u540E\u8BF7\u91CD\u65B0\u63D0\u4EA4" }),
12233
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: [
12234
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(FormDataBridge2, { formDataRef }),
12235
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(FormRenderer, { columns: 2 })
12236
- ] }) }),
12237
- afterForm,
12238
- /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: [
12239
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { className: "mb-4 flex items-center justify-between gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { children: [
12240
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("h3", { className: "text-base font-semibold text-ant-color-text", children: "\u5BA1\u6279\u8FDB\u5EA6" }),
12241
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { className: "mt-1 text-xs text-ant-color-text-tertiary", children: "\u8282\u70B9\u3001\u5BA1\u6279\u4EBA\u3001\u5904\u7406\u610F\u89C1\u548C\u7B49\u5F85\u72B6\u6001" })
12242
- ] }) }),
12243
- renderTimeline ? renderTimeline(progressList) : /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(ApprovalTimeline, { tasks: progressList, showRemarks: true, showApproverInfo: true })
12244
- ] })
12245
- ] }) });
12644
+ )
12645
+ ] });
12246
12646
  };
12247
12647
  var ProcessDetailTemplate = (props) => {
12248
12648
  const { schema, formUuid, appType, formInstanceId } = props;
@@ -12333,6 +12733,7 @@ var ProcessDetailTemplate = (props) => {
12333
12733
  getProcessBasic,
12334
12734
  getProcessDefinition,
12335
12735
  getProcessProgress,
12736
+ getReturnableNodeResult,
12336
12737
  getReturnableNodes,
12337
12738
  getSystemFieldsForFormType,
12338
12739
  getViewPermission,