sy-form-components 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -31,55 +31,91 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  AddressField: () => AddressField,
34
+ ApprovalActions: () => ApprovalActions,
35
+ ApprovalTimeline: () => ApprovalTimeline,
34
36
  AssociationFormField: () => AssociationFormField,
35
37
  AttachmentField: () => AttachmentField,
36
38
  CascadeDateField: () => CascadeDateField,
37
39
  CascadeSelectField: () => CascadeSelectField,
40
+ ChangeRecords: () => ChangeRecords,
38
41
  CheckboxField: () => CheckboxField,
39
42
  ComponentRegistryContext: () => ComponentRegistryContext,
40
43
  ComponentRegistryProvider: () => ComponentRegistryProvider,
41
44
  DateField: () => DateField,
42
45
  DepartmentSelectField: () => DepartmentSelectField,
43
46
  DigitalSignatureField: () => DigitalSignatureField,
47
+ DraftManager: () => DraftManager,
44
48
  EditorField: () => EditorField,
45
49
  EmployeeSelectField: () => UserSelectField,
46
50
  FieldWrapper: () => FieldWrapper,
51
+ FormActionBar: () => FormActionBar,
47
52
  FormActions: () => FormActions,
48
53
  FormContainer: () => FormContainer,
49
54
  FormContext: () => FormContext,
55
+ FormDetailTemplate: () => FormDetailTemplate,
50
56
  FormGrid: () => FormGrid,
51
57
  FormProvider: () => FormProvider,
52
58
  FormRenderer: () => FormRenderer,
53
59
  FormSection: () => FormSection,
54
60
  FormSteps: () => FormSteps,
61
+ FormSubmitTemplate: () => FormSubmitTemplate,
55
62
  FormSummary: () => FormSummary,
63
+ FormSummaryCard: () => FormSummaryCard,
56
64
  FormTabs: () => FormTabs,
57
65
  ImageField: () => ImageField,
58
66
  JSONField: () => JSONField,
59
67
  LocationField: () => LocationField,
60
68
  MultiSelectField: () => MultiSelectField,
61
69
  NumberField: () => NumberField,
70
+ PROCESS_STATUS_META: () => PROCESS_STATUS_META,
71
+ PageSkeleton: () => PageSkeleton,
72
+ ProcessDetailTemplate: () => ProcessDetailTemplate,
73
+ ProcessPreview: () => ProcessPreview,
62
74
  RadioField: () => RadioField,
63
75
  SelectField: () => SelectField,
64
76
  SerialNumberField: () => SerialNumberField,
65
77
  SubFormField: () => SubFormField,
78
+ TASK_STATUS_META: () => TASK_STATUS_META,
66
79
  TextAreaField: () => TextAreaField,
67
80
  TextField: () => TextField,
68
81
  TextareaField: () => TextAreaField,
69
82
  UserSelectField: () => UserSelectField,
83
+ checkUserApproval: () => checkUserApproval,
70
84
  createFormRuntimeApi: () => createFormRuntimeApi,
71
85
  defaultComponentRegistry: () => defaultComponentRegistry,
72
86
  defineFormSchema: () => defineFormSchema,
87
+ deleteFormData: () => deleteFormData,
73
88
  evaluateEffects: () => evaluateEffects,
89
+ getChangeRecords: () => getChangeRecords,
90
+ getFormData: () => getFormData,
91
+ getProcessBasic: () => getProcessBasic,
92
+ getProcessDefinition: () => getProcessDefinition,
93
+ getProcessProgress: () => getProcessProgress,
94
+ getReturnableNodes: () => getReturnableNodes,
95
+ getViewPermission: () => getViewPermission,
96
+ handleApproval: () => handleApproval,
97
+ previewProcess: () => previewProcess,
98
+ resubmitTask: () => resubmitTask,
99
+ returnTask: () => returnTask,
100
+ saveTask: () => saveTask,
101
+ transferTask: () => transferTask,
102
+ useApprovalActions: () => useApprovalActions,
103
+ useChangeRecords: () => useChangeRecords,
74
104
  useComponent: () => useComponent,
75
105
  useDeviceDetect: () => useDeviceDetect,
106
+ useDraftStorage: () => useDraftStorage,
76
107
  useFieldBehavior: () => useFieldBehavior,
108
+ useFieldPermission: () => useFieldPermission,
77
109
  useFormContext: () => useFormContext,
78
110
  useFormData: () => useFormData,
111
+ useFormDetail: () => useFormDetail,
79
112
  useFormEngine: () => useFormEngine,
113
+ useFormNavigation: () => useFormNavigation,
80
114
  useFormSubmit: () => useFormSubmit,
115
+ useProcessDetail: () => useProcessDetail,
81
116
  validateAllFields: () => validateAllFields,
82
- validateField: () => validateField
117
+ validateField: () => validateField,
118
+ withdrawProcess: () => withdrawProcess
83
119
  });
84
120
  module.exports = __toCommonJS(index_exports);
85
121
 
@@ -3757,7 +3793,12 @@ var CHUNK_UPLOAD_THRESHOLD = 10 * 1024 * 1024;
3757
3793
  var trimTrailingSlash = (value) => String(value || "").replace(/\/$/, "");
3758
3794
  var getDefaultBaseUrl = () => {
3759
3795
  const globalEnv = globalThis.process?.env;
3760
- return trimTrailingSlash(globalEnv?.FORM_API_BASE_URL || globalEnv?.BASE_API_URL || "");
3796
+ const envBaseUrl = globalEnv?.FORM_API_BASE_URL || globalEnv?.BASE_API_URL;
3797
+ if (envBaseUrl) return trimTrailingSlash(envBaseUrl);
3798
+ const browserGlobal = typeof window !== "undefined" ? window : void 0;
3799
+ const windowBaseUrl = browserGlobal?.FORM_API_BASE_URL || browserGlobal?.BASE_API_URL || browserGlobal?.__FORM_API_BASE_URL__ || browserGlobal?.__LOWCODE_API_BASE_URL__;
3800
+ if (windowBaseUrl) return trimTrailingSlash(windowBaseUrl);
3801
+ return typeof window !== "undefined" ? "/service" : "";
3761
3802
  };
3762
3803
  var appendQuery = (url, params) => {
3763
3804
  if (!params) return url;
@@ -4121,7 +4162,7 @@ function FormProvider({
4121
4162
  });
4122
4163
  }, []);
4123
4164
  const getFieldValue = (0, import_react34.useCallback)((fieldId) => formData[fieldId], [formData]);
