sy-form-components 0.2.6 → 0.2.7

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.mjs CHANGED
@@ -5886,8 +5886,8 @@ var parseResponse = async (response) => {
5886
5886
  const contentType = response.headers.get("content-type") || "";
5887
5887
  const payload = contentType.includes("application/json") ? await response.json() : await response.text();
5888
5888
  if (!response.ok) {
5889
- const message = typeof payload === "object" && payload ? payload.message || payload.error || response.statusText : response.statusText;
5890
- throw new Error(message || "\u8BF7\u6C42\u5931\u8D25");
5889
+ const message2 = typeof payload === "object" && payload ? payload.message || payload.error || response.statusText : response.statusText;
5890
+ throw new Error(message2 || "\u8BF7\u6C42\u5931\u8D25");
5891
5891
  }
5892
5892
  if (typeof payload === "object" && payload) {
5893
5893
  return payload;
@@ -6568,6 +6568,26 @@ var normalizeApprovalPermission = (value) => {
6568
6568
  currentTasks
6569
6569
  };
6570
6570
  };
6571
+ var normalizeReturnableNodes = (value) => {
6572
+ const raw = value?.candidates || value?.nodes || value?.data || value;
6573
+ if (!Array.isArray(raw)) return [];
6574
+ return raw.map((node) => ({
6575
+ ...node,
6576
+ nodeId: node?.nodeId || node?.id || "",
6577
+ nodeName: node?.nodeName || node?.name || node?.title || node?.id || ""
6578
+ }));
6579
+ };
6580
+ var normalizeProcessDefinition = (value) => {
6581
+ const raw = value?.definitionJson || value?.viewJson || value || {};
6582
+ const nodes = Array.isArray(raw.nodes) ? raw.nodes : [];
6583
+ const startNode = nodes.find((node) => node?.type === "start" || node?.nodeType === "start");
6584
+ return {
6585
+ ...raw,
6586
+ processId: raw.processId || raw.id || value?.id || "",
6587
+ flowConfig: raw.flowConfig || value?.flowConfig || {},
6588
+ startNodeId: raw.startNodeId || startNode?.id || value?.startNodeId
6589
+ };
6590
+ };
6571
6591
  async function getProcessBasic(request, formInstId) {
6572
6592
  const response = await request({
6573
6593
  url: `/workflow/instance/${formInstId}/basic`,
@@ -6647,7 +6667,7 @@ async function getReturnableNodes(request, taskId) {
6647
6667
  url: `/workflow/task/${taskId}/returnable-nodes`,
6648
6668
  method: "get"
6649
6669
  });
6650
- return response.data || response.result || [];
6670
+ return normalizeReturnableNodes(response.data || response.result);
6651
6671
  }
6652
6672
  async function previewProcess(request, params) {
6653
6673
  const response = await request({
@@ -6663,6 +6683,14 @@ async function getProcessDefinition(request, formUuid) {
6663
6683
  method: "get",
6664
6684
  params: { formUuid }
6665
6685
  });
6686
+ return normalizeProcessDefinition(response.data || response.result);
6687
+ }
6688
+ async function triggerCallbackTask(request, params) {
6689
+ const response = await request({
6690
+ url: `/workflow/task/${params.taskId}/callback`,
6691
+ method: "post",
6692
+ data: params.payload || {}
6693
+ });
6666
6694
  return response.data || response.result;
6667
6695
  }
6668
6696
  async function getFormData(request, params) {
@@ -6698,6 +6726,256 @@ async function getViewPermission(request, params) {
6698
6726
  return response.data || response.result;
6699
6727
  }
6700
6728
 
6729
+ // src/core/dataManagementApi.ts
6730
+ var unwrap = (response) => {
6731
+ if (response instanceof Blob) return response;
6732
+ if (response?.data?.result !== void 0) return response.data.result;
6733
+ if (response?.result !== void 0) return response.result;
6734
+ if (response?.data !== void 0) return response.data;
6735
+ return response;
6736
+ };
6737
+ var pickData = (value) => value?.data ?? value?.result ?? value;
6738
+ var normalizeComponentName = (field) => field?.componentName || field?.component_name || field?.component_type || field?.componentType || field?.type || "TextField";
6739
+ var normalizeField = (key, field, system = false) => ({
6740
+ ...field,
6741
+ id: field?.id || field?.fieldId || key,
6742
+ fieldId: field?.fieldId || field?.id || key,
6743
+ componentName: normalizeComponentName(field),
6744
+ label: field?.label || field?.title || field?.name || key,
6745
+ width: field?.width,
6746
+ system
6747
+ });
6748
+ var PROCESS_INSTANCE_STATUS_OPTIONS = [
6749
+ { label: "\u5F85\u5904\u7406", value: "pending" },
6750
+ { label: "\u5BA1\u6279\u4E2D", value: "running" },
6751
+ { label: "\u7B49\u5F85\u4E2D", value: "waiting" },
6752
+ { label: "\u6D41\u7A0B\u5F02\u5E38", value: "exception" },
6753
+ { label: "\u5DF2\u5B8C\u6210", value: "completed" },
6754
+ { label: "\u5DF2\u62D2\u7EDD", value: "terminated" },
6755
+ { label: "\u5DF2\u64A4\u9500", value: "withdrawn" }
6756
+ ];
6757
+ var APPROVAL_RESULT_OPTIONS = [
6758
+ { label: "\u5BA1\u6279\u4E2D", value: "processing" },
6759
+ { label: "\u540C\u610F", value: "approved" },
6760
+ { label: "\u62D2\u7EDD", value: "rejected" },
6761
+ { label: "\u64A4\u9500", value: "withdrawn" },
6762
+ { label: "\u5F02\u5E38", value: "exception" }
6763
+ ];
6764
+ var PROCESS_SYSTEM_FIELDS = [
6765
+ normalizeField(
6766
+ "currentApprovalNodeName",
6767
+ {
6768
+ label: "\u5F53\u524D\u5BA1\u6279\u8282\u70B9",
6769
+ componentName: "TextField",
6770
+ width: 140,
6771
+ processOnly: true,
6772
+ displayable: true
6773
+ },
6774
+ true
6775
+ ),
6776
+ normalizeField(
6777
+ "processInstanceStatus",
6778
+ {
6779
+ label: "\u5B9E\u4F8B\u72B6\u6001",
6780
+ componentName: "SelectField",
6781
+ width: 110,
6782
+ options: PROCESS_INSTANCE_STATUS_OPTIONS,
6783
+ processOnly: true,
6784
+ displayable: true
6785
+ },
6786
+ true
6787
+ ),
6788
+ normalizeField(
6789
+ "approvalResult",
6790
+ {
6791
+ label: "\u5BA1\u6279\u7ED3\u679C",
6792
+ componentName: "SelectField",
6793
+ width: 110,
6794
+ options: APPROVAL_RESULT_OPTIONS,
6795
+ processOnly: true,
6796
+ displayable: true
6797
+ },
6798
+ true
6799
+ )
6800
+ ];
6801
+ var BASE_SYSTEM_FIELDS = [
6802
+ normalizeField("createTime", { label: "\u521B\u5EFA\u65F6\u95F4", componentName: "DateField", width: 170 }, true),
6803
+ normalizeField(
6804
+ "modifiedTime",
6805
+ { label: "\u66F4\u65B0\u65F6\u95F4", componentName: "DateField", width: 170 },
6806
+ true
6807
+ ),
6808
+ normalizeField(
6809
+ "originatorName",
6810
+ { label: "\u521B\u5EFA\u4EBA", componentName: "TextField", width: 130 },
6811
+ true
6812
+ )
6813
+ ];
6814
+ var getSystemFieldsForFormType = (formType) => formType === "process" ? [...BASE_SYSTEM_FIELDS, ...PROCESS_SYSTEM_FIELDS] : BASE_SYSTEM_FIELDS;
6815
+ var normalizeDataManagementFields = (payload) => {
6816
+ const data = pickData(payload);
6817
+ const formType = data?.formType || data?.schema?.formType || data?.type;
6818
+ const rawFields = data?.formFields || data?.schema?.formFields || data?.fields || data?.schema?.fields || data?.formSchema?.fields || [];
6819
+ const fields = Array.isArray(rawFields) ? rawFields.map((field) => normalizeField(field?.fieldId || field?.id, field)) : Object.entries(rawFields).map(([key, field]) => normalizeField(key, field));
6820
+ return {
6821
+ fields: fields.filter((field) => field.componentName !== "PageSection"),
6822
+ formType
6823
+ };
6824
+ };
6825
+ var normalizeDataManagementList = (payload) => {
6826
+ const data = unwrap(payload);
6827
+ const body = data?.result || data;
6828
+ const records = body?.data || body?.records || body?.list || body?.items || [];
6829
+ const total = body?.totalCount ?? body?.total ?? body?.count ?? records.length;
6830
+ return {
6831
+ records: Array.isArray(records) ? records : [],
6832
+ total: Number(total) || 0
6833
+ };
6834
+ };
6835
+ var buildFilterPayload = (group) => {
6836
+ if (!group) return void 0;
6837
+ const trimGroup = (current) => ({
6838
+ ...current,
6839
+ rules: (current.rules || []).filter(
6840
+ (rule) => rule.key && rule.operator && rule.value !== void 0 && rule.value !== ""
6841
+ ),
6842
+ conditions: (current.conditions || []).map(trimGroup).filter((item) => item.rules.length > 0 || item.conditions.length > 0)
6843
+ });
6844
+ const payload = trimGroup(group);
6845
+ if (payload.rules.length === 0 && payload.conditions.length === 0) return void 0;
6846
+ return JSON.stringify(payload);
6847
+ };
6848
+ var normalizeColumnConfig = (cfg, fields) => {
6849
+ const allowed = new Set(fields.map((field) => field.fieldId));
6850
+ const configured = Array.isArray(cfg?.showFields) ? cfg.showFields.filter((fieldId) => allowed.has(fieldId)) : [];
6851
+ const defaultShow = fields.filter((field) => !field.system || field.displayable).slice(0, 8).map((field) => field.fieldId);
6852
+ return {
6853
+ showFields: configured.length > 0 ? configured : defaultShow,
6854
+ widths: cfg?.widths || {},
6855
+ lockFieldIds: cfg?.lockFieldIds || [],
6856
+ sort: Array.isArray(cfg?.sort) ? cfg.sort : [],
6857
+ density: cfg?.density || "middle",
6858
+ detailOpenMode: cfg?.detailOpenMode === "newPage" ? "newPage" : "drawer",
6859
+ pageSize: cfg?.pageSize || 10
6860
+ };
6861
+ };
6862
+ async function getDataManagementSchema(request, params) {
6863
+ const response = await request({
6864
+ url: "/form/getFormSchemaAndPackages",
6865
+ method: "get",
6866
+ params
6867
+ });
6868
+ return normalizeDataManagementFields(response);
6869
+ }
6870
+ async function getDataManagementConfig(request, options) {
6871
+ const targetFormUuid = options.menuFormUuid || options.formUuid;
6872
+ const personal = options.scope === "personal";
6873
+ const response = await request({
6874
+ url: `/${options.appType}/v1/form/dataManagement/config/${personal ? "personal/" : ""}get.json`,
6875
+ method: "get",
6876
+ params: { formUuid: targetFormUuid }
6877
+ });
6878
+ return unwrap(response);
6879
+ }
6880
+ async function saveDataManagementConfig(request, options) {
6881
+ const targetFormUuid = options.menuFormUuid || options.formUuid;
6882
+ const personal = options.scope === "personal";
6883
+ const response = await request({
6884
+ url: `/${options.appType}/v1/form/dataManagement/config/${personal ? "personal/" : ""}save.json`,
6885
+ method: "post",
6886
+ data: { formUuid: targetFormUuid, config: options.config }
6887
+ });
6888
+ return unwrap(response);
6889
+ }
6890
+ async function advancedSearchDataManagement(request, query) {
6891
+ const response = await request({
6892
+ url: `/${query.appType}/v1/form/advancedSearch.json`,
6893
+ method: "get",
6894
+ params: {
6895
+ appType: query.appType,
6896
+ formUuid: query.formUuid,
6897
+ filters: query.rawFilters ?? buildFilterPayload(query.filters),
6898
+ conditionType: query.conditionType,
6899
+ searchKeyWord: query.searchKeyWord,
6900
+ currentPage: query.currentPage || 1,
6901
+ pageSize: query.pageSize || 10,
6902
+ order: JSON.stringify(query.order || []),
6903
+ instanceStatus: query.instanceStatus
6904
+ }
6905
+ });
6906
+ return normalizeDataManagementList(response);
6907
+ }
6908
+ async function deleteDataManagementRows(request, params) {
6909
+ const response = await request({
6910
+ url: `/${params.appType}/v1/form/deleteFormData.json`,
6911
+ method: "post",
6912
+ data: {
6913
+ appType: params.appType,
6914
+ formUuid: params.formUuid,
6915
+ formInstIds: params.formInstanceIds,
6916
+ formInstanceIds: params.formInstanceIds
6917
+ }
6918
+ });
6919
+ return unwrap(response);
6920
+ }
6921
+ async function batchApproveDataManagementRows(request, params) {
6922
+ const response = await request({
6923
+ url: "/workflow/approve/batch",
6924
+ method: "post",
6925
+ data: {
6926
+ instanceIds: params.formInstanceIds,
6927
+ action: params.action,
6928
+ comments: params.comments
6929
+ }
6930
+ });
6931
+ return unwrap(response);
6932
+ }
6933
+ async function exportDataManagementRows(request, params) {
6934
+ return request({
6935
+ url: `/${params.appType}/v1/form/advancedExport.xlsx`,
6936
+ method: "get",
6937
+ responseType: "blob",
6938
+ params: {
6939
+ appType: params.appType,
6940
+ formUuid: params.formUuid,
6941
+ filters: params.rawFilters ?? buildFilterPayload(params.filters),
6942
+ conditionType: params.conditionType,
6943
+ searchKeyWord: params.searchKeyWord,
6944
+ currentPage: params.currentPage,
6945
+ pageSize: params.pageSize,
6946
+ order: JSON.stringify(params.order || []),
6947
+ instanceStatus: params.instanceStatus,
6948
+ exportAll: params.exportAll || "n",
6949
+ embedImages: params.embedImages || "n",
6950
+ exportFields: (params.exportFields || []).join(",")
6951
+ }
6952
+ });
6953
+ }
6954
+ async function importPreviewDataManagementRows(request, params) {
6955
+ const response = await request({
6956
+ url: `/${params.appType}/v1/form/importPreview.xlsx`,
6957
+ method: "post",
6958
+ data: { formUuid: params.formUuid, fileBase64: params.fileBase64 }
6959
+ });
6960
+ return unwrap(response);
6961
+ }
6962
+ async function importDataManagementRows(request, params) {
6963
+ const response = await request({
6964
+ url: `/${params.appType}/v1/form/import.xlsx`,
6965
+ method: "post",
6966
+ data: { formUuid: params.formUuid, fileBase64: params.fileBase64 }
6967
+ });
6968
+ return unwrap(response);
6969
+ }
6970
+ async function getDataManagementTransferRecords(request, params) {
6971
+ const response = await request({
6972
+ url: `/${params.appType}/v1/form/${params.type}Records.json`,
6973
+ method: "get",
6974
+ params
6975
+ });
6976
+ return normalizeDataManagementList(response);
6977
+ }
6978
+
6701
6979
  // src/layout/FormSection/index.tsx
6702
6980
  import { useState as useState18 } from "react";
6703
6981
  import { jsx as jsx72, jsxs as jsxs25 } from "react/jsx-runtime";
@@ -7104,37 +7382,91 @@ function useFormSubmit(config) {
7104
7382
 
7105
7383
  // src/hooks/useFieldPermission.ts
7106
7384
  import { useMemo as useMemo12, useCallback as useCallback10 } from "react";
7385
+
7386
+ // src/utils/permissions.ts
7387
+ var OPERATION_ALIASES = {
7388
+ VIEW: "view",
7389
+ EDIT: "edit",
7390
+ DELETE: "delete",
7391
+ VIEW_CHANGE_RECORDS: "change_records",
7392
+ CHANGE_RECORDS: "change_records",
7393
+ VIEW_PROCESS: "workflow",
7394
+ WORKFLOW: "workflow"
7395
+ };
7396
+ function normalizeOperation(operation) {
7397
+ const raw = String(operation || "").trim();
7398
+ if (!raw) return "";
7399
+ const upper = raw.toUpperCase();
7400
+ return OPERATION_ALIASES[upper] || raw.toLowerCase();
7401
+ }
7402
+ function hasViewOperation(operations, expected) {
7403
+ const normalized = new Set((operations || []).map(normalizeOperation));
7404
+ return normalized.has(normalizeOperation(expected));
7405
+ }
7406
+ function normalizeFieldBehaviors(permissions, mode) {
7407
+ const behaviors = {};
7408
+ Object.entries(permissions?.fieldPermissions || {}).forEach(([fieldId, value]) => {
7409
+ if (value === "FORM_FILED_HIDDEN") {
7410
+ behaviors[fieldId] = "HIDDEN";
7411
+ } else if (value === "FORM_FILED_EDIT") {
7412
+ behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
7413
+ } else {
7414
+ behaviors[fieldId] = "READONLY";
7415
+ }
7416
+ });
7417
+ return behaviors;
7418
+ }
7419
+ function hasViewPermission(permissions) {
7420
+ const operations = permissions?.operations || [];
7421
+ return operations.length === 0 ? false : hasViewOperation(operations, "view");
7422
+ }
7423
+
7424
+ // src/hooks/useFieldPermission.ts
7425
+ var normalizeBehavior = (value) => {
7426
+ if (value === "EDITABLE") return "NORMAL";
7427
+ if (value === "READ_ONLY") return "READONLY";
7428
+ if (value === "DISABLED") return "DISABLED";
7429
+ if (value === "HIDDEN") return "HIDDEN";
7430
+ if (value === "NORMAL" || value === "READONLY") return value;
7431
+ return "READONLY";
7432
+ };
7433
+ var normalizeFlowConfig = (config) => {
7434
+ if (!config) return null;
7435
+ if (Array.isArray(config)) {
7436
+ const result = {};
7437
+ config.forEach((item) => {
7438
+ const fieldId = item?.fieldId || item?.field_id || item?.id;
7439
+ if (!fieldId) return;
7440
+ result[fieldId] = normalizeBehavior(item?.fieldBehavior || item?.behavior || item?.value);
7441
+ });
7442
+ return Object.keys(result).length > 0 ? result : null;
7443
+ }
7444
+ if (typeof config === "object") {
7445
+ const result = {};
7446
+ Object.entries(config).forEach(([fieldId, value]) => {
7447
+ result[fieldId] = normalizeBehavior(
7448
+ typeof value === "string" ? value : value?.fieldBehavior || value?.behavior
7449
+ );
7450
+ });
7451
+ return result;
7452
+ }
7453
+ return null;
7454
+ };
7107
7455
  function useFieldPermission(options) {
7108
7456
  const { viewPermissions, processDefinition, currentTask, isApprover, mode } = options;
7109
7457
  const computeBehaviors = useCallback10(() => {
7110
7458
  const behaviors = {};
7111
7459
  if (!currentTask && viewPermissions) {
7112
- const { fieldPermissions } = viewPermissions;
7113
- for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
7114
- if (perm === "FORM_FILED_HIDDEN") {
7115
- behaviors[fieldId] = "HIDDEN";
7116
- } else if (perm === "FORM_FILED_VIEW") {
7117
- behaviors[fieldId] = "READONLY";
7118
- } else if (perm === "FORM_FILED_EDIT") {
7119
- behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
7120
- }
7121
- }
7122
- return behaviors;
7460
+ return normalizeFieldBehaviors(viewPermissions, mode);
7123
7461
  }
7124
7462
  if (currentTask && !isApprover && viewPermissions) {
7125
- const { fieldPermissions } = viewPermissions;
7126
- for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
7127
- if (perm === "FORM_FILED_HIDDEN") {
7128
- behaviors[fieldId] = "HIDDEN";
7129
- } else {
7130
- behaviors[fieldId] = "READONLY";
7131
- }
7132
- }
7133
- return behaviors;
7463
+ return normalizeFieldBehaviors(viewPermissions, "readonly");
7134
7464
  }
7135
7465
  if (currentTask && isApprover && currentTask.nodeType === "originator_return") {
7136
7466
  if (processDefinition?.flowConfig && processDefinition.startNodeId) {
7137
- const startConfig = processDefinition.flowConfig[processDefinition.startNodeId];
7467
+ const startConfig = normalizeFlowConfig(
7468
+ processDefinition.flowConfig[processDefinition.startNodeId]
7469
+ );
7138
7470
  if (startConfig) {
7139
7471
  for (const [fieldId, behavior] of Object.entries(startConfig)) {
7140
7472
  behaviors[fieldId] = mode === "edit" ? behavior : "READONLY";
@@ -7154,7 +7486,7 @@ function useFieldPermission(options) {
7154
7486
  return behaviors;
7155
7487
  }
7156
7488
  if (currentTask && isApprover && processDefinition?.flowConfig) {
7157
- const nodeConfig = processDefinition.flowConfig[currentTask.nodeId];
7489
+ const nodeConfig = normalizeFlowConfig(processDefinition.flowConfig[currentTask.nodeId]);
7158
7490
  if (nodeConfig) {
7159
7491
  for (const [fieldId, behavior] of Object.entries(nodeConfig)) {
7160
7492
  behaviors[fieldId] = mode === "edit" ? behavior : "READONLY";
@@ -7163,16 +7495,7 @@ function useFieldPermission(options) {
7163
7495
  }
7164
7496
  }
7165
7497
  if (viewPermissions) {
7166
- const { fieldPermissions } = viewPermissions;
7167
- for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
7168
- if (perm === "FORM_FILED_HIDDEN") {
7169
- behaviors[fieldId] = "HIDDEN";
7170
- } else if (perm === "FORM_FILED_VIEW") {
7171
- behaviors[fieldId] = "READONLY";
7172
- } else if (perm === "FORM_FILED_EDIT") {
7173
- behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
7174
- }
7175
- }
7498
+ return normalizeFieldBehaviors(viewPermissions, mode);
7176
7499
  }
7177
7500
  return behaviors;
7178
7501
  }, [viewPermissions, processDefinition, currentTask, isApprover, mode]);
@@ -7251,20 +7574,6 @@ var extractFormValues = (formInstance, fieldIds) => {
7251
7574
  };
7252
7575
 
7253
7576
  // src/hooks/useFormDetail.ts
7254
- function buildFieldBehaviors(permissions, mode) {
7255
- const behaviors = {};
7256
- if (!permissions) return behaviors;
7257
- for (const [fieldId, perm] of Object.entries(permissions.fieldPermissions)) {
7258
- if (perm === "FORM_FILED_HIDDEN") {
7259
- behaviors[fieldId] = "HIDDEN";
7260
- } else if (perm === "FORM_FILED_VIEW") {
7261
- behaviors[fieldId] = "READONLY";
7262
- } else if (perm === "FORM_FILED_EDIT") {
7263
- behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
7264
- }
7265
- }
7266
- return behaviors;
7267
- }
7268
7577
  function useFormDetail(options) {
7269
7578
  const { formUuid, appType, formInstanceId, fieldIds, onPermissionDenied } = options;
7270
7579
  const { api } = useFormContext();
@@ -7290,7 +7599,7 @@ function useFormDetail(options) {
7290
7599
  getFormData(request, { formInstanceId, appType, formUuid })
7291
7600
  ]);
7292
7601
  if (!mountedRef.current) return;
7293
- if (!permResult || !permResult.operations || permResult.operations.length === 0) {
7602
+ if (!permResult || !hasViewOperation(permResult.operations, "view")) {
7294
7603
  onPermissionDenied?.();
7295
7604
  }
7296
7605
  setPermissions(permResult);
@@ -7312,10 +7621,10 @@ function useFormDetail(options) {
7312
7621
  useEffect29(() => {
7313
7622
  loadData();
7314
7623
  }, [loadData]);
7315
- const fieldBehaviors = buildFieldBehaviors(permissions, mode);
7316
- const canEdit = permissions?.operations?.includes("EDIT") ?? false;
7317
- const canDelete = permissions?.operations?.includes("DELETE") ?? false;
7318
- const canViewChangeRecords = permissions?.operations?.includes("VIEW_CHANGE_RECORDS") ?? false;
7624
+ const fieldBehaviors = normalizeFieldBehaviors(permissions, mode);
7625
+ const canEdit = hasViewOperation(permissions?.operations, "edit");
7626
+ const canDelete = hasViewOperation(permissions?.operations, "delete");
7627
+ const canViewChangeRecords = hasViewOperation(permissions?.operations, "change_records");
7319
7628
  const switchToEdit = useCallback11(() => {
7320
7629
  setMode("edit");
7321
7630
  loadData();
@@ -7719,6 +8028,30 @@ function useApprovalActions(options) {
7719
8028
  },
7720
8029
  [request, currentTaskId, formUuid, appType, getFormValues, onActionComplete, resetLoading]
7721
8030
  );
8031
+ const callbackTask = useCallback13(
8032
+ async (payload) => {
8033
+ if (!currentTaskId) {
8034
+ console.error("[useApprovalActions] callbackTask failed: no currentTaskId");
8035
+ return false;
8036
+ }
8037
+ setIsLoading(true);
8038
+ setCurrentAction("callback");
8039
+ try {
8040
+ await triggerCallbackTask(request, {
8041
+ taskId: currentTaskId,
8042
+ payload
8043
+ });
8044
+ resetLoading();
8045
+ onActionComplete?.("callback");
8046
+ return true;
8047
+ } catch (error) {
8048
+ console.error("[useApprovalActions] callbackTask failed:", error);
8049
+ resetLoading();
8050
+ return false;
8051
+ }
8052
+ },
8053
+ [request, currentTaskId, onActionComplete, resetLoading]
8054
+ );
7722
8055
  const loadReturnableNodes = useCallback13(async () => {
7723
8056
  if (!currentTaskId) return;
7724
8057
  try {
@@ -7738,6 +8071,7 @@ function useApprovalActions(options) {
7738
8071
  withdraw,
7739
8072
  save,
7740
8073
  resubmit,
8074
+ callbackTask,
7741
8075
  isLoading,
7742
8076
  currentAction,
7743
8077
  returnableNodes,
@@ -8105,179 +8439,657 @@ var FormSummaryCard = ({
8105
8439
  ] });
8106
8440
  };
8107
8441
 
8108
- // src/modules/ChangeRecords.tsx
8442
+ // src/modules/RecordChangePanel.tsx
8109
8443
  import { useState as useState30 } from "react";
8110
- import { Skeleton } from "antd";
8111
- import { DownOutlined, UpOutlined } from "@ant-design/icons";
8444
+ import { Button as Button9, Empty as Empty3, Pagination, Skeleton, Tag as Tag4, Tooltip } from "antd";
8445
+ import {
8446
+ ArrowRightOutlined,
8447
+ DownOutlined,
8448
+ HistoryOutlined,
8449
+ ReloadOutlined,
8450
+ UpOutlined
8451
+ } from "@ant-design/icons";
8112
8452
  import { jsx as jsx78, jsxs as jsxs30 } from "react/jsx-runtime";
8113
- var ChangeRecords = ({
8453
+ var sourceLabels = {
8454
+ frontend: "\u524D\u7AEF",
8455
+ integration: "\u96C6\u6210",
8456
+ automation: "\u81EA\u52A8\u5316",
8457
+ import: "\u5BFC\u5165"
8458
+ };
8459
+ var typeLabels = {
8460
+ create: "\u65B0\u589E",
8461
+ update: "\u4FEE\u6539",
8462
+ delete: "\u5220\u9664"
8463
+ };
8464
+ function formatValue(value) {
8465
+ if (value === null || value === void 0 || value === "")
8466
+ return /* @__PURE__ */ jsx78("span", { className: "text-ant-text-tertiary", children: "\u7A7A" });
8467
+ if (Array.isArray(value)) {
8468
+ return /* @__PURE__ */ jsx78("span", { className: "inline-flex flex-wrap gap-1", children: value.map((item, index) => /* @__PURE__ */ jsx78(Tag4, { className: "m-0", children: String(
8469
+ typeof item === "object" ? item.label || item.value || JSON.stringify(item) : item
8470
+ ) }, `${index}-${String(item)}`)) });
8471
+ }
8472
+ if (typeof value === "object") {
8473
+ const label = value.label ?? value.value;
8474
+ return label ? String(label) : /* @__PURE__ */ jsx78("code", { className: "text-xs", children: JSON.stringify(value) });
8475
+ }
8476
+ return String(value);
8477
+ }
8478
+ function getInitial(name) {
8479
+ return String(name || "?").trim().slice(0, 1).toUpperCase() || "?";
8480
+ }
8481
+ var RecordChangePanel = ({
8114
8482
  records = [],
8115
8483
  loading = false,
8484
+ total,
8485
+ page = 1,
8486
+ pageSize = 20,
8116
8487
  defaultExpanded = false,
8117
8488
  hasMore = false,
8118
8489
  onLoadMore,
8490
+ onRefresh,
8119
8491
  onExpand,
8120
- className = "",
8121
- renderItem
8492
+ onPageChange,
8493
+ className = ""
8122
8494
  }) => {
8123
8495
  const [expanded, setExpanded] = useState30(defaultExpanded);
8496
+ const count = total ?? records.length;
8124
8497
  const handleToggle = () => {
8125
8498
  const next = !expanded;
8126
8499
  setExpanded(next);
8127
- if (next && onExpand) {
8128
- onExpand();
8129
- }
8500
+ if (next) onExpand?.();
8130
8501
  };
8131
- const defaultRenderItem = (record) => /* @__PURE__ */ jsxs30("div", { className: "pl-4 py-3 border-l-2 border-gray-200 ml-1", children: [
8132
- /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2 text-xs text-gray-400", children: [
8133
- /* @__PURE__ */ jsx78("span", { children: record.operatedAt }),
8134
- /* @__PURE__ */ jsx78("span", { className: "text-gray-600 font-medium", children: record.operatorName }),
8135
- /* @__PURE__ */ jsx78("span", { children: "\u4FEE\u6539\u4E86" }),
8136
- /* @__PURE__ */ jsx78("span", { className: "text-gray-800 font-medium", children: record.fieldLabel })
8137
- ] }),
8138
- /* @__PURE__ */ jsxs30("div", { className: "mt-1.5 text-sm text-gray-600 flex items-center gap-2", children: [
8139
- /* @__PURE__ */ jsx78("span", { className: "bg-red-50 text-red-600 px-1.5 py-0.5 rounded text-xs line-through", children: formatValue(record.oldValue) }),
8140
- /* @__PURE__ */ jsx78("span", { className: "text-gray-400", children: "\u2192" }),
8141
- /* @__PURE__ */ jsx78("span", { className: "bg-green-50 text-green-600 px-1.5 py-0.5 rounded text-xs", children: formatValue(record.newValue) })
8142
- ] })
8143
- ] });
8144
- return /* @__PURE__ */ jsxs30("div", { className: `bg-white rounded-xl shadow-sm border border-gray-100 ${className}`, children: [
8145
- /* @__PURE__ */ jsxs30(
8146
- "button",
8502
+ return /* @__PURE__ */ jsxs30(
8503
+ "section",
8504
+ {
8505
+ className: `rounded-lg border border-ant-border-secondary bg-ant-bg-container ${className}`,
8506
+ children: [
8507
+ /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-3 border-b border-ant-border-secondary px-5 py-4", children: [
8508
+ /* @__PURE__ */ jsxs30(
8509
+ "button",
8510
+ {
8511
+ type: "button",
8512
+ className: "flex min-w-0 items-center gap-2 bg-transparent p-0 text-left",
8513
+ onClick: handleToggle,
8514
+ children: [
8515
+ /* @__PURE__ */ jsx78(HistoryOutlined, { className: "text-ant-primary" }),
8516
+ /* @__PURE__ */ jsx78("span", { className: "font-semibold text-ant-text", children: "\u53D8\u66F4\u8BB0\u5F55" }),
8517
+ /* @__PURE__ */ jsxs30("span", { className: "rounded-full bg-gray-100 px-2 py-0.5 text-xs text-ant-text-tertiary", children: [
8518
+ count,
8519
+ " \u6761"
8520
+ ] }),
8521
+ expanded ? /* @__PURE__ */ jsx78(UpOutlined, { className: "text-xs" }) : /* @__PURE__ */ jsx78(DownOutlined, { className: "text-xs" })
8522
+ ]
8523
+ }
8524
+ ),
8525
+ expanded && /* @__PURE__ */ jsx78(
8526
+ Button9,
8527
+ {
8528
+ type: "text",
8529
+ size: "small",
8530
+ icon: /* @__PURE__ */ jsx78(ReloadOutlined, {}),
8531
+ onClick: onRefresh,
8532
+ disabled: loading,
8533
+ children: "\u5237\u65B0"
8534
+ }
8535
+ )
8536
+ ] }),
8537
+ expanded ? /* @__PURE__ */ jsxs30("div", { className: "p-5", children: [
8538
+ loading && records.length === 0 ? /* @__PURE__ */ jsx78(Skeleton, { active: true, paragraph: { rows: 3 } }) : records.length === 0 ? /* @__PURE__ */ jsx78(Empty3, { description: "\u6682\u65E0\u53D8\u66F4\u8BB0\u5F55" }) : /* @__PURE__ */ jsx78("div", { className: "space-y-4", children: records.map((record) => {
8539
+ const changes = record.changes && record.changes.length > 0 ? record.changes : [
8540
+ {
8541
+ fieldKey: record.fieldId,
8542
+ fieldLabel: record.fieldLabel,
8543
+ beforeValue: record.oldValue,
8544
+ afterValue: record.newValue
8545
+ }
8546
+ ];
8547
+ const operator = record.operatorName || (record.changeSource ? "\u7CFB\u7EDF" : "\u672A\u77E5");
8548
+ const operatedAt = record.operatedAt || record.createdAt || "-";
8549
+ return /* @__PURE__ */ jsxs30(
8550
+ "article",
8551
+ {
8552
+ className: "rounded-md border border-ant-border-secondary p-4",
8553
+ children: [
8554
+ /* @__PURE__ */ jsxs30("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
8555
+ /* @__PURE__ */ jsxs30("div", { className: "flex min-w-0 items-center gap-3", children: [
8556
+ /* @__PURE__ */ jsx78("span", { className: "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-blue-50 text-sm font-semibold text-blue-700", children: getInitial(operator) }),
8557
+ /* @__PURE__ */ jsxs30("span", { className: "min-w-0", children: [
8558
+ /* @__PURE__ */ jsxs30("span", { className: "block text-sm font-medium text-ant-text", children: [
8559
+ operator,
8560
+ record.operatorDepartmentName && /* @__PURE__ */ jsx78("span", { className: "ml-2 font-normal text-ant-text-tertiary", children: record.operatorDepartmentName })
8561
+ ] }),
8562
+ /* @__PURE__ */ jsxs30("span", { className: "block text-xs text-ant-text-tertiary", children: [
8563
+ "\u53D8\u66F4 ",
8564
+ record.changedCount || changes.length,
8565
+ " \u9879 \xB7 ",
8566
+ operatedAt
8567
+ ] })
8568
+ ] })
8569
+ ] }),
8570
+ /* @__PURE__ */ jsxs30("span", { className: "flex flex-wrap justify-end gap-2", children: [
8571
+ record.changeType && /* @__PURE__ */ jsx78(Tag4, { children: typeLabels[record.changeType] || record.changeType }),
8572
+ record.changeSource && /* @__PURE__ */ jsx78(Tag4, { color: "blue", children: sourceLabels[record.changeSource] || record.changeSource }),
8573
+ record.operationId && /* @__PURE__ */ jsx78(Tooltip, { title: `\u64CD\u4F5CID\uFF1A${record.operationId}`, children: /* @__PURE__ */ jsx78(Tag4, { children: record.operationId.slice(0, 8) }) })
8574
+ ] })
8575
+ ] }),
8576
+ /* @__PURE__ */ jsx78("div", { className: "mt-4 space-y-3", children: changes.map((change) => /* @__PURE__ */ jsxs30(
8577
+ "div",
8578
+ {
8579
+ className: "grid gap-2 md:grid-cols-[160px_1fr]",
8580
+ children: [
8581
+ /* @__PURE__ */ jsx78("div", { className: "text-sm font-medium text-ant-text-secondary", children: change.fieldLabel || change.fieldKey || "-" }),
8582
+ /* @__PURE__ */ jsxs30("div", { className: "grid min-w-0 grid-cols-[1fr_auto_1fr] items-start gap-2 text-sm", children: [
8583
+ /* @__PURE__ */ jsx78("div", { className: "min-w-0 rounded bg-red-50 px-2 py-1 text-red-700", children: formatValue(change.beforeValue) }),
8584
+ /* @__PURE__ */ jsx78(ArrowRightOutlined, { className: "mt-1 text-xs text-ant-text-tertiary" }),
8585
+ /* @__PURE__ */ jsx78("div", { className: "min-w-0 rounded bg-emerald-50 px-2 py-1 text-emerald-700", children: formatValue(change.afterValue) })
8586
+ ] })
8587
+ ]
8588
+ },
8589
+ change.fieldKey || change.fieldLabel
8590
+ )) })
8591
+ ]
8592
+ },
8593
+ record.id || record.operationId
8594
+ );
8595
+ }) }),
8596
+ onPageChange && count > pageSize ? /* @__PURE__ */ jsx78("div", { className: "mt-4 flex justify-end", children: /* @__PURE__ */ jsx78(
8597
+ Pagination,
8598
+ {
8599
+ size: "small",
8600
+ current: page,
8601
+ pageSize,
8602
+ total: count,
8603
+ onChange: onPageChange,
8604
+ showSizeChanger: true
8605
+ }
8606
+ ) }) : hasMore ? /* @__PURE__ */ jsx78(Button9, { block: true, className: "mt-4", onClick: onLoadMore, loading, children: "\u52A0\u8F7D\u66F4\u591A" }) : null
8607
+ ] }) : /* @__PURE__ */ jsx78("div", { className: "px-5 py-4 text-sm text-ant-text-tertiary", children: "\u70B9\u51FB\u5C55\u5F00\u67E5\u770B\u53D8\u66F4\u8BB0\u5F55" })
8608
+ ]
8609
+ }
8610
+ );
8611
+ };
8612
+
8613
+ // src/modules/ChangeRecords.tsx
8614
+ import { jsx as jsx79, jsxs as jsxs31 } from "react/jsx-runtime";
8615
+ var ChangeRecords = ({
8616
+ records = [],
8617
+ loading = false,
8618
+ defaultExpanded = false,
8619
+ hasMore = false,
8620
+ onLoadMore,
8621
+ onExpand,
8622
+ className = "",
8623
+ renderItem
8624
+ }) => {
8625
+ if (renderItem) {
8626
+ return /* @__PURE__ */ jsxs31(
8627
+ "section",
8147
8628
  {
8148
- type: "button",
8149
- className: "w-full flex items-center justify-between p-6 text-left hover:bg-gray-50/50 transition-colors rounded-xl",
8150
- onClick: handleToggle,
8629
+ className: `rounded-lg border border-ant-border-secondary bg-ant-bg-container ${className}`,
8151
8630
  children: [
8152
- /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2", children: [
8153
- /* @__PURE__ */ jsx78("h3", { className: "text-lg font-semibold text-gray-900", children: "\u53D8\u66F4\u8BB0\u5F55" }),
8154
- /* @__PURE__ */ jsx78("span", { className: "text-xs text-gray-400 bg-gray-100 px-1.5 py-0.5 rounded-full", children: records.length })
8155
- ] }),
8156
- /* @__PURE__ */ jsx78("span", { className: "text-gray-400 text-xs", children: expanded ? /* @__PURE__ */ jsx78(UpOutlined, {}) : /* @__PURE__ */ jsx78(DownOutlined, {}) })
8631
+ /* @__PURE__ */ jsx79("div", { className: "border-b border-ant-border-secondary px-5 py-4 font-semibold", children: "\u53D8\u66F4\u8BB0\u5F55" }),
8632
+ /* @__PURE__ */ jsxs31("div", { className: "p-5", children: [
8633
+ records.length === 0 ? /* @__PURE__ */ jsx79("p", { className: "m-0 text-center text-sm text-ant-text-tertiary", children: loading ? "\u52A0\u8F7D\u4E2D..." : "\u6682\u65E0\u53D8\u66F4\u8BB0\u5F55" }) : /* @__PURE__ */ jsx79("div", { className: "space-y-2", children: records.map((record) => /* @__PURE__ */ jsx79("div", { children: renderItem(record) }, record.id)) }),
8634
+ hasMore && /* @__PURE__ */ jsx79(
8635
+ "button",
8636
+ {
8637
+ type: "button",
8638
+ className: "mt-4 w-full rounded-md border border-ant-border-secondary py-2 text-sm text-ant-primary",
8639
+ onClick: onLoadMore,
8640
+ disabled: loading,
8641
+ children: loading ? "\u52A0\u8F7D\u4E2D..." : "\u52A0\u8F7D\u66F4\u591A"
8642
+ }
8643
+ )
8644
+ ] })
8157
8645
  ]
8158
8646
  }
8159
- ),
8160
- expanded && /* @__PURE__ */ jsxs30("div", { className: "px-6 pb-6", children: [
8161
- loading && records.length === 0 ? /* @__PURE__ */ jsx78(Skeleton, { active: true, paragraph: { rows: 3 } }) : records.length === 0 ? /* @__PURE__ */ jsx78("p", { className: "text-sm text-gray-400 text-center py-4", children: "\u6682\u65E0\u53D8\u66F4\u8BB0\u5F55" }) : /* @__PURE__ */ jsx78("div", { className: "space-y-1", children: records.map((record) => /* @__PURE__ */ jsx78("div", { children: renderItem ? renderItem(record) : defaultRenderItem(record) }, record.id)) }),
8162
- hasMore && /* @__PURE__ */ jsx78(
8163
- "button",
8164
- {
8165
- type: "button",
8166
- className: "mt-4 w-full text-center text-sm text-blue-600 hover:text-blue-700 py-2 rounded-lg hover:bg-blue-50/50 transition-colors",
8167
- onClick: onLoadMore,
8168
- disabled: loading,
8169
- children: loading ? "\u52A0\u8F7D\u4E2D..." : "\u52A0\u8F7D\u66F4\u591A"
8170
- }
8171
- )
8172
- ] })
8173
- ] });
8647
+ );
8648
+ }
8649
+ return /* @__PURE__ */ jsx79(
8650
+ RecordChangePanel,
8651
+ {
8652
+ records,
8653
+ loading,
8654
+ defaultExpanded,
8655
+ hasMore,
8656
+ onLoadMore,
8657
+ onRefresh: onExpand,
8658
+ onExpand,
8659
+ className
8660
+ }
8661
+ );
8174
8662
  };
8175
- function formatValue(value) {
8176
- if (value === null || value === void 0) return "\u7A7A";
8177
- if (typeof value === "object") return JSON.stringify(value);
8178
- return String(value);
8179
- }
8180
8663
 
8181
8664
  // src/modules/ApprovalTimeline.tsx
8182
- import { Fragment as Fragment2, jsx as jsx79, jsxs as jsxs31 } from "react/jsx-runtime";
8665
+ import { useMemo as useMemo14 } from "react";
8666
+ import {
8667
+ ApiOutlined,
8668
+ CheckCircleFilled,
8669
+ ClockCircleOutlined,
8670
+ CloseCircleFilled,
8671
+ CodeOutlined,
8672
+ CopyOutlined,
8673
+ EditOutlined,
8674
+ FileTextOutlined,
8675
+ LoadingOutlined,
8676
+ NotificationOutlined,
8677
+ ReloadOutlined as ReloadOutlined2,
8678
+ RollbackOutlined,
8679
+ UserOutlined as UserOutlined2
8680
+ } from "@ant-design/icons";
8681
+ import { jsx as jsx80, jsxs as jsxs32 } from "react/jsx-runtime";
8682
+ var systemNodeTypes = /* @__PURE__ */ new Set([
8683
+ "condition",
8684
+ "condition_branch",
8685
+ "js_code",
8686
+ "data_retrieve_single",
8687
+ "data_retrieve_batch",
8688
+ "data_create",
8689
+ "data_update",
8690
+ "connector_call",
8691
+ "loop_container",
8692
+ "work_notification",
8693
+ "dingtalk_card",
8694
+ "system"
8695
+ ]);
8696
+ var systemLabels = {
8697
+ condition: "\u6761\u4EF6\u5224\u65AD",
8698
+ condition_branch: "\u6761\u4EF6\u5206\u652F",
8699
+ js_code: "JS \u4EE3\u7801",
8700
+ data_retrieve_single: "\u6570\u636E\u8BFB\u53D6",
8701
+ data_retrieve_batch: "\u6279\u91CF\u8BFB\u53D6",
8702
+ data_create: "\u6570\u636E\u521B\u5EFA",
8703
+ data_update: "\u6570\u636E\u66F4\u65B0",
8704
+ connector_call: "\u8FDE\u63A5\u5668\u8C03\u7528",
8705
+ loop_container: "\u5FAA\u73AF\u8282\u70B9",
8706
+ work_notification: "\u5DE5\u4F5C\u901A\u77E5",
8707
+ dingtalk_card: "\u9489\u9489\u5361\u7247",
8708
+ system: "\u7CFB\u7EDF\u52A8\u4F5C"
8709
+ };
8183
8710
  var toneClasses2 = {
8184
- brand: "bg-blue-50 text-blue-600",
8185
- success: "bg-green-50 text-green-600",
8186
- danger: "bg-red-50 text-red-600",
8187
- neutral: "bg-gray-100 text-gray-500",
8188
- warning: "bg-amber-50 text-amber-600"
8711
+ brand: "bg-blue-600 text-white border-blue-600",
8712
+ success: "bg-emerald-50 text-emerald-700 border-emerald-200",
8713
+ danger: "bg-red-50 text-red-700 border-red-200",
8714
+ neutral: "bg-gray-50 text-gray-600 border-gray-200",
8715
+ warning: "bg-amber-50 text-amber-700 border-amber-200",
8716
+ return: "bg-amber-50 text-amber-700 border-amber-200",
8717
+ future: "bg-gray-50 text-gray-400 border-gray-200"
8189
8718
  };
8190
- function getNodePhase(task) {
8191
- if (task.status === "approved" || task.status === "rejected" || task.status === "returned" || task.status === "copied") {
8719
+ function groupTasks(tasks) {
8720
+ const groups = /* @__PURE__ */ new Map();
8721
+ tasks.forEach((task, index) => {
8722
+ const key = task.nodeVisitId || `${task.nodeId || "node"}-${task.id || task.taskId || index}`;
8723
+ const group = groups.get(key) || [];
8724
+ group.push(task);
8725
+ groups.set(key, group);
8726
+ });
8727
+ return Array.from(groups.values()).map((group) => {
8728
+ const hasOrSignResult = group.some(
8729
+ (task) => task.nodeType === "approval" && task.multiApproveMode === "or" && !task.isSimulated && ["approved", "rejected", "returned"].includes(task.status)
8730
+ );
8731
+ if (!hasOrSignResult) return group;
8732
+ const outcome = group.filter(
8733
+ (task) => !task.isSimulated && ["approved", "rejected", "returned"].includes(task.status)
8734
+ );
8735
+ return outcome.length > 0 ? outcome : group;
8736
+ });
8737
+ }
8738
+ function isCompactNode(task) {
8739
+ return task.nodeType === "start" || task.nodeType === "copy" || task.nodeType === "end" || systemNodeTypes.has(task.nodeType);
8740
+ }
8741
+ function getNodeTitle(task) {
8742
+ if (task.nodeType === "start") return task.title || task.nodeName || "\u6D41\u7A0B\u63D0\u4EA4";
8743
+ if (task.nodeType === "originator_return") return task.title || task.nodeName || "\u53D1\u8D77\u4EBA\u4FEE\u6539";
8744
+ if (task.nodeType === "copy") return task.title || task.nodeName || "\u6284\u9001\u901A\u77E5";
8745
+ if (task.nodeType === "callback_wait") return task.title || task.nodeName || "\u7B49\u5F85\u7B2C\u4E09\u65B9\u56DE\u8C03";
8746
+ if (task.nodeType === "end") return task.title || task.nodeName || "\u6D41\u7A0B\u5B8C\u6210";
8747
+ if (systemNodeTypes.has(task.nodeType))
8748
+ return task.title || task.nodeName || systemLabels[task.nodeType] || "\u7CFB\u7EDF\u52A8\u4F5C";
8749
+ return task.title || task.nodeName || "\u5BA1\u6279";
8750
+ }
8751
+ function getVisualState(task, isFutureGroup) {
8752
+ if (isFutureGroup || task.isSimulated || task.status === "simulated") return "future";
8753
+ if (task.status === "rejected") return "rejected";
8754
+ if (task.status === "returned") return "returned";
8755
+ if (task.status === "pending" || task.status === "waiting" || task.canApprove)
8756
+ return task.canApprove ? "current" : "waiting";
8757
+ if (task.status === "approved" || task.status === "copied" || task.nodeType === "start" || task.nodeType === "end") {
8192
8758
  return "completed";
8193
8759
  }
8194
- if (task.status === "pending" || task.status === "waiting") {
8195
- return "active";
8760
+ return "neutral";
8761
+ }
8762
+ function getStatusMeta(task, state, compact) {
8763
+ if (state === "future") return { label: "\u672A\u5F00\u59CB", tone: "neutral" };
8764
+ if (state === "current")
8765
+ return { label: task.nodeType === "callback_wait" ? "\u7B49\u5F85\u56DE\u8C03" : "\u5BA1\u6279\u4E2D", tone: "brand" };
8766
+ if (state === "waiting") return { label: "\u7B49\u5F85\u5904\u7406\u4E2D", tone: "neutral" };
8767
+ if (state === "rejected") return TASK_STATUS_META.rejected;
8768
+ if (state === "returned") return TASK_STATUS_META.returned;
8769
+ if (task.nodeType === "copy" || task.status === "copied") return TASK_STATUS_META.copied;
8770
+ if (compact) return { label: "\u5DF2\u5B8C\u6210", tone: "neutral" };
8771
+ return TASK_STATUS_META[task.status] || TASK_STATUS_META.approved;
8772
+ }
8773
+ function getIcon(task, state) {
8774
+ if (state === "current")
8775
+ return task.nodeType === "callback_wait" ? /* @__PURE__ */ jsx80(ClockCircleOutlined, {}) : /* @__PURE__ */ jsx80(LoadingOutlined, {});
8776
+ if (state === "future" || state === "waiting")
8777
+ return task.nodeType === "approval" ? /* @__PURE__ */ jsx80(UserOutlined2, {}) : /* @__PURE__ */ jsx80(ClockCircleOutlined, {});
8778
+ if (state === "rejected") return /* @__PURE__ */ jsx80(CloseCircleFilled, {});
8779
+ if (state === "returned") return /* @__PURE__ */ jsx80(RollbackOutlined, {});
8780
+ switch (task.nodeType) {
8781
+ case "start":
8782
+ return /* @__PURE__ */ jsx80(FileTextOutlined, {});
8783
+ case "approval":
8784
+ return /* @__PURE__ */ jsx80(CheckCircleFilled, {});
8785
+ case "originator_return":
8786
+ return /* @__PURE__ */ jsx80(EditOutlined, {});
8787
+ case "copy":
8788
+ return /* @__PURE__ */ jsx80(CopyOutlined, {});
8789
+ case "callback_wait":
8790
+ return /* @__PURE__ */ jsx80(ClockCircleOutlined, {});
8791
+ case "js_code":
8792
+ return /* @__PURE__ */ jsx80(CodeOutlined, {});
8793
+ case "connector_call":
8794
+ return /* @__PURE__ */ jsx80(ApiOutlined, {});
8795
+ case "work_notification":
8796
+ case "dingtalk_card":
8797
+ return /* @__PURE__ */ jsx80(NotificationOutlined, {});
8798
+ case "data_retrieve_single":
8799
+ case "data_retrieve_batch":
8800
+ case "data_create":
8801
+ case "data_update":
8802
+ case "loop_container":
8803
+ return /* @__PURE__ */ jsx80(ReloadOutlined2, {});
8804
+ default:
8805
+ return /* @__PURE__ */ jsx80(CheckCircleFilled, {});
8196
8806
  }
8197
- return "pending";
8807
+ }
8808
+ function getDotClass(state) {
8809
+ const map = {
8810
+ completed: "border-emerald-500 text-emerald-600 bg-white",
8811
+ current: "border-blue-600 bg-blue-600 text-white",
8812
+ waiting: "border-gray-200 text-gray-300 bg-white",
8813
+ future: "border-dashed border-gray-300 text-gray-300 bg-white",
8814
+ rejected: "border-red-500 text-red-600 bg-white",
8815
+ returned: "border-amber-500 text-amber-600 bg-white",
8816
+ neutral: "border-gray-200 text-gray-400 bg-white"
8817
+ };
8818
+ return map[state];
8198
8819
  }
8199
8820
  var ApprovalTimeline = ({
8200
8821
  tasks,
8201
8822
  className = "",
8202
8823
  renderNode,
8203
8824
  showRemarks = true,
8204
- compactMode = false
8825
+ compactMode = false,
8826
+ showApproverInfo = true
8205
8827
  }) => {
8206
- const taskList = Array.isArray(tasks) ? tasks : [];
8828
+ const taskList = useMemo14(() => Array.isArray(tasks) ? tasks : [], [tasks]);
8829
+ const groups = useMemo14(() => groupTasks(taskList), [taskList]);
8207
8830
  if (taskList.length === 0) {
8208
- return /* @__PURE__ */ jsx79("div", { className: `bg-white rounded-xl shadow-sm border border-gray-100 p-6 ${className}`, children: /* @__PURE__ */ jsx79("p", { className: "text-sm text-gray-400 text-center", children: "\u6682\u65E0\u5BA1\u6279\u8BB0\u5F55" }) });
8831
+ return /* @__PURE__ */ jsx80(
8832
+ "div",
8833
+ {
8834
+ className: `rounded-lg border border-ant-border-secondary bg-ant-bg-container p-6 ${className}`,
8835
+ children: /* @__PURE__ */ jsx80("p", { className: "m-0 text-center text-sm text-ant-text-tertiary", children: "\u6682\u65E0\u5BA1\u6279\u8BB0\u5F55" })
8836
+ }
8837
+ );
8209
8838
  }
8210
- return /* @__PURE__ */ jsx79("div", { className: `${className}`, children: taskList.map((task, index) => {
8211
- const taskKey = task.taskId || task.id || `${task.nodeId}-${index}`;
8212
- if (renderNode) {
8213
- return /* @__PURE__ */ jsx79("div", { children: renderNode(task, index) }, taskKey);
8214
- }
8215
- const phase = getNodePhase(task);
8216
- const isLast = index === taskList.length - 1;
8217
- const statusMeta = TASK_STATUS_META[task.status];
8218
- return /* @__PURE__ */ jsxs31("div", { className: "flex gap-4", children: [
8219
- /* @__PURE__ */ jsxs31("div", { className: "flex flex-col items-center", children: [
8220
- phase === "completed" && /* @__PURE__ */ jsx79("div", { className: "w-3 h-3 rounded-full bg-green-500 flex-shrink-0" }),
8221
- phase === "active" && /* @__PURE__ */ jsx79("div", { className: "w-3 h-3 rounded-full bg-blue-500 ring-4 ring-blue-100 flex-shrink-0" }),
8222
- phase === "pending" && /* @__PURE__ */ jsx79("div", { className: "w-3 h-3 rounded-full bg-gray-300 flex-shrink-0" }),
8223
- !isLast && /* @__PURE__ */ jsx79(
8224
- "div",
8225
- {
8226
- className: `w-0.5 flex-1 mt-1 ${phase === "completed" ? "bg-green-300" : phase === "active" ? "bg-blue-400" : "border-l-2 border-dashed border-gray-200"}`
8227
- }
8228
- )
8229
- ] }),
8230
- /* @__PURE__ */ jsx79("div", { className: `flex-1 pb-6 ${isLast ? "pb-0" : ""}`, children: /* @__PURE__ */ jsxs31(
8231
- "div",
8232
- {
8233
- className: `rounded-lg p-4 ${phase === "completed" ? "bg-white border border-gray-100" : phase === "active" ? "bg-white border-l-4 border-l-blue-500 border border-gray-100 shadow-sm" : "bg-gray-50 border border-gray-100 opacity-60"}`,
8234
- children: [
8235
- /* @__PURE__ */ jsxs31("div", { className: "flex items-center justify-between", children: [
8236
- /* @__PURE__ */ jsx79("span", { className: "text-sm font-medium text-gray-900", children: task.nodeName }),
8237
- statusMeta && /* @__PURE__ */ jsx79(
8238
- "span",
8239
- {
8240
- className: `px-2 py-0.5 rounded-full text-xs font-medium ${toneClasses2[statusMeta.tone] || toneClasses2.neutral}`,
8241
- children: statusMeta.label
8242
- }
8243
- )
8244
- ] }),
8245
- task.assigneeName && /* @__PURE__ */ jsxs31("div", { className: "mt-2 flex items-center gap-1.5 text-sm text-gray-600", children: [
8246
- /* @__PURE__ */ jsx79("span", { className: "text-gray-400", children: "\u{1F464}" }),
8247
- /* @__PURE__ */ jsxs31("span", { children: [
8248
- phase === "active" ? "\u5F53\u524D\u5BA1\u6279\u4EBA: " : "",
8249
- task.assigneeName
8250
- ] }),
8251
- task.departmentName && /* @__PURE__ */ jsxs31(Fragment2, { children: [
8252
- /* @__PURE__ */ jsx79("span", { className: "text-gray-300", children: "\xB7" }),
8253
- /* @__PURE__ */ jsx79("span", { className: "text-gray-400", children: task.departmentName })
8254
- ] })
8255
- ] }),
8256
- !compactMode && showRemarks && task.comments && /* @__PURE__ */ jsxs31("div", { className: "mt-2 bg-gray-50 rounded-md p-3 text-sm text-gray-600 italic", children: [
8257
- "\u{1F4AC} \u201C",
8258
- task.comments,
8259
- "\u201D"
8260
- ] }),
8261
- !compactMode && phase === "active" && !task.comments && /* @__PURE__ */ jsx79("div", { className: "mt-2 text-xs text-gray-400", children: "\u23F3 \u7B49\u5F85\u5904\u7406\u4E2D..." }),
8262
- !compactMode && (task.actionAt || task.createdAt) && /* @__PURE__ */ jsxs31("div", { className: "mt-2 text-xs text-gray-400", children: [
8263
- "\u{1F550} ",
8264
- task.actionAt || task.createdAt
8265
- ] }),
8266
- compactMode && (task.actionAt || task.createdAt) && /* @__PURE__ */ jsx79("div", { className: "mt-1 text-xs text-gray-400", children: task.actionAt || task.createdAt })
8267
- ]
8268
- }
8269
- ) })
8270
- ] }, taskKey);
8839
+ if (renderNode) {
8840
+ return /* @__PURE__ */ jsx80("div", { className, children: taskList.map((task, index) => /* @__PURE__ */ jsx80("div", { children: renderNode(task, index) }, task.taskId || task.id || index)) });
8841
+ }
8842
+ return /* @__PURE__ */ jsx80("div", { className: `approval-timeline ${className}`, children: groups.map((group, index) => {
8843
+ const node = group[0];
8844
+ const isLast = index === groups.length - 1;
8845
+ const isFutureGroup = group.some((task) => task.isSimulated || task.status === "simulated");
8846
+ const compact = compactMode || isCompactNode(node);
8847
+ const state = getVisualState(node, isFutureGroup);
8848
+ const statusMeta = getStatusMeta(node, state, compact);
8849
+ const title = getNodeTitle(node);
8850
+ const time = node.actionAt || node.createdAt;
8851
+ return /* @__PURE__ */ jsxs32(
8852
+ "div",
8853
+ {
8854
+ className: `relative flex gap-4 pb-5 ${isLast ? "pb-0" : ""}`,
8855
+ children: [
8856
+ !isLast && /* @__PURE__ */ jsx80(
8857
+ "div",
8858
+ {
8859
+ className: `absolute bottom-0 left-[21px] top-11 w-px ${state === "future" ? "border-l border-dashed border-gray-300" : "bg-ant-border-secondary"}`
8860
+ }
8861
+ ),
8862
+ /* @__PURE__ */ jsx80(
8863
+ "div",
8864
+ {
8865
+ className: `relative z-10 flex h-11 w-11 shrink-0 items-center justify-center rounded-full border-2 shadow-[0_0_0_4px_var(--ant-color-bg-layout,#f5f5f5)] ${getDotClass(state)}`,
8866
+ children: getIcon(node, state)
8867
+ }
8868
+ ),
8869
+ /* @__PURE__ */ jsx80("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxs32(
8870
+ "div",
8871
+ {
8872
+ className: `rounded-lg border p-4 ${state === "current" ? "border-blue-300 bg-blue-50/60" : state === "future" ? "border-dashed border-gray-200 bg-gray-50/70" : "border-ant-border-secondary bg-ant-bg-container"}`,
8873
+ children: [
8874
+ /* @__PURE__ */ jsxs32("div", { className: "flex flex-wrap items-start justify-between gap-2", children: [
8875
+ /* @__PURE__ */ jsxs32("div", { className: "flex min-w-0 flex-wrap items-center gap-2", children: [
8876
+ /* @__PURE__ */ jsx80("span", { className: "font-medium text-ant-text", children: title }),
8877
+ /* @__PURE__ */ jsx80(
8878
+ "span",
8879
+ {
8880
+ className: `inline-flex min-h-6 items-center rounded-md border px-2 text-xs font-medium ${state === "future" ? toneClasses2.future : toneClasses2[statusMeta.tone]}`,
8881
+ children: statusMeta.label
8882
+ }
8883
+ ),
8884
+ node.nodeType === "originator_return" && /* @__PURE__ */ jsx80("span", { className: "rounded-md bg-amber-50 px-2 py-1 text-xs text-amber-700", children: "\u53D1\u8D77\u4EBA\u64CD\u4F5C" })
8885
+ ] }),
8886
+ !isFutureGroup && time && /* @__PURE__ */ jsx80("span", { className: "text-xs text-ant-text-tertiary", children: time })
8887
+ ] }),
8888
+ showApproverInfo && !compact && group.length > 0 && /* @__PURE__ */ jsxs32("div", { className: "mt-3 flex flex-wrap gap-3", children: [
8889
+ /* @__PURE__ */ jsx80("span", { className: "w-full text-xs font-medium text-ant-text-tertiary", children: state === "current" || state === "waiting" ? "\u5F53\u524D\u5BA1\u6279\u4EBA" : "\u5904\u7406\u4EBA" }),
8890
+ group.map((assignee) => /* @__PURE__ */ jsxs32(
8891
+ "span",
8892
+ {
8893
+ className: "inline-flex min-w-0 items-center gap-2",
8894
+ children: [
8895
+ /* @__PURE__ */ jsx80("span", { className: "inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-blue-50 text-xs font-semibold text-blue-700", children: assignee.assigneeName?.slice(0, 1) || "?" }),
8896
+ /* @__PURE__ */ jsxs32("span", { className: "min-w-0", children: [
8897
+ /* @__PURE__ */ jsx80("span", { className: "block text-sm font-medium text-ant-text", children: assignee.assigneeName || "\u7CFB\u7EDF" }),
8898
+ /* @__PURE__ */ jsx80("span", { className: "block text-xs text-ant-text-tertiary", children: assignee.departmentName || assignee.actionAt || assignee.createdAt || "" })
8899
+ ] })
8900
+ ]
8901
+ },
8902
+ assignee.taskId || assignee.id
8903
+ ))
8904
+ ] }),
8905
+ showApproverInfo && compact && /* @__PURE__ */ jsx80("div", { className: "mt-2 text-sm text-ant-text-secondary", children: group.map((item) => item.assigneeName).filter(Boolean).join("\u3001") || (node.nodeType === "start" ? "\u63D0\u4EA4\u7533\u8BF7" : systemNodeTypes.has(node.nodeType) ? node.comments || "\u7CFB\u7EDF\u81EA\u52A8\u5904\u7406" : "") }),
8906
+ showRemarks && node.comments && /* @__PURE__ */ jsx80(
8907
+ "div",
8908
+ {
8909
+ className: `mt-3 border-l-2 pl-3 text-sm leading-6 ${state === "rejected" ? "border-red-300 text-red-700" : state === "returned" ? "border-amber-300 text-amber-700" : "border-ant-border-secondary text-ant-text-secondary"}`,
8910
+ children: node.comments
8911
+ }
8912
+ )
8913
+ ]
8914
+ }
8915
+ ) })
8916
+ ]
8917
+ },
8918
+ node.nodeVisitId || `${node.nodeId}-${node.taskId}-${index}`
8919
+ );
8271
8920
  }) });
8272
8921
  };
8273
8922
 
8274
- // src/modules/ApprovalActions.tsx
8275
- import { useState as useState31 } from "react";
8276
- import { Button as Button9, Drawer as Drawer2, Input as Input10, Dropdown } from "antd";
8277
- import { MoreOutlined, LoadingOutlined } from "@ant-design/icons";
8278
- import { Fragment as Fragment3, jsx as jsx80, jsxs as jsxs32 } from "react/jsx-runtime";
8279
- var { TextArea: TextArea3 } = Input10;
8280
- var ApprovalActions = ({
8923
+ // src/modules/ApprovalActionBar.tsx
8924
+ import { useMemo as useMemo16, useState as useState32 } from "react";
8925
+ import { Form, Input as Input10, Modal as Modal6, Select as Select5 } from "antd";
8926
+ import {
8927
+ CheckOutlined,
8928
+ CloseOutlined,
8929
+ RollbackOutlined as RollbackOutlined2,
8930
+ SaveOutlined,
8931
+ SwapOutlined
8932
+ } from "@ant-design/icons";
8933
+
8934
+ // src/modules/StickyActionBar.tsx
8935
+ import { useEffect as useEffect35, useMemo as useMemo15, useState as useState31 } from "react";
8936
+ import { Button as Button10, Dropdown, Modal as Modal5 } from "antd";
8937
+ import { MoreOutlined } from "@ant-design/icons";
8938
+ import { Fragment as Fragment2, jsx as jsx81, jsxs as jsxs33 } from "react/jsx-runtime";
8939
+ var getActionPriority = (action) => {
8940
+ const maybePriority = action.priority;
8941
+ if (typeof maybePriority === "number") return maybePriority;
8942
+ if (action.type === "primary") return 10;
8943
+ if (action.type === "danger") return 90;
8944
+ return 50;
8945
+ };
8946
+ var getPlacement = (action) => action.placement;
8947
+ var StickyActionBar = ({
8948
+ actions,
8949
+ className = "",
8950
+ maxMobileButtons = 2,
8951
+ layoutMode = "default",
8952
+ inDrawer = false,
8953
+ maxWidth = 1120
8954
+ }) => {
8955
+ const [isMobile, setIsMobile] = useState31(false);
8956
+ useEffect35(() => {
8957
+ const update = () => setIsMobile(typeof window !== "undefined" && window.innerWidth <= 768);
8958
+ update();
8959
+ window.addEventListener("resize", update);
8960
+ return () => window.removeEventListener("resize", update);
8961
+ }, []);
8962
+ const visibleActions = useMemo15(
8963
+ () => actions.filter((action) => action.visible !== false).sort((left, right) => getActionPriority(left) - getActionPriority(right)),
8964
+ [actions]
8965
+ );
8966
+ if (visibleActions.length === 0) return null;
8967
+ const maxWidthStyle = typeof maxWidth === "number" ? `${maxWidth}px` : maxWidth;
8968
+ const primaryMobile = visibleActions.slice(0, maxMobileButtons);
8969
+ const moreMobile = visibleActions.slice(maxMobileButtons);
8970
+ const leftActions = visibleActions.filter((action) => getPlacement(action) === "left");
8971
+ const rightActions = visibleActions.filter((action) => getPlacement(action) !== "left");
8972
+ const renderButton = (action, mobile = false) => /* @__PURE__ */ jsx81(
8973
+ Button10,
8974
+ {
8975
+ type: action.type === "danger" ? "primary" : action.type === "text" ? "text" : action.type || "default",
8976
+ danger: action.type === "danger",
8977
+ loading: action.loading,
8978
+ disabled: action.disabled,
8979
+ icon: action.icon,
8980
+ onClick: () => {
8981
+ if (action.confirm) {
8982
+ Modal5.confirm({
8983
+ title: action.confirm.title,
8984
+ content: action.confirm.content,
8985
+ okText: action.confirm.okText || "\u786E\u8BA4",
8986
+ cancelText: action.confirm.cancelText || "\u53D6\u6D88",
8987
+ onOk: action.onClick
8988
+ });
8989
+ return;
8990
+ }
8991
+ action.onClick();
8992
+ },
8993
+ className: `${mobile ? "min-w-0 flex-1" : "min-w-[88px]"} rounded-md`,
8994
+ children: action.label
8995
+ },
8996
+ action.key
8997
+ );
8998
+ return /* @__PURE__ */ jsx81(
8999
+ "div",
9000
+ {
9001
+ className: `fixed bottom-0 left-0 right-0 z-50 border-t border-ant-border-secondary bg-ant-bg-container/95 px-4 py-3 shadow-[0_-8px_24px_rgba(15,23,42,0.06)] backdrop-blur supports-[padding:max(0px)]:pb-[max(0.75rem,env(safe-area-inset-bottom))] ${inDrawer ? "absolute" : ""} ${className}`,
9002
+ children: /* @__PURE__ */ jsx81(
9003
+ "div",
9004
+ {
9005
+ className: `mx-auto flex w-full items-center gap-3 ${layoutMode === "approval" && !isMobile ? "justify-between" : "justify-end"}`,
9006
+ style: { maxWidth: maxWidthStyle },
9007
+ children: isMobile ? /* @__PURE__ */ jsxs33(Fragment2, { children: [
9008
+ /* @__PURE__ */ jsx81("div", { className: "flex flex-1 gap-2", children: primaryMobile.map((action) => renderButton(action, true)) }),
9009
+ moreMobile.length > 0 && /* @__PURE__ */ jsx81(
9010
+ Dropdown,
9011
+ {
9012
+ trigger: ["click"],
9013
+ placement: "topRight",
9014
+ menu: {
9015
+ items: moreMobile.map((action) => ({
9016
+ key: action.key,
9017
+ label: action.label,
9018
+ danger: action.type === "danger",
9019
+ disabled: action.disabled,
9020
+ icon: action.icon,
9021
+ onClick: () => {
9022
+ if (action.confirm) {
9023
+ Modal5.confirm({
9024
+ title: action.confirm.title,
9025
+ content: action.confirm.content,
9026
+ okText: action.confirm.okText || "\u786E\u8BA4",
9027
+ cancelText: action.confirm.cancelText || "\u53D6\u6D88",
9028
+ onOk: action.onClick
9029
+ });
9030
+ return;
9031
+ }
9032
+ action.onClick();
9033
+ }
9034
+ }))
9035
+ },
9036
+ children: /* @__PURE__ */ jsx81(Button10, { icon: /* @__PURE__ */ jsx81(MoreOutlined, {}), className: "rounded-md", children: "\u66F4\u591A" })
9037
+ }
9038
+ )
9039
+ ] }) : layoutMode === "approval" && leftActions.length > 0 ? /* @__PURE__ */ jsxs33(Fragment2, { children: [
9040
+ /* @__PURE__ */ jsx81("div", { className: "flex flex-wrap items-center gap-3", children: leftActions.map((action) => renderButton(action)) }),
9041
+ /* @__PURE__ */ jsx81("div", { className: "flex flex-wrap items-center justify-end gap-3", children: rightActions.map((action) => renderButton(action)) })
9042
+ ] }) : /* @__PURE__ */ jsx81("div", { className: "flex flex-wrap items-center justify-end gap-3", children: visibleActions.map((action) => renderButton(action)) })
9043
+ }
9044
+ )
9045
+ }
9046
+ );
9047
+ };
9048
+
9049
+ // src/modules/ApprovalActionBar.tsx
9050
+ import { Fragment as Fragment3, jsx as jsx82, jsxs as jsxs34 } from "react/jsx-runtime";
9051
+ var actionPriority = {
9052
+ agree: 10,
9053
+ approved: 10,
9054
+ return: 20,
9055
+ transfer: 30,
9056
+ resubmit: 40,
9057
+ save: 80,
9058
+ withdraw: 90,
9059
+ rejected: 100,
9060
+ reject: 100
9061
+ };
9062
+ function getActionLabel(action) {
9063
+ return action.name?.zh_CN || action.text?.zh_CN || action.action;
9064
+ }
9065
+ function normalizeAction(action) {
9066
+ if (action === "approved") return "agree";
9067
+ if (action === "reject") return "rejected";
9068
+ if (action === "agree" || action === "rejected" || action === "withdraw" || action === "transfer" || action === "return" || action === "resubmit") {
9069
+ return action;
9070
+ }
9071
+ if (action === "save" || action === "callback") return action;
9072
+ return "agree";
9073
+ }
9074
+ function getModalTitle(action) {
9075
+ switch (action) {
9076
+ case "agree":
9077
+ return "\u5BA1\u6279\u610F\u89C1";
9078
+ case "rejected":
9079
+ return "\u62D2\u7EDD\u7406\u7531";
9080
+ case "withdraw":
9081
+ return "\u64A4\u9500\u6D41\u7A0B";
9082
+ case "transfer":
9083
+ return "\u8F6C\u4EA4\u4EFB\u52A1";
9084
+ case "return":
9085
+ return "\u9000\u56DE\u4EFB\u52A1";
9086
+ case "resubmit":
9087
+ return "\u91CD\u65B0\u63D0\u4EA4";
9088
+ default:
9089
+ return "\u786E\u8BA4\u64CD\u4F5C";
9090
+ }
9091
+ }
9092
+ var ApprovalActionBar = ({
8281
9093
  actions,
8282
9094
  onApprove,
8283
9095
  onReject,
@@ -8285,171 +9097,335 @@ var ApprovalActions = ({
8285
9097
  onReturn,
8286
9098
  onWithdraw,
8287
9099
  onSave,
8288
- layout = "horizontal",
8289
- maxVisible = 3,
8290
- className = ""
9100
+ onResubmit,
9101
+ onCallback,
9102
+ returnableNodes = [],
9103
+ onLoadReturnableNodes,
9104
+ renderTransferSelector,
9105
+ renderReturnNodeLabel,
9106
+ renderActionModalExtra,
9107
+ maxMobileButtons = 2,
9108
+ className = "",
9109
+ inDrawer = false
8291
9110
  }) => {
8292
- const [drawerAction, setDrawerAction] = useState31(null);
8293
- const [comments, setComments] = useState31("");
8294
- const [loading, setLoading] = useState31(false);
8295
- const [saveLoading, setSaveLoading] = useState31(false);
8296
- const handleOpenDrawer = (action) => {
8297
- setComments("");
8298
- setDrawerAction(action);
9111
+ const [form] = Form.useForm();
9112
+ const [modalAction, setModalAction] = useState32(null);
9113
+ const [activeAction, setActiveAction] = useState32(null);
9114
+ const [loading, setLoading] = useState32(false);
9115
+ const visibleActions = useMemo16(
9116
+ () => actions.filter((action) => !action.hidden).sort((a, b) => (actionPriority[a.action] ?? 50) - (actionPriority[b.action] ?? 50)),
9117
+ [actions]
9118
+ );
9119
+ const openModal = async (action, target) => {
9120
+ setActiveAction(action);
9121
+ const defaultComments = action.remark?.content?.zh_CN;
9122
+ form.setFieldsValue({
9123
+ comments: defaultComments || "",
9124
+ reason: "",
9125
+ userId: void 0,
9126
+ nodeId: void 0
9127
+ });
9128
+ if (target === "return") await onLoadReturnableNodes?.();
9129
+ setModalAction(target);
8299
9130
  };
8300
- const handleConfirm = async () => {
9131
+ const executeDirect = async (action) => {
9132
+ const normalized = normalizeAction(action.action);
9133
+ if (normalized === "save") {
9134
+ await onSave?.();
9135
+ return;
9136
+ }
9137
+ if (normalized === "callback") {
9138
+ await onCallback?.();
9139
+ return;
9140
+ }
9141
+ if (normalized === "agree") {
9142
+ await onApprove?.();
9143
+ }
9144
+ };
9145
+ const handleActionClick = async (action) => {
9146
+ const normalized = normalizeAction(action.action);
9147
+ if (normalized === "save" || normalized === "callback") {
9148
+ await executeDirect(action);
9149
+ return;
9150
+ }
9151
+ await openModal(action, normalized);
9152
+ };
9153
+ const handleOk = async () => {
9154
+ if (!modalAction) return;
9155
+ const values = await form.validateFields();
8301
9156
  setLoading(true);
8302
9157
  try {
8303
- if (drawerAction === "approve" && onApprove) {
8304
- await onApprove(comments || void 0);
8305
- } else if (drawerAction === "reject" && onReject) {
8306
- await onReject(comments || void 0);
8307
- } else if (drawerAction === "withdraw" && onWithdraw) {
8308
- await onWithdraw(comments || void 0);
8309
- }
8310
- setDrawerAction(null);
9158
+ if (modalAction === "agree") await onApprove?.(values.comments || void 0);
9159
+ if (modalAction === "rejected") await onReject?.(values.comments || void 0);
9160
+ if (modalAction === "withdraw")
9161
+ await onWithdraw?.(values.reason || values.comments || void 0);
9162
+ if (modalAction === "transfer") await onTransfer?.(values.userId, values.reason || void 0);
9163
+ if (modalAction === "return") await onReturn?.(values.nodeId, values.reason || void 0);
9164
+ if (modalAction === "resubmit") await onResubmit?.(values.comments || void 0);
9165
+ setModalAction(null);
9166
+ setActiveAction(null);
9167
+ form.resetFields();
8311
9168
  } finally {
8312
9169
  setLoading(false);
8313
9170
  }
8314
9171
  };
9172
+ const actionConfigs = visibleActions.map((action) => {
9173
+ const normalized = normalizeAction(action.action);
9174
+ const danger = normalized === "rejected" || normalized === "withdraw";
9175
+ return {
9176
+ key: action.action,
9177
+ label: getActionLabel(action),
9178
+ type: normalized === "agree" ? "primary" : danger ? "danger" : "default",
9179
+ icon: normalized === "agree" ? /* @__PURE__ */ jsx82(CheckOutlined, {}) : normalized === "rejected" ? /* @__PURE__ */ jsx82(CloseOutlined, {}) : normalized === "transfer" ? /* @__PURE__ */ jsx82(SwapOutlined, {}) : normalized === "return" || normalized === "withdraw" ? /* @__PURE__ */ jsx82(RollbackOutlined2, {}) : normalized === "save" ? /* @__PURE__ */ jsx82(SaveOutlined, {}) : void 0,
9180
+ onClick: () => handleActionClick(action),
9181
+ placement: danger || normalized === "save" ? "right" : "left",
9182
+ priority: actionPriority[action.action] ?? 50
9183
+ };
9184
+ });
9185
+ const requiredComment = activeAction?.remark?.required || modalAction === "rejected" || modalAction === "withdraw";
9186
+ return /* @__PURE__ */ jsxs34(Fragment3, { children: [
9187
+ /* @__PURE__ */ jsx82(
9188
+ StickyActionBar,
9189
+ {
9190
+ actions: actionConfigs,
9191
+ layoutMode: "approval",
9192
+ maxMobileButtons,
9193
+ className,
9194
+ inDrawer
9195
+ }
9196
+ ),
9197
+ /* @__PURE__ */ jsx82(
9198
+ Modal6,
9199
+ {
9200
+ title: getModalTitle(modalAction),
9201
+ open: modalAction !== null,
9202
+ okText: "\u786E\u8BA4",
9203
+ cancelText: "\u53D6\u6D88",
9204
+ confirmLoading: loading,
9205
+ onOk: handleOk,
9206
+ onCancel: () => {
9207
+ setModalAction(null);
9208
+ setActiveAction(null);
9209
+ form.resetFields();
9210
+ },
9211
+ destroyOnClose: true,
9212
+ children: /* @__PURE__ */ jsxs34(Form, { form, layout: "vertical", children: [
9213
+ modalAction === "transfer" && /* @__PURE__ */ jsx82(
9214
+ Form.Item,
9215
+ {
9216
+ name: "userId",
9217
+ label: "\u8F6C\u4EA4\u7ED9",
9218
+ rules: [{ required: true, message: "\u8BF7\u9009\u62E9\u8F6C\u4EA4\u7528\u6237" }],
9219
+ children: renderTransferSelector ? renderTransferSelector({
9220
+ value: form.getFieldValue("userId"),
9221
+ onChange: (userId) => form.setFieldsValue({ userId })
9222
+ }) : /* @__PURE__ */ jsx82(Input10, { placeholder: "\u8BF7\u8F93\u5165\u7528\u6237 ID" })
9223
+ }
9224
+ ),
9225
+ modalAction === "return" && /* @__PURE__ */ jsx82(
9226
+ Form.Item,
9227
+ {
9228
+ name: "nodeId",
9229
+ label: "\u9000\u56DE\u5230\u8282\u70B9",
9230
+ rules: [{ required: true, message: "\u8BF7\u9009\u62E9\u9000\u56DE\u8282\u70B9" }],
9231
+ children: /* @__PURE__ */ jsx82(
9232
+ Select5,
9233
+ {
9234
+ placeholder: "\u8BF7\u9009\u62E9\u9000\u56DE\u8282\u70B9",
9235
+ options: returnableNodes.map((node) => ({
9236
+ value: node.nodeId || node.id || "",
9237
+ label: renderReturnNodeLabel ? renderReturnNodeLabel(node) : node.nodeName || node.name || node.nodeId || node.id
9238
+ }))
9239
+ }
9240
+ )
9241
+ }
9242
+ ),
9243
+ /* @__PURE__ */ jsx82(
9244
+ Form.Item,
9245
+ {
9246
+ name: modalAction === "withdraw" || modalAction === "transfer" || modalAction === "return" ? "reason" : "comments",
9247
+ label: modalAction === "withdraw" ? "\u64A4\u9500\u539F\u56E0" : modalAction === "transfer" ? "\u8F6C\u4EA4\u539F\u56E0" : modalAction === "return" ? "\u9000\u56DE\u539F\u56E0" : "\u5BA1\u6279\u610F\u89C1",
9248
+ rules: [{ required: requiredComment, message: "\u8BF7\u586B\u5199\u8BF4\u660E" }],
9249
+ children: /* @__PURE__ */ jsx82(Input10.TextArea, { rows: 4, maxLength: 500, showCount: true, placeholder: "\u8BF7\u8F93\u5165\u8BF4\u660E" })
9250
+ }
9251
+ ),
9252
+ activeAction && renderActionModalExtra?.(activeAction)
9253
+ ] })
9254
+ }
9255
+ )
9256
+ ] });
9257
+ };
9258
+
9259
+ // src/modules/ApprovalActions.tsx
9260
+ import { useMemo as useMemo17, useState as useState33 } from "react";
9261
+ import { Button as Button11, Dropdown as Dropdown2, Form as Form2, Input as Input11, Modal as Modal7 } from "antd";
9262
+ import { MoreOutlined as MoreOutlined2 } from "@ant-design/icons";
9263
+ import { Fragment as Fragment4, jsx as jsx83, jsxs as jsxs35 } from "react/jsx-runtime";
9264
+ var priority = {
9265
+ agree: 10,
9266
+ approved: 10,
9267
+ transfer: 20,
9268
+ return: 30,
9269
+ save: 40,
9270
+ withdraw: 90,
9271
+ rejected: 100,
9272
+ reject: 100
9273
+ };
9274
+ var getLabel = (action) => action.name?.zh_CN || action.text?.zh_CN || action.action;
9275
+ var ApprovalActions = ({
9276
+ actions,
9277
+ onApprove,
9278
+ onReject,
9279
+ onTransfer,
9280
+ onReturn,
9281
+ onWithdraw,
9282
+ onSave,
9283
+ layout = "horizontal",
9284
+ maxVisible = 3,
9285
+ className = ""
9286
+ }) => {
9287
+ const [form] = Form2.useForm();
9288
+ const [modalAction, setModalAction] = useState33(null);
9289
+ const [activeAction, setActiveAction] = useState33(null);
9290
+ const [loading, setLoading] = useState33(false);
9291
+ const [saveLoading, setSaveLoading] = useState33(false);
9292
+ const renderableActions = useMemo17(
9293
+ () => actions.filter((action) => !action.hidden).sort((a, b) => (priority[a.action] ?? 50) - (priority[b.action] ?? 50)),
9294
+ [actions]
9295
+ );
9296
+ const openModal = (target, action) => {
9297
+ setActiveAction(action);
9298
+ form.setFieldsValue({ comments: action.remark?.content?.zh_CN || "" });
9299
+ setModalAction(target);
9300
+ };
8315
9301
  const handleSave = async () => {
8316
- if (!onSave) return;
8317
9302
  setSaveLoading(true);
8318
9303
  try {
8319
- await onSave();
9304
+ await onSave?.();
8320
9305
  } finally {
8321
9306
  setSaveLoading(false);
8322
9307
  }
8323
9308
  };
8324
- const actionMap = {};
8325
- actions.forEach((action) => {
8326
- switch (action.action) {
8327
- case "agree":
8328
- actionMap["agree"] = {
8329
- label: action.name.zh_CN || "\u540C\u610F",
8330
- handler: () => handleOpenDrawer("approve"),
8331
- type: "primary",
8332
- color: "green"
8333
- };
8334
- break;
8335
- case "rejected":
8336
- actionMap["rejected"] = {
8337
- label: action.name.zh_CN || "\u62D2\u7EDD",
8338
- handler: () => handleOpenDrawer("reject"),
8339
- type: "default"
8340
- };
8341
- break;
8342
- case "transfer":
8343
- actionMap["transfer"] = {
8344
- label: action.name.zh_CN || "\u8F6C\u4EA4",
8345
- handler: () => onTransfer?.(),
8346
- type: "default"
8347
- };
8348
- break;
8349
- case "return":
8350
- actionMap["return"] = {
8351
- label: action.name.zh_CN || "\u9000\u56DE",
8352
- handler: () => onReturn?.(),
8353
- type: "default"
8354
- };
8355
- break;
8356
- case "withdraw":
8357
- actionMap["withdraw"] = {
8358
- label: action.name.zh_CN || "\u64A4\u9500",
8359
- handler: () => handleOpenDrawer("withdraw"),
8360
- type: "default"
8361
- };
8362
- break;
8363
- case "save":
8364
- actionMap["save"] = {
8365
- label: action.name.zh_CN || "\u6682\u5B58",
8366
- handler: handleSave,
8367
- type: "default"
8368
- };
8369
- break;
9309
+ const handleAction = (action) => {
9310
+ if (action.action === "transfer") {
9311
+ onTransfer?.();
9312
+ return;
8370
9313
  }
8371
- });
8372
- const allButtons = Object.entries(actionMap);
8373
- const visibleButtons = allButtons.slice(0, maxVisible);
8374
- const moreButtons = allButtons.slice(maxVisible);
8375
- const drawerTitle = drawerAction === "approve" ? "\u5BA1\u6279\u610F\u89C1" : drawerAction === "reject" ? "\u62D2\u7EDD\u7406\u7531" : drawerAction === "withdraw" ? "\u64A4\u9500\u539F\u56E0" : "\u5BA1\u6279\u610F\u89C1";
8376
- return /* @__PURE__ */ jsxs32(Fragment3, { children: [
8377
- /* @__PURE__ */ jsxs32(
9314
+ if (action.action === "return") {
9315
+ onReturn?.();
9316
+ return;
9317
+ }
9318
+ if (action.action === "save") {
9319
+ void handleSave();
9320
+ return;
9321
+ }
9322
+ if (action.action === "withdraw") {
9323
+ openModal("withdraw", action);
9324
+ return;
9325
+ }
9326
+ if (action.action === "rejected" || action.action === "reject") {
9327
+ openModal("reject", action);
9328
+ return;
9329
+ }
9330
+ openModal("approve", action);
9331
+ };
9332
+ const handleConfirm = async () => {
9333
+ const values = await form.validateFields();
9334
+ setLoading(true);
9335
+ try {
9336
+ if (modalAction === "approve") await onApprove?.(values.comments || void 0);
9337
+ if (modalAction === "reject") await onReject?.(values.comments || void 0);
9338
+ if (modalAction === "withdraw") await onWithdraw?.(values.comments || void 0);
9339
+ setModalAction(null);
9340
+ setActiveAction(null);
9341
+ form.resetFields();
9342
+ } finally {
9343
+ setLoading(false);
9344
+ }
9345
+ };
9346
+ const visibleButtons = renderableActions.slice(0, maxVisible);
9347
+ const moreButtons = renderableActions.slice(maxVisible);
9348
+ const title = modalAction === "approve" ? "\u5BA1\u6279\u610F\u89C1" : modalAction === "reject" ? "\u62D2\u7EDD\u7406\u7531" : "\u64A4\u9500\u539F\u56E0";
9349
+ const button = (action) => /* @__PURE__ */ jsx83(
9350
+ Button11,
9351
+ {
9352
+ type: action.action === "agree" || action.action === "approved" ? "primary" : "default",
9353
+ danger: action.action === "rejected" || action.action === "reject" || action.action === "withdraw",
9354
+ onClick: () => handleAction(action),
9355
+ loading: action.action === "save" && saveLoading,
9356
+ children: getLabel(action)
9357
+ },
9358
+ action.action
9359
+ );
9360
+ return /* @__PURE__ */ jsxs35(Fragment4, { children: [
9361
+ /* @__PURE__ */ jsxs35(
8378
9362
  "div",
8379
9363
  {
8380
9364
  className: `${layout === "horizontal" ? "flex items-center gap-3" : "flex flex-col gap-2"} ${className}`,
8381
9365
  children: [
8382
- visibleButtons.map(([key, btn]) => /* @__PURE__ */ jsx80(
8383
- Button9,
8384
- {
8385
- type: btn.type === "primary" ? "primary" : "default",
8386
- className: btn.color === "green" ? "!bg-green-600 !border-green-600 hover:!bg-green-700" : "",
8387
- onClick: btn.handler,
8388
- loading: key === "save" && saveLoading,
8389
- children: btn.label
8390
- },
8391
- key
8392
- )),
8393
- moreButtons.length > 0 && /* @__PURE__ */ jsx80(
8394
- Dropdown,
9366
+ visibleButtons.map(button),
9367
+ moreButtons.length > 0 && /* @__PURE__ */ jsx83(
9368
+ Dropdown2,
8395
9369
  {
9370
+ trigger: ["click"],
8396
9371
  menu: {
8397
- items: moreButtons.map(([key, btn]) => ({
8398
- key,
8399
- label: btn.label,
8400
- onClick: btn.handler
9372
+ items: moreButtons.map((action) => ({
9373
+ key: action.action,
9374
+ label: getLabel(action),
9375
+ danger: action.action === "rejected" || action.action === "reject" || action.action === "withdraw",
9376
+ onClick: () => handleAction(action)
8401
9377
  }))
8402
9378
  },
8403
- trigger: ["click"],
8404
- children: /* @__PURE__ */ jsx80(Button9, { icon: /* @__PURE__ */ jsx80(MoreOutlined, {}), children: "\u66F4\u591A" })
9379
+ children: /* @__PURE__ */ jsx83(Button11, { icon: /* @__PURE__ */ jsx83(MoreOutlined2, {}), children: "\u66F4\u591A" })
8405
9380
  }
8406
9381
  )
8407
9382
  ]
8408
9383
  }
8409
9384
  ),
8410
- /* @__PURE__ */ jsx80(
8411
- Drawer2,
9385
+ /* @__PURE__ */ jsx83(
9386
+ Modal7,
8412
9387
  {
8413
- title: drawerTitle,
8414
- open: drawerAction !== null,
8415
- onClose: () => setDrawerAction(null),
8416
- width: 400,
8417
- footer: /* @__PURE__ */ jsxs32("div", { className: "flex justify-end gap-3", children: [
8418
- /* @__PURE__ */ jsx80(Button9, { onClick: () => setDrawerAction(null), children: "\u53D6\u6D88" }),
8419
- /* @__PURE__ */ jsxs32(Button9, { type: "primary", onClick: handleConfirm, loading, children: [
8420
- loading && /* @__PURE__ */ jsx80(LoadingOutlined, {}),
8421
- "\u786E\u8BA4"
8422
- ] })
8423
- ] }),
8424
- children: /* @__PURE__ */ jsx80("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs32("div", { children: [
8425
- /* @__PURE__ */ jsx80("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: drawerAction === "approve" ? "\u5BA1\u6279\u610F\u89C1\uFF08\u53EF\u9009\uFF09" : "\u8BF7\u8F93\u5165\u7406\u7531" }),
8426
- /* @__PURE__ */ jsx80(
8427
- TextArea3,
8428
- {
8429
- rows: 4,
8430
- value: comments,
8431
- onChange: (e) => setComments(e.target.value),
8432
- placeholder: drawerAction === "approve" ? "\u8BF7\u8F93\u5165\u5BA1\u6279\u610F\u89C1..." : drawerAction === "reject" ? "\u8BF7\u8F93\u5165\u62D2\u7EDD\u7406\u7531..." : "\u8BF7\u8F93\u5165\u64A4\u9500\u539F\u56E0...",
8433
- maxLength: 500,
8434
- showCount: true
8435
- }
8436
- )
8437
- ] }) })
9388
+ title,
9389
+ open: modalAction !== null,
9390
+ okText: "\u786E\u8BA4",
9391
+ cancelText: "\u53D6\u6D88",
9392
+ confirmLoading: loading,
9393
+ onOk: handleConfirm,
9394
+ onCancel: () => {
9395
+ setModalAction(null);
9396
+ setActiveAction(null);
9397
+ form.resetFields();
9398
+ },
9399
+ destroyOnClose: true,
9400
+ children: /* @__PURE__ */ jsx83(Form2, { form, layout: "vertical", children: /* @__PURE__ */ jsx83(
9401
+ Form2.Item,
9402
+ {
9403
+ name: "comments",
9404
+ label: modalAction === "approve" ? "\u5BA1\u6279\u610F\u89C1" : "\u8BF7\u8F93\u5165\u7406\u7531",
9405
+ rules: [
9406
+ {
9407
+ required: Boolean(activeAction?.remark?.required) || modalAction !== "approve",
9408
+ message: "\u8BF7\u586B\u5199\u8BF4\u660E"
9409
+ }
9410
+ ],
9411
+ children: /* @__PURE__ */ jsx83(Input11.TextArea, { rows: 4, maxLength: 500, showCount: true, placeholder: "\u8BF7\u8F93\u5165\u8BF4\u660E" })
9412
+ }
9413
+ ) })
8438
9414
  }
8439
9415
  )
8440
9416
  ] });
8441
9417
  };
8442
9418
 
8443
9419
  // src/modules/FormActionBar.tsx
8444
- import { useState as useState32 } from "react";
8445
- import { Button as Button10, Modal as Modal5 } from "antd";
8446
- import { Fragment as Fragment4, jsx as jsx81, jsxs as jsxs33 } from "react/jsx-runtime";
9420
+ import { useState as useState34 } from "react";
9421
+ import { Button as Button12, Modal as Modal8 } from "antd";
9422
+ import { Fragment as Fragment5, jsx as jsx84, jsxs as jsxs36 } from "react/jsx-runtime";
8447
9423
  var FormActionBar = ({
8448
9424
  actions,
8449
9425
  position = "bottom-fixed",
8450
9426
  className = ""
8451
9427
  }) => {
8452
- const [loadingKeys, setLoadingKeys] = useState32(/* @__PURE__ */ new Set());
9428
+ const [loadingKeys, setLoadingKeys] = useState34(/* @__PURE__ */ new Set());
8453
9429
  const visibleActions = actions.filter((a) => a.visible !== false);
8454
9430
  const sortedActions = [...visibleActions].sort((a, b) => {
8455
9431
  if (a.type === "danger" && b.type !== "danger") return -1;
@@ -8460,7 +9436,7 @@ var FormActionBar = ({
8460
9436
  });
8461
9437
  const handleClick = async (action) => {
8462
9438
  if (action.confirm) {
8463
- Modal5.confirm({
9439
+ Modal8.confirm({
8464
9440
  title: action.confirm.title,
8465
9441
  content: action.confirm.content,
8466
9442
  okText: "\u786E\u8BA4",
@@ -8486,14 +9462,14 @@ var FormActionBar = ({
8486
9462
  }
8487
9463
  };
8488
9464
  const isFixed = position === "bottom-fixed";
8489
- const bar = /* @__PURE__ */ jsx81(
9465
+ const bar = /* @__PURE__ */ jsx84(
8490
9466
  "div",
8491
9467
  {
8492
9468
  className: `${isFixed ? "fixed bottom-0 left-0 right-0 z-50 backdrop-blur-lg bg-white/80 border-t border-gray-200 shadow-[0_-1px_3px_rgba(0,0,0,0.05)] px-6 py-3" : ""} ${className}`,
8493
- children: /* @__PURE__ */ jsx81("div", { className: "flex items-center justify-end gap-3 flex-wrap md:flex-nowrap", children: sortedActions.map((action) => {
9469
+ children: /* @__PURE__ */ jsx84("div", { className: "flex items-center justify-end gap-3 flex-wrap md:flex-nowrap", children: sortedActions.map((action) => {
8494
9470
  const isLoading = action.loading || loadingKeys.has(action.key);
8495
- return /* @__PURE__ */ jsx81(
8496
- Button10,
9471
+ return /* @__PURE__ */ jsx84(
9472
+ Button12,
8497
9473
  {
8498
9474
  type: action.type === "danger" ? "primary" : action.type === "text" ? "text" : action.type || "default",
8499
9475
  danger: action.type === "danger",
@@ -8510,18 +9486,137 @@ var FormActionBar = ({
8510
9486
  }
8511
9487
  );
8512
9488
  if (isFixed) {
8513
- return /* @__PURE__ */ jsxs33(Fragment4, { children: [
9489
+ return /* @__PURE__ */ jsxs36(Fragment5, { children: [
8514
9490
  bar,
8515
- /* @__PURE__ */ jsx81("div", { className: "h-16" })
9491
+ /* @__PURE__ */ jsx84("div", { className: "h-16" })
8516
9492
  ] });
8517
9493
  }
8518
9494
  return bar;
8519
9495
  };
8520
9496
 
9497
+ // src/modules/RuntimePageShell.tsx
9498
+ import { Alert, Empty as Empty4, Spin as Spin5 } from "antd";
9499
+ import { Fragment as Fragment6, jsx as jsx85, jsxs as jsxs37 } from "react/jsx-runtime";
9500
+ var RuntimePageShell = ({
9501
+ children,
9502
+ actions,
9503
+ loading = false,
9504
+ loadingTip = "\u6B63\u5728\u52A0\u8F7D\u9875\u9762...",
9505
+ accessDenied = false,
9506
+ error,
9507
+ empty,
9508
+ className = "",
9509
+ contentClassName = "",
9510
+ maxWidth = 1120,
9511
+ inDrawer = false
9512
+ }) => {
9513
+ const maxWidthStyle = typeof maxWidth === "number" ? `${maxWidth}px` : maxWidth;
9514
+ const renderState = () => {
9515
+ if (loading) {
9516
+ return /* @__PURE__ */ jsx85("div", { className: "min-h-[360px] flex items-center justify-center", children: /* @__PURE__ */ jsx85(Spin5, { tip: loadingTip }) });
9517
+ }
9518
+ if (accessDenied) {
9519
+ return /* @__PURE__ */ jsx85(Empty4, { description: "\u65E0\u6743\u9650\u67E5\u770B\u8BE6\u60C5" });
9520
+ }
9521
+ if (error) {
9522
+ return /* @__PURE__ */ jsx85(Alert, { type: "error", showIcon: true, message: "\u9875\u9762\u52A0\u8F7D\u5931\u8D25", description: error });
9523
+ }
9524
+ if (empty) {
9525
+ return /* @__PURE__ */ jsx85(Fragment6, { children: empty });
9526
+ }
9527
+ return children;
9528
+ };
9529
+ return /* @__PURE__ */ jsxs37("div", { className: `sy-runtime-page min-h-screen bg-ant-bg-layout text-ant-text ${className}`, children: [
9530
+ /* @__PURE__ */ jsx85(
9531
+ "div",
9532
+ {
9533
+ className: `sy-runtime-page__content mx-auto w-full px-4 py-6 pb-24 md:px-6 ${inDrawer ? "py-4 md:px-4" : ""} ${contentClassName}`,
9534
+ style: { maxWidth: maxWidthStyle },
9535
+ children: renderState()
9536
+ }
9537
+ ),
9538
+ actions
9539
+ ] });
9540
+ };
9541
+
9542
+ // src/modules/SummaryPanel.tsx
9543
+ import { Avatar as Avatar2 } from "antd";
9544
+ import { ApartmentOutlined as ApartmentOutlined2, CalendarOutlined, FileTextOutlined as FileTextOutlined2 } from "@ant-design/icons";
9545
+ import { jsx as jsx86, jsxs as jsxs38 } from "react/jsx-runtime";
9546
+ var toneClasses3 = {
9547
+ brand: "bg-blue-50 text-blue-700 border-blue-200",
9548
+ success: "bg-emerald-50 text-emerald-700 border-emerald-200",
9549
+ danger: "bg-red-50 text-red-700 border-red-200",
9550
+ neutral: "bg-gray-50 text-gray-600 border-gray-200",
9551
+ warning: "bg-amber-50 text-amber-700 border-amber-200"
9552
+ };
9553
+ var SummaryPanel = ({
9554
+ title = "\u8BE6\u60C5",
9555
+ eyebrow,
9556
+ status,
9557
+ creator,
9558
+ createdAt,
9559
+ metaItems,
9560
+ className = "",
9561
+ children
9562
+ }) => {
9563
+ const defaultItems = [
9564
+ {
9565
+ key: "creator",
9566
+ label: "\u521B\u5EFA\u4EBA",
9567
+ value: creator?.name || "\u672A\u77E5\u7528\u6237",
9568
+ icon: creator?.avatar ? /* @__PURE__ */ jsx86(Avatar2, { size: 24, src: creator.avatar }) : /* @__PURE__ */ jsx86(Avatar2, { size: 24, children: creator?.name?.slice(0, 1) || "\u8868" })
9569
+ },
9570
+ {
9571
+ key: "department",
9572
+ label: "\u6240\u5C5E\u90E8\u95E8",
9573
+ value: creator?.department || "-",
9574
+ icon: /* @__PURE__ */ jsx86(ApartmentOutlined2, {})
9575
+ },
9576
+ {
9577
+ key: "createdAt",
9578
+ label: "\u521B\u5EFA\u65F6\u95F4",
9579
+ value: createdAt || "-",
9580
+ icon: /* @__PURE__ */ jsx86(CalendarOutlined, {})
9581
+ }
9582
+ ];
9583
+ const items = metaItems || defaultItems;
9584
+ return /* @__PURE__ */ jsx86(
9585
+ "section",
9586
+ {
9587
+ className: `rounded-lg border border-ant-border-secondary bg-ant-bg-container ${className}`,
9588
+ children: /* @__PURE__ */ jsxs38("div", { className: "p-5 md:p-6", children: [
9589
+ /* @__PURE__ */ jsxs38("div", { className: "mb-2 flex items-center justify-between gap-3", children: [
9590
+ /* @__PURE__ */ jsx86("div", { className: "min-w-0 text-sm text-ant-text-tertiary", children: eyebrow || /* @__PURE__ */ jsxs38("span", { className: "inline-flex items-center gap-2", children: [
9591
+ /* @__PURE__ */ jsx86(FileTextOutlined2, {}),
9592
+ "\u6570\u636E\u5B9E\u4F8B"
9593
+ ] }) }),
9594
+ status && /* @__PURE__ */ jsx86(
9595
+ "span",
9596
+ {
9597
+ className: `inline-flex min-h-6 items-center rounded-md border px-2.5 text-xs font-medium ${toneClasses3[status.tone] || toneClasses3.neutral}`,
9598
+ children: status.label
9599
+ }
9600
+ )
9601
+ ] }),
9602
+ /* @__PURE__ */ jsx86("h1", { className: "m-0 break-words text-2xl font-semibold leading-9 text-ant-text md:text-[28px]", children: title }),
9603
+ items.length > 0 && /* @__PURE__ */ jsx86("div", { className: "mt-5 grid grid-cols-1 gap-4 md:grid-cols-3", children: items.map((item) => /* @__PURE__ */ jsxs38("div", { className: "flex min-w-0 items-center gap-3", children: [
9604
+ /* @__PURE__ */ jsx86("span", { className: "inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-gray-100 text-ant-text-secondary", children: item.icon }),
9605
+ /* @__PURE__ */ jsxs38("span", { className: "min-w-0", children: [
9606
+ /* @__PURE__ */ jsx86("span", { className: "block text-xs leading-5 text-ant-text-tertiary", children: item.label }),
9607
+ /* @__PURE__ */ jsx86("span", { className: "block break-words text-sm font-medium leading-6 text-ant-text", children: item.value || "-" })
9608
+ ] })
9609
+ ] }, item.key)) }),
9610
+ children && /* @__PURE__ */ jsx86("div", { className: "mt-5", children })
9611
+ ] })
9612
+ }
9613
+ );
9614
+ };
9615
+
8521
9616
  // src/modules/DraftManager.tsx
8522
- import { Button as Button11 } from "antd";
8523
- import { EditOutlined } from "@ant-design/icons";
8524
- import { jsx as jsx82, jsxs as jsxs34 } from "react/jsx-runtime";
9617
+ import { Button as Button13 } from "antd";
9618
+ import { EditOutlined as EditOutlined2 } from "@ant-design/icons";
9619
+ import { jsx as jsx87, jsxs as jsxs39 } from "react/jsx-runtime";
8525
9620
  function formatRelativeTime(timestamp) {
8526
9621
  const now = Date.now();
8527
9622
  const diff = now - timestamp;
@@ -8542,25 +9637,25 @@ var DraftManager = ({
8542
9637
  }) => {
8543
9638
  if (!hasDraft) return null;
8544
9639
  const timeLabel = draftTimestamp ? formatRelativeTime(draftTimestamp) : null;
8545
- return /* @__PURE__ */ jsx82(
9640
+ return /* @__PURE__ */ jsx87(
8546
9641
  "div",
8547
9642
  {
8548
9643
  className: `bg-blue-50 border border-blue-200 rounded-lg p-4 animate-[slideDown_0.3s_ease-out] ${className}`,
8549
- children: /* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [
8550
- /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2 text-sm text-blue-700", children: [
8551
- /* @__PURE__ */ jsx82(EditOutlined, { className: "text-blue-500" }),
8552
- /* @__PURE__ */ jsxs34("span", { children: [
9644
+ children: /* @__PURE__ */ jsxs39("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [
9645
+ /* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-2 text-sm text-blue-700", children: [
9646
+ /* @__PURE__ */ jsx87(EditOutlined2, { className: "text-blue-500" }),
9647
+ /* @__PURE__ */ jsxs39("span", { children: [
8553
9648
  "\u68C0\u6D4B\u5230\u672A\u63D0\u4EA4\u7684\u8349\u7A3F",
8554
- timeLabel && /* @__PURE__ */ jsxs34("span", { className: "text-blue-500 ml-1", children: [
9649
+ timeLabel && /* @__PURE__ */ jsxs39("span", { className: "text-blue-500 ml-1", children: [
8555
9650
  "\uFF08\u4FDD\u5B58\u4E8E ",
8556
9651
  timeLabel,
8557
9652
  "\uFF09"
8558
9653
  ] })
8559
9654
  ] })
8560
9655
  ] }),
8561
- /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2", children: [
8562
- /* @__PURE__ */ jsx82(Button11, { type: "text", size: "small", onClick: onDiscard, className: "!text-gray-500", children: "\u4E22\u5F03" }),
8563
- /* @__PURE__ */ jsx82(Button11, { type: "primary", size: "small", onClick: onRestore, children: "\u6062\u590D\u586B\u5199" })
9656
+ /* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-2", children: [
9657
+ /* @__PURE__ */ jsx87(Button13, { type: "text", size: "small", onClick: onDiscard, className: "!text-gray-500", children: "\u4E22\u5F03" }),
9658
+ /* @__PURE__ */ jsx87(Button13, { type: "primary", size: "small", onClick: onRestore, children: "\u6062\u590D\u586B\u5199" })
8564
9659
  ] })
8565
9660
  ] })
8566
9661
  }
@@ -8568,9 +9663,9 @@ var DraftManager = ({
8568
9663
  };
8569
9664
 
8570
9665
  // src/modules/ProcessPreview.tsx
8571
- import { Modal as Modal6, Skeleton as Skeleton2, Button as Button12 } from "antd";
8572
- import { CheckCircleOutlined, UserOutlined as UserOutlined2 } from "@ant-design/icons";
8573
- import { jsx as jsx83, jsxs as jsxs35 } from "react/jsx-runtime";
9666
+ import { Modal as Modal9, Skeleton as Skeleton2, Button as Button14 } from "antd";
9667
+ import { CheckCircleOutlined, UserOutlined as UserOutlined3 } from "@ant-design/icons";
9668
+ import { jsx as jsx88, jsxs as jsxs40 } from "react/jsx-runtime";
8574
9669
  var ProcessPreview = ({
8575
9670
  open,
8576
9671
  onClose,
@@ -8578,49 +9673,1144 @@ var ProcessPreview = ({
8578
9673
  routes,
8579
9674
  loading = false
8580
9675
  }) => {
8581
- return /* @__PURE__ */ jsx83(
8582
- Modal6,
9676
+ return /* @__PURE__ */ jsx88(
9677
+ Modal9,
8583
9678
  {
8584
9679
  title: "\u6D41\u7A0B\u9884\u89C8",
8585
9680
  open,
8586
9681
  onCancel: onClose,
8587
9682
  width: 520,
8588
- footer: /* @__PURE__ */ jsxs35("div", { className: "flex justify-end gap-3", children: [
8589
- /* @__PURE__ */ jsx83(Button12, { onClick: onClose, children: "\u53D6\u6D88" }),
8590
- /* @__PURE__ */ jsx83(Button12, { type: "primary", onClick: onConfirm, loading, children: "\u786E\u8BA4\u63D0\u4EA4" })
9683
+ footer: /* @__PURE__ */ jsxs40("div", { className: "flex justify-end gap-3", children: [
9684
+ /* @__PURE__ */ jsx88(Button14, { onClick: onClose, children: "\u53D6\u6D88" }),
9685
+ /* @__PURE__ */ jsx88(Button14, { type: "primary", onClick: onConfirm, loading, children: "\u786E\u8BA4\u63D0\u4EA4" })
8591
9686
  ] }),
8592
- children: loading && routes.length === 0 ? /* @__PURE__ */ jsx83(Skeleton2, { active: true, paragraph: { rows: 4 } }) : routes.length === 0 ? /* @__PURE__ */ jsx83("p", { className: "text-sm text-gray-400 text-center py-8", children: "\u6682\u65E0\u6D41\u7A0B\u8282\u70B9" }) : /* @__PURE__ */ jsx83("div", { className: "py-2", children: routes.map((route, index) => {
9687
+ children: loading && routes.length === 0 ? /* @__PURE__ */ jsx88(Skeleton2, { active: true, paragraph: { rows: 4 } }) : routes.length === 0 ? /* @__PURE__ */ jsx88("p", { className: "text-sm text-gray-400 text-center py-8", children: "\u6682\u65E0\u6D41\u7A0B\u8282\u70B9" }) : /* @__PURE__ */ jsx88("div", { className: "py-2", children: routes.map((route, index) => {
8593
9688
  const isLast = index === routes.length - 1;
8594
- return /* @__PURE__ */ jsxs35("div", { className: "flex gap-3", children: [
8595
- /* @__PURE__ */ jsxs35("div", { className: "flex flex-col items-center", children: [
8596
- /* @__PURE__ */ jsx83("div", { className: "w-6 h-6 rounded-full bg-blue-50 border-2 border-blue-400 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx83(CheckCircleOutlined, { className: "text-blue-500 text-xs" }) }),
8597
- !isLast && /* @__PURE__ */ jsx83("div", { className: "w-0.5 flex-1 bg-blue-200 mt-1" })
9689
+ return /* @__PURE__ */ jsxs40("div", { className: "flex gap-3", children: [
9690
+ /* @__PURE__ */ jsxs40("div", { className: "flex flex-col items-center", children: [
9691
+ /* @__PURE__ */ jsx88("div", { className: "w-6 h-6 rounded-full bg-blue-50 border-2 border-blue-400 flex items-center justify-center flex-shrink-0", children: /* @__PURE__ */ jsx88(CheckCircleOutlined, { className: "text-blue-500 text-xs" }) }),
9692
+ !isLast && /* @__PURE__ */ jsx88("div", { className: "w-0.5 flex-1 bg-blue-200 mt-1" })
9693
+ ] }),
9694
+ /* @__PURE__ */ jsxs40("div", { className: `flex-1 ${isLast ? "pb-0" : "pb-5"}`, children: [
9695
+ /* @__PURE__ */ jsx88("div", { className: "text-sm font-medium text-gray-900", children: route.nodeName }),
9696
+ route.assignees && route.assignees.length > 0 && /* @__PURE__ */ jsxs40("div", { className: "mt-1 flex items-center gap-1.5 flex-wrap", children: [
9697
+ /* @__PURE__ */ jsx88(UserOutlined3, { className: "text-gray-400 text-xs" }),
9698
+ route.assignees.map((assignee) => /* @__PURE__ */ jsx88(
9699
+ "span",
9700
+ {
9701
+ className: "text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded",
9702
+ children: assignee.name
9703
+ },
9704
+ assignee.id
9705
+ ))
9706
+ ] })
9707
+ ] })
9708
+ ] }, route.nodeId);
9709
+ }) })
9710
+ }
9711
+ );
9712
+ };
9713
+
9714
+ // src/modules/DataManagementList.tsx
9715
+ import { useCallback as useCallback17, useEffect as useEffect36, useMemo as useMemo18, useRef as useRef14, useState as useState35 } from "react";
9716
+ import {
9717
+ Button as Button15,
9718
+ Checkbox as Checkbox5,
9719
+ Drawer as Drawer2,
9720
+ Dropdown as Dropdown3,
9721
+ Empty as Empty5,
9722
+ Input as Input12,
9723
+ Modal as Modal10,
9724
+ Segmented,
9725
+ Select as Select6,
9726
+ Space as Space9,
9727
+ Table as Table3,
9728
+ Tag as Tag5,
9729
+ Tooltip as Tooltip2,
9730
+ Upload as Upload3,
9731
+ message
9732
+ } from "antd";
9733
+ import {
9734
+ DeleteOutlined,
9735
+ DownloadOutlined,
9736
+ FilterOutlined,
9737
+ HistoryOutlined as HistoryOutlined2,
9738
+ ImportOutlined,
9739
+ MoreOutlined as MoreOutlined3,
9740
+ PlusOutlined,
9741
+ ReloadOutlined as ReloadOutlined3,
9742
+ SettingOutlined,
9743
+ SwapOutlined as SwapOutlined2
9744
+ } from "@ant-design/icons";
9745
+ import { jsx as jsx89, jsxs as jsxs41 } from "react/jsx-runtime";
9746
+ var createGroup = () => ({
9747
+ id: `group_${Date.now()}_${Math.random().toString(36).slice(2)}`,
9748
+ logic: "AND",
9749
+ rules: [],
9750
+ conditions: []
9751
+ });
9752
+ var createRule = (field) => ({
9753
+ id: `rule_${Date.now()}_${Math.random().toString(36).slice(2)}`,
9754
+ key: field?.fieldId || "",
9755
+ operator: "contains",
9756
+ value: "",
9757
+ componentName: field?.componentName
9758
+ });
9759
+ var getRecordId = (record) => record?.formInstanceId || record?.formInstId || record?.form_instance_id || record?.instanceId || record?.id || record?.processInstanceId;
9760
+ var getSelectedRecordId = (record, fallback) => record?.formInstId || record?.formInstanceId || record?.form_instance_id || record?.id || fallback;
9761
+ var hydrateFilterGroup = (group) => {
9762
+ if (!group) return createGroup();
9763
+ return {
9764
+ id: group.id || createGroup().id,
9765
+ logic: group.logic === "OR" ? "OR" : "AND",
9766
+ rules: Array.isArray(group.rules) ? group.rules.map((rule) => ({
9767
+ ...rule,
9768
+ id: rule.id || `rule_${Date.now()}_${Math.random().toString(36).slice(2)}`
9769
+ })) : [],
9770
+ conditions: Array.isArray(group.conditions) ? group.conditions.map(hydrateFilterGroup) : []
9771
+ };
9772
+ };
9773
+ var formatPrimitive = (value) => {
9774
+ if (value === void 0 || value === null || value === "")
9775
+ return /* @__PURE__ */ jsx89("span", { className: "text-ant-color-text-quaternary", children: "--" });
9776
+ return String(value);
9777
+ };
9778
+ var pickOptionLabel = (field, value) => {
9779
+ const options = field.options || field.optionList || field.option_list || field.componentProps?.options || [];
9780
+ const scalar = typeof value === "object" ? value?.value ?? value?.id ?? value?.label ?? value?.name : value;
9781
+ const match = Array.isArray(options) ? options.find((option) => String(option.value ?? option.id) === String(scalar)) : void 0;
9782
+ return match?.label || match?.name || value?.label || value?.name || scalar;
9783
+ };
9784
+ var renderStatusTag = (value, fieldId) => {
9785
+ const raw = String(value || "");
9786
+ const statusMap = {
9787
+ pending: { label: "\u5F85\u5904\u7406", color: "processing" },
9788
+ running: { label: "\u5BA1\u6279\u4E2D", color: "processing" },
9789
+ waiting: { label: "\u7B49\u5F85\u4E2D", color: "default" },
9790
+ exception: { label: "\u6D41\u7A0B\u5F02\u5E38", color: "error" },
9791
+ completed: { label: "\u5DF2\u5B8C\u6210", color: "success" },
9792
+ terminated: { label: "\u5DF2\u62D2\u7EDD", color: "error" },
9793
+ withdrawn: { label: "\u5DF2\u64A4\u9500", color: "default" },
9794
+ processing: { label: "\u5BA1\u6279\u4E2D", color: "processing" },
9795
+ approved: { label: "\u540C\u610F", color: "success" },
9796
+ rejected: { label: "\u62D2\u7EDD", color: "error" }
9797
+ };
9798
+ if (fieldId !== "processInstanceStatus" && fieldId !== "approvalResult") return null;
9799
+ const meta = statusMap[raw];
9800
+ return /* @__PURE__ */ jsx89(Tag5, { color: meta?.color, children: meta?.label || raw || "--" });
9801
+ };
9802
+ var renderCellValue = (value, field) => {
9803
+ const status = renderStatusTag(value, field.fieldId);
9804
+ if (status) return status;
9805
+ if (Array.isArray(value)) {
9806
+ if (value.length === 0) return formatPrimitive("");
9807
+ if (field.componentName === "ImageField") {
9808
+ return /* @__PURE__ */ jsx89("div", { className: "flex max-w-[180px] gap-1 overflow-hidden", children: value.slice(0, 3).map((item, index) => /* @__PURE__ */ jsx89(
9809
+ "img",
9810
+ {
9811
+ alt: item?.name || field.label,
9812
+ src: item?.url || item?.previewUrl,
9813
+ className: "h-8 w-8 rounded object-cover"
9814
+ },
9815
+ item?.uid || item?.id || item?.url || index
9816
+ )) });
9817
+ }
9818
+ if (field.componentName === "AttachmentField") {
9819
+ return /* @__PURE__ */ jsxs41(Space9, { size: 4, wrap: true, children: [
9820
+ value.slice(0, 3).map((item, index) => /* @__PURE__ */ jsx89(Tag5, { children: item?.name || item?.originalName || `\u9644\u4EF6${index + 1}` }, item?.uid || item?.id || index)),
9821
+ value.length > 3 && /* @__PURE__ */ jsxs41(Tag5, { children: [
9822
+ "+",
9823
+ value.length - 3
9824
+ ] })
9825
+ ] });
9826
+ }
9827
+ return /* @__PURE__ */ jsxs41(Space9, { size: 4, wrap: true, children: [
9828
+ value.slice(0, 4).map((item, index) => /* @__PURE__ */ jsx89(Tag5, { children: pickOptionLabel(field, item) }, `${field.fieldId}_${index}`)),
9829
+ value.length > 4 && /* @__PURE__ */ jsxs41(Tag5, { children: [
9830
+ "+",
9831
+ value.length - 4
9832
+ ] })
9833
+ ] });
9834
+ }
9835
+ if (value && typeof value === "object") {
9836
+ if (field.componentName === "UserSelectField" || field.componentName === "DepartmentSelectField") {
9837
+ return value.name || value.label || value.username || formatPrimitive(value.id);
9838
+ }
9839
+ if (value.start || value.end) {
9840
+ return [value.start, value.end].filter(Boolean).join(" \u81F3 ");
9841
+ }
9842
+ if (value.label || value.name || value.value) {
9843
+ return pickOptionLabel(field, value);
9844
+ }
9845
+ return /* @__PURE__ */ jsx89(Tooltip2, { title: JSON.stringify(value), children: /* @__PURE__ */ jsx89("span", { className: "text-ant-color-text-secondary", children: "\u5BF9\u8C61\u6570\u636E" }) });
9846
+ }
9847
+ if (["SelectField", "RadioField", "CheckboxField", "MultiSelectField"].includes(field.componentName)) {
9848
+ return pickOptionLabel(field, value);
9849
+ }
9850
+ return formatPrimitive(value);
9851
+ };
9852
+ var fileToBase64 = (file) => new Promise((resolve, reject) => {
9853
+ const reader = new FileReader();
9854
+ reader.onload = () => {
9855
+ const result = String(reader.result || "");
9856
+ resolve(result.includes(",") ? result.split(",")[1] : result);
9857
+ };
9858
+ reader.onerror = reject;
9859
+ reader.readAsDataURL(file);
9860
+ });
9861
+ function FilterGroupEditor({
9862
+ group,
9863
+ fields,
9864
+ onChange,
9865
+ level = 0
9866
+ }) {
9867
+ const fieldOptions = fields.map((field) => ({ label: field.label, value: field.fieldId }));
9868
+ const updateRule = (ruleId, patch) => {
9869
+ onChange({
9870
+ ...group,
9871
+ rules: group.rules.map((rule) => rule.id === ruleId ? { ...rule, ...patch } : rule)
9872
+ });
9873
+ };
9874
+ return /* @__PURE__ */ jsxs41(
9875
+ "div",
9876
+ {
9877
+ className: `${level > 0 ? "ml-4 border-l border-ant-border-secondary pl-4" : ""} space-y-3`,
9878
+ children: [
9879
+ /* @__PURE__ */ jsxs41("div", { className: "flex items-center justify-between", children: [
9880
+ /* @__PURE__ */ jsx89(
9881
+ Segmented,
9882
+ {
9883
+ size: "small",
9884
+ value: group.logic,
9885
+ options: [
9886
+ { label: "\u6EE1\u8DB3\u5168\u90E8", value: "AND" },
9887
+ { label: "\u6EE1\u8DB3\u4EFB\u4E00", value: "OR" }
9888
+ ],
9889
+ onChange: (value) => onChange({ ...group, logic: value })
9890
+ }
9891
+ ),
9892
+ /* @__PURE__ */ jsxs41(Space9, { children: [
9893
+ /* @__PURE__ */ jsx89(
9894
+ Button15,
9895
+ {
9896
+ size: "small",
9897
+ onClick: () => onChange({ ...group, rules: [...group.rules, createRule(fields[0])] }),
9898
+ children: "\u6DFB\u52A0\u6761\u4EF6"
9899
+ }
9900
+ ),
9901
+ /* @__PURE__ */ jsx89(
9902
+ Button15,
9903
+ {
9904
+ size: "small",
9905
+ onClick: () => onChange({ ...group, conditions: [...group.conditions, createGroup()] }),
9906
+ children: "\u6DFB\u52A0\u5206\u7EC4"
9907
+ }
9908
+ )
9909
+ ] })
9910
+ ] }),
9911
+ group.rules.map((rule) => /* @__PURE__ */ jsxs41(
9912
+ "div",
9913
+ {
9914
+ className: "grid grid-cols-[minmax(120px,1fr)_120px_minmax(160px,1fr)_auto] gap-2",
9915
+ children: [
9916
+ /* @__PURE__ */ jsx89(
9917
+ Select6,
9918
+ {
9919
+ showSearch: true,
9920
+ placeholder: "\u5B57\u6BB5",
9921
+ value: rule.key,
9922
+ options: fieldOptions,
9923
+ optionFilterProp: "label",
9924
+ onChange: (fieldId) => {
9925
+ const field = fields.find((item) => item.fieldId === fieldId);
9926
+ updateRule(rule.id, { key: fieldId, componentName: field?.componentName });
9927
+ }
9928
+ }
9929
+ ),
9930
+ /* @__PURE__ */ jsx89(
9931
+ Select6,
9932
+ {
9933
+ value: rule.operator,
9934
+ options: [
9935
+ { label: "\u5305\u542B", value: "contains" },
9936
+ { label: "\u7B49\u4E8E", value: "eq" },
9937
+ { label: "\u4E0D\u7B49\u4E8E", value: "ne" },
9938
+ { label: "\u5927\u4E8E", value: "gt" },
9939
+ { label: "\u5C0F\u4E8E", value: "lt" }
9940
+ ],
9941
+ onChange: (operator) => updateRule(rule.id, { operator })
9942
+ }
9943
+ ),
9944
+ /* @__PURE__ */ jsx89(
9945
+ Input12,
9946
+ {
9947
+ value: rule.value,
9948
+ placeholder: "\u8F93\u5165\u7B5B\u9009\u503C",
9949
+ onChange: (event) => updateRule(rule.id, { value: event.target.value })
9950
+ }
9951
+ ),
9952
+ /* @__PURE__ */ jsx89(
9953
+ Button15,
9954
+ {
9955
+ danger: true,
9956
+ type: "text",
9957
+ icon: /* @__PURE__ */ jsx89(DeleteOutlined, {}),
9958
+ onClick: () => onChange({ ...group, rules: group.rules.filter((item) => item.id !== rule.id) })
9959
+ }
9960
+ )
9961
+ ]
9962
+ },
9963
+ rule.id
9964
+ )),
9965
+ group.conditions.map((child) => /* @__PURE__ */ jsx89(
9966
+ FilterGroupEditor,
9967
+ {
9968
+ group: child,
9969
+ fields,
9970
+ level: level + 1,
9971
+ onChange: (next) => onChange({
9972
+ ...group,
9973
+ conditions: group.conditions.map((item) => item.id === child.id ? next : item)
9974
+ })
9975
+ },
9976
+ child.id
9977
+ )),
9978
+ group.rules.length === 0 && group.conditions.length === 0 && /* @__PURE__ */ jsx89(Empty5, { image: Empty5.PRESENTED_IMAGE_SIMPLE, description: "\u6682\u65E0\u7B5B\u9009\u6761\u4EF6" })
9979
+ ]
9980
+ }
9981
+ );
9982
+ }
9983
+ var DataManagementList = ({
9984
+ appType,
9985
+ formUuid,
9986
+ menuFormUuid,
9987
+ readonly = false,
9988
+ fullHeight = true,
9989
+ configScope = "global",
9990
+ title,
9991
+ detailRenderer,
9992
+ submitRenderer,
9993
+ requestOverride,
9994
+ rowActions = []
9995
+ }) => {
9996
+ const api = useMemo18(() => {
9997
+ if (typeof requestOverride === "function") {
9998
+ return createFormRuntimeApi({ request: requestOverride });
9999
+ }
10000
+ return createFormRuntimeApi(requestOverride);
10001
+ }, [requestOverride]);
10002
+ const [fields, setFields] = useState35([]);
10003
+ const [config, setConfig] = useState35({});
10004
+ const [showFields, setShowFields] = useState35([]);
10005
+ const [lockFieldIds, setLockFieldIds] = useState35([]);
10006
+ const [widths, setWidths] = useState35({});
10007
+ const [sort, setSort] = useState35([]);
10008
+ const [density, setDensity] = useState35("middle");
10009
+ const [detailOpenMode, setDetailOpenMode] = useState35("drawer");
10010
+ const [searchKeyWord, setSearchKeyWord] = useState35("");
10011
+ const [filterGroup, setFilterGroup] = useState35(createGroup);
10012
+ const [dataSource, setDataSource] = useState35([]);
10013
+ const [total, setTotal] = useState35(0);
10014
+ const [current, setCurrent] = useState35(1);
10015
+ const [pageSize, setPageSize] = useState35(10);
10016
+ const [loading, setLoading] = useState35(false);
10017
+ const [schemaLoading, setSchemaLoading] = useState35(true);
10018
+ const [selectedRowKeys, setSelectedRowKeys] = useState35([]);
10019
+ const [filterOpen, setFilterOpen] = useState35(false);
10020
+ const [columnOpen, setColumnOpen] = useState35(false);
10021
+ const [exportOpen, setExportOpen] = useState35(false);
10022
+ const [exportScope, setExportScope] = useState35("all");
10023
+ const [exportFields, setExportFields] = useState35([]);
10024
+ const [exporting, setExporting] = useState35(false);
10025
+ const [importOpen, setImportOpen] = useState35(false);
10026
+ const [importPreview, setImportPreview] = useState35([]);
10027
+ const [importBase64, setImportBase64] = useState35("");
10028
+ const [recordsOpen, setRecordsOpen] = useState35(false);
10029
+ const [recordTab, setRecordTab] = useState35("export");
10030
+ const [transferRecords, setTransferRecords] = useState35([]);
10031
+ const [batchApprovalOpen, setBatchApprovalOpen] = useState35(false);
10032
+ const [batchApprovalAction, setBatchApprovalAction] = useState35(
10033
+ "approved"
10034
+ );
10035
+ const [batchApprovalComments, setBatchApprovalComments] = useState35("");
10036
+ const [batchApproving, setBatchApproving] = useState35(false);
10037
+ const [activeRecord, setActiveRecord] = useState35(null);
10038
+ const [detailOpen, setDetailOpen] = useState35(false);
10039
+ const [submitOpen, setSubmitOpen] = useState35(false);
10040
+ const fetchStateRef = useRef14({});
10041
+ const request = api.request;
10042
+ const visibleFields = useMemo18(
10043
+ () => showFields.map((fieldId) => fields.find((field) => field.fieldId === fieldId)).filter(Boolean),
10044
+ [fields, showFields]
10045
+ );
10046
+ useEffect36(() => {
10047
+ fetchStateRef.current = {
10048
+ current,
10049
+ pageSize,
10050
+ searchKeyWord,
10051
+ filterGroup,
10052
+ sort
10053
+ };
10054
+ }, [current, filterGroup, pageSize, searchKeyWord, sort]);
10055
+ const loadData = useCallback17(
10056
+ async (overrides = {}) => {
10057
+ if (!appType || !formUuid) return;
10058
+ const fetchState = { ...fetchStateRef.current, ...overrides };
10059
+ const nextCurrent = fetchState.current || 1;
10060
+ const nextPageSize = fetchState.pageSize || 10;
10061
+ fetchStateRef.current = {
10062
+ ...fetchState,
10063
+ current: nextCurrent,
10064
+ pageSize: nextPageSize
10065
+ };
10066
+ setLoading(true);
10067
+ try {
10068
+ const result = await advancedSearchDataManagement(request, {
10069
+ appType,
10070
+ formUuid,
10071
+ currentPage: nextCurrent,
10072
+ pageSize: nextPageSize,
10073
+ searchKeyWord: fetchState.searchKeyWord,
10074
+ filters: fetchState.filterGroup,
10075
+ order: fetchState.sort
10076
+ });
10077
+ setDataSource(result.records);
10078
+ setTotal(result.total);
10079
+ setCurrent(nextCurrent);
10080
+ setPageSize(nextPageSize);
10081
+ } catch (error) {
10082
+ console.error("[DataManagementList] loadData failed:", error);
10083
+ message.error("\u52A0\u8F7D\u6570\u636E\u5931\u8D25");
10084
+ } finally {
10085
+ setLoading(false);
10086
+ }
10087
+ },
10088
+ [appType, formUuid, request]
10089
+ );
10090
+ useEffect36(() => {
10091
+ let mounted = true;
10092
+ const loadSchemaAndConfig = async () => {
10093
+ if (!appType || !formUuid) return;
10094
+ setSchemaLoading(true);
10095
+ setDataSource([]);
10096
+ setTotal(0);
10097
+ setSelectedRowKeys([]);
10098
+ try {
10099
+ const schemaResult = await getDataManagementSchema(request, { appType, formUuid });
10100
+ if (!mounted) return;
10101
+ const allFields = [
10102
+ ...schemaResult.fields,
10103
+ ...getSystemFieldsForFormType(schemaResult.formType)
10104
+ ];
10105
+ const saved = await getDataManagementConfig(request, {
10106
+ appType,
10107
+ formUuid,
10108
+ menuFormUuid,
10109
+ scope: configScope
10110
+ }).catch(() => void 0);
10111
+ if (!mounted) return;
10112
+ const resolved = normalizeColumnConfig(saved, allFields);
10113
+ const nextSearchKeyWord = saved?.filter?.searchKeyWord || "";
10114
+ const nextFilterGroup = hydrateFilterGroup(saved?.filter?.group);
10115
+ setFields(allFields);
10116
+ setConfig(saved || {});
10117
+ setShowFields(resolved.showFields);
10118
+ setWidths(resolved.widths);
10119
+ setLockFieldIds(resolved.lockFieldIds);
10120
+ setSort(resolved.sort);
10121
+ setDensity(resolved.density);
10122
+ setDetailOpenMode(resolved.detailOpenMode);
10123
+ setPageSize(resolved.pageSize);
10124
+ setSearchKeyWord(nextSearchKeyWord);
10125
+ setFilterGroup(nextFilterGroup);
10126
+ await loadData({
10127
+ current: 1,
10128
+ pageSize: resolved.pageSize,
10129
+ searchKeyWord: nextSearchKeyWord,
10130
+ filterGroup: nextFilterGroup,
10131
+ sort: resolved.sort
10132
+ });
10133
+ } catch (error) {
10134
+ console.error("[DataManagementList] load schema failed:", error);
10135
+ message.error("\u52A0\u8F7D\u8868\u5355\u914D\u7F6E\u5931\u8D25");
10136
+ } finally {
10137
+ if (mounted) setSchemaLoading(false);
10138
+ }
10139
+ };
10140
+ loadSchemaAndConfig();
10141
+ return () => {
10142
+ mounted = false;
10143
+ };
10144
+ }, [appType, configScope, formUuid, loadData, menuFormUuid, request]);
10145
+ const persistConfig = useCallback17(
10146
+ async (patch) => {
10147
+ const nextConfig = { ...config, ...patch };
10148
+ setConfig(nextConfig);
10149
+ await saveDataManagementConfig(request, {
10150
+ appType,
10151
+ formUuid,
10152
+ menuFormUuid,
10153
+ scope: configScope,
10154
+ config: nextConfig
10155
+ }).catch((error) => {
10156
+ console.error("[DataManagementList] save config failed:", error);
10157
+ message.warning("\u914D\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u672C\u6B21\u4EC5\u5728\u5F53\u524D\u9875\u9762\u751F\u6548");
10158
+ });
10159
+ },
10160
+ [appType, config, configScope, formUuid, menuFormUuid, request]
10161
+ );
10162
+ const handleColumnCommit = async () => {
10163
+ setColumnOpen(false);
10164
+ await persistConfig({
10165
+ showFields,
10166
+ lockFieldIds,
10167
+ widths,
10168
+ density,
10169
+ detailOpenMode,
10170
+ pageSize
10171
+ });
10172
+ };
10173
+ const handleDetail = useCallback17(
10174
+ (record) => {
10175
+ const formInstanceId = getRecordId(record);
10176
+ if (detailOpenMode === "newPage" && typeof window !== "undefined") {
10177
+ window.open(`/${appType}/forms/${formUuid}/detail/${formInstanceId}`, "_blank");
10178
+ return;
10179
+ }
10180
+ setActiveRecord(record);
10181
+ setDetailOpen(true);
10182
+ },
10183
+ [appType, detailOpenMode, formUuid]
10184
+ );
10185
+ const handleDelete = useCallback17(
10186
+ async (ids) => {
10187
+ if (ids.length === 0) return;
10188
+ await deleteDataManagementRows(request, { appType, formUuid, formInstanceIds: ids });
10189
+ setSelectedRowKeys([]);
10190
+ await loadData({ current, pageSize });
10191
+ },
10192
+ [appType, current, formUuid, loadData, pageSize, request]
10193
+ );
10194
+ const getSelectedRecordIds = useCallback17(
10195
+ () => selectedRowKeys.map((key) => {
10196
+ const record = dataSource.find((item) => String(getRecordId(item)) === String(key));
10197
+ return String(getSelectedRecordId(record, key));
10198
+ }),
10199
+ [dataSource, selectedRowKeys]
10200
+ );
10201
+ const handleBatchApprove = () => {
10202
+ if (selectedRowKeys.length === 0) return;
10203
+ setBatchApprovalOpen(true);
10204
+ };
10205
+ const handleBatchApprovalConfirm = async () => {
10206
+ const ids = getSelectedRecordIds();
10207
+ if (ids.length === 0) return;
10208
+ setBatchApproving(true);
10209
+ try {
10210
+ await batchApproveDataManagementRows(request, {
10211
+ appType,
10212
+ formUuid,
10213
+ formInstanceIds: ids,
10214
+ action: batchApprovalAction,
10215
+ comments: batchApprovalComments || void 0
10216
+ });
10217
+ message.success(`\u6279\u91CF${batchApprovalAction === "approved" ? "\u901A\u8FC7" : "\u62D2\u7EDD"}\u5DF2\u63D0\u4EA4`);
10218
+ setSelectedRowKeys([]);
10219
+ setBatchApprovalOpen(false);
10220
+ setBatchApprovalAction("approved");
10221
+ setBatchApprovalComments("");
10222
+ await loadData({ current, pageSize });
10223
+ } catch (error) {
10224
+ console.error("[DataManagementList] batch approval failed:", error);
10225
+ message.error("\u6279\u91CF\u5BA1\u6279\u5931\u8D25");
10226
+ } finally {
10227
+ setBatchApproving(false);
10228
+ }
10229
+ };
10230
+ const handleExport = async (scope) => {
10231
+ const selectedIds = scope === "selected" ? getSelectedRecordIds() : [];
10232
+ if (scope === "selected" && selectedIds.length === 0) {
10233
+ message.warning("\u8BF7\u5148\u9009\u62E9\u8981\u5BFC\u51FA\u7684\u8BB0\u5F55");
10234
+ return;
10235
+ }
10236
+ const selectedFilters = selectedIds.map((id) => ({
10237
+ key: "form_instance_id",
10238
+ operator: "EQ",
10239
+ value: id
10240
+ }));
10241
+ setExporting(true);
10242
+ try {
10243
+ await exportDataManagementRows(request, {
10244
+ appType,
10245
+ formUuid,
10246
+ currentPage: scope === "selected" ? 1 : current,
10247
+ pageSize: scope === "selected" ? selectedIds.length : pageSize,
10248
+ searchKeyWord: scope === "selected" ? void 0 : searchKeyWord,
10249
+ filters: scope === "selected" ? void 0 : filterGroup,
10250
+ rawFilters: scope === "selected" ? JSON.stringify(selectedFilters) : void 0,
10251
+ conditionType: scope === "selected" ? "OR" : void 0,
10252
+ order: sort,
10253
+ exportAll: scope === "all" ? "y" : "n",
10254
+ exportFields
10255
+ });
10256
+ message.success("\u5BFC\u51FA\u4EFB\u52A1\u5DF2\u521B\u5EFA\uFF0C\u53EF\u5728\u5BFC\u5165\u5BFC\u51FA\u8BB0\u5F55\u4E2D\u67E5\u770B");
10257
+ setExportOpen(false);
10258
+ } catch (error) {
10259
+ console.error("[DataManagementList] export failed:", error);
10260
+ message.error("\u5BFC\u51FA\u5931\u8D25");
10261
+ } finally {
10262
+ setExporting(false);
10263
+ }
10264
+ };
10265
+ const loadTransferRecords = async (type) => {
10266
+ setRecordTab(type);
10267
+ setRecordsOpen(true);
10268
+ const result = await getDataManagementTransferRecords(request, {
10269
+ appType,
10270
+ formUuid,
10271
+ type,
10272
+ currentPage: 1,
10273
+ pageSize: 10
10274
+ });
10275
+ setTransferRecords(result.records);
10276
+ };
10277
+ const handleImportPreview = async (file) => {
10278
+ const base64 = await fileToBase64(file);
10279
+ setImportBase64(base64);
10280
+ const result = await importPreviewDataManagementRows(request, {
10281
+ appType,
10282
+ formUuid,
10283
+ fileBase64: base64
10284
+ });
10285
+ const records = result?.data || result?.records || result?.list || result || [];
10286
+ setImportPreview(Array.isArray(records) ? records : []);
10287
+ return false;
10288
+ };
10289
+ const handleImportConfirm = async () => {
10290
+ if (!importBase64) return;
10291
+ await importDataManagementRows(request, { appType, formUuid, fileBase64: importBase64 });
10292
+ message.success("\u5BFC\u5165\u4EFB\u52A1\u5DF2\u521B\u5EFA");
10293
+ setImportOpen(false);
10294
+ setImportPreview([]);
10295
+ setImportBase64("");
10296
+ await loadData({ current: 1, pageSize });
10297
+ };
10298
+ const columns = useMemo18(() => {
10299
+ const baseColumns = visibleFields.map((field) => ({
10300
+ title: field.label,
10301
+ dataIndex: field.fieldId,
10302
+ key: field.fieldId,
10303
+ width: widths[field.fieldId] || field.width || 160,
10304
+ fixed: lockFieldIds.includes(field.fieldId) ? "left" : void 0,
10305
+ ellipsis: true,
10306
+ sorter: true,
10307
+ render: (value) => renderCellValue(value, field)
10308
+ })) || [];
10309
+ return [
10310
+ ...baseColumns,
10311
+ {
10312
+ title: "\u64CD\u4F5C",
10313
+ key: "__actions",
10314
+ width: 148,
10315
+ fixed: "right",
10316
+ render: (_, record) => /* @__PURE__ */ jsxs41(Space9, { size: 4, children: [
10317
+ /* @__PURE__ */ jsx89(Button15, { type: "link", size: "small", onClick: () => handleDetail(record), children: "\u8BE6\u60C5" }),
10318
+ /* @__PURE__ */ jsx89(
10319
+ Dropdown3,
10320
+ {
10321
+ trigger: ["click"],
10322
+ menu: {
10323
+ items: [
10324
+ ...rowActions.map((action) => ({
10325
+ key: action.key,
10326
+ label: action.label,
10327
+ danger: action.danger,
10328
+ onClick: () => action.onClick(record)
10329
+ })),
10330
+ {
10331
+ key: "workflow",
10332
+ label: "\u6D41\u7A0B\u65E5\u5FD7",
10333
+ icon: /* @__PURE__ */ jsx89(HistoryOutlined2, {}),
10334
+ onClick: () => message.info("\u8BF7\u901A\u8FC7 detailRenderer \u63A5\u5165\u6D41\u7A0B\u65E5\u5FD7\u6216\u6D41\u7A0B\u56FE\u5165\u53E3")
10335
+ },
10336
+ ...!readonly ? [
10337
+ {
10338
+ key: "delete",
10339
+ label: "\u5220\u9664",
10340
+ danger: true,
10341
+ icon: /* @__PURE__ */ jsx89(DeleteOutlined, {}),
10342
+ onClick: () => Modal10.confirm({
10343
+ title: "\u786E\u8BA4\u5220\u9664",
10344
+ content: "\u5220\u9664\u540E\u4E0D\u53EF\u6062\u590D\uFF0C\u786E\u8BA4\u7EE7\u7EED\u5417\uFF1F",
10345
+ onOk: () => handleDelete([String(getRecordId(record))])
10346
+ })
10347
+ }
10348
+ ] : []
10349
+ ]
10350
+ },
10351
+ children: /* @__PURE__ */ jsx89(Button15, { type: "text", size: "small", icon: /* @__PURE__ */ jsx89(MoreOutlined3, {}) })
10352
+ }
10353
+ )
10354
+ ] })
10355
+ }
10356
+ ];
10357
+ }, [handleDelete, handleDetail, lockFieldIds, readonly, rowActions, visibleFields, widths]);
10358
+ const tableSize = density === "compact" ? "small" : density === "loose" ? "large" : "middle";
10359
+ const importPreviewColumns = useMemo18(() => {
10360
+ const keys = Array.from(
10361
+ new Set(importPreview.flatMap((record) => Object.keys(record || {})))
10362
+ ).slice(0, 16);
10363
+ return keys.map((key) => {
10364
+ const field = fields.find((item) => item.fieldId === key || item.id === key);
10365
+ return {
10366
+ title: field?.label || key,
10367
+ dataIndex: key,
10368
+ key,
10369
+ width: 150,
10370
+ ellipsis: true,
10371
+ render: (value) => field ? renderCellValue(value, field) : formatPrimitive(value)
10372
+ };
10373
+ });
10374
+ }, [fields, importPreview]);
10375
+ return /* @__PURE__ */ jsxs41("div", { className: `${fullHeight ? "h-full min-h-screen" : ""} bg-ant-bg-layout`, children: [
10376
+ /* @__PURE__ */ jsxs41("div", { className: "mx-auto flex h-full max-w-[1440px] flex-col px-4 py-4 md:px-6", children: [
10377
+ /* @__PURE__ */ jsxs41("div", { className: "mb-4 flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
10378
+ /* @__PURE__ */ jsxs41("div", { children: [
10379
+ /* @__PURE__ */ jsx89("h1", { className: "text-xl font-semibold text-ant-color-text", children: title || "\u6570\u636E\u7BA1\u7406" }),
10380
+ /* @__PURE__ */ jsxs41("p", { className: "mt-1 text-sm text-ant-color-text-secondary", children: [
10381
+ "\u5171 ",
10382
+ total,
10383
+ " \u6761\u6570\u636E\uFF0C\u5DF2\u9009\u62E9 ",
10384
+ selectedRowKeys.length,
10385
+ " \u6761"
10386
+ ] })
10387
+ ] }),
10388
+ /* @__PURE__ */ jsxs41(Space9, { wrap: true, children: [
10389
+ !readonly && submitRenderer && /* @__PURE__ */ jsx89(Button15, { icon: /* @__PURE__ */ jsx89(PlusOutlined, {}), type: "primary", onClick: () => setSubmitOpen(true), children: "\u65B0\u589E" }),
10390
+ /* @__PURE__ */ jsx89(
10391
+ Input12.Search,
10392
+ {
10393
+ allowClear: true,
10394
+ className: "w-[260px]",
10395
+ placeholder: "\u641C\u7D22\u5173\u952E\u5B57",
10396
+ value: searchKeyWord,
10397
+ onChange: (event) => setSearchKeyWord(event.target.value),
10398
+ onSearch: (value) => {
10399
+ const nextSearchKeyWord = String(value || "");
10400
+ setSearchKeyWord(nextSearchKeyWord);
10401
+ persistConfig({ filter: { searchKeyWord: nextSearchKeyWord, group: filterGroup } });
10402
+ loadData({
10403
+ current: 1,
10404
+ pageSize,
10405
+ searchKeyWord: nextSearchKeyWord,
10406
+ filterGroup
10407
+ });
10408
+ }
10409
+ }
10410
+ ),
10411
+ /* @__PURE__ */ jsx89(Button15, { icon: /* @__PURE__ */ jsx89(FilterOutlined, {}), onClick: () => setFilterOpen(true), children: "\u7B5B\u9009" }),
10412
+ /* @__PURE__ */ jsx89(Button15, { icon: /* @__PURE__ */ jsx89(SettingOutlined, {}), onClick: () => setColumnOpen(true), children: "\u5217\u8BBE\u7F6E" }),
10413
+ /* @__PURE__ */ jsx89(
10414
+ Dropdown3,
10415
+ {
10416
+ menu: {
10417
+ items: [
10418
+ {
10419
+ key: "selected",
10420
+ label: "\u5BFC\u51FA\u9009\u4E2D",
10421
+ disabled: selectedRowKeys.length === 0,
10422
+ onClick: () => {
10423
+ setExportScope("selected");
10424
+ setExportFields(showFields);
10425
+ setExportOpen(true);
10426
+ }
10427
+ },
10428
+ {
10429
+ key: "all",
10430
+ label: "\u5BFC\u51FA\u5168\u90E8",
10431
+ onClick: () => {
10432
+ setExportScope("all");
10433
+ setExportFields(showFields);
10434
+ setExportOpen(true);
10435
+ }
10436
+ },
10437
+ {
10438
+ key: "records",
10439
+ label: "\u5BFC\u51FA\u8BB0\u5F55",
10440
+ onClick: () => loadTransferRecords("export")
10441
+ }
10442
+ ]
10443
+ },
10444
+ children: /* @__PURE__ */ jsx89(Button15, { icon: /* @__PURE__ */ jsx89(DownloadOutlined, {}), children: "\u5BFC\u51FA" })
10445
+ }
10446
+ ),
10447
+ !readonly && /* @__PURE__ */ jsx89(
10448
+ Dropdown3,
10449
+ {
10450
+ menu: {
10451
+ items: [
10452
+ { key: "import", label: "\u5BFC\u5165\u6570\u636E", onClick: () => setImportOpen(true) },
10453
+ {
10454
+ key: "records",
10455
+ label: "\u5BFC\u5165\u8BB0\u5F55",
10456
+ onClick: () => loadTransferRecords("import")
10457
+ }
10458
+ ]
10459
+ },
10460
+ children: /* @__PURE__ */ jsx89(Button15, { icon: /* @__PURE__ */ jsx89(ImportOutlined, {}), children: "\u5BFC\u5165" })
10461
+ }
10462
+ ),
10463
+ /* @__PURE__ */ jsx89(Button15, { icon: /* @__PURE__ */ jsx89(ReloadOutlined3, {}), onClick: () => loadData({ current, pageSize }) })
10464
+ ] })
10465
+ ] }),
10466
+ /* @__PURE__ */ jsxs41("div", { className: "relative flex-1 overflow-hidden rounded-lg border border-ant-border-secondary bg-ant-bg-container", children: [
10467
+ /* @__PURE__ */ jsx89(
10468
+ Table3,
10469
+ {
10470
+ rowKey: (record) => String(getRecordId(record)),
10471
+ loading: loading || schemaLoading,
10472
+ columns,
10473
+ dataSource,
10474
+ size: tableSize,
10475
+ scroll: {
10476
+ x: Math.max(900, visibleFields.length * 160),
10477
+ y: fullHeight ? "calc(100vh - 260px)" : void 0
10478
+ },
10479
+ rowSelection: {
10480
+ selectedRowKeys,
10481
+ onChange: setSelectedRowKeys
10482
+ },
10483
+ pagination: {
10484
+ current,
10485
+ pageSize,
10486
+ total,
10487
+ showSizeChanger: true,
10488
+ showTotal: (count) => `\u5171 ${count} \u6761`
10489
+ },
10490
+ onChange: (pagination, _filters, sorter) => {
10491
+ const sorters = Array.isArray(sorter) ? sorter : [sorter];
10492
+ const nextSort = sorters.filter((item) => item?.field && item?.order).map((item) => ({
10493
+ id: String(item.field),
10494
+ isAsc: item.order === "ascend" ? "y" : "n"
10495
+ }));
10496
+ setSort(nextSort);
10497
+ persistConfig({ sort: nextSort });
10498
+ loadData({
10499
+ current: pagination.current || 1,
10500
+ pageSize: pagination.pageSize || pageSize,
10501
+ sort: nextSort
10502
+ });
10503
+ }
10504
+ }
10505
+ ),
10506
+ selectedRowKeys.length > 0 && /* @__PURE__ */ jsxs41("div", { className: "absolute bottom-4 left-1/2 z-10 flex -translate-x-1/2 items-center gap-3 rounded-lg border border-ant-border-secondary bg-ant-bg-elevated px-4 py-3 shadow-lg", children: [
10507
+ /* @__PURE__ */ jsxs41("span", { className: "text-sm text-ant-color-text-secondary", children: [
10508
+ "\u5DF2\u9009 ",
10509
+ selectedRowKeys.length,
10510
+ " \u6761"
10511
+ ] }),
10512
+ !readonly && /* @__PURE__ */ jsx89(Button15, { icon: /* @__PURE__ */ jsx89(SwapOutlined2, {}), onClick: handleBatchApprove, children: "\u6279\u91CF\u5BA1\u6279" }),
10513
+ !readonly && /* @__PURE__ */ jsx89(
10514
+ Button15,
10515
+ {
10516
+ danger: true,
10517
+ icon: /* @__PURE__ */ jsx89(DeleteOutlined, {}),
10518
+ onClick: () => Modal10.confirm({
10519
+ title: "\u786E\u8BA4\u6279\u91CF\u5220\u9664",
10520
+ content: `\u5C06\u5220\u9664 ${selectedRowKeys.length} \u6761\u6570\u636E\uFF0C\u786E\u8BA4\u7EE7\u7EED\u5417\uFF1F`,
10521
+ onOk: () => handleDelete(selectedRowKeys.map(String))
10522
+ }),
10523
+ children: "\u6279\u91CF\u5220\u9664"
10524
+ }
10525
+ ),
10526
+ /* @__PURE__ */ jsx89(Button15, { type: "link", onClick: () => setSelectedRowKeys([]), children: "\u53D6\u6D88\u9009\u62E9" })
10527
+ ] })
10528
+ ] })
10529
+ ] }),
10530
+ /* @__PURE__ */ jsx89(
10531
+ Modal10,
10532
+ {
10533
+ title: "\u9AD8\u7EA7\u7B5B\u9009",
10534
+ open: filterOpen,
10535
+ width: 760,
10536
+ onCancel: () => setFilterOpen(false),
10537
+ onOk: () => {
10538
+ setFilterOpen(false);
10539
+ persistConfig({ filter: { searchKeyWord, group: filterGroup } });
10540
+ loadData({ current: 1, pageSize, searchKeyWord, filterGroup });
10541
+ },
10542
+ okText: "\u5E94\u7528\u7B5B\u9009",
10543
+ children: /* @__PURE__ */ jsx89(FilterGroupEditor, { group: filterGroup, fields, onChange: setFilterGroup })
10544
+ }
10545
+ ),
10546
+ /* @__PURE__ */ jsx89(
10547
+ Modal10,
10548
+ {
10549
+ title: "\u5217\u8BBE\u7F6E",
10550
+ open: columnOpen,
10551
+ width: 720,
10552
+ onCancel: () => setColumnOpen(false),
10553
+ onOk: handleColumnCommit,
10554
+ children: /* @__PURE__ */ jsxs41("div", { className: "space-y-5", children: [
10555
+ /* @__PURE__ */ jsxs41("div", { children: [
10556
+ /* @__PURE__ */ jsx89("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u663E\u793A\u5217" }),
10557
+ /* @__PURE__ */ jsx89(
10558
+ Checkbox5.Group,
10559
+ {
10560
+ className: "grid grid-cols-2 gap-2 md:grid-cols-3",
10561
+ value: showFields,
10562
+ options: fields.map((field) => ({ label: field.label, value: field.fieldId })),
10563
+ onChange: (values) => setShowFields(values.map(String))
10564
+ }
10565
+ )
8598
10566
  ] }),
8599
- /* @__PURE__ */ jsxs35("div", { className: `flex-1 ${isLast ? "pb-0" : "pb-5"}`, children: [
8600
- /* @__PURE__ */ jsx83("div", { className: "text-sm font-medium text-gray-900", children: route.nodeName }),
8601
- route.assignees && route.assignees.length > 0 && /* @__PURE__ */ jsxs35("div", { className: "mt-1 flex items-center gap-1.5 flex-wrap", children: [
8602
- /* @__PURE__ */ jsx83(UserOutlined2, { className: "text-gray-400 text-xs" }),
8603
- route.assignees.map((assignee) => /* @__PURE__ */ jsx83(
8604
- "span",
10567
+ /* @__PURE__ */ jsxs41("div", { children: [
10568
+ /* @__PURE__ */ jsx89("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u51BB\u7ED3\u5217" }),
10569
+ /* @__PURE__ */ jsx89(
10570
+ Select6,
10571
+ {
10572
+ mode: "multiple",
10573
+ className: "w-full",
10574
+ value: lockFieldIds,
10575
+ options: showFields.map((fieldId) => {
10576
+ const field = fields.find((item) => item.fieldId === fieldId);
10577
+ return { label: field?.label || fieldId, value: fieldId };
10578
+ }),
10579
+ onChange: setLockFieldIds
10580
+ }
10581
+ )
10582
+ ] }),
10583
+ /* @__PURE__ */ jsxs41("div", { className: "grid gap-4 md:grid-cols-3", children: [
10584
+ /* @__PURE__ */ jsxs41("div", { children: [
10585
+ /* @__PURE__ */ jsx89("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u8868\u683C\u5BC6\u5EA6" }),
10586
+ /* @__PURE__ */ jsx89(
10587
+ Segmented,
8605
10588
  {
8606
- className: "text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded",
8607
- children: assignee.name
8608
- },
8609
- assignee.id
8610
- ))
10589
+ block: true,
10590
+ value: density,
10591
+ options: [
10592
+ { label: "\u7D27\u51D1", value: "compact" },
10593
+ { label: "\u6807\u51C6", value: "middle" },
10594
+ { label: "\u5BBD\u677E", value: "loose" }
10595
+ ],
10596
+ onChange: (value) => setDensity(value)
10597
+ }
10598
+ )
10599
+ ] }),
10600
+ /* @__PURE__ */ jsxs41("div", { children: [
10601
+ /* @__PURE__ */ jsx89("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u8BE6\u60C5\u6253\u5F00\u65B9\u5F0F" }),
10602
+ /* @__PURE__ */ jsx89(
10603
+ Segmented,
10604
+ {
10605
+ block: true,
10606
+ value: detailOpenMode,
10607
+ options: [
10608
+ { label: "\u62BD\u5C49", value: "drawer" },
10609
+ { label: "\u65B0\u9875", value: "newPage" }
10610
+ ],
10611
+ onChange: (value) => setDetailOpenMode(value)
10612
+ }
10613
+ )
10614
+ ] }),
10615
+ /* @__PURE__ */ jsxs41("div", { children: [
10616
+ /* @__PURE__ */ jsx89("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u9875\u5927\u5C0F" }),
10617
+ /* @__PURE__ */ jsx89(
10618
+ Select6,
10619
+ {
10620
+ className: "w-full",
10621
+ value: pageSize,
10622
+ options: [10, 20, 50, 100].map((value) => ({ label: `${value} \u6761`, value })),
10623
+ onChange: setPageSize
10624
+ }
10625
+ )
8611
10626
  ] })
8612
10627
  ] })
8613
- ] }, route.nodeId);
8614
- }) })
8615
- }
8616
- );
10628
+ ] })
10629
+ }
10630
+ ),
10631
+ /* @__PURE__ */ jsx89(
10632
+ Modal10,
10633
+ {
10634
+ title: exportScope === "selected" ? "\u5BFC\u51FA\u9009\u4E2D\u6570\u636E" : "\u5BFC\u51FA\u5168\u90E8\u6570\u636E",
10635
+ open: exportOpen,
10636
+ onCancel: () => setExportOpen(false),
10637
+ footer: /* @__PURE__ */ jsxs41(Space9, { children: [
10638
+ /* @__PURE__ */ jsx89(Button15, { onClick: () => setExportOpen(false), children: "\u53D6\u6D88" }),
10639
+ /* @__PURE__ */ jsx89(
10640
+ Button15,
10641
+ {
10642
+ type: "primary",
10643
+ loading: exporting,
10644
+ disabled: exportScope === "selected" && selectedRowKeys.length === 0,
10645
+ onClick: () => handleExport(exportScope),
10646
+ children: exportScope === "selected" ? `\u5BFC\u51FA\u9009\u4E2D (${selectedRowKeys.length})` : "\u5BFC\u51FA\u5168\u90E8"
10647
+ }
10648
+ )
10649
+ ] }),
10650
+ children: /* @__PURE__ */ jsx89(
10651
+ Checkbox5.Group,
10652
+ {
10653
+ className: "grid grid-cols-2 gap-2",
10654
+ value: exportFields,
10655
+ options: fields.map((field) => ({ label: field.label, value: field.fieldId })),
10656
+ onChange: (values) => setExportFields(values.map(String))
10657
+ }
10658
+ )
10659
+ }
10660
+ ),
10661
+ /* @__PURE__ */ jsx89(
10662
+ Modal10,
10663
+ {
10664
+ title: "\u6279\u91CF\u5BA1\u6279",
10665
+ open: batchApprovalOpen,
10666
+ onCancel: () => setBatchApprovalOpen(false),
10667
+ onOk: handleBatchApprovalConfirm,
10668
+ okText: batchApprovalAction === "approved" ? "\u786E\u8BA4\u901A\u8FC7" : "\u786E\u8BA4\u62D2\u7EDD",
10669
+ confirmLoading: batchApproving,
10670
+ children: /* @__PURE__ */ jsxs41("div", { className: "space-y-4", children: [
10671
+ /* @__PURE__ */ jsxs41("div", { className: "text-sm text-ant-color-text-secondary", children: [
10672
+ "\u5DF2\u9009\u62E9 ",
10673
+ selectedRowKeys.length,
10674
+ " \u6761\u8BB0\u5F55"
10675
+ ] }),
10676
+ /* @__PURE__ */ jsx89(
10677
+ Segmented,
10678
+ {
10679
+ block: true,
10680
+ value: batchApprovalAction,
10681
+ options: [
10682
+ { label: "\u540C\u610F", value: "approved" },
10683
+ { label: "\u62D2\u7EDD", value: "rejected" }
10684
+ ],
10685
+ onChange: (value) => setBatchApprovalAction(value)
10686
+ }
10687
+ ),
10688
+ /* @__PURE__ */ jsx89(
10689
+ Input12.TextArea,
10690
+ {
10691
+ value: batchApprovalComments,
10692
+ rows: 4,
10693
+ maxLength: 500,
10694
+ showCount: true,
10695
+ placeholder: "\u586B\u5199\u5BA1\u6279\u610F\u89C1",
10696
+ onChange: (event) => setBatchApprovalComments(event.target.value)
10697
+ }
10698
+ )
10699
+ ] })
10700
+ }
10701
+ ),
10702
+ /* @__PURE__ */ jsxs41(
10703
+ Modal10,
10704
+ {
10705
+ title: "\u5BFC\u5165\u6570\u636E",
10706
+ open: importOpen,
10707
+ width: 720,
10708
+ onCancel: () => setImportOpen(false),
10709
+ onOk: handleImportConfirm,
10710
+ okButtonProps: { disabled: !importBase64 },
10711
+ okText: "\u786E\u8BA4\u5BFC\u5165",
10712
+ children: [
10713
+ /* @__PURE__ */ jsx89(
10714
+ Upload3.Dragger,
10715
+ {
10716
+ accept: ".xlsx,.xls",
10717
+ maxCount: 1,
10718
+ beforeUpload: handleImportPreview,
10719
+ onRemove: () => {
10720
+ setImportBase64("");
10721
+ setImportPreview([]);
10722
+ },
10723
+ children: /* @__PURE__ */ jsx89("p", { className: "text-ant-color-text-secondary", children: "\u62D6\u62FD Excel \u6587\u4EF6\u5230\u6B64\u5904\uFF0C\u6216\u70B9\u51FB\u9009\u62E9\u6587\u4EF6" })
10724
+ }
10725
+ ),
10726
+ importPreview.length > 0 && /* @__PURE__ */ jsxs41("div", { className: "mt-4", children: [
10727
+ /* @__PURE__ */ jsx89("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u5BFC\u5165\u9884\u89C8" }),
10728
+ /* @__PURE__ */ jsx89(
10729
+ Table3,
10730
+ {
10731
+ size: "small",
10732
+ dataSource: importPreview,
10733
+ columns: importPreviewColumns,
10734
+ scroll: { x: Math.max(600, (importPreviewColumns?.length || 0) * 150) },
10735
+ pagination: false,
10736
+ rowKey: (_, index) => String(index)
10737
+ }
10738
+ )
10739
+ ] })
10740
+ ]
10741
+ }
10742
+ ),
10743
+ /* @__PURE__ */ jsxs41(
10744
+ Drawer2,
10745
+ {
10746
+ title: recordTab === "import" ? "\u5BFC\u5165\u8BB0\u5F55" : "\u5BFC\u51FA\u8BB0\u5F55",
10747
+ open: recordsOpen,
10748
+ width: 720,
10749
+ onClose: () => setRecordsOpen(false),
10750
+ children: [
10751
+ /* @__PURE__ */ jsx89(
10752
+ Segmented,
10753
+ {
10754
+ value: recordTab,
10755
+ options: [
10756
+ { label: "\u5BFC\u5165\u8BB0\u5F55", value: "import" },
10757
+ { label: "\u5BFC\u51FA\u8BB0\u5F55", value: "export" }
10758
+ ],
10759
+ onChange: (value) => loadTransferRecords(value)
10760
+ }
10761
+ ),
10762
+ /* @__PURE__ */ jsx89(
10763
+ Table3,
10764
+ {
10765
+ className: "mt-4",
10766
+ size: "small",
10767
+ dataSource: transferRecords,
10768
+ rowKey: (record) => record.id || record.recordId
10769
+ }
10770
+ )
10771
+ ]
10772
+ }
10773
+ ),
10774
+ /* @__PURE__ */ jsx89(
10775
+ Drawer2,
10776
+ {
10777
+ title: "\u8BE6\u60C5",
10778
+ open: detailOpen,
10779
+ width: 720,
10780
+ onClose: () => setDetailOpen(false),
10781
+ destroyOnClose: true,
10782
+ children: activeRecord && detailRenderer ? detailRenderer({
10783
+ record: activeRecord,
10784
+ formInstanceId: String(getRecordId(activeRecord)),
10785
+ onClose: () => setDetailOpen(false)
10786
+ }) : /* @__PURE__ */ jsx89(Empty5, { description: "\u8BF7\u901A\u8FC7 detailRenderer \u63A5\u5165\u8BE6\u60C5\u6A21\u677F" })
10787
+ }
10788
+ ),
10789
+ /* @__PURE__ */ jsx89(
10790
+ Drawer2,
10791
+ {
10792
+ title: "\u65B0\u589E\u6570\u636E",
10793
+ open: submitOpen,
10794
+ width: 720,
10795
+ onClose: () => setSubmitOpen(false),
10796
+ destroyOnClose: true,
10797
+ children: submitRenderer ? submitRenderer({
10798
+ onClose: () => setSubmitOpen(false),
10799
+ onSubmitted: () => {
10800
+ setSubmitOpen(false);
10801
+ loadData({ current: 1, pageSize });
10802
+ }
10803
+ }) : /* @__PURE__ */ jsx89(Empty5, { description: "\u8BF7\u901A\u8FC7 submitRenderer \u63A5\u5165\u63D0\u4EA4\u6A21\u677F" })
10804
+ }
10805
+ )
10806
+ ] });
8617
10807
  };
8618
10808
 
8619
10809
  // src/templates/FormSubmitTemplate.tsx
8620
- import { useState as useState33, useCallback as useCallback17 } from "react";
8621
- import { Button as Button13 } from "antd";
8622
- import { CheckCircleFilled } from "@ant-design/icons";
8623
- import { Fragment as Fragment5, jsx as jsx84, jsxs as jsxs36 } from "react/jsx-runtime";
10810
+ import { useState as useState36, useCallback as useCallback18 } from "react";
10811
+ import { Button as Button16, Select as Select7 } from "antd";
10812
+ import { CheckCircleFilled as CheckCircleFilled2 } from "@ant-design/icons";
10813
+ import { Fragment as Fragment7, jsx as jsx90, jsxs as jsxs42 } from "react/jsx-runtime";
8624
10814
  var pickFormInstanceId = (value) => {
8625
10815
  if (!value) return void 0;
8626
10816
  if (typeof value === "string") return value;
@@ -8637,22 +10827,22 @@ var SubmitSuccessCard = ({
8637
10827
  renderSuccess
8638
10828
  }) => {
8639
10829
  if (renderSuccess) {
8640
- return /* @__PURE__ */ jsx84(Fragment5, { children: renderSuccess(info) });
10830
+ return /* @__PURE__ */ jsx90(Fragment7, { children: renderSuccess(info) });
8641
10831
  }
8642
- return /* @__PURE__ */ jsx84("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ jsxs36("div", { className: "flex flex-col items-center py-16 animate-[fadeIn_0.3s_ease-out,scaleIn_0.3s_ease-out]", children: [
8643
- /* @__PURE__ */ jsx84("div", { className: "w-12 h-12 rounded-full bg-green-100 flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx84(CheckCircleFilled, { className: "text-2xl text-green-500" }) }),
8644
- /* @__PURE__ */ jsx84("h2", { className: "text-lg font-semibold text-gray-900 mb-1", children: "\u63D0\u4EA4\u6210\u529F" }),
8645
- /* @__PURE__ */ jsx84("p", { className: "text-sm text-gray-500 mb-6", children: info.message || "\u5DF2\u6210\u529F\u521B\u5EFA\u4E00\u6761\u65B0\u8BB0\u5F55" }),
8646
- /* @__PURE__ */ jsxs36("div", { className: "flex gap-3", children: [
8647
- (mode === "stay" || mode === "redirect") && /* @__PURE__ */ jsx84(Button13, { onClick: onContinue, children: "\u7EE7\u7EED\u63D0\u4EA4" }),
8648
- /* @__PURE__ */ jsx84(Button13, { type: "primary", onClick: onViewDetail, children: "\u67E5\u770B\u8BE6\u60C5" })
10832
+ return /* @__PURE__ */ jsx90("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ jsxs42("div", { className: "flex flex-col items-center py-16 animate-[fadeIn_0.3s_ease-out,scaleIn_0.3s_ease-out]", children: [
10833
+ /* @__PURE__ */ jsx90("div", { className: "w-12 h-12 rounded-full bg-green-100 flex items-center justify-center mb-4", children: /* @__PURE__ */ jsx90(CheckCircleFilled2, { className: "text-2xl text-green-500" }) }),
10834
+ /* @__PURE__ */ jsx90("h2", { className: "text-lg font-semibold text-gray-900 mb-1", children: "\u63D0\u4EA4\u6210\u529F" }),
10835
+ /* @__PURE__ */ jsx90("p", { className: "text-sm text-gray-500 mb-6", children: info.message || "\u5DF2\u6210\u529F\u521B\u5EFA\u4E00\u6761\u65B0\u8BB0\u5F55" }),
10836
+ /* @__PURE__ */ jsxs42("div", { className: "flex gap-3", children: [
10837
+ (mode === "stay" || mode === "redirect") && /* @__PURE__ */ jsx90(Button16, { onClick: onContinue, children: "\u7EE7\u7EED\u63D0\u4EA4" }),
10838
+ /* @__PURE__ */ jsx90(Button16, { type: "primary", onClick: onViewDetail, children: "\u67E5\u770B\u8BE6\u60C5" })
8649
10839
  ] }),
8650
- isRedirecting && /* @__PURE__ */ jsxs36("div", { className: "mt-6 w-48", children: [
8651
- /* @__PURE__ */ jsxs36("div", { className: "text-xs text-gray-400 text-center mb-1", children: [
10840
+ isRedirecting && /* @__PURE__ */ jsxs42("div", { className: "mt-6 w-48", children: [
10841
+ /* @__PURE__ */ jsxs42("div", { className: "text-xs text-gray-400 text-center mb-1", children: [
8652
10842
  countdown,
8653
10843
  "\u79D2\u540E\u81EA\u52A8\u8DF3\u8F6C"
8654
10844
  ] }),
8655
- /* @__PURE__ */ jsx84("div", { className: "h-1 bg-gray-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx84(
10845
+ /* @__PURE__ */ jsx90("div", { className: "h-1 bg-gray-200 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx90(
8656
10846
  "div",
8657
10847
  {
8658
10848
  className: "h-full bg-blue-500 transition-all duration-1000",
@@ -8668,18 +10858,28 @@ var InnerFormContent = ({
8668
10858
  formType,
8669
10859
  submitSuccessMode,
8670
10860
  enableDraft,
10861
+ enableProcessPreview,
10862
+ enableSubmissionDepartmentSelect,
10863
+ departmentOptions,
8671
10864
  header,
8672
10865
  footer,
8673
10866
  beforeForm,
8674
10867
  afterForm,
10868
+ renderDepartmentSelector,
8675
10869
  renderForm,
8676
10870
  renderSuccess,
8677
- onSubmitSuccess
10871
+ onSubmitSuccess,
10872
+ inDrawer = false
8678
10873
  }) => {
8679
- const { validateAll, getFormData: getFormData2, resetForm, api } = useFormContext();
8680
- const [submitted, setSubmitted] = useState33(false);
8681
- const [successInfo, setSuccessInfo] = useState33(null);
8682
- const [submitting, setSubmitting] = useState33(false);
10874
+ const { validateAll, getFormData: getFormData2, setFieldValue, resetForm, api } = useFormContext();
10875
+ const [submitted, setSubmitted] = useState36(false);
10876
+ const [successInfo, setSuccessInfo] = useState36(null);
10877
+ const [submitting, setSubmitting] = useState36(false);
10878
+ const [departmentId, setDepartmentId] = useState36();
10879
+ const [previewOpen, setPreviewOpen] = useState36(false);
10880
+ const [previewLoading, setPreviewLoading] = useState36(false);
10881
+ const [previewRoutes, setPreviewRoutes] = useState36([]);
10882
+ const [pendingFormData, setPendingFormData] = useState36(null);
8683
10883
  const { hasDraft, draftTimestamp, saveDraft, restoreDraft, clearDraft } = useDraftStorage({
8684
10884
  appType: config.appType,
8685
10885
  formUuid: config.formUuid
@@ -8691,79 +10891,123 @@ var InnerFormContent = ({
8691
10891
  mode: submitSuccessMode === "continue" ? "stay" : submitSuccessMode,
8692
10892
  basePath: config.navigation?.basePath
8693
10893
  });
8694
- const handleSubmit = useCallback17(async () => {
10894
+ const performSubmit = useCallback18(
10895
+ async (formData) => {
10896
+ setSubmitting(true);
10897
+ try {
10898
+ const submitResponse = config.mode === "edit" && config.formInstanceId ? await api.updateFormData({
10899
+ appType: config.appType,
10900
+ formUuid: config.formUuid,
10901
+ formInstId: config.formInstanceId,
10902
+ formInstanceId: config.formInstanceId,
10903
+ updateFormDataJson: JSON.stringify(formData)
10904
+ }) : await api.submitFormData({
10905
+ appType: config.appType,
10906
+ formUuid: config.formUuid,
10907
+ data: formData,
10908
+ submissionDepartmentId: departmentId
10909
+ });
10910
+ const formInstId = pickFormInstanceId(submitResponse) || config.formInstanceId || `inst_${Date.now()}`;
10911
+ if (config.submit?.afterSubmit) {
10912
+ await config.submit.afterSubmit({
10913
+ formInstanceId: formInstId,
10914
+ data: formData,
10915
+ response: submitResponse
10916
+ });
10917
+ }
10918
+ if (enableDraft) {
10919
+ clearDraft();
10920
+ }
10921
+ onSubmitSuccess?.(formInstId);
10922
+ if (submitSuccessMode === "continue") {
10923
+ resetForm();
10924
+ } else {
10925
+ setSuccessInfo({ formInstanceId: formInstId });
10926
+ setSubmitted(true);
10927
+ handlePostSubmit(formInstId);
10928
+ }
10929
+ } catch (error) {
10930
+ console.error("[FormSubmitTemplate] Submit failed:", error);
10931
+ } finally {
10932
+ setSubmitting(false);
10933
+ }
10934
+ },
10935
+ [
10936
+ api,
10937
+ clearDraft,
10938
+ config,
10939
+ departmentId,
10940
+ enableDraft,
10941
+ handlePostSubmit,
10942
+ onSubmitSuccess,
10943
+ resetForm,
10944
+ submitSuccessMode
10945
+ ]
10946
+ );
10947
+ const prepareSubmit = useCallback18(async () => {
8695
10948
  const valid = await validateAll();
8696
10949
  if (!valid) return;
8697
- setSubmitting(true);
8698
- try {
8699
- const formData = getFormData2();
8700
- if (config.submit?.beforeSubmit) {
8701
- const shouldContinue = await config.submit.beforeSubmit(formData);
8702
- if (shouldContinue === false) {
8703
- setSubmitting(false);
8704
- return;
8705
- }
10950
+ const formData = getFormData2();
10951
+ if (config.submit?.beforeSubmit) {
10952
+ const shouldContinue = await config.submit.beforeSubmit(formData);
10953
+ if (shouldContinue === false) {
10954
+ return;
8706
10955
  }
8707
- const submitResponse = config.mode === "edit" && config.formInstanceId ? await api.updateFormData({
8708
- appType: config.appType,
8709
- formUuid: config.formUuid,
8710
- formInstId: config.formInstanceId,
8711
- formInstanceId: config.formInstanceId,
8712
- updateFormDataJson: JSON.stringify(formData)
8713
- }) : await api.submitFormData({
8714
- appType: config.appType,
8715
- formUuid: config.formUuid,
8716
- data: formData
8717
- });
8718
- const formInstId = pickFormInstanceId(submitResponse) || config.formInstanceId || `inst_${Date.now()}`;
8719
- if (config.submit?.afterSubmit) {
8720
- await config.submit.afterSubmit({
8721
- formInstanceId: formInstId,
10956
+ }
10957
+ if (formType === "process" && enableProcessPreview) {
10958
+ setPendingFormData(formData);
10959
+ setPreviewOpen(true);
10960
+ setPreviewLoading(true);
10961
+ try {
10962
+ const routes = await previewProcess(api.request, {
10963
+ appType: config.appType,
10964
+ formUuid: config.formUuid,
8722
10965
  data: formData,
8723
- response: submitResponse
10966
+ submissionDepartmentId: departmentId
8724
10967
  });
10968
+ setPreviewRoutes(routes);
10969
+ } catch (error) {
10970
+ console.error("[FormSubmitTemplate] Preview failed:", error);
10971
+ setPreviewRoutes([]);
10972
+ } finally {
10973
+ setPreviewLoading(false);
8725
10974
  }
8726
- if (enableDraft) {
8727
- clearDraft();
8728
- }
8729
- onSubmitSuccess?.(formInstId);
8730
- if (submitSuccessMode === "continue") {
8731
- resetForm();
8732
- } else {
8733
- setSuccessInfo({ formInstanceId: formInstId });
8734
- setSubmitted(true);
8735
- handlePostSubmit(formInstId);
8736
- }
8737
- } catch (error) {
8738
- console.error("[FormSubmitTemplate] Submit failed:", error);
8739
- } finally {
8740
- setSubmitting(false);
10975
+ return;
8741
10976
  }
10977
+ await performSubmit(formData);
8742
10978
  }, [
8743
10979
  validateAll,
8744
10980
  getFormData2,
8745
10981
  config,
8746
10982
  api,
8747
- enableDraft,
8748
- clearDraft,
8749
- onSubmitSuccess,
8750
- submitSuccessMode,
8751
- resetForm,
8752
- handlePostSubmit
10983
+ formType,
10984
+ enableProcessPreview,
10985
+ departmentId,
10986
+ performSubmit
8753
10987
  ]);
8754
- const handleSaveDraft = useCallback17(() => {
10988
+ const handlePreviewConfirm = useCallback18(async () => {
10989
+ const data = pendingFormData ?? getFormData2();
10990
+ setPreviewOpen(false);
10991
+ setPendingFormData(null);
10992
+ await performSubmit(data);
10993
+ }, [getFormData2, pendingFormData, performSubmit]);
10994
+ const handleSaveDraft = useCallback18(() => {
8755
10995
  const data = getFormData2();
8756
10996
  saveDraft(data);
8757
10997
  }, [getFormData2, saveDraft]);
8758
- const handleRestoreDraft = useCallback17(() => {
8759
- restoreDraft();
8760
- }, [restoreDraft]);
8761
- const handleContinue = useCallback17(() => {
10998
+ const handleRestoreDraft = useCallback18(() => {
10999
+ const data = restoreDraft();
11000
+ if (!data) return;
11001
+ Object.entries(data).forEach(([fieldId, value]) => {
11002
+ setFieldValue(fieldId, value);
11003
+ });
11004
+ }, [restoreDraft, setFieldValue]);
11005
+ const handleContinue = useCallback18(() => {
8762
11006
  setSubmitted(false);
8763
11007
  setSuccessInfo(null);
8764
11008
  resetForm();
8765
11009
  }, [resetForm]);
8766
- const handleViewDetail = useCallback17(() => {
11010
+ const handleViewDetail = useCallback18(() => {
8767
11011
  if (!successInfo) return;
8768
11012
  if (formType === "process") {
8769
11013
  navigateToProcessDetail(successInfo.formInstanceId);
@@ -8791,15 +11035,38 @@ var InnerFormContent = ({
8791
11035
  label: "\u63D0\u4EA4",
8792
11036
  type: "primary",
8793
11037
  loading: submitting,
8794
- onClick: handleSubmit
11038
+ onClick: prepareSubmit
8795
11039
  });
8796
- return /* @__PURE__ */ jsxs36("div", { className: "min-h-screen bg-gray-50/50", children: [
8797
- /* @__PURE__ */ jsxs36("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: [
8798
- header || /* @__PURE__ */ jsxs36("div", { className: "mb-6", children: [
8799
- /* @__PURE__ */ jsx84("h1", { className: "text-2xl font-bold text-gray-900", children: schema.formMeta.title }),
8800
- /* @__PURE__ */ jsx84("p", { className: "text-sm text-gray-500 mt-1", children: "\u8BF7\u586B\u5199\u4EE5\u4E0B\u4FE1\u606F" })
8801
- ] }),
8802
- enableDraft && hasDraft && !submitted && /* @__PURE__ */ jsx84("div", { className: "mb-6", children: /* @__PURE__ */ jsx84(
11040
+ const departmentSelector = formType === "process" && enableSubmissionDepartmentSelect ? /* @__PURE__ */ jsxs42("div", { className: "mb-5 rounded-lg border border-ant-border-secondary bg-ant-bg-elevated px-4 py-3", children: [
11041
+ /* @__PURE__ */ jsx90("div", { className: "mb-2 text-sm font-medium text-ant-color-text", children: "\u63D0\u4EA4\u90E8\u95E8" }),
11042
+ renderDepartmentSelector ? renderDepartmentSelector({
11043
+ value: departmentId,
11044
+ onChange: setDepartmentId,
11045
+ options: departmentOptions
11046
+ }) : /* @__PURE__ */ jsx90(
11047
+ Select7,
11048
+ {
11049
+ allowClear: true,
11050
+ className: "w-full",
11051
+ placeholder: "\u8BF7\u9009\u62E9\u672C\u6B21\u63D0\u4EA4\u6D41\u7A0B\u6240\u5C5E\u90E8\u95E8",
11052
+ value: departmentId,
11053
+ options: departmentOptions,
11054
+ onChange: setDepartmentId
11055
+ }
11056
+ )
11057
+ ] }) : null;
11058
+ const actionsNode = !submitted ? /* @__PURE__ */ jsx90(StickyActionBar, { actions, inDrawer }) : null;
11059
+ return /* @__PURE__ */ jsxs42(RuntimePageShell, { actions: actionsNode, inDrawer, children: [
11060
+ /* @__PURE__ */ jsxs42("div", { className: "space-y-6", children: [
11061
+ header || /* @__PURE__ */ jsx90(
11062
+ SummaryPanel,
11063
+ {
11064
+ title: schema.formMeta.title,
11065
+ eyebrow: formType === "process" ? "\u6D41\u7A0B\u53D1\u8D77" : "\u6570\u636E\u63D0\u4EA4",
11066
+ status: formType === "process" ? { label: "\u5F85\u63D0\u4EA4", tone: "brand" } : void 0
11067
+ }
11068
+ ),
11069
+ enableDraft && hasDraft && !submitted && /* @__PURE__ */ jsx90("div", { children: /* @__PURE__ */ jsx90(
8803
11070
  DraftManager,
8804
11071
  {
8805
11072
  hasDraft,
@@ -8808,11 +11075,12 @@ var InnerFormContent = ({
8808
11075
  onDiscard: clearDraft
8809
11076
  }
8810
11077
  ) }),
8811
- !submitted ? /* @__PURE__ */ jsxs36("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6 animate-[fadeIn_0.2s_ease-out]", children: [
11078
+ !submitted ? /* @__PURE__ */ jsxs42("div", { className: "rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: [
11079
+ departmentSelector,
8812
11080
  beforeForm,
8813
- renderForm ? renderForm({ schema, config }) : /* @__PURE__ */ jsx84(FormRenderer, { columns: 2 }),
11081
+ renderForm ? renderForm({ schema, config }) : /* @__PURE__ */ jsx90(FormRenderer, { columns: 2 }),
8814
11082
  afterForm
8815
- ] }) : successInfo && /* @__PURE__ */ jsx84(
11083
+ ] }) : successInfo && /* @__PURE__ */ jsx90(
8816
11084
  SubmitSuccessCard,
8817
11085
  {
8818
11086
  info: successInfo,
@@ -8826,7 +11094,16 @@ var InnerFormContent = ({
8826
11094
  ),
8827
11095
  footer
8828
11096
  ] }),
8829
- !submitted && /* @__PURE__ */ jsx84(FormActionBar, { actions, position: "bottom-fixed" })
11097
+ /* @__PURE__ */ jsx90(
11098
+ ProcessPreview,
11099
+ {
11100
+ open: previewOpen,
11101
+ routes: previewRoutes,
11102
+ loading: previewLoading,
11103
+ onClose: () => setPreviewOpen(false),
11104
+ onConfirm: handlePreviewConfirm
11105
+ }
11106
+ )
8830
11107
  ] });
8831
11108
  };
8832
11109
  var FormSubmitTemplate = ({
@@ -8835,15 +11112,20 @@ var FormSubmitTemplate = ({
8835
11112
  formType = "form",
8836
11113
  submitSuccessMode = "redirect",
8837
11114
  enableDraft = false,
11115
+ enableProcessPreview = false,
11116
+ enableSubmissionDepartmentSelect = false,
11117
+ departmentOptions = [],
8838
11118
  header,
8839
11119
  footer,
8840
11120
  beforeForm,
8841
11121
  afterForm,
11122
+ renderDepartmentSelector,
8842
11123
  renderForm,
8843
11124
  renderSuccess,
8844
- onSubmitSuccess
11125
+ onSubmitSuccess,
11126
+ inDrawer = false
8845
11127
  }) => {
8846
- return /* @__PURE__ */ jsx84(FormProvider, { schema, config, children: /* @__PURE__ */ jsx84(
11128
+ return /* @__PURE__ */ jsx90(FormProvider, { schema, config, children: /* @__PURE__ */ jsx90(
8847
11129
  InnerFormContent,
8848
11130
  {
8849
11131
  schema,
@@ -8851,83 +11133,95 @@ var FormSubmitTemplate = ({
8851
11133
  formType,
8852
11134
  submitSuccessMode,
8853
11135
  enableDraft,
11136
+ enableProcessPreview,
11137
+ enableSubmissionDepartmentSelect,
11138
+ departmentOptions,
8854
11139
  header,
8855
11140
  footer,
8856
11141
  beforeForm,
8857
11142
  afterForm,
11143
+ renderDepartmentSelector,
8858
11144
  renderForm,
8859
11145
  renderSuccess,
8860
- onSubmitSuccess
11146
+ onSubmitSuccess,
11147
+ inDrawer
8861
11148
  }
8862
11149
  ) });
8863
11150
  };
8864
11151
 
8865
11152
  // src/templates/FormDetailTemplate.tsx
8866
- import { useCallback as useCallback18, useMemo as useMemo14 } from "react";
11153
+ import { useCallback as useCallback19, useMemo as useMemo19, useRef as useRef15, useState as useState37 } from "react";
8867
11154
 
8868
11155
  // src/templates/PageSkeleton.tsx
8869
11156
  import { Skeleton as Skeleton3 } from "antd";
8870
- import { jsx as jsx85, jsxs as jsxs37 } from "react/jsx-runtime";
8871
- var CardSkeleton = ({ children }) => /* @__PURE__ */ jsx85("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children });
8872
- var SummaryCardSkeleton = () => /* @__PURE__ */ jsxs37(CardSkeleton, { children: [
8873
- /* @__PURE__ */ jsxs37("div", { className: "flex items-start justify-between", children: [
8874
- /* @__PURE__ */ jsxs37("div", { className: "flex-1", children: [
8875
- /* @__PURE__ */ jsx85(Skeleton3.Input, { active: true, size: "large", style: { width: 200 } }),
8876
- /* @__PURE__ */ jsx85("div", { className: "mt-2", children: /* @__PURE__ */ jsx85(Skeleton3.Input, { active: true, size: "small", style: { width: 80 } }) })
11157
+ import { jsx as jsx91, jsxs as jsxs43 } from "react/jsx-runtime";
11158
+ var CardSkeleton = ({ children }) => /* @__PURE__ */ jsx91("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children });
11159
+ var SummaryCardSkeleton = () => /* @__PURE__ */ jsxs43(CardSkeleton, { children: [
11160
+ /* @__PURE__ */ jsxs43("div", { className: "flex items-start justify-between", children: [
11161
+ /* @__PURE__ */ jsxs43("div", { className: "flex-1", children: [
11162
+ /* @__PURE__ */ jsx91(Skeleton3.Input, { active: true, size: "large", style: { width: 200 } }),
11163
+ /* @__PURE__ */ jsx91("div", { className: "mt-2", children: /* @__PURE__ */ jsx91(Skeleton3.Input, { active: true, size: "small", style: { width: 80 } }) })
8877
11164
  ] }),
8878
- /* @__PURE__ */ jsx85(Skeleton3.Button, { active: true, size: "small", shape: "round", style: { width: 60 } })
11165
+ /* @__PURE__ */ jsx91(Skeleton3.Button, { active: true, size: "small", shape: "round", style: { width: 60 } })
8879
11166
  ] }),
8880
- /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-3 mt-4", children: [
8881
- /* @__PURE__ */ jsx85(Skeleton3.Avatar, { active: true, size: "small" }),
8882
- /* @__PURE__ */ jsx85(Skeleton3.Input, { active: true, size: "small", style: { width: 120 } })
11167
+ /* @__PURE__ */ jsxs43("div", { className: "flex items-center gap-3 mt-4", children: [
11168
+ /* @__PURE__ */ jsx91(Skeleton3.Avatar, { active: true, size: "small" }),
11169
+ /* @__PURE__ */ jsx91(Skeleton3.Input, { active: true, size: "small", style: { width: 120 } })
8883
11170
  ] })
8884
11171
  ] });
8885
- var FormGridSkeleton = () => /* @__PURE__ */ jsx85(CardSkeleton, { children: /* @__PURE__ */ jsx85("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
8886
- /* @__PURE__ */ jsx85(Skeleton3.Input, { active: true, size: "small", style: { width: 80 } }),
8887
- /* @__PURE__ */ jsx85(Skeleton3.Input, { active: true, block: true, style: { width: "100%" } })
11172
+ var FormGridSkeleton = () => /* @__PURE__ */ jsx91(CardSkeleton, { children: /* @__PURE__ */ jsx91("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs43("div", { className: "space-y-2", children: [
11173
+ /* @__PURE__ */ jsx91(Skeleton3.Input, { active: true, size: "small", style: { width: 80 } }),
11174
+ /* @__PURE__ */ jsx91(Skeleton3.Input, { active: true, block: true, style: { width: "100%" } })
8888
11175
  ] }, i)) }) });
8889
- var ActionBarSkeleton = () => /* @__PURE__ */ jsx85("div", { className: "fixed bottom-0 left-0 right-0 backdrop-blur-lg bg-white/80 border-t border-gray-200 px-6 py-3", children: /* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-end gap-3", children: [
8890
- /* @__PURE__ */ jsx85(Skeleton3.Button, { active: true, style: { width: 80 } }),
8891
- /* @__PURE__ */ jsx85(Skeleton3.Button, { active: true, style: { width: 80 } })
11176
+ var ActionBarSkeleton = () => /* @__PURE__ */ jsx91("div", { className: "fixed bottom-0 left-0 right-0 backdrop-blur-lg bg-white/80 border-t border-gray-200 px-6 py-3", children: /* @__PURE__ */ jsxs43("div", { className: "flex items-center justify-end gap-3", children: [
11177
+ /* @__PURE__ */ jsx91(Skeleton3.Button, { active: true, style: { width: 80 } }),
11178
+ /* @__PURE__ */ jsx91(Skeleton3.Button, { active: true, style: { width: 80 } })
8892
11179
  ] }) });
8893
- var TimelineSkeleton = () => /* @__PURE__ */ jsxs37(CardSkeleton, { children: [
8894
- /* @__PURE__ */ jsx85(Skeleton3.Input, { active: true, size: "default", style: { width: 100, marginBottom: 16 } }),
8895
- /* @__PURE__ */ jsx85("div", { className: "space-y-4", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs37("div", { className: "flex gap-4", children: [
8896
- /* @__PURE__ */ jsxs37("div", { className: "flex flex-col items-center", children: [
8897
- /* @__PURE__ */ jsx85("div", { className: "w-3 h-3 rounded-full bg-gray-200 animate-pulse" }),
8898
- i < 2 && /* @__PURE__ */ jsx85("div", { className: "w-0.5 flex-1 bg-gray-200 mt-1" })
11180
+ var TimelineSkeleton = () => /* @__PURE__ */ jsxs43(CardSkeleton, { children: [
11181
+ /* @__PURE__ */ jsx91(Skeleton3.Input, { active: true, size: "default", style: { width: 100, marginBottom: 16 } }),
11182
+ /* @__PURE__ */ jsx91("div", { className: "space-y-4", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs43("div", { className: "flex gap-4", children: [
11183
+ /* @__PURE__ */ jsxs43("div", { className: "flex flex-col items-center", children: [
11184
+ /* @__PURE__ */ jsx91("div", { className: "w-3 h-3 rounded-full bg-gray-200 animate-pulse" }),
11185
+ i < 2 && /* @__PURE__ */ jsx91("div", { className: "w-0.5 flex-1 bg-gray-200 mt-1" })
8899
11186
  ] }),
8900
- /* @__PURE__ */ jsx85("div", { className: "flex-1 pb-4", children: /* @__PURE__ */ jsx85(Skeleton3, { active: true, paragraph: { rows: 1 }, title: { width: "60%" } }) })
11187
+ /* @__PURE__ */ jsx91("div", { className: "flex-1 pb-4", children: /* @__PURE__ */ jsx91(Skeleton3, { active: true, paragraph: { rows: 1 }, title: { width: "60%" } }) })
8901
11188
  ] }, i)) })
8902
11189
  ] });
8903
11190
  var PageSkeleton = ({ type }) => {
8904
11191
  if (type === "submit") {
8905
- return /* @__PURE__ */ jsxs37("div", { className: "space-y-6", children: [
8906
- /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
8907
- /* @__PURE__ */ jsx85(Skeleton3.Input, { active: true, size: "large", style: { width: 200 } }),
8908
- /* @__PURE__ */ jsx85(Skeleton3.Input, { active: true, size: "small", style: { width: 300 } })
11192
+ return /* @__PURE__ */ jsxs43("div", { className: "space-y-6", children: [
11193
+ /* @__PURE__ */ jsxs43("div", { className: "space-y-2", children: [
11194
+ /* @__PURE__ */ jsx91(Skeleton3.Input, { active: true, size: "large", style: { width: 200 } }),
11195
+ /* @__PURE__ */ jsx91(Skeleton3.Input, { active: true, size: "small", style: { width: 300 } })
8909
11196
  ] }),
8910
- /* @__PURE__ */ jsx85(FormGridSkeleton, {}),
8911
- /* @__PURE__ */ jsx85(ActionBarSkeleton, {})
11197
+ /* @__PURE__ */ jsx91(FormGridSkeleton, {}),
11198
+ /* @__PURE__ */ jsx91(ActionBarSkeleton, {})
8912
11199
  ] });
8913
11200
  }
8914
11201
  if (type === "detail") {
8915
- return /* @__PURE__ */ jsxs37("div", { className: "space-y-6", children: [
8916
- /* @__PURE__ */ jsx85(SummaryCardSkeleton, {}),
8917
- /* @__PURE__ */ jsx85(FormGridSkeleton, {}),
8918
- /* @__PURE__ */ jsx85(ActionBarSkeleton, {})
11202
+ return /* @__PURE__ */ jsxs43("div", { className: "space-y-6", children: [
11203
+ /* @__PURE__ */ jsx91(SummaryCardSkeleton, {}),
11204
+ /* @__PURE__ */ jsx91(FormGridSkeleton, {}),
11205
+ /* @__PURE__ */ jsx91(ActionBarSkeleton, {})
8919
11206
  ] });
8920
11207
  }
8921
- return /* @__PURE__ */ jsxs37("div", { className: "space-y-6", children: [
8922
- /* @__PURE__ */ jsx85(SummaryCardSkeleton, {}),
8923
- /* @__PURE__ */ jsx85(FormGridSkeleton, {}),
8924
- /* @__PURE__ */ jsx85(TimelineSkeleton, {}),
8925
- /* @__PURE__ */ jsx85(ActionBarSkeleton, {})
11208
+ return /* @__PURE__ */ jsxs43("div", { className: "space-y-6", children: [
11209
+ /* @__PURE__ */ jsx91(SummaryCardSkeleton, {}),
11210
+ /* @__PURE__ */ jsx91(FormGridSkeleton, {}),
11211
+ /* @__PURE__ */ jsx91(TimelineSkeleton, {}),
11212
+ /* @__PURE__ */ jsx91(ActionBarSkeleton, {})
8926
11213
  ] });
8927
11214
  };
8928
11215
 
8929
11216
  // src/templates/FormDetailTemplate.tsx
8930
- import { Fragment as Fragment6, jsx as jsx86, jsxs as jsxs38 } from "react/jsx-runtime";
11217
+ import { jsx as jsx92, jsxs as jsxs44 } from "react/jsx-runtime";
11218
+ function FormDataBridge({
11219
+ formDataRef
11220
+ }) {
11221
+ const { getFormData: getFormData2 } = useFormContext();
11222
+ formDataRef.current = getFormData2;
11223
+ return null;
11224
+ }
8931
11225
  var InnerDetailContent = ({
8932
11226
  schema,
8933
11227
  formUuid,
@@ -8941,9 +11235,12 @@ var InnerDetailContent = ({
8941
11235
  renderSummary,
8942
11236
  renderActions,
8943
11237
  onDelete,
8944
- onSave
11238
+ onSave,
11239
+ inDrawer = false
8945
11240
  }) => {
8946
- const fieldIds = useMemo14(() => schema.fields.map((field) => field.fieldId), [schema.fields]);
11241
+ const formDataRef = useRef15(void 0);
11242
+ const [accessDenied, setAccessDenied] = useState37(false);
11243
+ const fieldIds = useMemo19(() => schema.fields.map((field) => field.fieldId), [schema.fields]);
8947
11244
  const {
8948
11245
  loading,
8949
11246
  mode,
@@ -8957,7 +11254,13 @@ var InnerDetailContent = ({
8957
11254
  canEdit,
8958
11255
  canDelete,
8959
11256
  canViewChangeRecords
8960
- } = useFormDetail({ formUuid, appType, formInstanceId, fieldIds });
11257
+ } = useFormDetail({
11258
+ formUuid,
11259
+ appType,
11260
+ formInstanceId,
11261
+ fieldIds,
11262
+ onPermissionDenied: () => setAccessDenied(true)
11263
+ });
8961
11264
  const {
8962
11265
  records,
8963
11266
  loading: recordsLoading,
@@ -8970,20 +11273,21 @@ var InnerDetailContent = ({
8970
11273
  formInstanceId,
8971
11274
  autoLoad: enableChangeRecords && canViewChangeRecords
8972
11275
  });
8973
- const handleSave = useCallback18(async () => {
8974
- if (!formData) return;
8975
- const success = await saveChanges(formData);
11276
+ const handleSave = useCallback19(async () => {
11277
+ const values = formDataRef.current?.() ?? formData;
11278
+ if (!values) return;
11279
+ const success = await saveChanges(values);
8976
11280
  if (success) {
8977
- onSave?.(formData);
11281
+ onSave?.(values);
8978
11282
  }
8979
11283
  }, [formData, saveChanges, onSave]);
8980
- const handleDelete = useCallback18(async () => {
11284
+ const handleDelete = useCallback19(async () => {
8981
11285
  const success = await deleteInstance();
8982
11286
  if (success) {
8983
11287
  onDelete?.();
8984
11288
  }
8985
11289
  }, [deleteInstance, onDelete]);
8986
- const handleCancel = useCallback18(() => {
11290
+ const handleCancel = useCallback19(() => {
8987
11291
  switchToReadonly();
8988
11292
  }, [switchToReadonly]);
8989
11293
  const readonlyActions = [];
@@ -9020,41 +11324,44 @@ var InnerDetailContent = ({
9020
11324
  }
9021
11325
  };
9022
11326
  if (loading) {
9023
- return /* @__PURE__ */ jsx86("div", { className: "min-h-screen bg-gray-50/50", children: /* @__PURE__ */ jsx86("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: /* @__PURE__ */ jsx86(PageSkeleton, { type: "detail" }) }) });
11327
+ return /* @__PURE__ */ jsx92("div", { className: "min-h-screen bg-ant-bg-layout", children: /* @__PURE__ */ jsx92("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: /* @__PURE__ */ jsx92(PageSkeleton, { type: "detail" }) }) });
9024
11328
  }
9025
- return /* @__PURE__ */ jsxs38("div", { className: "min-h-screen bg-gray-50/50", children: [
9026
- /* @__PURE__ */ jsx86("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24 space-y-6", children: /* @__PURE__ */ jsxs38("div", { className: "animate-[fadeIn_0.2s_ease-out]", children: [
9027
- header,
9028
- renderSummary && instanceInfo ? renderSummary(instanceInfo) : /* @__PURE__ */ jsx86(
9029
- FormSummaryCard,
9030
- {
9031
- title: schema.formMeta.title,
9032
- formInstanceId,
9033
- creator: instanceInfo?.creator ? {
9034
- name: instanceInfo.creator.name,
9035
- avatar: instanceInfo.creator.avatar,
9036
- department: instanceInfo.creator.department
9037
- } : void 0,
9038
- createdAt: instanceInfo?.createdAt,
9039
- status: mode === "edit" ? { label: "\u7F16\u8F91\u4E2D", tone: "brand" } : void 0
9040
- }
9041
- ),
9042
- mode === "edit" && /* @__PURE__ */ jsx86("div", { className: "bg-blue-50 border border-blue-200 rounded-lg px-4 py-3 text-sm text-blue-700 transition-all duration-150", children: "\u6B63\u5728\u7F16\u8F91\uFF0C\u4FEE\u6539\u540E\u8BF7\u4FDD\u5B58" }),
9043
- /* @__PURE__ */ jsx86("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ jsx86(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: /* @__PURE__ */ jsx86(FormRenderer, { columns: 2 }) }) }),
9044
- enableChangeRecords && canViewChangeRecords && /* @__PURE__ */ jsx86(
9045
- ChangeRecords,
9046
- {
9047
- records,
9048
- loading: recordsLoading,
9049
- hasMore,
9050
- onLoadMore: loadMore,
9051
- onExpand: refreshRecords
9052
- }
9053
- ),
9054
- footer
11329
+ const actionsNode = currentActions.length > 0 ? renderActions ? renderActions(currentActions) : /* @__PURE__ */ jsx92(StickyActionBar, { actions: currentActions, inDrawer }) : null;
11330
+ return /* @__PURE__ */ jsx92(RuntimePageShell, { actions: actionsNode, accessDenied, inDrawer, children: /* @__PURE__ */ jsx92("div", { className: "space-y-6", children: /* @__PURE__ */ jsxs44("div", { children: [
11331
+ header,
11332
+ renderSummary && instanceInfo ? renderSummary(instanceInfo) : /* @__PURE__ */ jsx92(
11333
+ SummaryPanel,
11334
+ {
11335
+ title: instanceInfo?.title || formData?.instanceTitle || schema.formMeta.title,
11336
+ eyebrow: `\u6570\u636E\u5B9E\u4F8B ${formInstanceId?.slice(0, 8) || "-"}`,
11337
+ creator: instanceInfo?.creator ? {
11338
+ name: instanceInfo.creator.name,
11339
+ avatar: instanceInfo.creator.avatar,
11340
+ department: instanceInfo.creator.department
11341
+ } : void 0,
11342
+ createdAt: instanceInfo?.createdAt,
11343
+ status: mode === "edit" ? { label: "\u7F16\u8F91\u4E2D", tone: "brand" } : void 0
11344
+ }
11345
+ ),
11346
+ mode === "edit" && /* @__PURE__ */ jsx92("div", { className: "bg-blue-50 border border-blue-200 rounded-lg px-4 py-3 text-sm text-blue-700 transition-all duration-150", children: "\u6B63\u5728\u7F16\u8F91\uFF0C\u4FEE\u6539\u540E\u8BF7\u4FDD\u5B58" }),
11347
+ /* @__PURE__ */ jsx92("div", { className: "mt-6 rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: /* @__PURE__ */ jsxs44(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: [
11348
+ /* @__PURE__ */ jsx92(FormDataBridge, { formDataRef }),
11349
+ /* @__PURE__ */ jsx92(FormRenderer, { columns: 2 })
9055
11350
  ] }) }),
9056
- currentActions.length > 0 && (renderActions ? /* @__PURE__ */ jsx86(Fragment6, { children: renderActions(currentActions) }) : /* @__PURE__ */ jsx86(FormActionBar, { position: "bottom-fixed", actions: currentActions }))
9057
- ] });
11351
+ enableChangeRecords && canViewChangeRecords && /* @__PURE__ */ jsx92("div", { className: "mt-6", children: /* @__PURE__ */ jsx92(
11352
+ RecordChangePanel,
11353
+ {
11354
+ records,
11355
+ loading: recordsLoading,
11356
+ total: records.length,
11357
+ hasMore,
11358
+ onLoadMore: loadMore,
11359
+ onRefresh: refreshRecords,
11360
+ onExpand: refreshRecords
11361
+ }
11362
+ ) }),
11363
+ footer
11364
+ ] }) }) });
9058
11365
  };
9059
11366
  var FormDetailTemplate = (props) => {
9060
11367
  const { schema, formUuid, appType, formInstanceId } = props;
@@ -9064,13 +11371,13 @@ var FormDetailTemplate = (props) => {
9064
11371
  appType,
9065
11372
  formInstanceId
9066
11373
  };
9067
- return /* @__PURE__ */ jsx86(FormProvider, { schema, config: wrapperConfig, children: /* @__PURE__ */ jsx86(InnerDetailContent, { ...props }) });
11374
+ return /* @__PURE__ */ jsx92(FormProvider, { schema, config: wrapperConfig, children: /* @__PURE__ */ jsx92(InnerDetailContent, { ...props }) });
9068
11375
  };
9069
11376
 
9070
11377
  // src/templates/ProcessDetailTemplate.tsx
9071
- import { useCallback as useCallback19, useMemo as useMemo15, useRef as useRef14 } from "react";
9072
- import { Fragment as Fragment7, jsx as jsx87, jsxs as jsxs39 } from "react/jsx-runtime";
9073
- function FormDataBridge({
11378
+ import { useCallback as useCallback20, useMemo as useMemo20, useRef as useRef16 } from "react";
11379
+ import { jsx as jsx93, jsxs as jsxs45 } from "react/jsx-runtime";
11380
+ function FormDataBridge2({
9074
11381
  formDataRef
9075
11382
  }) {
9076
11383
  const { getFormData: getFormData2 } = useFormContext();
@@ -9085,12 +11392,16 @@ var InnerProcessContent = ({
9085
11392
  header,
9086
11393
  renderTimeline,
9087
11394
  renderActions,
11395
+ renderTransferSelector,
11396
+ renderReturnNodeLabel,
11397
+ renderActionModalExtra,
9088
11398
  beforeForm,
9089
11399
  afterForm,
9090
- onActionComplete
11400
+ onActionComplete,
11401
+ inDrawer = false
9091
11402
  }) => {
9092
- const formDataRef = useRef14(void 0);
9093
- const fieldIds = useMemo15(() => schema.fields.map((field) => field.fieldId), [schema.fields]);
11403
+ const formDataRef = useRef16(void 0);
11404
+ const fieldIds = useMemo20(() => schema.fields.map((field) => field.fieldId), [schema.fields]);
9094
11405
  const {
9095
11406
  loading,
9096
11407
  processInfo,
@@ -9098,6 +11409,7 @@ var InnerProcessContent = ({
9098
11409
  currentTask,
9099
11410
  progressList,
9100
11411
  formData,
11412
+ instanceInfo,
9101
11413
  isApprover,
9102
11414
  activeActions,
9103
11415
  fieldBehaviors,
@@ -9108,7 +11420,18 @@ var InnerProcessContent = ({
9108
11420
  switchToReadonly,
9109
11421
  refreshProgress
9110
11422
  } = useProcessDetail({ formUuid, appType, formInstanceId, fieldIds });
9111
- const { approve, reject, withdraw, save, resubmit } = useApprovalActions({
11423
+ const {
11424
+ approve,
11425
+ reject,
11426
+ transfer,
11427
+ returnTo,
11428
+ withdraw,
11429
+ save,
11430
+ resubmit,
11431
+ callbackTask,
11432
+ returnableNodes,
11433
+ loadReturnableNodes
11434
+ } = useApprovalActions({
9112
11435
  formInstanceId,
9113
11436
  formUuid,
9114
11437
  appType,
@@ -9117,72 +11440,102 @@ var InnerProcessContent = ({
9117
11440
  onActionComplete?.(action);
9118
11441
  await refreshProgress();
9119
11442
  },
9120
- getFormValues: () => formDataRef.current?.() ?? {}
11443
+ getFormValues: () => formDataRef.current?.() ?? formData ?? {}
9121
11444
  });
9122
- const handleApprove = useCallback19(
11445
+ const handleApprove = useCallback20(
9123
11446
  async (comments) => {
9124
11447
  await approve(comments);
9125
11448
  },
9126
11449
  [approve]
9127
11450
  );
9128
- const handleReject = useCallback19(
11451
+ const handleReject = useCallback20(
9129
11452
  async (comments) => {
9130
11453
  await reject(comments);
9131
11454
  },
9132
11455
  [reject]
9133
11456
  );
9134
- const handleWithdraw = useCallback19(
11457
+ const handleTransfer = useCallback20(
11458
+ async (userId, reason) => {
11459
+ await transfer(userId, reason);
11460
+ },
11461
+ [transfer]
11462
+ );
11463
+ const handleReturn = useCallback20(
11464
+ async (nodeId, reason) => {
11465
+ await returnTo(nodeId, reason);
11466
+ },
11467
+ [returnTo]
11468
+ );
11469
+ const handleWithdraw = useCallback20(
9135
11470
  async (reason) => {
9136
11471
  await withdraw(reason);
9137
11472
  },
9138
11473
  [withdraw]
9139
11474
  );
9140
- const handleSave = useCallback19(async () => {
11475
+ const handleSave = useCallback20(async () => {
9141
11476
  await save();
9142
11477
  }, [save]);
9143
- const handleResubmit = useCallback19(async () => {
9144
- await resubmit();
9145
- }, [resubmit]);
9146
- const buildActions = () => {
9147
- const actions = [];
9148
- if (isApprover && activeActions.length > 0) {
9149
- return [];
9150
- }
11478
+ const handleResubmit = useCallback20(
11479
+ async (comments) => {
11480
+ await resubmit(comments);
11481
+ },
11482
+ [resubmit]
11483
+ );
11484
+ const handleCallback = useCallback20(async () => {
11485
+ await callbackTask();
11486
+ }, [callbackTask]);
11487
+ const bottomActions = useMemo20(() => {
11488
+ if (isApprover && activeActions.length > 0) return [];
9151
11489
  if (isOriginatorReturn) {
9152
11490
  if (mode === "readonly") {
9153
- actions.push({
9154
- key: "edit",
9155
- label: "\u7F16\u8F91",
9156
- type: "primary",
9157
- onClick: switchToEdit
9158
- });
9159
- } else {
9160
- actions.push({
11491
+ return [
11492
+ {
11493
+ key: "edit",
11494
+ label: "\u7F16\u8F91",
11495
+ type: "primary",
11496
+ onClick: switchToEdit
11497
+ }
11498
+ ];
11499
+ }
11500
+ return [
11501
+ {
9161
11502
  key: "cancel",
9162
11503
  label: "\u53D6\u6D88",
9163
11504
  type: "default",
9164
- onClick: switchToReadonly
9165
- });
9166
- actions.push({
11505
+ onClick: switchToReadonly,
11506
+ placement: "left"
11507
+ },
11508
+ {
9167
11509
  key: "resubmit",
9168
11510
  label: "\u91CD\u65B0\u63D0\u4EA4",
9169
11511
  type: "primary",
9170
- onClick: handleResubmit
9171
- });
9172
- }
9173
- return actions;
11512
+ onClick: () => handleResubmit()
11513
+ }
11514
+ ];
9174
11515
  }
9175
11516
  if (canWithdraw) {
9176
- actions.push({
9177
- key: "withdraw",
9178
- label: "\u64A4\u9500",
9179
- type: "default",
9180
- onClick: () => handleWithdraw(),
9181
- confirm: { title: "\u786E\u8BA4\u64A4\u9500", content: "\u786E\u8BA4\u8981\u64A4\u9500\u6B64\u6D41\u7A0B\u5417\uFF1F" }
9182
- });
11517
+ return [
11518
+ {
11519
+ key: "withdraw",
11520
+ label: "\u64A4\u9500",
11521
+ type: "danger",
11522
+ onClick: () => handleWithdraw(),
11523
+ confirm: { title: "\u786E\u8BA4\u64A4\u9500", content: "\u64A4\u9500\u540E\u6D41\u7A0B\u5C06\u7EC8\u6B62\uFF0C\u786E\u8BA4\u7EE7\u7EED\u5417\uFF1F" }
11524
+ }
11525
+ ];
9183
11526
  }
9184
- return actions;
9185
- };
11527
+ return [];
11528
+ }, [
11529
+ activeActions.length,
11530
+ canWithdraw,
11531
+ handleResubmit,
11532
+ handleWithdraw,
11533
+ isApprover,
11534
+ isOriginatorReturn,
11535
+ mode,
11536
+ switchToEdit,
11537
+ switchToReadonly
11538
+ ]);
9186
11539
  const formConfig = {
9187
11540
  mode: mode === "edit" ? "edit" : "readonly",
9188
11541
  formUuid,
@@ -9194,50 +11547,68 @@ var InnerProcessContent = ({
9194
11547
  }
9195
11548
  };
9196
11549
  if (loading) {
9197
- return /* @__PURE__ */ jsx87("div", { className: "min-h-screen bg-gray-50/50", children: /* @__PURE__ */ jsx87("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: /* @__PURE__ */ jsx87(PageSkeleton, { type: "process" }) }) });
11550
+ return /* @__PURE__ */ jsx93("div", { className: "min-h-screen bg-ant-bg-layout", children: /* @__PURE__ */ jsx93("div", { className: "mx-auto max-w-4xl px-6 py-8 pb-24", children: /* @__PURE__ */ jsx93(PageSkeleton, { type: "process" }) }) });
9198
11551
  }
9199
- const bottomActions = buildActions();
9200
11552
  const showApprovalActions = isApprover && activeActions.length > 0;
9201
- return /* @__PURE__ */ jsxs39("div", { className: "min-h-screen bg-gray-50/50", children: [
9202
- /* @__PURE__ */ jsx87("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24 space-y-6", children: /* @__PURE__ */ jsxs39("div", { className: "animate-[fadeIn_0.2s_ease-out]", children: [
9203
- header,
9204
- /* @__PURE__ */ jsx87(
9205
- FormSummaryCard,
9206
- {
9207
- title: schema.formMeta.title,
9208
- formInstanceId,
9209
- creator: processInfo?.originatorName ? {
9210
- name: processInfo.originatorName,
9211
- department: processInfo.originatorDepartment
9212
- } : void 0,
9213
- createdAt: processInfo?.createdAt,
9214
- status: processStatus ? PROCESS_STATUS_META[processStatus] : void 0
9215
- }
9216
- ),
9217
- beforeForm,
9218
- mode === "edit" && /* @__PURE__ */ jsx87("div", { className: "bg-blue-50 border border-blue-200 rounded-lg 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" }),
9219
- /* @__PURE__ */ jsx87("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ jsxs39(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: [
9220
- /* @__PURE__ */ jsx87(FormDataBridge, { formDataRef }),
9221
- /* @__PURE__ */ jsx87(FormRenderer, { columns: 2 })
9222
- ] }) }),
9223
- afterForm,
9224
- /* @__PURE__ */ jsxs39("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: [
9225
- /* @__PURE__ */ jsx87("h3", { className: "text-lg font-semibold text-gray-900 mb-4", children: "\u5BA1\u6279\u8FDB\u5EA6" }),
9226
- renderTimeline ? renderTimeline(progressList) : /* @__PURE__ */ jsx87(ApprovalTimeline, { tasks: progressList, showRemarks: true })
9227
- ] })
9228
- ] }) }),
9229
- showApprovalActions && (renderActions ? /* @__PURE__ */ jsx87(Fragment7, { children: renderActions(activeActions) }) : /* @__PURE__ */ jsx87("div", { className: "fixed bottom-0 left-0 right-0 z-50 backdrop-blur-lg bg-white/80 border-t border-gray-200 shadow-[0_-1px_3px_rgba(0,0,0,0.05)] px-6 py-3", children: /* @__PURE__ */ jsx87("div", { className: "max-w-4xl mx-auto flex items-center justify-end", children: /* @__PURE__ */ jsx87(
9230
- ApprovalActions,
11553
+ const actionsNode = showApprovalActions ? renderActions ? renderActions(activeActions) : /* @__PURE__ */ jsx93(
11554
+ ApprovalActionBar,
11555
+ {
11556
+ actions: activeActions,
11557
+ onApprove: handleApprove,
11558
+ onReject: handleReject,
11559
+ onTransfer: handleTransfer,
11560
+ onReturn: handleReturn,
11561
+ onWithdraw: handleWithdraw,
11562
+ onSave: handleSave,
11563
+ onResubmit: handleResubmit,
11564
+ onCallback: handleCallback,
11565
+ returnableNodes,
11566
+ onLoadReturnableNodes: loadReturnableNodes,
11567
+ renderTransferSelector,
11568
+ renderReturnNodeLabel,
11569
+ renderActionModalExtra,
11570
+ inDrawer
11571
+ }
11572
+ ) : bottomActions.length > 0 ? /* @__PURE__ */ jsx93(StickyActionBar, { actions: bottomActions, inDrawer }) : null;
11573
+ const statusMeta = processStatus ? PROCESS_STATUS_META[processStatus] : void 0;
11574
+ return /* @__PURE__ */ jsx93(RuntimePageShell, { actions: actionsNode, inDrawer, children: /* @__PURE__ */ jsxs45("div", { className: "space-y-6", children: [
11575
+ header,
11576
+ /* @__PURE__ */ jsx93(
11577
+ SummaryPanel,
9231
11578
  {
9232
- actions: activeActions,
9233
- onApprove: handleApprove,
9234
- onReject: handleReject,
9235
- onWithdraw: handleWithdraw,
9236
- onSave: handleSave
9237
- }
9238
- ) }) })),
9239
- !showApprovalActions && bottomActions.length > 0 && /* @__PURE__ */ jsx87(FormActionBar, { position: "bottom-fixed", actions: bottomActions })
9240
- ] });
11579
+ title: processInfo?.title || instanceInfo?.title || schema.formMeta.title,
11580
+ eyebrow: `\u6D41\u7A0B\u5B9E\u4F8B ${formInstanceId?.slice(0, 8) || "-"}`,
11581
+ creator: processInfo?.originatorName ? {
11582
+ name: processInfo.originatorName,
11583
+ department: processInfo.originatorDepartment
11584
+ } : void 0,
11585
+ createdAt: processInfo?.createdAt,
11586
+ status: statusMeta,
11587
+ metaItems: [
11588
+ { key: "currentTask", label: "\u5F53\u524D\u8282\u70B9", value: currentTask?.nodeName || "\u65E0" },
11589
+ {
11590
+ key: "processStatus",
11591
+ label: "\u5B9E\u4F8B\u72B6\u6001",
11592
+ value: statusMeta?.label || processStatus || "-"
11593
+ }
11594
+ ]
11595
+ }
11596
+ ),
11597
+ beforeForm,
11598
+ mode === "edit" && /* @__PURE__ */ jsx93("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" }),
11599
+ /* @__PURE__ */ jsx93("div", { className: "rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: /* @__PURE__ */ jsxs45(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: [
11600
+ /* @__PURE__ */ jsx93(FormDataBridge2, { formDataRef }),
11601
+ /* @__PURE__ */ jsx93(FormRenderer, { columns: 2 })
11602
+ ] }) }),
11603
+ afterForm,
11604
+ /* @__PURE__ */ jsxs45("div", { className: "rounded-lg border border-ant-border-secondary bg-ant-bg-container p-5 md:p-6", children: [
11605
+ /* @__PURE__ */ jsx93("div", { className: "mb-4 flex items-center justify-between gap-3", children: /* @__PURE__ */ jsxs45("div", { children: [
11606
+ /* @__PURE__ */ jsx93("h3", { className: "text-base font-semibold text-ant-color-text", children: "\u5BA1\u6279\u8FDB\u5EA6" }),
11607
+ /* @__PURE__ */ jsx93("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" })
11608
+ ] }) }),
11609
+ renderTimeline ? renderTimeline(progressList) : /* @__PURE__ */ jsx93(ApprovalTimeline, { tasks: progressList, showRemarks: true, showApproverInfo: true })
11610
+ ] })
11611
+ ] }) });
9241
11612
  };
9242
11613
  var ProcessDetailTemplate = (props) => {
9243
11614
  const { schema, formUuid, appType, formInstanceId } = props;
@@ -9247,10 +11618,11 @@ var ProcessDetailTemplate = (props) => {
9247
11618
  appType,
9248
11619
  formInstanceId
9249
11620
  };
9250
- return /* @__PURE__ */ jsx87(FormProvider, { schema, config: wrapperConfig, children: /* @__PURE__ */ jsx87(InnerProcessContent, { ...props }) });
11621
+ return /* @__PURE__ */ jsx93(FormProvider, { schema, config: wrapperConfig, children: /* @__PURE__ */ jsx93(InnerProcessContent, { ...props }) });
9251
11622
  };
9252
11623
  export {
9253
11624
  AddressField,
11625
+ ApprovalActionBar,
9254
11626
  ApprovalActions,
9255
11627
  ApprovalTimeline,
9256
11628
  AssociationFormField,
@@ -9261,6 +11633,7 @@ export {
9261
11633
  CheckboxField,
9262
11634
  ComponentRegistryContext,
9263
11635
  ComponentRegistryProvider,
11636
+ DataManagementList,
9264
11637
  DateField,
9265
11638
  DepartmentSelectField,
9266
11639
  DigitalSignatureField,
@@ -9292,34 +11665,58 @@ export {
9292
11665
  ProcessDetailTemplate,
9293
11666
  ProcessPreview,
9294
11667
  RadioField,
11668
+ RecordChangePanel,
11669
+ RuntimePageShell,
9295
11670
  SelectField,
9296
11671
  SerialNumberField,
11672
+ StickyActionBar,
9297
11673
  SubFormField,
11674
+ SummaryPanel,
9298
11675
  TASK_STATUS_META,
9299
11676
  TextAreaField,
9300
11677
  TextField,
9301
11678
  TextAreaField as TextareaField,
9302
11679
  UserSelectField,
11680
+ advancedSearchDataManagement,
11681
+ batchApproveDataManagementRows,
11682
+ buildFilterPayload,
9303
11683
  checkUserApproval,
9304
11684
  createFormRuntimeApi,
9305
11685
  defaultComponentRegistry,
9306
11686
  defineFormSchema,
11687
+ deleteDataManagementRows,
9307
11688
  deleteFormData,
9308
11689
  evaluateEffects,
11690
+ exportDataManagementRows,
9309
11691
  extractFormValues,
9310
11692
  getChangeRecords,
11693
+ getDataManagementConfig,
11694
+ getDataManagementSchema,
11695
+ getDataManagementTransferRecords,
9311
11696
  getFormData,
9312
11697
  getProcessBasic,
9313
11698
  getProcessDefinition,
9314
11699
  getProcessProgress,
9315
11700
  getReturnableNodes,
11701
+ getSystemFieldsForFormType,
9316
11702
  getViewPermission,
9317
11703
  handleApproval,
11704
+ hasViewOperation,
11705
+ hasViewPermission,
11706
+ importDataManagementRows,
11707
+ importPreviewDataManagementRows,
11708
+ normalizeColumnConfig,
11709
+ normalizeDataManagementFields,
11710
+ normalizeDataManagementList,
11711
+ normalizeFieldBehaviors,
11712
+ normalizeOperation,
9318
11713
  previewProcess,
9319
11714
  resubmitTask,
9320
11715
  returnTask,
11716
+ saveDataManagementConfig,
9321
11717
  saveTask,
9322
11718
  transferTask,
11719
+ triggerCallbackTask,
9323
11720
  useApprovalActions,
9324
11721
  useChangeRecords,
9325
11722
  useComponent,