4124
- const getFormData = (0, import_react34.useCallback)(() => ({ ...formData }), [formData]);
4165
+ const getFormData2 = (0, import_react34.useCallback)(() => ({ ...formData }), [formData]);
4125
4166
  const validateFieldById = (0, import_react34.useCallback)(
4126
4167
  async (fieldId) => {
4127
4168
  const field = schema.fields.find((f) => f.fieldId === fieldId);
@@ -4198,7 +4239,7 @@ function FormProvider({
4198
4239
  },
4199
4240
  setFieldValue,
4200
4241
  getFieldValue,
4201
- getFormData,
4242
+ getFormData: getFormData2,
4202
4243
  validateField: validateFieldById,
4203
4244
  validateAll,
4204
4245
  resetForm,
@@ -4218,7 +4259,7 @@ function FormProvider({
4218
4259
  config.submit,
4219
4260
  setFieldValue,
4220
4261
  getFieldValue,
4221
- getFormData,
4262
+ getFormData2,
4222
4263
  validateFieldById,
4223
4264
  validateAll,
4224
4265
  resetForm,
@@ -4289,14 +4330,14 @@ function FormActions({
4289
4330
  showReset = true,
4290
4331
  onSubmit
4291
4332
  }) {
4292
- const { mode, validateAll, getFormData, resetForm, api, config } = useFormContext();
4333
+ const { mode, validateAll, getFormData: getFormData2, resetForm, api, config } = useFormContext();
4293
4334
  const [isSubmitting, setIsSubmitting] = (0, import_react36.useState)(false);
4294
4335
  const [submitError, setSubmitError] = (0, import_react36.useState)(null);
4295
4336
  const handleSubmit = (0, import_react36.useCallback)(async () => {
4296
4337
  setSubmitError(null);
4297
4338
  const valid = await validateAll();
4298
4339
  if (!valid) return;
4299
- const values = getFormData();
4340
+ const values = getFormData2();
4300
4341
  setIsSubmitting(true);
4301
4342
  try {
4302
4343
  const beforeResult = await config.submit?.beforeSubmit?.(values);
@@ -4327,7 +4368,7 @@ function FormActions({
4327
4368
  } finally {
4328
4369
  setIsSubmitting(false);
4329
4370
  }
4330
- }, [api, config, getFormData, mode, onSubmit, validateAll]);
4371
+ }, [api, config, getFormData2, mode, onSubmit, validateAll]);
4331
4372
  const handleReset = (0, import_react36.useCallback)(() => {
4332
4373
  resetForm();
4333
4374
  }, [resetForm]);
@@ -4387,6 +4428,160 @@ function FormContainer({
4387
4428
  ] });
4388
4429
  }
4389
4430
 
4431
+ // src/core/constants.ts
4432
+ var PROCESS_STATUS_META = {
4433
+ running: { label: "\u5BA1\u6279\u4E2D", tone: "brand" },
4434
+ waiting: { label: "\u7B49\u5F85\u4E2D", tone: "neutral" },
4435
+ exception: { label: "\u6D41\u7A0B\u5F02\u5E38", tone: "danger" },
4436
+ completed: { label: "\u5DF2\u5B8C\u6210", tone: "success" },
4437
+ terminated: { label: "\u5DF2\u62D2\u7EDD", tone: "danger" },
4438
+ withdrawn: { label: "\u5DF2\u64A4\u9500", tone: "neutral" },
4439
+ pending: { label: "\u5F85\u5904\u7406", tone: "brand" },
4440
+ cancelled: { label: "\u5DF2\u53D6\u6D88", tone: "neutral" }
4441
+ };
4442
+ var TASK_STATUS_META = {
4443
+ pending: { label: "\u5F85\u5904\u7406", tone: "brand" },
4444
+ approved: { label: "\u5DF2\u540C\u610F", tone: "success" },
4445
+ rejected: { label: "\u5DF2\u62D2\u7EDD", tone: "danger" },
4446
+ returned: { label: "\u5DF2\u9000\u56DE", tone: "warning" },
4447
+ suspended: { label: "\u5DF2\u6302\u8D77", tone: "neutral" },
4448
+ cancelled: { label: "\u5DF2\u53D6\u6D88", tone: "neutral" },
4449
+ copied: { label: "\u5DF2\u6284\u9001", tone: "neutral" },
4450
+ waiting: { label: "\u7B49\u5F85\u4E2D", tone: "neutral" },
4451
+ simulated: { label: "\u672A\u5F00\u59CB", tone: "neutral" }
4452
+ };
4453
+
4454
+ // src/core/processApi.ts
4455
+ async function getProcessBasic(request, formInstId) {
4456
+ const response = await request({
4457
+ url: `/workflow/instance/${formInstId}/basic`,
4458
+ method: "get"
4459
+ });
4460
+ return response.data || response.result;
4461
+ }
4462
+ async function getProcessProgress(request, formInstId) {
4463
+ const response = await request({
4464
+ url: `/workflow/instance/${formInstId}`,
4465
+ method: "get"
4466
+ });
4467
+ return response.data || response.result || [];
4468
+ }
4469
+ async function checkUserApproval(request, formInstId) {
4470
+ const response = await request({
4471
+ url: `/workflow/instance/${formInstId}/permission`,
4472
+ method: "get"
4473
+ });
4474
+ return response.data || response.result;
4475
+ }
4476
+ async function handleApproval(request, params) {
4477
+ const response = await request({
4478
+ url: "/workflow/approve",
4479
+ method: "post",
4480
+ data: params
4481
+ });
4482
+ return response.data || response.result;
4483
+ }
4484
+ async function withdrawProcess(request, params) {
4485
+ const response = await request({
4486
+ url: `/workflow/instance/${params.instanceId}/withdraw`,
4487
+ method: "put",
4488
+ data: { reason: params.reason }
4489
+ });
4490
+ return response.data || response.result;
4491
+ }
4492
+ async function transferTask(request, params) {
4493
+ const response = await request({
4494
+ url: `/workflow/task/${params.taskId}/transfer`,
4495
+ method: "put",
4496
+ data: { newAssignee: params.newAssignee, reason: params.reason }
4497
+ });
4498
+ return response.data || response.result;
4499
+ }
4500
+ async function returnTask(request, params) {
4501
+ const response = await request({
4502
+ url: `/workflow/task/${params.taskId}/return`,
4503
+ method: "put",
4504
+ data: { targetNodeId: params.targetNodeId, reason: params.reason }
4505
+ });
4506
+ return response.data || response.result;
4507
+ }
4508
+ async function resubmitTask(request, params) {
4509
+ const response = await request({
4510
+ url: `/workflow/task/${params.taskId}/resubmit`,
4511
+ method: "post",
4512
+ data: {
4513
+ formUuid: params.formUuid,
4514
+ appType: params.appType,
4515
+ updateFormDataJson: params.updateFormDataJson,
4516
+ comments: params.comments
4517
+ }
4518
+ });
4519
+ return response.data || response.result;
4520
+ }
4521
+ async function saveTask(request, params) {
4522
+ const response = await request({
4523
+ url: "/workflow/task/save",
4524
+ method: "post",
4525
+ data: params
4526
+ });
4527
+ return response.data || response.result;
4528
+ }
4529
+ async function getReturnableNodes(request, taskId) {
4530
+ const response = await request({
4531
+ url: `/workflow/task/${taskId}/returnable-nodes`,
4532
+ method: "get"
4533
+ });
4534
+ return response.data || response.result || [];
4535
+ }
4536
+ async function previewProcess(request, params) {
4537
+ const response = await request({
4538
+ url: "/workflow/preview",
4539
+ method: "post",
4540
+ data: params
4541
+ });
4542
+ return response.data || response.result || [];
4543
+ }
4544
+ async function getProcessDefinition(request, formUuid) {
4545
+ const response = await request({
4546
+ url: "/workflow/definition/form",
4547
+ method: "get",
4548
+ params: { formUuid }
4549
+ });
4550
+ return response.data || response.result;
4551
+ }
4552
+ async function getFormData(request, params) {
4553
+ const response = await request({
4554
+ url: "/form/queryFormDataByFormInstanceId",
4555
+ method: "get",
4556
+ params
4557
+ });
4558
+ return response.data || response.result;
4559
+ }
4560
+ async function deleteFormData(request, params) {
4561
+ const response = await request({
4562
+ url: `/${params.appType}/v1/form/deleteFormData.json`,
4563
+ method: "post",
4564
+ data: params
4565
+ });
4566
+ return response.data || response.result;
4567
+ }
4568
+ async function getChangeRecords(request, params) {
4569
+ const response = await request({
4570
+ url: "/form/getFormDataChangeRecords",
4571
+ method: "get",
4572
+ params
4573
+ });
4574
+ return response.data || response.result;
4575
+ }
4576
+ async function getViewPermission(request, params) {
4577
+ const response = await request({
4578
+ url: "/permission/form-group/view-permissions",
4579
+ method: "get",
4580
+ params
4581
+ });
4582
+ return response.data || response.result;
4583
+ }
4584
+
4390
4585
  // src/layout/FormSection/index.tsx
4391
4586
  var import_react37 = require("react");
4392
4587
  var import_jsx_runtime70 = require("react/jsx-runtime");
@@ -4587,7 +4782,7 @@ function FormSummary({
4587
4782
  const { schema, formData } = useFormContext();
4588
4783
  const displayFields = fields ? schema.fields.filter((f) => fields.includes(f.fieldId)) : schema.fields;
4589
4784
  const colClass = columnClasses2[columns];
4590
- const formatValue = (value) => {
4785
+ const formatValue2 = (value) => {
4591
4786
  if (value === null || value === void 0 || value === "") return "--";
4592
4787
  if (Array.isArray(value)) {
4593
4788
  if (value.length === 0) return "--";
@@ -4603,7 +4798,7 @@ function FormSummary({
4603
4798
  "data-testid": `summary-field-${field.fieldId}`,
4604
4799
  children: [
4605
4800
  /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: labelClassName ?? "text-sm text-gray-500 mb-1", children: field.label }),
4606
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: valueClassName ?? "text-sm text-gray-900", children: formatValue(formData[field.fieldId]) })
4801
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: valueClassName ?? "text-sm text-gray-900", children: formatValue2(formData[field.fieldId]) })
4607
4802
  ]
4608
4803
  },
4609
4804
  field.fieldId
@@ -4660,7 +4855,7 @@ function useFormEngine(schema, config) {
4660
4855
  });
4661
4856
  }, []);
4662
4857
  const getFieldValue = (0, import_react40.useCallback)((fieldId) => formData[fieldId], [formData]);
4663
- const getFormData = (0, import_react40.useCallback)(() => ({ ...formData }), [formData]);
4858
+ const getFormData2 = (0, import_react40.useCallback)(() => ({ ...formData }), [formData]);
4664
4859
  const validateAll = (0, import_react40.useCallback)(async () => {
4665
4860
  const fieldRules = {};
4666
4861
  for (const field of schema.fields) {
@@ -4687,7 +4882,7 @@ function useFormEngine(schema, config) {
4687
4882
  formData,
4688
4883
  setFieldValue,
4689
4884
  getFieldValue,
4690
- getFormData,
4885
+ getFormData: getFormData2,
4691
4886
  validateAll,
4692
4887
  resetForm,
4693
4888
  mode: config.mode,
@@ -4716,7 +4911,7 @@ function useFormData(initialValues = {}) {
4716
4911
  },
4717
4912
  [formData]
4718
4913
  );
4719
- const getFormData = (0, import_react41.useCallback)(() => {
4914
+ const getFormData2 = (0, import_react41.useCallback)(() => {
4720
4915
  return { ...formData };
4721
4916
  }, [formData]);
4722
4917
  const resetForm = (0, import_react41.useCallback)(() => {
@@ -4727,7 +4922,7 @@ function useFormData(initialValues = {}) {
4727
4922
  formData,
4728
4923
  setFieldValue,
4729
4924
  getFieldValue,
4730
- getFormData,
4925
+ getFormData: getFormData2,
4731
4926
  resetForm,
4732
4927
  dirtyFields
4733
4928
  };
@@ -4791,61 +4986,2138 @@ function useFormSubmit(config) {
4791
4986
  return { submit, isSubmitting, submitError };
4792
4987
  }
4793
4988
 
4989
+ // src/hooks/useFieldPermission.ts
4990
+ var import_react44 = require("react");
4991
+ function useFieldPermission(options) {
4992
+ const { viewPermissions, processDefinition, currentTask, isApprover, mode } = options;
4993
+ const computeBehaviors = (0, import_react44.useCallback)(() => {
4994
+ const behaviors = {};
4995
+ if (!currentTask && viewPermissions) {
4996
+ const { fieldPermissions } = viewPermissions;
4997
+ for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
4998
+ if (perm === "FORM_FILED_HIDDEN") {
4999
+ behaviors[fieldId] = "HIDDEN";
5000
+ } else if (perm === "FORM_FILED_VIEW") {
5001
+ behaviors[fieldId] = "READONLY";
5002
+ } else if (perm === "FORM_FILED_EDIT") {
5003
+ behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
5004
+ }
5005
+ }
5006
+ return behaviors;
5007
+ }
5008
+ if (currentTask && !isApprover && viewPermissions) {
5009
+ const { fieldPermissions } = viewPermissions;
5010
+ for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
5011
+ if (perm === "FORM_FILED_HIDDEN") {
5012
+ behaviors[fieldId] = "HIDDEN";
5013
+ } else {
5014
+ behaviors[fieldId] = "READONLY";
5015
+ }
5016
+ }
5017
+ return behaviors;
5018
+ }
5019
+ if (currentTask && isApprover && currentTask.nodeType === "originator_return") {
5020
+ if (processDefinition?.flowConfig && processDefinition.startNodeId) {
5021
+ const startConfig = processDefinition.flowConfig[processDefinition.startNodeId];
5022
+ if (startConfig) {
5023
+ for (const [fieldId, behavior] of Object.entries(startConfig)) {
5024
+ behaviors[fieldId] = mode === "edit" ? behavior : "READONLY";
5025
+ }
5026
+ return behaviors;
5027
+ }
5028
+ }
5029
+ if (viewPermissions) {
5030
+ for (const fieldId of Object.keys(viewPermissions.fieldPermissions)) {
5031
+ if (viewPermissions.fieldPermissions[fieldId] === "FORM_FILED_HIDDEN") {
5032
+ behaviors[fieldId] = "HIDDEN";
5033
+ } else {
5034
+ behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
5035
+ }
5036
+ }
5037
+ }
5038
+ return behaviors;
5039
+ }
5040
+ if (currentTask && isApprover && processDefinition?.flowConfig) {
5041
+ const nodeConfig = processDefinition.flowConfig[currentTask.nodeId];
5042
+ if (nodeConfig) {
5043
+ for (const [fieldId, behavior] of Object.entries(nodeConfig)) {
5044
+ behaviors[fieldId] = mode === "edit" ? behavior : "READONLY";
5045
+ }
5046
+ return behaviors;
5047
+ }
5048
+ }
5049
+ if (viewPermissions) {
5050
+ const { fieldPermissions } = viewPermissions;
5051
+ for (const [fieldId, perm] of Object.entries(fieldPermissions)) {
5052
+ if (perm === "FORM_FILED_HIDDEN") {
5053
+ behaviors[fieldId] = "HIDDEN";
5054
+ } else if (perm === "FORM_FILED_VIEW") {
5055
+ behaviors[fieldId] = "READONLY";
5056
+ } else if (perm === "FORM_FILED_EDIT") {
5057
+ behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
5058
+ }
5059
+ }
5060
+ }
5061
+ return behaviors;
5062
+ }, [viewPermissions, processDefinition, currentTask, isApprover, mode]);
5063
+ const fieldBehaviors = (0, import_react44.useMemo)(() => computeBehaviors(), [computeBehaviors]);
5064
+ return { fieldBehaviors, computeBehaviors };
5065
+ }
5066
+
5067
+ // src/hooks/useFormDetail.ts
5068
+ var import_react45 = require("react");
5069
+ function buildFieldBehaviors(permissions, mode) {
5070
+ const behaviors = {};
5071
+ if (!permissions) return behaviors;
5072
+ for (const [fieldId, perm] of Object.entries(permissions.fieldPermissions)) {
5073
+ if (perm === "FORM_FILED_HIDDEN") {
5074
+ behaviors[fieldId] = "HIDDEN";
5075
+ } else if (perm === "FORM_FILED_VIEW") {
5076
+ behaviors[fieldId] = "READONLY";
5077
+ } else if (perm === "FORM_FILED_EDIT") {
5078
+ behaviors[fieldId] = mode === "edit" ? "NORMAL" : "READONLY";
5079
+ }
5080
+ }
5081
+ return behaviors;
5082
+ }
5083
+ function useFormDetail(options) {
5084
+ const { formUuid, appType, formInstanceId, onPermissionDenied } = options;
5085
+ const { api } = useFormContext();
5086
+ const request = api.request;
5087
+ const [loading, setLoading] = (0, import_react45.useState)(true);
5088
+ const [mode, setMode] = (0, import_react45.useState)("readonly");
5089
+ const [formData, setFormData] = (0, import_react45.useState)(null);
5090
+ const [instanceInfo, setInstanceInfo] = (0, import_react45.useState)(null);
5091
+ const [permissions, setPermissions] = (0, import_react45.useState)(null);
5092
+ const mountedRef = (0, import_react45.useRef)(true);
5093
+ (0, import_react45.useEffect)(() => {
5094
+ mountedRef.current = true;
5095
+ return () => {
5096
+ mountedRef.current = false;
5097
+ };
5098
+ }, []);
5099
+ const loadData = (0, import_react45.useCallback)(async () => {
5100
+ if (!mountedRef.current) return;
5101
+ setLoading(true);
5102
+ try {
5103
+ const [permResult, formResult] = await Promise.all([
5104
+ getViewPermission(request, { formUuid, appType, formInstanceId }),
5105
+ getFormData(request, { formInstanceId, appType, formUuid })
5106
+ ]);
5107
+ if (!mountedRef.current) return;
5108
+ if (!permResult || !permResult.operations || permResult.operations.length === 0) {
5109
+ onPermissionDenied?.();
5110
+ }
5111
+ setPermissions(permResult);
5112
+ setInstanceInfo(formResult);
5113
+ setFormData(formResult?.data ?? null);
5114
+ } catch (error) {
5115
+ console.error("[useFormDetail] Failed to load data:", error);
5116
+ if (mountedRef.current) {
5117
+ setPermissions(null);
5118
+ setInstanceInfo(null);
5119
+ setFormData(null);
5120
+ }
5121
+ } finally {
5122
+ if (mountedRef.current) {
5123
+ setLoading(false);
5124
+ }
5125
+ }
5126
+ }, [request, formUuid, appType, formInstanceId, onPermissionDenied]);
5127
+ (0, import_react45.useEffect)(() => {
5128
+ loadData();
5129
+ }, [loadData]);
5130
+ const fieldBehaviors = buildFieldBehaviors(permissions, mode);
5131
+ const canEdit = permissions?.operations?.includes("EDIT") ?? false;
5132
+ const canDelete = permissions?.operations?.includes("DELETE") ?? false;
5133
+ const canViewChangeRecords = permissions?.operations?.includes("VIEW_CHANGE_RECORDS") ?? false;
5134
+ const switchToEdit = (0, import_react45.useCallback)(() => {
5135
+ setMode("edit");
5136
+ loadData();
5137
+ }, [loadData]);
5138
+ const switchToReadonly = (0, import_react45.useCallback)(() => {
5139
+ setMode("readonly");
5140
+ }, []);
5141
+ const saveChanges = (0, import_react45.useCallback)(
5142
+ async (values) => {
5143
+ try {
5144
+ await api.updateFormData({
5145
+ formInstanceId,
5146
+ formUuid,
5147
+ appType,
5148
+ updateFormDataJson: JSON.stringify(values)
5149
+ });
5150
+ if (mountedRef.current) {
5151
+ setFormData(values);
5152
+ setMode("readonly");
5153
+ }
5154
+ return true;
5155
+ } catch (error) {
5156
+ console.error("[useFormDetail] Failed to save changes:", error);
5157
+ return false;
5158
+ }
5159
+ },
5160
+ [api, formInstanceId, formUuid, appType]
5161
+ );
5162
+ const deleteInstance = (0, import_react45.useCallback)(async () => {
5163
+ try {
5164
+ await deleteFormData(request, { formInstanceId, appType, formUuid });
5165
+ return true;
5166
+ } catch (error) {
5167
+ console.error("[useFormDetail] Failed to delete instance:", error);
5168
+ return false;
5169
+ }
5170
+ }, [request, formInstanceId, appType, formUuid]);
5171
+ return {
5172
+ loading,
5173
+ mode,
5174
+ formData,
5175
+ instanceInfo,
5176
+ permissions,
5177
+ fieldBehaviors,
5178
+ switchToEdit,
5179
+ switchToReadonly,
5180
+ saveChanges,
5181
+ deleteInstance,
5182
+ canEdit,
5183
+ canDelete,
5184
+ canViewChangeRecords
5185
+ };
5186
+ }
5187
+
5188
+ // src/hooks/useProcessDetail.ts
5189
+ var import_react46 = require("react");
5190
+ function useProcessDetail(options) {
5191
+ const { formUuid, appType, formInstanceId } = options;
5192
+ const { api } = useFormContext();
5193
+ const request = api.request;
5194
+ const [loading, setLoading] = (0, import_react46.useState)(true);
5195
+ const [mode, setMode] = (0, import_react46.useState)("readonly");
5196
+ const [processInfo, setProcessInfo] = (0, import_react46.useState)(null);
5197
+ const [progressList, setProgressList] = (0, import_react46.useState)([]);
5198
+ const [formData, setFormData] = (0, import_react46.useState)(null);
5199
+ const [instanceInfo, setInstanceInfo] = (0, import_react46.useState)(null);
5200
+ const [isApprover, setIsApprover] = (0, import_react46.useState)(false);
5201
+ const [canWithdraw, setCanWithdraw] = (0, import_react46.useState)(false);
5202
+ const [permissions, setPermissions] = (0, import_react46.useState)(null);
5203
+ const [processDefinition, setProcessDefinition] = (0, import_react46.useState)(null);
5204
+ const mountedRef = (0, import_react46.useRef)(true);
5205
+ (0, import_react46.useEffect)(() => {
5206
+ mountedRef.current = true;
5207
+ return () => {
5208
+ mountedRef.current = false;
5209
+ };
5210
+ }, []);
5211
+ const currentTask = processInfo?.currentTask ?? null;
5212
+ const processStatus = processInfo?.processStatus ?? null;
5213
+ const isOriginatorReturn = currentTask?.nodeType === "originator_return";
5214
+ const isProcessCompleted = processStatus === "completed" || processStatus === "terminated";
5215
+ const { fieldBehaviors } = useFieldPermission({
5216
+ viewPermissions: permissions ?? void 0,
5217
+ processDefinition: processDefinition ?? void 0,
5218
+ currentTask: currentTask ?? void 0,
5219
+ isApprover,
5220
+ mode
5221
+ });
5222
+ const activeActions = isApprover && currentTask?.actions ? currentTask.actions : [];
5223
+ const loadData = (0, import_react46.useCallback)(async () => {
5224
+ if (!mountedRef.current) return;
5225
+ setLoading(true);
5226
+ try {
5227
+ const [basicResult, approvalResult, permResult, formResult] = await Promise.all([
5228
+ getProcessBasic(request, formInstanceId),
5229
+ checkUserApproval(request, formInstanceId),
5230
+ getViewPermission(request, { formUuid, appType, formInstanceId }),
5231
+ getFormData(request, { formInstanceId, appType, formUuid })
5232
+ ]);
5233
+ if (!mountedRef.current) return;
5234
+ setProcessInfo(basicResult);
5235
+ setIsApprover(approvalResult?.isApprover ?? false);
5236
+ setCanWithdraw(approvalResult?.canUndo ?? false);
5237
+ setPermissions(permResult);
5238
+ setInstanceInfo(formResult);
5239
+ setFormData(formResult?.data ?? null);
5240
+ if (permResult?.operations?.includes("VIEW_PROCESS") || permResult?.operations?.length > 0) {
5241
+ try {
5242
+ const progress = await getProcessProgress(request, formInstanceId);
5243
+ if (mountedRef.current) {
5244
+ setProgressList(progress);
5245
+ }
5246
+ } catch (error) {
5247
+ console.error("[useProcessDetail] Failed to load progress:", error);
5248
+ }
5249
+ }
5250
+ const task = basicResult?.currentTask;
5251
+ if (approvalResult?.isApprover && task && (task.nodeType === "originator_return" || task.nodeType === "approval")) {
5252
+ try {
5253
+ const definition = await getProcessDefinition(request, formUuid);
5254
+ if (mountedRef.current) {
5255
+ setProcessDefinition(definition);
5256
+ }
5257
+ } catch (error) {
5258
+ console.error("[useProcessDetail] Failed to load process definition:", error);
5259
+ }
5260
+ }
5261
+ } catch (error) {
5262
+ console.error("[useProcessDetail] Failed to load data:", error);
5263
+ if (mountedRef.current) {
5264
+ setProcessInfo(null);
5265
+ setFormData(null);
5266
+ setInstanceInfo(null);
5267
+ }
5268
+ } finally {
5269
+ if (mountedRef.current) {
5270
+ setLoading(false);
5271
+ }
5272
+ }
5273
+ }, [request, formUuid, appType, formInstanceId]);
5274
+ (0, import_react46.useEffect)(() => {
5275
+ loadData();
5276
+ }, [loadData]);
5277
+ const switchToEdit = (0, import_react46.useCallback)(() => {
5278
+ setMode("edit");
5279
+ }, []);
5280
+ const switchToReadonly = (0, import_react46.useCallback)(() => {
5281
+ setMode("readonly");
5282
+ }, []);
5283
+ const refreshProgress = (0, import_react46.useCallback)(async () => {
5284
+ try {
5285
+ const [progress, basicResult] = await Promise.all([
5286
+ getProcessProgress(request, formInstanceId),
5287
+ getProcessBasic(request, formInstanceId)
5288
+ ]);
5289
+ if (mountedRef.current) {
5290
+ setProgressList(progress);
5291
+ setProcessInfo(basicResult);
5292
+ }
5293
+ } catch (error) {
5294
+ console.error("[useProcessDetail] Failed to refresh progress:", error);
5295
+ }
5296
+ }, [request, formInstanceId]);
5297
+ return {
5298
+ loading,
5299
+ processInfo,
5300
+ processStatus,
5301
+ currentTask,
5302
+ progressList,
5303
+ formData,
5304
+ instanceInfo,
5305
+ isApprover,
5306
+ activeActions,
5307
+ fieldBehaviors,
5308
+ mode,
5309
+ isOriginatorReturn,
5310
+ isProcessCompleted,
5311
+ canWithdraw,
5312
+ switchToEdit,
5313
+ switchToReadonly,
5314
+ refreshProgress
5315
+ };
5316
+ }
5317
+
5318
+ // src/hooks/useApprovalActions.ts
5319
+ var import_react47 = require("react");
5320
+ function useApprovalActions(options) {
5321
+ const { formInstanceId, formUuid, appType, currentTaskId, onActionComplete, getFormValues } = options;
5322
+ const { api } = useFormContext();
5323
+ const request = api.request;
5324
+ const [isLoading, setIsLoading] = (0, import_react47.useState)(false);
5325
+ const [currentAction, setCurrentAction] = (0, import_react47.useState)(null);
5326
+ const [returnableNodes, setReturnableNodes] = (0, import_react47.useState)([]);
5327
+ const mountedRef = (0, import_react47.useRef)(true);
5328
+ (0, import_react47.useEffect)(() => {
5329
+ mountedRef.current = true;
5330
+ return () => {
5331
+ mountedRef.current = false;
5332
+ };
5333
+ }, []);
5334
+ const resetLoading = (0, import_react47.useCallback)(() => {
5335
+ if (mountedRef.current) {
5336
+ setIsLoading(false);
5337
+ setCurrentAction(null);
5338
+ }
5339
+ }, []);
5340
+ const approve = (0, import_react47.useCallback)(
5341
+ async (comments) => {
5342
+ setIsLoading(true);
5343
+ setCurrentAction("approve");
5344
+ try {
5345
+ const formValues = getFormValues?.();
5346
+ await handleApproval(request, {
5347
+ instanceId: formInstanceId,
5348
+ action: "approved",
5349
+ comments,
5350
+ appType,
5351
+ formUuid,
5352
+ updateFormDataJson: formValues ? JSON.stringify(formValues) : void 0
5353
+ });
5354
+ resetLoading();
5355
+ onActionComplete?.("approve");
5356
+ return true;
5357
+ } catch (error) {
5358
+ console.error("[useApprovalActions] approve failed:", error);
5359
+ resetLoading();
5360
+ return false;
5361
+ }
5362
+ },
5363
+ [request, formInstanceId, appType, formUuid, getFormValues, onActionComplete, resetLoading]
5364
+ );
5365
+ const reject = (0, import_react47.useCallback)(
5366
+ async (comments) => {
5367
+ setIsLoading(true);
5368
+ setCurrentAction("reject");
5369
+ try {
5370
+ const formValues = getFormValues?.();
5371
+ await handleApproval(request, {
5372
+ instanceId: formInstanceId,
5373
+ action: "rejected",
5374
+ comments,
5375
+ appType,
5376
+ formUuid,
5377
+ updateFormDataJson: formValues ? JSON.stringify(formValues) : void 0
5378
+ });
5379
+ resetLoading();
5380
+ onActionComplete?.("reject");
5381
+ return true;
5382
+ } catch (error) {
5383
+ console.error("[useApprovalActions] reject failed:", error);
5384
+ resetLoading();
5385
+ return false;
5386
+ }
5387
+ },
5388
+ [request, formInstanceId, appType, formUuid, getFormValues, onActionComplete, resetLoading]
5389
+ );
5390
+ const transfer = (0, import_react47.useCallback)(
5391
+ async (userId, reason) => {
5392
+ if (!currentTaskId) {
5393
+ console.error("[useApprovalActions] transfer failed: no currentTaskId");
5394
+ return false;
5395
+ }
5396
+ setIsLoading(true);
5397
+ setCurrentAction("transfer");
5398
+ try {
5399
+ await transferTask(request, {
5400
+ taskId: currentTaskId,
5401
+ newAssignee: userId,
5402
+ reason
5403
+ });
5404
+ resetLoading();
5405
+ onActionComplete?.("transfer");
5406
+ return true;
5407
+ } catch (error) {
5408
+ console.error("[useApprovalActions] transfer failed:", error);
5409
+ resetLoading();
5410
+ return false;
5411
+ }
5412
+ },
5413
+ [request, currentTaskId, onActionComplete, resetLoading]
5414
+ );
5415
+ const returnTo = (0, import_react47.useCallback)(
5416
+ async (nodeId, reason) => {
5417
+ if (!currentTaskId) {
5418
+ console.error("[useApprovalActions] returnTo failed: no currentTaskId");
5419
+ return false;
5420
+ }
5421
+ setIsLoading(true);
5422
+ setCurrentAction("return");
5423
+ try {
5424
+ await returnTask(request, {
5425
+ taskId: currentTaskId,
5426
+ targetNodeId: nodeId,
5427
+ reason
5428
+ });
5429
+ resetLoading();
5430
+ onActionComplete?.("return");
5431
+ return true;
5432
+ } catch (error) {
5433
+ console.error("[useApprovalActions] returnTo failed:", error);
5434
+ resetLoading();
5435
+ return false;
5436
+ }
5437
+ },
5438
+ [request, currentTaskId, onActionComplete, resetLoading]
5439
+ );
5440
+ const withdraw = (0, import_react47.useCallback)(
5441
+ async (reason) => {
5442
+ setIsLoading(true);
5443
+ setCurrentAction("withdraw");
5444
+ try {
5445
+ await withdrawProcess(request, {
5446
+ instanceId: formInstanceId,
5447
+ reason
5448
+ });
5449
+ resetLoading();
5450
+ onActionComplete?.("withdraw");
5451
+ return true;
5452
+ } catch (error) {
5453
+ console.error("[useApprovalActions] withdraw failed:", error);
5454
+ resetLoading();
5455
+ return false;
5456
+ }
5457
+ },
5458
+ [request, formInstanceId, onActionComplete, resetLoading]
5459
+ );
5460
+ const save = (0, import_react47.useCallback)(async () => {
5461
+ setIsLoading(true);
5462
+ setCurrentAction("save");
5463
+ try {
5464
+ const formValues = getFormValues?.() ?? {};
5465
+ await saveTask(request, {
5466
+ instanceId: formInstanceId,
5467
+ formUuid,
5468
+ appType,
5469
+ updateFormDataJson: JSON.stringify(formValues)
5470
+ });
5471
+ resetLoading();
5472
+ onActionComplete?.("save");
5473
+ return true;
5474
+ } catch (error) {
5475
+ console.error("[useApprovalActions] save failed:", error);
5476
+ resetLoading();
5477
+ return false;
5478
+ }
5479
+ }, [request, formInstanceId, formUuid, appType, getFormValues, onActionComplete, resetLoading]);
5480
+ const resubmit = (0, import_react47.useCallback)(
5481
+ async (comments) => {
5482
+ if (!currentTaskId) {
5483
+ console.error("[useApprovalActions] resubmit failed: no currentTaskId");
5484
+ return false;
5485
+ }
5486
+ setIsLoading(true);
5487
+ setCurrentAction("resubmit");
5488
+ try {
5489
+ const formValues = getFormValues?.() ?? {};
5490
+ await resubmitTask(request, {
5491
+ taskId: currentTaskId,
5492
+ formUuid,
5493
+ appType,
5494
+ updateFormDataJson: JSON.stringify(formValues),
5495
+ comments
5496
+ });
5497
+ resetLoading();
5498
+ onActionComplete?.("resubmit");
5499
+ return true;
5500
+ } catch (error) {
5501
+ console.error("[useApprovalActions] resubmit failed:", error);
5502
+ resetLoading();
5503
+ return false;
5504
+ }
5505
+ },
5506
+ [request, currentTaskId, formUuid, appType, getFormValues, onActionComplete, resetLoading]
5507
+ );
5508
+ const loadReturnableNodes = (0, import_react47.useCallback)(async () => {
5509
+ if (!currentTaskId) return;
5510
+ try {
5511
+ const nodes = await getReturnableNodes(request, currentTaskId);
5512
+ if (mountedRef.current) {
5513
+ setReturnableNodes(nodes);
5514
+ }
5515
+ } catch (error) {
5516
+ console.error("[useApprovalActions] loadReturnableNodes failed:", error);
5517
+ }
5518
+ }, [request, currentTaskId]);
5519
+ return {
5520
+ approve,
5521
+ reject,
5522
+ transfer,
5523
+ returnTo,
5524
+ withdraw,
5525
+ save,
5526
+ resubmit,
5527
+ isLoading,
5528
+ currentAction,
5529
+ returnableNodes,
5530
+ loadReturnableNodes
5531
+ };
5532
+ }
5533
+
5534
+ // src/hooks/useChangeRecords.ts
5535
+ var import_react48 = require("react");
5536
+ function useChangeRecords(options) {
5537
+ const { formUuid, appType, formInstanceId, pageSize = 20, autoLoad = true } = options;
5538
+ const { api } = useFormContext();
5539
+ const request = api.request;
5540
+ const [records, setRecords] = (0, import_react48.useState)([]);
5541
+ const [loading, setLoading] = (0, import_react48.useState)(false);
5542
+ const [total, setTotal] = (0, import_react48.useState)(0);
5543
+ const [page, setPage] = (0, import_react48.useState)(1);
5544
+ const mountedRef = (0, import_react48.useRef)(true);
5545
+ (0, import_react48.useEffect)(() => {
5546
+ mountedRef.current = true;
5547
+ return () => {
5548
+ mountedRef.current = false;
5549
+ };
5550
+ }, []);
5551
+ const fetchRecords = (0, import_react48.useCallback)(
5552
+ async (pageNum, append) => {
5553
+ if (!mountedRef.current) return;
5554
+ setLoading(true);
5555
+ try {
5556
+ const result = await getChangeRecords(request, {
5557
+ formUuid,
5558
+ appType,
5559
+ formInstanceId,
5560
+ page: pageNum,
5561
+ pageSize
5562
+ });
5563
+ if (!mountedRef.current) return;
5564
+ if (append) {
5565
+ setRecords((prev) => [...prev, ...result.records]);
5566
+ } else {
5567
+ setRecords(result.records);
5568
+ }
5569
+ setTotal(result.total);
5570
+ setPage(pageNum);
5571
+ } catch (error) {
5572
+ console.error("[useChangeRecords] Failed to load change records:", error);
5573
+ } finally {
5574
+ if (mountedRef.current) {
5575
+ setLoading(false);
5576
+ }
5577
+ }
5578
+ },
5579
+ [request, formUuid, appType, formInstanceId, pageSize]
5580
+ );
5581
+ (0, import_react48.useEffect)(() => {
5582
+ if (autoLoad) {
5583
+ fetchRecords(1, false);
5584
+ }
5585
+ }, [autoLoad, fetchRecords]);
5586
+ const hasMore = records.length < total;
5587
+ const loadMore = (0, import_react48.useCallback)(async () => {
5588
+ if (!hasMore || loading) return;
5589
+ await fetchRecords(page + 1, true);
5590
+ }, [hasMore, loading, page, fetchRecords]);
5591
+ const refresh = (0, import_react48.useCallback)(async () => {
5592
+ setRecords([]);
5593
+ setPage(1);
5594
+ setTotal(0);
5595
+ await fetchRecords(1, false);
5596
+ }, [fetchRecords]);
5597
+ return {
5598
+ records,
5599
+ loading,
5600
+ total,
5601
+ page,
5602
+ loadMore,
5603
+ refresh,
5604
+ hasMore
5605
+ };
5606
+ }
5607
+
5608
+ // src/hooks/useFormNavigation.ts
5609
+ var import_react49 = require("react");
5610
+ var normalizeBasePath = (basePath) => {
5611
+ const normalized = String(basePath || "").replace(/^\/+|\/+$/g, "");
5612
+ return normalized ? `/${normalized}` : "";
5613
+ };
5614
+ var inferBasePath = (appType) => {
5615
+ if (typeof window === "undefined") return "";
5616
+ const pathname = window.location?.pathname || "";
5617
+ const marker = `/${appType}/`;
5618
+ const markerIndex = pathname.indexOf(marker);
5619
+ if (markerIndex <= 0) return "";
5620
+ return pathname.slice(0, markerIndex);
5621
+ };
5622
+ var buildDetailUrl = (appType, formUuid, formInstId, detailType, basePath) => {
5623
+ const prefix = normalizeBasePath(basePath ?? inferBasePath(appType));
5624
+ return `${prefix}/${appType}/${detailType}/${formUuid}?formInstId=${encodeURIComponent(formInstId)}`;
5625
+ };
5626
+ function useFormNavigation(options) {
5627
+ const {
5628
+ appType,
5629
+ formUuid,
5630
+ formType = "form",
5631
+ mode = "redirect",
5632
+ redirectDelay = 3e3,
5633
+ basePath,
5634
+ onStay
5635
+ } = options;
5636
+ const [isRedirecting, setIsRedirecting] = (0, import_react49.useState)(false);
5637
+ const [countdown, setCountdown] = (0, import_react49.useState)(0);
5638
+ const timerRef = (0, import_react49.useRef)(null);
5639
+ const redirectTargetRef = (0, import_react49.useRef)(null);
5640
+ const mountedRef = (0, import_react49.useRef)(true);
5641
+ (0, import_react49.useEffect)(() => {
5642
+ mountedRef.current = true;
5643
+ return () => {
5644
+ mountedRef.current = false;
5645
+ if (timerRef.current) {
5646
+ clearInterval(timerRef.current);
5647
+ timerRef.current = null;
5648
+ }
5649
+ };
5650
+ }, []);
5651
+ const navigateToDetail = (0, import_react49.useCallback)(
5652
+ (formInstId) => {
5653
+ window.location.href = buildDetailUrl(appType, formUuid, formInstId, "formDetail", basePath);
5654
+ },
5655
+ [appType, basePath, formUuid]
5656
+ );
5657
+ const navigateToProcessDetail = (0, import_react49.useCallback)(
5658
+ (formInstId) => {
5659
+ window.location.href = buildDetailUrl(
5660
+ appType,
5661
+ formUuid,
5662
+ formInstId,
5663
+ "processDetail",
5664
+ basePath
5665
+ );
5666
+ },
5667
+ [appType, basePath, formUuid]
5668
+ );
5669
+ const startRedirectCountdown = (0, import_react49.useCallback)(
5670
+ (targetUrl) => {
5671
+ const totalSeconds = Math.ceil(redirectDelay / 1e3);
5672
+ setIsRedirecting(true);
5673
+ setCountdown(totalSeconds);
5674
+ redirectTargetRef.current = targetUrl;
5675
+ timerRef.current = setInterval(() => {
5676
+ if (!mountedRef.current) {
5677
+ if (timerRef.current) {
5678
+ clearInterval(timerRef.current);
5679
+ timerRef.current = null;
5680
+ }
5681
+ return;
5682
+ }
5683
+ setCountdown((prev) => {
5684
+ const next = prev - 1;
5685
+ if (next <= 0) {
5686
+ if (timerRef.current) {
5687
+ clearInterval(timerRef.current);
5688
+ timerRef.current = null;
5689
+ }
5690
+ setIsRedirecting(false);
5691
+ if (redirectTargetRef.current) {
5692
+ window.location.href = redirectTargetRef.current;
5693
+ }
5694
+ return 0;
5695
+ }
5696
+ return next;
5697
+ });
5698
+ }, 1e3);
5699
+ },
5700
+ [redirectDelay]
5701
+ );
5702
+ const cancelRedirect = (0, import_react49.useCallback)(() => {
5703
+ if (timerRef.current) {
5704
+ clearInterval(timerRef.current);
5705
+ timerRef.current = null;
5706
+ }
5707
+ setIsRedirecting(false);
5708
+ setCountdown(0);
5709
+ redirectTargetRef.current = null;
5710
+ }, []);
5711
+ const handlePostSubmit = (0, import_react49.useCallback)(
5712
+ (formInstId) => {
5713
+ if (mode === "stay") {
5714
+ onStay?.(formInstId);
5715
+ return;
5716
+ }
5717
+ if (mode === "callback") {
5718
+ onStay?.(formInstId);
5719
+ return;
5720
+ }
5721
+ const targetUrl = buildDetailUrl(
5722
+ appType,
5723
+ formUuid,
5724
+ formInstId,
5725
+ formType === "process" ? "processDetail" : "formDetail",
5726
+ basePath
5727
+ );
5728
+ startRedirectCountdown(targetUrl);
5729
+ },
5730
+ [mode, formType, appType, formUuid, basePath, onStay, startRedirectCountdown]
5731
+ );
5732
+ return {
5733
+ navigateToDetail,
5734
+ navigateToProcessDetail,
5735
+ handlePostSubmit,
5736
+ isRedirecting,
5737
+ countdown,
5738
+ cancelRedirect
5739
+ };
5740
+ }
5741
+
5742
+ // src/hooks/useDraftStorage.ts
5743
+ var import_react50 = require("react");
5744
+ function getDraftKey(appType, formUuid) {
5745
+ return `${appType}__${formUuid}__draft`;
5746
+ }
5747
+ function readDraft(key) {
5748
+ try {
5749
+ const raw = localStorage.getItem(key);
5750
+ if (!raw) return null;
5751
+ const parsed = JSON.parse(raw);
5752
+ if (parsed && typeof parsed.data === "object" && typeof parsed.ts === "number") {
5753
+ return parsed;
5754
+ }
5755
+ return null;
5756
+ } catch {
5757
+ return null;
5758
+ }
5759
+ }
5760
+ function useDraftStorage(options) {
5761
+ const { appType, formUuid, autoRestore = false } = options;
5762
+ const key = getDraftKey(appType, formUuid);
5763
+ const [hasDraft, setHasDraft] = (0, import_react50.useState)(false);
5764
+ const [draftData, setDraftData] = (0, import_react50.useState)(null);
5765
+ const [draftTimestamp, setDraftTimestamp] = (0, import_react50.useState)(null);
5766
+ (0, import_react50.useEffect)(() => {
5767
+ const stored = readDraft(key);
5768
+ if (stored) {
5769
+ setHasDraft(true);
5770
+ setDraftTimestamp(stored.ts);
5771
+ if (autoRestore) {
5772
+ setDraftData(stored.data);
5773
+ }
5774
+ } else {
5775
+ setHasDraft(false);
5776
+ setDraftData(null);
5777
+ setDraftTimestamp(null);
5778
+ }
5779
+ }, [key, autoRestore]);
5780
+ const saveDraft = (0, import_react50.useCallback)(
5781
+ (data) => {
5782
+ const payload = { data, ts: Date.now() };
5783
+ try {
5784
+ localStorage.setItem(key, JSON.stringify(payload));
5785
+ setHasDraft(true);
5786
+ setDraftData(data);
5787
+ setDraftTimestamp(payload.ts);
5788
+ } catch (error) {
5789
+ console.error("[useDraftStorage] Failed to save draft:", error);
5790
+ }
5791
+ },
5792
+ [key]
5793
+ );
5794
+ const restoreDraft = (0, import_react50.useCallback)(() => {
5795
+ const stored = readDraft(key);
5796
+ if (stored) {
5797
+ setDraftData(stored.data);
5798
+ return stored.data;
5799
+ }
5800
+ return null;
5801
+ }, [key]);
5802
+ const clearDraft = (0, import_react50.useCallback)(() => {
5803
+ try {
5804
+ localStorage.removeItem(key);
5805
+ } catch (error) {
5806
+ console.error("[useDraftStorage] Failed to clear draft:", error);
5807
+ }
5808
+ setHasDraft(false);
5809
+ setDraftData(null);
5810
+ setDraftTimestamp(null);
5811
+ }, [key]);
5812
+ return {
5813
+ hasDraft,
5814
+ draftData,
5815
+ draftTimestamp,
5816
+ saveDraft,
5817
+ restoreDraft,
5818
+ clearDraft
5819
+ };
5820
+ }
5821
+
4794
5822
  // src/utils/defineFormSchema.ts
4795
5823
  function defineFormSchema(schema) {
4796
5824
  return schema;
4797
5825
  }
5826
+
5827
+ // src/modules/FormSummaryCard.tsx
5828
+ var import_jsx_runtime75 = require("react/jsx-runtime");
5829
+ var toneClasses = {
5830
+ brand: "bg-blue-50 text-blue-600",
5831
+ success: "bg-green-50 text-green-600",
5832
+ danger: "bg-red-50 text-red-600",
5833
+ neutral: "bg-gray-100 text-gray-500",
5834
+ warning: "bg-amber-50 text-amber-600"
5835
+ };
5836
+ var FormSummaryCard = ({
5837
+ title,
5838
+ formInstanceId,
5839
+ creator,
5840
+ createdAt,
5841
+ status,
5842
+ className = "",
5843
+ children
5844
+ }) => {
5845
+ const shortId = formInstanceId ? formInstanceId.slice(0, 8) : null;
5846
+ const renderAvatar = () => {
5847
+ if (!creator) return null;
5848
+ if (creator.avatar) {
5849
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
5850
+ "img",
5851
+ {
5852
+ src: creator.avatar,
5853
+ alt: creator.name,
5854
+ className: "w-7 h-7 rounded-full object-cover"
5855
+ }
5856
+ );
5857
+ }
5858
+ const initial = creator.name.charAt(0);
5859
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "w-7 h-7 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center text-xs font-medium", children: initial });
5860
+ };
5861
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: `bg-white rounded-xl shadow-sm border border-gray-100 p-6 ${className}`, children: [
5862
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex items-start justify-between", children: [
5863
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "min-w-0 flex-1", children: [
5864
+ title && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("h2", { className: "text-xl font-semibold text-gray-900 truncate", children: title }),
5865
+ shortId && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("span", { className: "text-xs text-gray-400 mt-0.5 inline-block", children: [
5866
+ "#",
5867
+ shortId
5868
+ ] })
5869
+ ] }),
5870
+ status && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
5871
+ "span",
5872
+ {
5873
+ className: `px-2.5 py-0.5 rounded-full text-xs font-medium whitespace-nowrap ${toneClasses[status.tone] || toneClasses.neutral}`,
5874
+ children: status.label
5875
+ }
5876
+ )
5877
+ ] }),
5878
+ creator && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex items-center gap-2 mt-4 text-sm text-gray-600", children: [
5879
+ renderAvatar(),
5880
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "font-medium", children: creator.name }),
5881
+ creator.department && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
5882
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "text-gray-300", children: "\xB7" }),
5883
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { children: creator.department })
5884
+ ] }),
5885
+ createdAt && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
5886
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "text-gray-300", children: "\xB7" }),
5887
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "text-gray-400", children: createdAt })
5888
+ ] })
5889
+ ] }),
5890
+ children && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "mt-4", children })
5891
+ ] });
5892
+ };
5893
+
5894
+ // src/modules/ChangeRecords.tsx
5895
+ var import_react51 = require("react");
5896
+ var import_antd22 = require("antd");
5897
+ var import_icons = require("@ant-design/icons");
5898
+ var import_jsx_runtime76 = require("react/jsx-runtime");
5899
+ var ChangeRecords = ({
5900
+ records = [],
5901
+ loading = false,
5902
+ defaultExpanded = false,
5903
+ hasMore = false,
5904
+ onLoadMore,
5905
+ onExpand,
5906
+ className = "",
5907
+ renderItem
5908
+ }) => {
5909
+ const [expanded, setExpanded] = (0, import_react51.useState)(defaultExpanded);
5910
+ const handleToggle = () => {
5911
+ const next = !expanded;
5912
+ setExpanded(next);
5913
+ if (next && onExpand) {
5914
+ onExpand();
5915
+ }
5916
+ };
5917
+ const defaultRenderItem = (record) => /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "pl-4 py-3 border-l-2 border-gray-200 ml-1", children: [
5918
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex items-center gap-2 text-xs text-gray-400", children: [
5919
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { children: record.operatedAt }),
5920
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "text-gray-600 font-medium", children: record.operatorName }),
5921
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { children: "\u4FEE\u6539\u4E86" }),
5922
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "text-gray-800 font-medium", children: record.fieldLabel })
5923
+ ] }),
5924
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "mt-1.5 text-sm text-gray-600 flex items-center gap-2", children: [
5925
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "bg-red-50 text-red-600 px-1.5 py-0.5 rounded text-xs line-through", children: formatValue(record.oldValue) }),
5926
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "text-gray-400", children: "\u2192" }),
5927
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "bg-green-50 text-green-600 px-1.5 py-0.5 rounded text-xs", children: formatValue(record.newValue) })
5928
+ ] })
5929
+ ] });
5930
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: `bg-white rounded-xl shadow-sm border border-gray-100 ${className}`, children: [
5931
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
5932
+ "button",
5933
+ {
5934
+ type: "button",
5935
+ className: "w-full flex items-center justify-between p-6 text-left hover:bg-gray-50/50 transition-colors rounded-xl",
5936
+ onClick: handleToggle,
5937
+ children: [
5938
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex items-center gap-2", children: [
5939
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("h3", { className: "text-lg font-semibold text-gray-900", children: "\u53D8\u66F4\u8BB0\u5F55" }),
5940
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "text-xs text-gray-400 bg-gray-100 px-1.5 py-0.5 rounded-full", children: records.length })
5941
+ ] }),
5942
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "text-gray-400 text-xs", children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(import_icons.UpOutlined, {}) : /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(import_icons.DownOutlined, {}) })
5943
+ ]
5944
+ }
5945
+ ),
5946
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "px-6 pb-6", children: [
5947
+ loading && records.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(import_antd22.Skeleton, { active: true, paragraph: { rows: 3 } }) : records.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { className: "text-sm text-gray-400 text-center py-4", children: "\u6682\u65E0\u53D8\u66F4\u8BB0\u5F55" }) : /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "space-y-1", children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { children: renderItem ? renderItem(record) : defaultRenderItem(record) }, record.id)) }),
5948
+ hasMore && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
5949
+ "button",
5950
+ {
5951
+ type: "button",
5952
+ 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",
5953
+ onClick: onLoadMore,
5954
+ disabled: loading,
5955
+ children: loading ? "\u52A0\u8F7D\u4E2D..." : "\u52A0\u8F7D\u66F4\u591A"
5956
+ }
5957
+ )
5958
+ ] })
5959
+ ] });
5960
+ };
5961
+ function formatValue(value) {
5962
+ if (value === null || value === void 0) return "\u7A7A";
5963
+ if (typeof value === "object") return JSON.stringify(value);
5964
+ return String(value);
5965
+ }
5966
+
5967
+ // src/modules/ApprovalTimeline.tsx
5968
+ var import_jsx_runtime77 = require("react/jsx-runtime");
5969
+ var toneClasses2 = {
5970
+ brand: "bg-blue-50 text-blue-600",
5971
+ success: "bg-green-50 text-green-600",
5972
+ danger: "bg-red-50 text-red-600",
5973
+ neutral: "bg-gray-100 text-gray-500",
5974
+ warning: "bg-amber-50 text-amber-600"
5975
+ };
5976
+ function getNodePhase(task) {
5977
+ if (task.status === "approved" || task.status === "rejected" || task.status === "returned" || task.status === "copied") {
5978
+ return "completed";
5979
+ }
5980
+ if (task.status === "pending" || task.status === "waiting") {
5981
+ return "active";
5982
+ }
5983
+ return "pending";
5984
+ }
5985
+ var ApprovalTimeline = ({
5986
+ tasks,
5987
+ className = "",
5988
+ renderNode,
5989
+ showRemarks = true,
5990
+ compactMode = false
5991
+ }) => {
5992
+ if (!tasks || tasks.length === 0) {
5993
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: `bg-white rounded-xl shadow-sm border border-gray-100 p-6 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { className: "text-sm text-gray-400 text-center", children: "\u6682\u65E0\u5BA1\u6279\u8BB0\u5F55" }) });
5994
+ }
5995
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: `${className}`, children: tasks.map((task, index) => {
5996
+ if (renderNode) {
5997
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { children: renderNode(task, index) }, task.taskId);
5998
+ }
5999
+ const phase = getNodePhase(task);
6000
+ const isLast = index === tasks.length - 1;
6001
+ const statusMeta = TASK_STATUS_META[task.status];
6002
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "flex gap-4", children: [
6003
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "flex flex-col items-center", children: [
6004
+ phase === "completed" && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "w-3 h-3 rounded-full bg-green-500 flex-shrink-0" }),
6005
+ phase === "active" && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "w-3 h-3 rounded-full bg-blue-500 ring-4 ring-blue-100 flex-shrink-0" }),
6006
+ phase === "pending" && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "w-3 h-3 rounded-full bg-gray-300 flex-shrink-0" }),
6007
+ !isLast && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
6008
+ "div",
6009
+ {
6010
+ 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"}`
6011
+ }
6012
+ )
6013
+ ] }),
6014
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: `flex-1 pb-6 ${isLast ? "pb-0" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
6015
+ "div",
6016
+ {
6017
+ 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"}`,
6018
+ children: [
6019
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "flex items-center justify-between", children: [
6020
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: "text-sm font-medium text-gray-900", children: task.nodeName }),
6021
+ statusMeta && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
6022
+ "span",
6023
+ {
6024
+ className: `px-2 py-0.5 rounded-full text-xs font-medium ${toneClasses2[statusMeta.tone] || toneClasses2.neutral}`,
6025
+ children: statusMeta.label
6026
+ }
6027
+ )
6028
+ ] }),
6029
+ task.assigneeName && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "mt-2 flex items-center gap-1.5 text-sm text-gray-600", children: [
6030
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: "text-gray-400", children: "\u{1F464}" }),
6031
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("span", { children: [
6032
+ phase === "active" ? "\u5F53\u524D\u5BA1\u6279\u4EBA: " : "",
6033
+ task.assigneeName
6034
+ ] }),
6035
+ task.departmentName && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(import_jsx_runtime77.Fragment, { children: [
6036
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: "text-gray-300", children: "\xB7" }),
6037
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: "text-gray-400", children: task.departmentName })
6038
+ ] })
6039
+ ] }),
6040
+ !compactMode && showRemarks && task.comments && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "mt-2 bg-gray-50 rounded-md p-3 text-sm text-gray-600 italic", children: [
6041
+ "\u{1F4AC} \u201C",
6042
+ task.comments,
6043
+ "\u201D"
6044
+ ] }),
6045
+ !compactMode && phase === "active" && !task.comments && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "mt-2 text-xs text-gray-400", children: "\u23F3 \u7B49\u5F85\u5904\u7406\u4E2D..." }),
6046
+ !compactMode && (task.actionAt || task.createdAt) && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "mt-2 text-xs text-gray-400", children: [
6047
+ "\u{1F550} ",
6048
+ task.actionAt || task.createdAt
6049
+ ] }),
6050
+ compactMode && (task.actionAt || task.createdAt) && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "mt-1 text-xs text-gray-400", children: task.actionAt || task.createdAt })
6051
+ ]
6052
+ }
6053
+ ) })
6054
+ ] }, task.taskId);
6055
+ }) });
6056
+ };
6057
+
6058
+ // src/modules/ApprovalActions.tsx
6059
+ var import_react52 = require("react");
6060
+ var import_antd23 = require("antd");
6061
+ var import_icons2 = require("@ant-design/icons");
6062
+ var import_jsx_runtime78 = require("react/jsx-runtime");
6063
+ var { TextArea: TextArea4 } = import_antd23.Input;
6064
+ var ApprovalActions = ({
6065
+ actions,
6066
+ onApprove,
6067
+ onReject,
6068
+ onTransfer,
6069
+ onReturn,
6070
+ onWithdraw,
6071
+ onSave,
6072
+ layout = "horizontal",
6073
+ maxVisible = 3,
6074
+ className = ""
6075
+ }) => {
6076
+ const [drawerAction, setDrawerAction] = (0, import_react52.useState)(null);
6077
+ const [comments, setComments] = (0, import_react52.useState)("");
6078
+ const [loading, setLoading] = (0, import_react52.useState)(false);
6079
+ const [saveLoading, setSaveLoading] = (0, import_react52.useState)(false);
6080
+ const handleOpenDrawer = (action) => {
6081
+ setComments("");
6082
+ setDrawerAction(action);
6083
+ };
6084
+ const handleConfirm = async () => {
6085
+ setLoading(true);
6086
+ try {
6087
+ if (drawerAction === "approve" && onApprove) {
6088
+ await onApprove(comments || void 0);
6089
+ } else if (drawerAction === "reject" && onReject) {
6090
+ await onReject(comments || void 0);
6091
+ } else if (drawerAction === "withdraw" && onWithdraw) {
6092
+ await onWithdraw(comments || void 0);
6093
+ }
6094
+ setDrawerAction(null);
6095
+ } finally {
6096
+ setLoading(false);
6097
+ }
6098
+ };
6099
+ const handleSave = async () => {
6100
+ if (!onSave) return;
6101
+ setSaveLoading(true);
6102
+ try {
6103
+ await onSave();
6104
+ } finally {
6105
+ setSaveLoading(false);
6106
+ }
6107
+ };
6108
+ const actionMap = {};
6109
+ actions.forEach((action) => {
6110
+ switch (action.action) {
6111
+ case "agree":
6112
+ actionMap["agree"] = {
6113
+ label: action.name.zh_CN || "\u540C\u610F",
6114
+ handler: () => handleOpenDrawer("approve"),
6115
+ type: "primary",
6116
+ color: "green"
6117
+ };
6118
+ break;
6119
+ case "rejected":
6120
+ actionMap["rejected"] = {
6121
+ label: action.name.zh_CN || "\u62D2\u7EDD",
6122
+ handler: () => handleOpenDrawer("reject"),
6123
+ type: "default"
6124
+ };
6125
+ break;
6126
+ case "transfer":
6127
+ actionMap["transfer"] = {
6128
+ label: action.name.zh_CN || "\u8F6C\u4EA4",
6129
+ handler: () => onTransfer?.(),
6130
+ type: "default"
6131
+ };
6132
+ break;
6133
+ case "return":
6134
+ actionMap["return"] = {
6135
+ label: action.name.zh_CN || "\u9000\u56DE",
6136
+ handler: () => onReturn?.(),
6137
+ type: "default"
6138
+ };
6139
+ break;
6140
+ case "withdraw":
6141
+ actionMap["withdraw"] = {
6142
+ label: action.name.zh_CN || "\u64A4\u9500",
6143
+ handler: () => handleOpenDrawer("withdraw"),
6144
+ type: "default"
6145
+ };
6146
+ break;
6147
+ case "save":
6148
+ actionMap["save"] = {
6149
+ label: action.name.zh_CN || "\u6682\u5B58",
6150
+ handler: handleSave,
6151
+ type: "default"
6152
+ };
6153
+ break;
6154
+ }
6155
+ });
6156
+ const allButtons = Object.entries(actionMap);
6157
+ const visibleButtons = allButtons.slice(0, maxVisible);
6158
+ const moreButtons = allButtons.slice(maxVisible);
6159
+ const drawerTitle = drawerAction === "approve" ? "\u5BA1\u6279\u610F\u89C1" : drawerAction === "reject" ? "\u62D2\u7EDD\u7406\u7531" : drawerAction === "withdraw" ? "\u64A4\u9500\u539F\u56E0" : "\u5BA1\u6279\u610F\u89C1";
6160
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
6161
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
6162
+ "div",
6163
+ {
6164
+ className: `${layout === "horizontal" ? "flex items-center gap-3" : "flex flex-col gap-2"} ${className}`,
6165
+ children: [
6166
+ visibleButtons.map(([key, btn]) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
6167
+ import_antd23.Button,
6168
+ {
6169
+ type: btn.type === "primary" ? "primary" : "default",
6170
+ className: btn.color === "green" ? "!bg-green-600 !border-green-600 hover:!bg-green-700" : "",
6171
+ onClick: btn.handler,
6172
+ loading: key === "save" && saveLoading,
6173
+ children: btn.label
6174
+ },
6175
+ key
6176
+ )),
6177
+ moreButtons.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
6178
+ import_antd23.Dropdown,
6179
+ {
6180
+ menu: {
6181
+ items: moreButtons.map(([key, btn]) => ({
6182
+ key,
6183
+ label: btn.label,
6184
+ onClick: btn.handler
6185
+ }))
6186
+ },
6187
+ trigger: ["click"],
6188
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_antd23.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_icons2.MoreOutlined, {}), children: "\u66F4\u591A" })
6189
+ }
6190
+ )
6191
+ ]
6192
+ }
6193
+ ),
6194
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
6195
+ import_antd23.Drawer,
6196
+ {
6197
+ title: drawerTitle,
6198
+ open: drawerAction !== null,
6199
+ onClose: () => setDrawerAction(null),
6200
+ width: 400,
6201
+ footer: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex justify-end gap-3", children: [
6202
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_antd23.Button, { onClick: () => setDrawerAction(null), children: "\u53D6\u6D88" }),
6203
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_antd23.Button, { type: "primary", onClick: handleConfirm, loading, children: [
6204
+ loading && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_icons2.LoadingOutlined, {}),
6205
+ "\u786E\u8BA4"
6206
+ ] })
6207
+ ] }),
6208
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { children: [
6209
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("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" }),
6210
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
6211
+ TextArea4,
6212
+ {
6213
+ rows: 4,
6214
+ value: comments,
6215
+ onChange: (e) => setComments(e.target.value),
6216
+ 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...",
6217
+ maxLength: 500,
6218
+ showCount: true
6219
+ }
6220
+ )
6221
+ ] }) })
6222
+ }
6223
+ )
6224
+ ] });
6225
+ };
6226
+
6227
+ // src/modules/FormActionBar.tsx
6228
+ var import_react53 = require("react");
6229
+ var import_antd24 = require("antd");
6230
+ var import_jsx_runtime79 = require("react/jsx-runtime");
6231
+ var FormActionBar = ({
6232
+ actions,
6233
+ position = "bottom-fixed",
6234
+ className = ""
6235
+ }) => {
6236
+ const [loadingKeys, setLoadingKeys] = (0, import_react53.useState)(/* @__PURE__ */ new Set());
6237
+ const visibleActions = actions.filter((a) => a.visible !== false);
6238
+ const sortedActions = [...visibleActions].sort((a, b) => {
6239
+ if (a.type === "danger" && b.type !== "danger") return -1;
6240
+ if (a.type !== "danger" && b.type === "danger") return 1;
6241
+ if (a.type === "primary" && b.type !== "primary") return 1;
6242
+ if (a.type !== "primary" && b.type === "primary") return -1;
6243
+ return 0;
6244
+ });
6245
+ const handleClick = async (action) => {
6246
+ if (action.confirm) {
6247
+ import_antd24.Modal.confirm({
6248
+ title: action.confirm.title,
6249
+ content: action.confirm.content,
6250
+ okText: "\u786E\u8BA4",
6251
+ cancelText: "\u53D6\u6D88",
6252
+ onOk: async () => {
6253
+ await executeAction(action);
6254
+ }
6255
+ });
6256
+ } else {
6257
+ await executeAction(action);
6258
+ }
6259
+ };
6260
+ const executeAction = async (action) => {
6261
+ setLoadingKeys((prev) => new Set(prev).add(action.key));
6262
+ try {
6263
+ await action.onClick();
6264
+ } finally {
6265
+ setLoadingKeys((prev) => {
6266
+ const next = new Set(prev);
6267
+ next.delete(action.key);
6268
+ return next;
6269
+ });
6270
+ }
6271
+ };
6272
+ const isFixed = position === "bottom-fixed";
6273
+ const bar = /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
6274
+ "div",
6275
+ {
6276
+ 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}`,
6277
+ children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "flex items-center justify-end gap-3 flex-wrap md:flex-nowrap", children: sortedActions.map((action) => {
6278
+ const isLoading = action.loading || loadingKeys.has(action.key);
6279
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
6280
+ import_antd24.Button,
6281
+ {
6282
+ type: action.type === "danger" ? "primary" : action.type === "text" ? "text" : action.type || "default",
6283
+ danger: action.type === "danger",
6284
+ loading: isLoading,
6285
+ disabled: action.disabled,
6286
+ icon: action.icon,
6287
+ onClick: () => handleClick(action),
6288
+ className: "md:w-auto w-full",
6289
+ children: action.label
6290
+ },
6291
+ action.key
6292
+ );
6293
+ }) })
6294
+ }
6295
+ );
6296
+ if (isFixed) {
6297
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(import_jsx_runtime79.Fragment, { children: [
6298
+ bar,
6299
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "h-16" })
6300
+ ] });
6301
+ }
6302
+ return bar;
6303
+ };
6304
+
6305
+ // src/modules/DraftManager.tsx
6306
+ var import_antd25 = require("antd");
6307
+ var import_icons3 = require("@ant-design/icons");
6308
+ var import_jsx_runtime80 = require("react/jsx-runtime");
6309
+ function formatRelativeTime(timestamp) {
6310
+ const now = Date.now();
6311
+ const diff = now - timestamp;
6312
+ const minutes = Math.floor(diff / 6e4);
6313
+ const hours = Math.floor(diff / 36e5);
6314
+ const days = Math.floor(diff / 864e5);
6315
+ if (minutes < 1) return "\u521A\u521A";
6316
+ if (minutes < 60) return `${minutes}\u5206\u949F\u524D`;
6317
+ if (hours < 24) return `${hours}\u5C0F\u65F6\u524D`;
6318
+ return `${days}\u5929\u524D`;
6319
+ }
6320
+ var DraftManager = ({
6321
+ hasDraft,
6322
+ draftTimestamp,
6323
+ onRestore,
6324
+ onDiscard,
6325
+ className = ""
6326
+ }) => {
6327
+ if (!hasDraft) return null;
6328
+ const timeLabel = draftTimestamp ? formatRelativeTime(draftTimestamp) : null;
6329
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
6330
+ "div",
6331
+ {
6332
+ className: `bg-blue-50 border border-blue-200 rounded-lg p-4 animate-[slideDown_0.3s_ease-out] ${className}`,
6333
+ children: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex items-center justify-between flex-wrap gap-3", children: [
6334
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex items-center gap-2 text-sm text-blue-700", children: [
6335
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_icons3.EditOutlined, { className: "text-blue-500" }),
6336
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("span", { children: [
6337
+ "\u68C0\u6D4B\u5230\u672A\u63D0\u4EA4\u7684\u8349\u7A3F",
6338
+ timeLabel && /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("span", { className: "text-blue-500 ml-1", children: [
6339
+ "\uFF08\u4FDD\u5B58\u4E8E ",
6340
+ timeLabel,
6341
+ "\uFF09"
6342
+ ] })
6343
+ ] })
6344
+ ] }),
6345
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex items-center gap-2", children: [
6346
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_antd25.Button, { type: "text", size: "small", onClick: onDiscard, className: "!text-gray-500", children: "\u4E22\u5F03" }),
6347
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(import_antd25.Button, { type: "primary", size: "small", onClick: onRestore, children: "\u6062\u590D\u586B\u5199" })
6348
+ ] })
6349
+ ] })
6350
+ }
6351
+ );
6352
+ };
6353
+
6354
+ // src/modules/ProcessPreview.tsx
6355
+ var import_antd26 = require("antd");
6356
+ var import_icons4 = require("@ant-design/icons");
6357
+ var import_jsx_runtime81 = require("react/jsx-runtime");
6358
+ var ProcessPreview = ({
6359
+ open,
6360
+ onClose,
6361
+ onConfirm,
6362
+ routes,
6363
+ loading = false
6364
+ }) => {
6365
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
6366
+ import_antd26.Modal,
6367
+ {
6368
+ title: "\u6D41\u7A0B\u9884\u89C8",
6369
+ open,
6370
+ onCancel: onClose,
6371
+ width: 520,
6372
+ footer: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex justify-end gap-3", children: [
6373
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_antd26.Button, { onClick: onClose, children: "\u53D6\u6D88" }),
6374
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_antd26.Button, { type: "primary", onClick: onConfirm, loading, children: "\u786E\u8BA4\u63D0\u4EA4" })
6375
+ ] }),
6376
+ children: loading && routes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_antd26.Skeleton, { active: true, paragraph: { rows: 4 } }) : routes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("p", { className: "text-sm text-gray-400 text-center py-8", children: "\u6682\u65E0\u6D41\u7A0B\u8282\u70B9" }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "py-2", children: routes.map((route, index) => {
6377
+ const isLast = index === routes.length - 1;
6378
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex gap-3", children: [
6379
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex flex-col items-center", children: [
6380
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("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__ */ (0, import_jsx_runtime81.jsx)(import_icons4.CheckCircleOutlined, { className: "text-blue-500 text-xs" }) }),
6381
+ !isLast && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "w-0.5 flex-1 bg-blue-200 mt-1" })
6382
+ ] }),
6383
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: `flex-1 ${isLast ? "pb-0" : "pb-5"}`, children: [
6384
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "text-sm font-medium text-gray-900", children: route.nodeName }),
6385
+ route.assignees && route.assignees.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "mt-1 flex items-center gap-1.5 flex-wrap", children: [
6386
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(import_icons4.UserOutlined, { className: "text-gray-400 text-xs" }),
6387
+ route.assignees.map((assignee) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
6388
+ "span",
6389
+ {
6390
+ className: "text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded",
6391
+ children: assignee.name
6392
+ },
6393
+ assignee.id
6394
+ ))
6395
+ ] })
6396
+ ] })
6397
+ ] }, route.nodeId);
6398
+ }) })
6399
+ }
6400
+ );
6401
+ };
6402
+
6403
+ // src/templates/FormSubmitTemplate.tsx
6404
+ var import_react54 = require("react");
6405
+ var import_antd27 = require("antd");
6406
+ var import_icons5 = require("@ant-design/icons");
6407
+ var import_jsx_runtime82 = require("react/jsx-runtime");
6408
+ var pickFormInstanceId = (value) => {
6409
+ if (!value) return void 0;
6410
+ if (typeof value === "string") return value;
6411
+ if (typeof value !== "object") return void 0;
6412
+ return value.formInstanceId || value.formInstId || value.instanceId || value.id || pickFormInstanceId(value.result) || pickFormInstanceId(value.data);
6413
+ };
6414
+ var SubmitSuccessCard = ({
6415
+ info,
6416
+ mode,
6417
+ isRedirecting,
6418
+ countdown,
6419
+ onContinue,
6420
+ onViewDetail,
6421
+ renderSuccess
6422
+ }) => {
6423
+ if (renderSuccess) {
6424
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_jsx_runtime82.Fragment, { children: renderSuccess(info) });
6425
+ }
6426
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "flex flex-col items-center py-16 animate-[fadeIn_0.3s_ease-out,scaleIn_0.3s_ease-out]", children: [
6427
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "w-12 h-12 rounded-full bg-green-100 flex items-center justify-center mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_icons5.CheckCircleFilled, { className: "text-2xl text-green-500" }) }),
6428
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h2", { className: "text-lg font-semibold text-gray-900 mb-1", children: "\u63D0\u4EA4\u6210\u529F" }),
6429
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "text-sm text-gray-500 mb-6", children: info.message || "\u5DF2\u6210\u529F\u521B\u5EFA\u4E00\u6761\u65B0\u8BB0\u5F55" }),
6430
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "flex gap-3", children: [
6431
+ (mode === "stay" || mode === "redirect") && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_antd27.Button, { onClick: onContinue, children: "\u7EE7\u7EED\u63D0\u4EA4" }),
6432
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(import_antd27.Button, { type: "primary", onClick: onViewDetail, children: "\u67E5\u770B\u8BE6\u60C5" })
6433
+ ] }),
6434
+ isRedirecting && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "mt-6 w-48", children: [
6435
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "text-xs text-gray-400 text-center mb-1", children: [
6436
+ countdown,
6437
+ "\u79D2\u540E\u81EA\u52A8\u8DF3\u8F6C"
6438
+ ] }),
6439
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "h-1 bg-gray-200 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
6440
+ "div",
6441
+ {
6442
+ className: "h-full bg-blue-500 transition-all duration-1000",
6443
+ style: { width: `${countdown / 3 * 100}%` }
6444
+ }
6445
+ ) })
6446
+ ] })
6447
+ ] }) });
6448
+ };
6449
+ var InnerFormContent = ({
6450
+ schema,
6451
+ config,
6452
+ formType,
6453
+ submitSuccessMode,
6454
+ enableDraft,
6455
+ header,
6456
+ footer,
6457
+ beforeForm,
6458
+ afterForm,
6459
+ renderForm,
6460
+ renderSuccess,
6461
+ onSubmitSuccess
6462
+ }) => {
6463
+ const { validateAll, getFormData: getFormData2, resetForm, api } = useFormContext();
6464
+ const [submitted, setSubmitted] = (0, import_react54.useState)(false);
6465
+ const [successInfo, setSuccessInfo] = (0, import_react54.useState)(null);
6466
+ const [submitting, setSubmitting] = (0, import_react54.useState)(false);
6467
+ const { hasDraft, draftTimestamp, saveDraft, restoreDraft, clearDraft } = useDraftStorage({
6468
+ appType: config.appType,
6469
+ formUuid: config.formUuid
6470
+ });
6471
+ const { navigateToDetail, navigateToProcessDetail, isRedirecting, countdown, handlePostSubmit } = useFormNavigation({
6472
+ appType: config.appType,
6473
+ formUuid: config.formUuid,
6474
+ formType,
6475
+ mode: submitSuccessMode === "continue" ? "stay" : submitSuccessMode,
6476
+ basePath: config.navigation?.basePath
6477
+ });
6478
+ const handleSubmit = (0, import_react54.useCallback)(async () => {
6479
+ const valid = await validateAll();
6480
+ if (!valid) return;
6481
+ setSubmitting(true);
6482
+ try {
6483
+ const formData = getFormData2();
6484
+ if (config.submit?.beforeSubmit) {
6485
+ const shouldContinue = await config.submit.beforeSubmit(formData);
6486
+ if (shouldContinue === false) {
6487
+ setSubmitting(false);
6488
+ return;
6489
+ }
6490
+ }
6491
+ const submitResponse = config.mode === "edit" && config.formInstanceId ? await api.updateFormData({
6492
+ appType: config.appType,
6493
+ formUuid: config.formUuid,
6494
+ formInstId: config.formInstanceId,
6495
+ formInstanceId: config.formInstanceId,
6496
+ updateFormDataJson: JSON.stringify(formData)
6497
+ }) : await api.submitFormData({
6498
+ appType: config.appType,
6499
+ formUuid: config.formUuid,
6500
+ data: formData
6501
+ });
6502
+ const formInstId = pickFormInstanceId(submitResponse) || config.formInstanceId || `inst_${Date.now()}`;
6503
+ if (config.submit?.afterSubmit) {
6504
+ await config.submit.afterSubmit({
6505
+ formInstanceId: formInstId,
6506
+ data: formData,
6507
+ response: submitResponse
6508
+ });
6509
+ }
6510
+ if (enableDraft) {
6511
+ clearDraft();
6512
+ }
6513
+ onSubmitSuccess?.(formInstId);
6514
+ if (submitSuccessMode === "continue") {
6515
+ resetForm();
6516
+ } else {
6517
+ setSuccessInfo({ formInstanceId: formInstId });
6518
+ setSubmitted(true);
6519
+ handlePostSubmit(formInstId);
6520
+ }
6521
+ } catch (error) {
6522
+ console.error("[FormSubmitTemplate] Submit failed:", error);
6523
+ } finally {
6524
+ setSubmitting(false);
6525
+ }
6526
+ }, [
6527
+ validateAll,
6528
+ getFormData2,
6529
+ config,
6530
+ api,
6531
+ enableDraft,
6532
+ clearDraft,
6533
+ onSubmitSuccess,
6534
+ submitSuccessMode,
6535
+ resetForm,
6536
+ handlePostSubmit
6537
+ ]);
6538
+ const handleSaveDraft = (0, import_react54.useCallback)(() => {
6539
+ const data = getFormData2();
6540
+ saveDraft(data);
6541
+ }, [getFormData2, saveDraft]);
6542
+ const handleRestoreDraft = (0, import_react54.useCallback)(() => {
6543
+ restoreDraft();
6544
+ }, [restoreDraft]);
6545
+ const handleContinue = (0, import_react54.useCallback)(() => {
6546
+ setSubmitted(false);
6547
+ setSuccessInfo(null);
6548
+ resetForm();
6549
+ }, [resetForm]);
6550
+ const handleViewDetail = (0, import_react54.useCallback)(() => {
6551
+ if (!successInfo) return;
6552
+ if (formType === "process") {
6553
+ navigateToProcessDetail(successInfo.formInstanceId);
6554
+ } else {
6555
+ navigateToDetail(successInfo.formInstanceId);
6556
+ }
6557
+ }, [successInfo, formType, navigateToDetail, navigateToProcessDetail]);
6558
+ const actions = [];
6559
+ if (enableDraft) {
6560
+ actions.push({
6561
+ key: "draft",
6562
+ label: "\u6682\u5B58",
6563
+ type: "default",
6564
+ onClick: handleSaveDraft
6565
+ });
6566
+ }
6567
+ actions.push({
6568
+ key: "reset",
6569
+ label: "\u91CD\u7F6E",
6570
+ type: "default",
6571
+ onClick: () => resetForm()
6572
+ });
6573
+ actions.push({
6574
+ key: "submit",
6575
+ label: "\u63D0\u4EA4",
6576
+ type: "primary",
6577
+ loading: submitting,
6578
+ onClick: handleSubmit
6579
+ });
6580
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "min-h-screen bg-gray-50/50", children: [
6581
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: [
6582
+ header || /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "mb-6", children: [
6583
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h1", { className: "text-2xl font-bold text-gray-900", children: schema.formMeta.title }),
6584
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "text-sm text-gray-500 mt-1", children: "\u8BF7\u586B\u5199\u4EE5\u4E0B\u4FE1\u606F" })
6585
+ ] }),
6586
+ enableDraft && hasDraft && !submitted && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "mb-6", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
6587
+ DraftManager,
6588
+ {
6589
+ hasDraft,
6590
+ draftTimestamp,
6591
+ onRestore: handleRestoreDraft,
6592
+ onDiscard: clearDraft
6593
+ }
6594
+ ) }),
6595
+ !submitted ? /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6 animate-[fadeIn_0.2s_ease-out]", children: [
6596
+ beforeForm,
6597
+ renderForm ? renderForm({ schema, config }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(FormRenderer, { columns: 2 }),
6598
+ afterForm
6599
+ ] }) : successInfo && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
6600
+ SubmitSuccessCard,
6601
+ {
6602
+ info: successInfo,
6603
+ mode: submitSuccessMode,
6604
+ isRedirecting,
6605
+ countdown,
6606
+ onContinue: handleContinue,
6607
+ onViewDetail: handleViewDetail,
6608
+ renderSuccess
6609
+ }
6610
+ ),
6611
+ footer
6612
+ ] }),
6613
+ !submitted && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(FormActionBar, { actions, position: "bottom-fixed" })
6614
+ ] });
6615
+ };
6616
+ var FormSubmitTemplate = ({
6617
+ schema,
6618
+ config,
6619
+ formType = "form",
6620
+ submitSuccessMode = "redirect",
6621
+ enableDraft = false,
6622
+ header,
6623
+ footer,
6624
+ beforeForm,
6625
+ afterForm,
6626
+ renderForm,
6627
+ renderSuccess,
6628
+ onSubmitSuccess
6629
+ }) => {
6630
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(FormProvider, { schema, config, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
6631
+ InnerFormContent,
6632
+ {
6633
+ schema,
6634
+ config,
6635
+ formType,
6636
+ submitSuccessMode,
6637
+ enableDraft,
6638
+ header,
6639
+ footer,
6640
+ beforeForm,
6641
+ afterForm,
6642
+ renderForm,
6643
+ renderSuccess,
6644
+ onSubmitSuccess
6645
+ }
6646
+ ) });
6647
+ };
6648
+
6649
+ // src/templates/FormDetailTemplate.tsx
6650
+ var import_react55 = require("react");
6651
+
6652
+ // src/templates/PageSkeleton.tsx
6653
+ var import_antd28 = require("antd");
6654
+ var import_jsx_runtime83 = require("react/jsx-runtime");
6655
+ var CardSkeleton = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children });
6656
+ var SummaryCardSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(CardSkeleton, { children: [
6657
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex items-start justify-between", children: [
6658
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex-1", children: [
6659
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Input, { active: true, size: "large", style: { width: 200 } }),
6660
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "mt-2", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Input, { active: true, size: "small", style: { width: 80 } }) })
6661
+ ] }),
6662
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Button, { active: true, size: "small", shape: "round", style: { width: 60 } })
6663
+ ] }),
6664
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex items-center gap-3 mt-4", children: [
6665
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Avatar, { active: true, size: "small" }),
6666
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Input, { active: true, size: "small", style: { width: 120 } })
6667
+ ] })
6668
+ ] });
6669
+ var FormGridSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(CardSkeleton, { children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "space-y-2", children: [
6670
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Input, { active: true, size: "small", style: { width: 80 } }),
6671
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Input, { active: true, block: true, style: { width: "100%" } })
6672
+ ] }, i)) }) });
6673
+ var ActionBarSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("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__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex items-center justify-end gap-3", children: [
6674
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Button, { active: true, style: { width: 80 } }),
6675
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Button, { active: true, style: { width: 80 } })
6676
+ ] }) });
6677
+ var TimelineSkeleton = () => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(CardSkeleton, { children: [
6678
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Input, { active: true, size: "default", style: { width: 100, marginBottom: 16 } }),
6679
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "space-y-4", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex gap-4", children: [
6680
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "flex flex-col items-center", children: [
6681
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "w-3 h-3 rounded-full bg-gray-200 animate-pulse" }),
6682
+ i < 2 && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "w-0.5 flex-1 bg-gray-200 mt-1" })
6683
+ ] }),
6684
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "flex-1 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton, { active: true, paragraph: { rows: 1 }, title: { width: "60%" } }) })
6685
+ ] }, i)) })
6686
+ ] });
6687
+ var PageSkeleton = ({ type }) => {
6688
+ if (type === "submit") {
6689
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "space-y-6", children: [
6690
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "space-y-2", children: [
6691
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Input, { active: true, size: "large", style: { width: 200 } }),
6692
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(import_antd28.Skeleton.Input, { active: true, size: "small", style: { width: 300 } })
6693
+ ] }),
6694
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(FormGridSkeleton, {}),
6695
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(ActionBarSkeleton, {})
6696
+ ] });
6697
+ }
6698
+ if (type === "detail") {
6699
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "space-y-6", children: [
6700
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(SummaryCardSkeleton, {}),
6701
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(FormGridSkeleton, {}),
6702
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(ActionBarSkeleton, {})
6703
+ ] });
6704
+ }
6705
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "space-y-6", children: [
6706
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(SummaryCardSkeleton, {}),
6707
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(FormGridSkeleton, {}),
6708
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(TimelineSkeleton, {}),
6709
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(ActionBarSkeleton, {})
6710
+ ] });
6711
+ };
6712
+
6713
+ // src/templates/FormDetailTemplate.tsx
6714
+ var import_jsx_runtime84 = require("react/jsx-runtime");
6715
+ var InnerDetailContent = ({
6716
+ schema,
6717
+ formUuid,
6718
+ appType,
6719
+ formInstanceId,
6720
+ enableEdit = true,
6721
+ enableDelete = false,
6722
+ enableChangeRecords = false,
6723
+ header,
6724
+ footer,
6725
+ renderSummary,
6726
+ renderActions,
6727
+ onDelete,
6728
+ onSave
6729
+ }) => {
6730
+ const {
6731
+ loading,
6732
+ mode,
6733
+ formData,
6734
+ instanceInfo,
6735
+ fieldBehaviors,
6736
+ switchToEdit,
6737
+ switchToReadonly,
6738
+ saveChanges,
6739
+ deleteInstance,
6740
+ canEdit,
6741
+ canDelete,
6742
+ canViewChangeRecords
6743
+ } = useFormDetail({ formUuid, appType, formInstanceId });
6744
+ const {
6745
+ records,
6746
+ loading: recordsLoading,
6747
+ hasMore,
6748
+ loadMore,
6749
+ refresh: refreshRecords
6750
+ } = useChangeRecords({
6751
+ formUuid,
6752
+ appType,
6753
+ formInstanceId,
6754
+ autoLoad: enableChangeRecords && canViewChangeRecords
6755
+ });
6756
+ const handleSave = (0, import_react55.useCallback)(async () => {
6757
+ if (!formData) return;
6758
+ const success = await saveChanges(formData);
6759
+ if (success) {
6760
+ onSave?.(formData);
6761
+ }
6762
+ }, [formData, saveChanges, onSave]);
6763
+ const handleDelete = (0, import_react55.useCallback)(async () => {
6764
+ const success = await deleteInstance();
6765
+ if (success) {
6766
+ onDelete?.();
6767
+ }
6768
+ }, [deleteInstance, onDelete]);
6769
+ const handleCancel = (0, import_react55.useCallback)(() => {
6770
+ switchToReadonly();
6771
+ }, [switchToReadonly]);
6772
+ const readonlyActions = [];
6773
+ if (enableEdit && canEdit) {
6774
+ readonlyActions.push({
6775
+ key: "edit",
6776
+ label: "\u7F16\u8F91",
6777
+ type: "primary",
6778
+ onClick: switchToEdit
6779
+ });
6780
+ }
6781
+ if (enableDelete && canDelete) {
6782
+ readonlyActions.push({
6783
+ key: "delete",
6784
+ label: "\u5220\u9664",
6785
+ type: "danger",
6786
+ onClick: handleDelete,
6787
+ confirm: { title: "\u786E\u8BA4\u5220\u9664", content: "\u5220\u9664\u540E\u5C06\u65E0\u6CD5\u6062\u590D\uFF0C\u786E\u8BA4\u8981\u5220\u9664\u5417\uFF1F" }
6788
+ });
6789
+ }
6790
+ const editActions = [
6791
+ { key: "cancel", label: "\u53D6\u6D88", type: "default", onClick: handleCancel },
6792
+ { key: "save", label: "\u4FDD\u5B58", type: "primary", onClick: handleSave }
6793
+ ];
6794
+ const currentActions = mode === "readonly" ? readonlyActions : editActions;
6795
+ const formConfig = {
6796
+ mode: mode === "edit" ? "edit" : "readonly",
6797
+ formUuid,
6798
+ appType,
6799
+ formInstanceId,
6800
+ permissions: {
6801
+ fieldPermissions: fieldBehaviors,
6802
+ operations: []
6803
+ }
6804
+ };
6805
+ if (loading) {
6806
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "min-h-screen bg-gray-50/50", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(PageSkeleton, { type: "detail" }) }) });
6807
+ }
6808
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "min-h-screen bg-gray-50/50", children: [
6809
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24 space-y-6", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "animate-[fadeIn_0.2s_ease-out]", children: [
6810
+ header,
6811
+ renderSummary && instanceInfo ? renderSummary(instanceInfo) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
6812
+ FormSummaryCard,
6813
+ {
6814
+ title: schema.formMeta.title,
6815
+ formInstanceId,
6816
+ creator: instanceInfo?.creator ? {
6817
+ name: instanceInfo.creator.name,
6818
+ avatar: instanceInfo.creator.avatar,
6819
+ department: instanceInfo.creator.department
6820
+ } : void 0,
6821
+ createdAt: instanceInfo?.createdAt,
6822
+ status: mode === "edit" ? { label: "\u7F16\u8F91\u4E2D", tone: "brand" } : void 0
6823
+ }
6824
+ ),
6825
+ mode === "edit" && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("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" }),
6826
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(FormRenderer, { columns: 2 }) }) }),
6827
+ enableChangeRecords && canViewChangeRecords && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
6828
+ ChangeRecords,
6829
+ {
6830
+ records,
6831
+ loading: recordsLoading,
6832
+ hasMore,
6833
+ onLoadMore: loadMore,
6834
+ onExpand: refreshRecords
6835
+ }
6836
+ ),
6837
+ footer
6838
+ ] }) }),
6839
+ currentActions.length > 0 && (renderActions ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_jsx_runtime84.Fragment, { children: renderActions(currentActions) }) : /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(FormActionBar, { position: "bottom-fixed", actions: currentActions }))
6840
+ ] });
6841
+ };
6842
+ var FormDetailTemplate = (props) => {
6843
+ const { schema, formUuid, appType, formInstanceId } = props;
6844
+ const wrapperConfig = {
6845
+ mode: "readonly",
6846
+ formUuid,
6847
+ appType,
6848
+ formInstanceId
6849
+ };
6850
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(FormProvider, { schema, config: wrapperConfig, children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(InnerDetailContent, { ...props }) });
6851
+ };
6852
+
6853
+ // src/templates/ProcessDetailTemplate.tsx
6854
+ var import_react56 = require("react");
6855
+ var import_jsx_runtime85 = require("react/jsx-runtime");
6856
+ function FormDataBridge({
6857
+ formDataRef
6858
+ }) {
6859
+ const { getFormData: getFormData2 } = useFormContext();
6860
+ formDataRef.current = getFormData2;
6861
+ return null;
6862
+ }
6863
+ var InnerProcessContent = ({
6864
+ schema,
6865
+ formUuid,
6866
+ appType,
6867
+ formInstanceId,
6868
+ header,
6869
+ renderTimeline,
6870
+ renderActions,
6871
+ beforeForm,
6872
+ afterForm,
6873
+ onActionComplete
6874
+ }) => {
6875
+ const formDataRef = (0, import_react56.useRef)(void 0);
6876
+ const {
6877
+ loading,
6878
+ processInfo,
6879
+ processStatus,
6880
+ currentTask,
6881
+ progressList,
6882
+ formData,
6883
+ isApprover,
6884
+ activeActions,
6885
+ fieldBehaviors,
6886
+ mode,
6887
+ isOriginatorReturn,
6888
+ canWithdraw,
6889
+ switchToEdit,
6890
+ switchToReadonly,
6891
+ refreshProgress
6892
+ } = useProcessDetail({ formUuid, appType, formInstanceId });
6893
+ const { approve, reject, withdraw, save, resubmit } = useApprovalActions({
6894
+ formInstanceId,
6895
+ formUuid,
6896
+ appType,
6897
+ currentTaskId: currentTask?.taskId,
6898
+ onActionComplete: async (action) => {
6899
+ onActionComplete?.(action);
6900
+ await refreshProgress();
6901
+ },
6902
+ getFormValues: () => formDataRef.current?.() ?? {}
6903
+ });
6904
+ const handleApprove = (0, import_react56.useCallback)(
6905
+ async (comments) => {
6906
+ await approve(comments);
6907
+ },
6908
+ [approve]
6909
+ );
6910
+ const handleReject = (0, import_react56.useCallback)(
6911
+ async (comments) => {
6912
+ await reject(comments);
6913
+ },
6914
+ [reject]
6915
+ );
6916
+ const handleWithdraw = (0, import_react56.useCallback)(
6917
+ async (reason) => {
6918
+ await withdraw(reason);
6919
+ },
6920
+ [withdraw]
6921
+ );
6922
+ const handleSave = (0, import_react56.useCallback)(async () => {
6923
+ await save();
6924
+ }, [save]);
6925
+ const handleResubmit = (0, import_react56.useCallback)(async () => {
6926
+ await resubmit();
6927
+ }, [resubmit]);
6928
+ const buildActions = () => {
6929
+ const actions = [];
6930
+ if (isApprover && activeActions.length > 0) {
6931
+ return [];
6932
+ }
6933
+ if (isOriginatorReturn) {
6934
+ if (mode === "readonly") {
6935
+ actions.push({
6936
+ key: "edit",
6937
+ label: "\u7F16\u8F91",
6938
+ type: "primary",
6939
+ onClick: switchToEdit
6940
+ });
6941
+ } else {
6942
+ actions.push({
6943
+ key: "cancel",
6944
+ label: "\u53D6\u6D88",
6945
+ type: "default",
6946
+ onClick: switchToReadonly
6947
+ });
6948
+ actions.push({
6949
+ key: "resubmit",
6950
+ label: "\u91CD\u65B0\u63D0\u4EA4",
6951
+ type: "primary",
6952
+ onClick: handleResubmit
6953
+ });
6954
+ }
6955
+ return actions;
6956
+ }
6957
+ if (canWithdraw) {
6958
+ actions.push({
6959
+ key: "withdraw",
6960
+ label: "\u64A4\u9500",
6961
+ type: "default",
6962
+ onClick: () => handleWithdraw(),
6963
+ confirm: { title: "\u786E\u8BA4\u64A4\u9500", content: "\u786E\u8BA4\u8981\u64A4\u9500\u6B64\u6D41\u7A0B\u5417\uFF1F" }
6964
+ });
6965
+ }
6966
+ return actions;
6967
+ };
6968
+ const formConfig = {
6969
+ mode: mode === "edit" ? "edit" : "readonly",
6970
+ formUuid,
6971
+ appType,
6972
+ formInstanceId,
6973
+ permissions: {
6974
+ fieldPermissions: fieldBehaviors,
6975
+ operations: []
6976
+ }
6977
+ };
6978
+ if (loading) {
6979
+ return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "min-h-screen bg-gray-50/50", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(PageSkeleton, { type: "process" }) }) });
6980
+ }
6981
+ const bottomActions = buildActions();
6982
+ const showApprovalActions = isApprover && activeActions.length > 0;
6983
+ return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "min-h-screen bg-gray-50/50", children: [
6984
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "max-w-4xl mx-auto py-8 px-6 pb-24 space-y-6", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "animate-[fadeIn_0.2s_ease-out]", children: [
6985
+ header,
6986
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
6987
+ FormSummaryCard,
6988
+ {
6989
+ title: schema.formMeta.title,
6990
+ formInstanceId,
6991
+ creator: processInfo?.originatorName ? {
6992
+ name: processInfo.originatorName,
6993
+ department: processInfo.originatorDepartment
6994
+ } : void 0,
6995
+ createdAt: processInfo?.createdAt,
6996
+ status: processStatus ? PROCESS_STATUS_META[processStatus] : void 0
6997
+ }
6998
+ ),
6999
+ beforeForm,
7000
+ mode === "edit" && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("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" }),
7001
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(FormProvider, { schema, config: formConfig, initialValues: formData ?? void 0, children: [
7002
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(FormDataBridge, { formDataRef }),
7003
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(FormRenderer, { columns: 2 })
7004
+ ] }) }),
7005
+ afterForm,
7006
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: [
7007
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("h3", { className: "text-lg font-semibold text-gray-900 mb-4", children: "\u5BA1\u6279\u8FDB\u5EA6" }),
7008
+ renderTimeline ? renderTimeline(progressList) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(ApprovalTimeline, { tasks: progressList, showRemarks: true })
7009
+ ] })
7010
+ ] }) }),
7011
+ showApprovalActions && (renderActions ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(import_jsx_runtime85.Fragment, { children: renderActions(activeActions) }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("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__ */ (0, import_jsx_runtime85.jsx)("div", { className: "max-w-4xl mx-auto flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
7012
+ ApprovalActions,
7013
+ {
7014
+ actions: activeActions,
7015
+ onApprove: handleApprove,
7016
+ onReject: handleReject,
7017
+ onWithdraw: handleWithdraw,
7018
+ onSave: handleSave
7019
+ }
7020
+ ) }) })),
7021
+ !showApprovalActions && bottomActions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(FormActionBar, { position: "bottom-fixed", actions: bottomActions })
7022
+ ] });
7023
+ };
7024
+ var ProcessDetailTemplate = (props) => {
7025
+ const { schema, formUuid, appType, formInstanceId } = props;
7026
+ const wrapperConfig = {
7027
+ mode: "readonly",
7028
+ formUuid,
7029
+ appType,
7030
+ formInstanceId
7031
+ };
7032
+ return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(FormProvider, { schema, config: wrapperConfig, children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(InnerProcessContent, { ...props }) });
7033
+ };
4798
7034
  // Annotate the CommonJS export names for ESM import in node:
4799
7035
  0 && (module.exports = {
4800
7036
  AddressField,
7037
+ ApprovalActions,
7038
+ ApprovalTimeline,
4801
7039
  AssociationFormField,
4802
7040
  AttachmentField,
4803
7041
  CascadeDateField,
4804
7042
  CascadeSelectField,
7043
+ ChangeRecords,
4805
7044
  CheckboxField,
4806
7045
  ComponentRegistryContext,
4807
7046
  ComponentRegistryProvider,
4808
7047
  DateField,
4809
7048
  DepartmentSelectField,
4810
7049
  DigitalSignatureField,
7050
+ DraftManager,
4811
7051
  EditorField,
4812
7052
  EmployeeSelectField,
4813
7053
  FieldWrapper,
7054
+ FormActionBar,
4814
7055
  FormActions,
4815
7056
  FormContainer,
4816
7057
  FormContext,
7058
+ FormDetailTemplate,
4817
7059
  FormGrid,
4818
7060
  FormProvider,
4819
7061
  FormRenderer,
4820
7062
  FormSection,
4821
7063
  FormSteps,
7064
+ FormSubmitTemplate,
4822
7065
  FormSummary,
7066
+ FormSummaryCard,
4823
7067
  FormTabs,
4824
7068
  ImageField,
4825
7069
  JSONField,
4826
7070
  LocationField,
4827
7071
  MultiSelectField,
4828
7072
  NumberField,
7073
+ PROCESS_STATUS_META,
7074
+ PageSkeleton,
7075
+ ProcessDetailTemplate,
7076
+ ProcessPreview,
4829
7077
  RadioField,
4830
7078
  SelectField,
4831
7079
  SerialNumberField,
4832
7080
  SubFormField,
7081
+ TASK_STATUS_META,
4833
7082
  TextAreaField,
4834
7083
  TextField,
4835
7084
  TextareaField,
4836
7085
  UserSelectField,
7086
+ checkUserApproval,
4837
7087
  createFormRuntimeApi,
4838
7088
  defaultComponentRegistry,
4839
7089
  defineFormSchema,
7090
+ deleteFormData,
4840
7091
  evaluateEffects,
7092
+ getChangeRecords,
7093
+ getFormData,
7094
+ getProcessBasic,
7095
+ getProcessDefinition,
7096
+ getProcessProgress,
7097
+ getReturnableNodes,
7098
+ getViewPermission,
7099
+ handleApproval,
7100
+ previewProcess,
7101
+ resubmitTask,
7102
+ returnTask,
7103
+ saveTask,
7104
+ transferTask,
7105
+ useApprovalActions,
7106
+ useChangeRecords,
4841
7107
  useComponent,
4842
7108
  useDeviceDetect,
7109
+ useDraftStorage,
4843
7110
  useFieldBehavior,
7111
+ useFieldPermission,
4844
7112
  useFormContext,
4845
7113
  useFormData,
7114
+ useFormDetail,
4846
7115
  useFormEngine,
7116
+ useFormNavigation,
4847
7117
  useFormSubmit,
7118
+ useProcessDetail,
4848
7119
  validateAllFields,
4849
- validateField
7120
+ validateField,
7121
+ withdrawProcess
4850
7122
  });
4851
7123
  //# sourceMappingURL=index.js.map