openxiangda 2.44.0 → 2.55.1

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.
Files changed (247) hide show
  1. package/dist/browser/AuthoritativeSelector.d.ts +3 -2
  2. package/dist/browser/AuthoritativeSelector.d.ts.map +1 -1
  3. package/dist/browser/AuthoritativeSelector.js +32 -11
  4. package/dist/browser/AuthoritativeSelector.js.map +1 -1
  5. package/dist/browser/FilePreviewPage.d.ts.map +1 -1
  6. package/dist/browser/FilePreviewPage.js +4 -0
  7. package/dist/browser/FilePreviewPage.js.map +1 -1
  8. package/dist/browser/components/administration/RoleMembershipManager.d.ts.map +1 -1
  9. package/dist/browser/components/administration/RoleMembershipManager.js +5 -5
  10. package/dist/browser/components/administration/RoleMembershipManager.js.map +1 -1
  11. package/dist/browser/components/administration/scope-applicability.d.ts +3 -0
  12. package/dist/browser/components/administration/scope-applicability.d.ts.map +1 -0
  13. package/dist/browser/components/administration/scope-applicability.js +7 -0
  14. package/dist/browser/components/administration/scope-applicability.js.map +1 -0
  15. package/dist/browser/components/platform-fields/ConstrainedUserField.d.ts +16 -0
  16. package/dist/browser/components/platform-fields/ConstrainedUserField.d.ts.map +1 -0
  17. package/dist/browser/components/platform-fields/ConstrainedUserField.js +140 -0
  18. package/dist/browser/components/platform-fields/ConstrainedUserField.js.map +1 -0
  19. package/dist/browser/components/platform-fields/JsonField.d.ts.map +1 -1
  20. package/dist/browser/components/platform-fields/JsonField.js +6 -1
  21. package/dist/browser/components/platform-fields/JsonField.js.map +1 -1
  22. package/dist/browser/components/platform-fields/ManagedMediaPlayer.d.ts +19 -0
  23. package/dist/browser/components/platform-fields/ManagedMediaPlayer.d.ts.map +1 -0
  24. package/dist/browser/components/platform-fields/ManagedMediaPlayer.js +42 -0
  25. package/dist/browser/components/platform-fields/ManagedMediaPlayer.js.map +1 -0
  26. package/dist/browser/components/platform-fields/MobileManagedFileField.d.ts.map +1 -1
  27. package/dist/browser/components/platform-fields/MobileManagedFileField.js +6 -1
  28. package/dist/browser/components/platform-fields/MobileManagedFileField.js.map +1 -1
  29. package/dist/browser/components/platform-fields/MobileSelection.d.ts +3 -1
  30. package/dist/browser/components/platform-fields/MobileSelection.d.ts.map +1 -1
  31. package/dist/browser/components/platform-fields/MobileSelection.js +2 -2
  32. package/dist/browser/components/platform-fields/MobileSelection.js.map +1 -1
  33. package/dist/browser/components/platform-fields/MobileSubtableValidation.d.ts +2 -1
  34. package/dist/browser/components/platform-fields/MobileSubtableValidation.d.ts.map +1 -1
  35. package/dist/browser/components/platform-fields/MobileSubtableValidation.js +3 -1
  36. package/dist/browser/components/platform-fields/MobileSubtableValidation.js.map +1 -1
  37. package/dist/browser/components/platform-fields/ResourceReferenceField.d.ts +3 -2
  38. package/dist/browser/components/platform-fields/ResourceReferenceField.d.ts.map +1 -1
  39. package/dist/browser/components/platform-fields/ResourceReferenceField.js +2 -2
  40. package/dist/browser/components/platform-fields/ResourceReferenceField.js.map +1 -1
  41. package/dist/browser/components/platform-fields/RichTextField.d.ts +3 -2
  42. package/dist/browser/components/platform-fields/RichTextField.d.ts.map +1 -1
  43. package/dist/browser/components/platform-fields/RichTextField.js +96 -44
  44. package/dist/browser/components/platform-fields/RichTextField.js.map +1 -1
  45. package/dist/browser/components/platform-fields/SignatureField.d.ts +5 -4
  46. package/dist/browser/components/platform-fields/SignatureField.d.ts.map +1 -1
  47. package/dist/browser/components/platform-fields/SignatureField.js +69 -16
  48. package/dist/browser/components/platform-fields/SignatureField.js.map +1 -1
  49. package/dist/browser/components/platform-fields/SubtableField.d.ts +18 -2
  50. package/dist/browser/components/platform-fields/SubtableField.d.ts.map +1 -1
  51. package/dist/browser/components/platform-fields/SubtableField.js +146 -57
  52. package/dist/browser/components/platform-fields/SubtableField.js.map +1 -1
  53. package/dist/browser/components/platform-fields/managed-media-read.d.ts +19 -0
  54. package/dist/browser/components/platform-fields/managed-media-read.d.ts.map +1 -0
  55. package/dist/browser/components/platform-fields/managed-media-read.js +32 -0
  56. package/dist/browser/components/platform-fields/managed-media-read.js.map +1 -0
  57. package/dist/browser/components/platform-fields/subtable-pagination.d.ts +20 -0
  58. package/dist/browser/components/platform-fields/subtable-pagination.d.ts.map +1 -0
  59. package/dist/browser/components/platform-fields/subtable-pagination.js +39 -0
  60. package/dist/browser/components/platform-fields/subtable-pagination.js.map +1 -0
  61. package/dist/browser/components/platform-fields/subtable-value.d.ts.map +1 -1
  62. package/dist/browser/components/platform-fields/subtable-value.js +2 -1
  63. package/dist/browser/components/platform-fields/subtable-value.js.map +1 -1
  64. package/dist/browser/components/platform-fields/surface-field-validation.d.ts +31 -0
  65. package/dist/browser/components/platform-fields/surface-field-validation.d.ts.map +1 -0
  66. package/dist/browser/components/platform-fields/surface-field-validation.js +36 -0
  67. package/dist/browser/components/platform-fields/surface-field-validation.js.map +1 -0
  68. package/dist/browser/components/platform-fields/user-candidate-context.d.ts +51 -0
  69. package/dist/browser/components/platform-fields/user-candidate-context.d.ts.map +1 -0
  70. package/dist/browser/components/platform-fields/user-candidate-context.js +62 -0
  71. package/dist/browser/components/platform-fields/user-candidate-context.js.map +1 -0
  72. package/dist/browser/components/resource/GeneratedResourceCrud.d.ts.map +1 -1
  73. package/dist/browser/components/resource/GeneratedResourceCrud.js +26 -2
  74. package/dist/browser/components/resource/GeneratedResourceCrud.js.map +1 -1
  75. package/dist/browser/components/resource/GeneratedResourceForm.js +1 -1
  76. package/dist/browser/components/resource/GeneratedResourceForm.js.map +1 -1
  77. package/dist/browser/components/resource/RecordDetailFrame.d.ts +3 -1
  78. package/dist/browser/components/resource/RecordDetailFrame.d.ts.map +1 -1
  79. package/dist/browser/components/resource/RecordDetailFrame.js +2 -2
  80. package/dist/browser/components/resource/RecordDetailFrame.js.map +1 -1
  81. package/dist/browser/components/resource/ResourceFormFrame.d.ts +2 -1
  82. package/dist/browser/components/resource/ResourceFormFrame.d.ts.map +1 -1
  83. package/dist/browser/components/resource/ResourceFormFrame.js +2 -2
  84. package/dist/browser/components/resource/ResourceFormFrame.js.map +1 -1
  85. package/dist/browser/components/resource/ResourceRecordComments.d.ts +13 -0
  86. package/dist/browser/components/resource/ResourceRecordComments.d.ts.map +1 -0
  87. package/dist/browser/components/resource/ResourceRecordComments.js +75 -0
  88. package/dist/browser/components/resource/ResourceRecordComments.js.map +1 -0
  89. package/dist/browser/components/resource/ResourceRecordDeletion.d.ts +7 -0
  90. package/dist/browser/components/resource/ResourceRecordDeletion.d.ts.map +1 -0
  91. package/dist/browser/components/resource/ResourceRecordDeletion.js +53 -0
  92. package/dist/browser/components/resource/ResourceRecordDeletion.js.map +1 -0
  93. package/dist/browser/components/resource/ResourceRecordPrintPreview.d.ts +16 -0
  94. package/dist/browser/components/resource/ResourceRecordPrintPreview.d.ts.map +1 -0
  95. package/dist/browser/components/resource/ResourceRecordPrintPreview.js +92 -0
  96. package/dist/browser/components/resource/ResourceRecordPrintPreview.js.map +1 -0
  97. package/dist/browser/components/resource/SurfaceFields.d.ts +9 -4
  98. package/dist/browser/components/resource/SurfaceFields.d.ts.map +1 -1
  99. package/dist/browser/components/resource/SurfaceFields.js +54 -72
  100. package/dist/browser/components/resource/SurfaceFields.js.map +1 -1
  101. package/dist/browser/components/resource/generated-resource-definition.d.ts +13 -0
  102. package/dist/browser/components/resource/generated-resource-definition.d.ts.map +1 -1
  103. package/dist/browser/components/resource/record-comment-session.d.ts +17 -0
  104. package/dist/browser/components/resource/record-comment-session.d.ts.map +1 -0
  105. package/dist/browser/components/resource/record-comment-session.js +64 -0
  106. package/dist/browser/components/resource/record-comment-session.js.map +1 -0
  107. package/dist/browser/components/resource/record-deletion-session.d.ts +19 -0
  108. package/dist/browser/components/resource/record-deletion-session.d.ts.map +1 -0
  109. package/dist/browser/components/resource/record-deletion-session.js +64 -0
  110. package/dist/browser/components/resource/record-deletion-session.js.map +1 -0
  111. package/dist/browser/components/resource/record-print-session.d.ts +12 -0
  112. package/dist/browser/components/resource/record-print-session.d.ts.map +1 -0
  113. package/dist/browser/components/resource/record-print-session.js +32 -0
  114. package/dist/browser/components/resource/record-print-session.js.map +1 -0
  115. package/dist/browser/components/resource/resource-field-selection.d.ts +1 -0
  116. package/dist/browser/components/resource/resource-field-selection.d.ts.map +1 -1
  117. package/dist/browser/components/resource/resource-form-operations.d.ts.map +1 -1
  118. package/dist/browser/components/resource/resource-form-operations.js +5 -1
  119. package/dist/browser/components/resource/resource-form-operations.js.map +1 -1
  120. package/dist/browser/components/resource/useResourceFormDrafts.d.ts.map +1 -1
  121. package/dist/browser/components/workflow/StandardWorkflowPages.d.ts +13 -2
  122. package/dist/browser/components/workflow/StandardWorkflowPages.d.ts.map +1 -1
  123. package/dist/browser/components/workflow/StandardWorkflowPages.js +96 -47
  124. package/dist/browser/components/workflow/StandardWorkflowPages.js.map +1 -1
  125. package/dist/browser/components/workflow/WorkflowDiagram.d.ts.map +1 -1
  126. package/dist/browser/components/workflow/WorkflowDiagram.js +14 -1
  127. package/dist/browser/components/workflow/WorkflowDiagram.js.map +1 -1
  128. package/dist/browser/components/workflow/WorkflowFlowCanvas.d.ts.map +1 -1
  129. package/dist/browser/components/workflow/WorkflowFlowCanvas.js +27 -8
  130. package/dist/browser/components/workflow/WorkflowFlowCanvas.js.map +1 -1
  131. package/dist/browser/components/workflow/WorkflowNodeCard.js +2 -2
  132. package/dist/browser/components/workflow/WorkflowNodeCard.js.map +1 -1
  133. package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.d.ts.map +1 -1
  134. package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.js +4 -4
  135. package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.js.map +1 -1
  136. package/dist/browser/components/workflow/WorkflowRecordEditor.js +1 -1
  137. package/dist/browser/components/workflow/WorkflowRecordEditor.js.map +1 -1
  138. package/dist/browser/components/workflow/WorkflowRecordHistoryPanel.d.ts +9 -0
  139. package/dist/browser/components/workflow/WorkflowRecordHistoryPanel.d.ts.map +1 -0
  140. package/dist/browser/components/workflow/WorkflowRecordHistoryPanel.js +50 -0
  141. package/dist/browser/components/workflow/WorkflowRecordHistoryPanel.js.map +1 -0
  142. package/dist/browser/components/workflow/WorkflowTaskFiles.d.ts +5 -3
  143. package/dist/browser/components/workflow/WorkflowTaskFiles.d.ts.map +1 -1
  144. package/dist/browser/components/workflow/WorkflowTaskFiles.js +67 -27
  145. package/dist/browser/components/workflow/WorkflowTaskFiles.js.map +1 -1
  146. package/dist/browser/components/workflow/WorkflowTaskForm.d.ts +6 -1
  147. package/dist/browser/components/workflow/WorkflowTaskForm.d.ts.map +1 -1
  148. package/dist/browser/components/workflow/WorkflowTaskForm.js +65 -16
  149. package/dist/browser/components/workflow/WorkflowTaskForm.js.map +1 -1
  150. package/dist/browser/components/workflow/standard-process-values.d.ts +10 -0
  151. package/dist/browser/components/workflow/standard-process-values.d.ts.map +1 -0
  152. package/dist/browser/components/workflow/standard-process-values.js +25 -0
  153. package/dist/browser/components/workflow/standard-process-values.js.map +1 -0
  154. package/dist/browser/components/workflow/workflow-graph-presentation.d.ts +19 -0
  155. package/dist/browser/components/workflow/workflow-graph-presentation.d.ts.map +1 -0
  156. package/dist/browser/components/workflow/workflow-graph-presentation.js +28 -0
  157. package/dist/browser/components/workflow/workflow-graph-presentation.js.map +1 -0
  158. package/dist/browser/components/workflow/workflow-submission-form.d.ts +18 -0
  159. package/dist/browser/components/workflow/workflow-submission-form.d.ts.map +1 -0
  160. package/dist/browser/components/workflow/workflow-submission-form.js +44 -0
  161. package/dist/browser/components/workflow/workflow-submission-form.js.map +1 -0
  162. package/dist/browser/components/workflow/workflow-task-field-codec.d.ts +4 -0
  163. package/dist/browser/components/workflow/workflow-task-field-codec.d.ts.map +1 -0
  164. package/dist/browser/components/workflow/workflow-task-field-codec.js +9 -0
  165. package/dist/browser/components/workflow/workflow-task-field-codec.js.map +1 -0
  166. package/dist/browser/components/workflow/workflow-task-required-errors.d.ts +10 -0
  167. package/dist/browser/components/workflow/workflow-task-required-errors.d.ts.map +1 -0
  168. package/dist/browser/components/workflow/workflow-task-required-errors.js +28 -0
  169. package/dist/browser/components/workflow/workflow-task-required-errors.js.map +1 -0
  170. package/dist/browser/components/workflow/workflow-task-subtable.d.ts +7 -0
  171. package/dist/browser/components/workflow/workflow-task-subtable.d.ts.map +1 -0
  172. package/dist/browser/components/workflow/workflow-task-subtable.js +58 -0
  173. package/dist/browser/components/workflow/workflow-task-subtable.js.map +1 -0
  174. package/dist/browser/durable-command.d.ts.map +1 -1
  175. package/dist/browser/durable-command.js +6 -1
  176. package/dist/browser/durable-command.js.map +1 -1
  177. package/dist/browser/mobile-fields.css +4 -0
  178. package/dist/browser/platform-client.d.ts +30 -1
  179. package/dist/browser/platform-client.d.ts.map +1 -1
  180. package/dist/browser/platform-client.js +161 -5
  181. package/dist/browser/platform-client.js.map +1 -1
  182. package/dist/browser/record-comments.css +14 -0
  183. package/dist/browser/record-deletion.css +11 -0
  184. package/dist/browser/record-detail.css +4 -2
  185. package/dist/browser/record-print.css +31 -0
  186. package/dist/browser/styles.css +41 -0
  187. package/dist/browser/workflow-operation-input.d.ts +15 -0
  188. package/dist/browser/workflow-operation-input.d.ts.map +1 -0
  189. package/dist/browser/workflow-operation-input.js +64 -0
  190. package/dist/browser/workflow-operation-input.js.map +1 -0
  191. package/dist/browser/workflow-task-file-upload.d.ts.map +1 -1
  192. package/dist/browser/workflow-task-file-upload.js +1 -0
  193. package/dist/browser/workflow-task-file-upload.js.map +1 -1
  194. package/dist/core.d.ts +2 -2
  195. package/dist/core.d.ts.map +1 -1
  196. package/dist/core.js +1 -1
  197. package/dist/core.js.map +1 -1
  198. package/dist/field-kit.d.ts +3 -0
  199. package/dist/field-kit.d.ts.map +1 -1
  200. package/dist/field-kit.js +3 -0
  201. package/dist/field-kit.js.map +1 -1
  202. package/dist/nest.d.ts +1 -1
  203. package/dist/nest.d.ts.map +1 -1
  204. package/dist/nest.js.map +1 -1
  205. package/dist/react.d.ts +6 -2
  206. package/dist/react.d.ts.map +1 -1
  207. package/dist/react.js +5 -1
  208. package/dist/react.js.map +1 -1
  209. package/dist/testing.d.ts +1 -1
  210. package/dist/testing.d.ts.map +1 -1
  211. package/dist/testing.js +1 -1
  212. package/dist/testing.js.map +1 -1
  213. package/documentation/administration.md +7 -1
  214. package/documentation/backend.md +72 -1
  215. package/documentation/data-authz.md +42 -2
  216. package/documentation/declarations-cheatsheet.md +9 -0
  217. package/documentation/field-components.md +45 -1
  218. package/documentation/frontend.md +8 -0
  219. package/documentation/getting-started.md +7 -7
  220. package/documentation/managed-concurrency-frontend.md +1 -1
  221. package/documentation/manifest.json +11 -11
  222. package/documentation/testing.md +17 -0
  223. package/documentation/workflow-events.md +221 -6
  224. package/package.json +22 -25
  225. package/releases/2.51.0.json +32 -0
  226. package/releases/2.54.4.json +30 -0
  227. package/releases/2.54.6.json +30 -0
  228. package/releases/2.55.0.json +34 -0
  229. package/releases/2.55.1.json +32 -0
  230. package/skills/manifest.json +1 -1
  231. package/skills/openxiangda-v2/SKILL.md +4 -4
  232. package/skills/openxiangda-v2/references/administration.md +7 -1
  233. package/skills/openxiangda-v2/references/backend.md +72 -1
  234. package/skills/openxiangda-v2/references/data-authz.md +42 -2
  235. package/skills/openxiangda-v2/references/declarations-cheatsheet.md +9 -0
  236. package/skills/openxiangda-v2/references/field-components.md +45 -1
  237. package/skills/openxiangda-v2/references/frontend.md +8 -0
  238. package/skills/openxiangda-v2/references/getting-started.md +7 -7
  239. package/skills/openxiangda-v2/references/managed-concurrency-frontend.md +1 -1
  240. package/skills/openxiangda-v2/references/testing.md +17 -0
  241. package/skills/openxiangda-v2/references/workflow-events.md +221 -6
  242. package/dist/browser/components/platform-fields/MobileRichTextField.d.ts +0 -4
  243. package/dist/browser/components/platform-fields/MobileRichTextField.d.ts.map +0 -1
  244. package/dist/browser/components/platform-fields/MobileRichTextField.js +0 -38
  245. package/dist/browser/components/platform-fields/MobileRichTextField.js.map +0 -1
  246. package/releases/2.43.0.json +0 -38
  247. package/releases/2.44.0.json +0 -36
@@ -3,6 +3,7 @@ import { applicationCode } from '../../runtime-meta';
3
3
  import { readPendingWorkflowSubmission, writePendingWorkflowSubmission, clearPendingWorkflowSubmission, workflowSubmissionScope, submissionLocatorStorage, standardProcessWasRejected } from '../../workflow-submission-recovery';
4
4
  import { readPendingWorkflowTaskCommand, writePendingWorkflowTaskCommand, clearPendingWorkflowTaskCommand, workflowTaskCommandScope, workflowCommandTokenDigest, workflowTaskCommandWasRejected } from '../../workflow-task-command-recovery';
5
5
  import { WorkflowTaskForm, useWorkflowTaskForm } from './WorkflowTaskForm';
6
+ import { retainedWorkflowOperation, workflowOperationSignature, workflowOperationStringError, workflowOperationInputFailure } from '../../workflow-operation-input';
6
7
  import { WorkflowPendingCommandGuard, WorkflowTaskCommandReceipt } from './WorkflowTaskCommandReceipt';
7
8
  import { PresentationTime, usePresentationTimeZone } from '../../presentation-time';
8
9
  import { ArrowLeftOutlined, ClockCircleOutlined, EllipsisOutlined, ReloadOutlined, CloseOutlined, ExpandOutlined, CompressOutlined, ExportOutlined, } from '@ant-design/icons';
@@ -25,6 +26,10 @@ import { RecordChangeHistory } from '../resource/RecordChangeHistory';
25
26
  import { ResourceFormContent } from '../resource/ResourceFormFrame';
26
27
  import { WorkflowRecordEditor } from './WorkflowRecordEditor';
27
28
  import { PlatformAvatar } from '../PlatformAvatar';
29
+ import { SubtableField } from '../platform-fields/SubtableField';
30
+ import { standardProcessFormValues } from './standard-process-values';
31
+ import { fieldWritable } from '../resource/resource-page-helpers';
32
+ import { workflowSubmissionFormProjection, workflowSubmissionPrefill } from './workflow-submission-form';
28
33
  /**
29
34
  * An advanced task command has completed the current task and may have
30
35
  * created a new task. Reading the old task Surface in that case is expected
@@ -84,6 +89,7 @@ function workflowStatus(status) {
84
89
  running: { label: '审批中', color: 'processing' },
85
90
  returned: { label: '已退回', color: 'orange' },
86
91
  completed: { label: '已完成', color: 'success' },
92
+ skipped: { label: '已跳过', color: 'default' },
87
93
  approved: { label: '已同意', color: 'success' },
88
94
  rejected: { label: '已拒绝', color: 'error' },
89
95
  withdrawn: { label: '已撤回', color: 'default' },
@@ -129,32 +135,8 @@ function workflowSurfaceMatchesInstance(surface, instanceId) {
129
135
  function surfaceBusinessDetail(surface) {
130
136
  return normalizeWorkflowBusinessDetail(surface.presentation.businessDetail);
131
137
  }
132
- function workflowOperationSignature(operation) {
133
- return JSON.stringify({
134
- key: operation.key,
135
- kind: operation.kind,
136
- label: operation.label,
137
- placement: operation.placement,
138
- group: operation.group,
139
- audience: operation.audience,
140
- emphasis: operation.emphasis,
141
- tone: operation.tone,
142
- visible: operation.visible,
143
- enabled: operation.enabled,
144
- disabledReason: operation.disabledReason,
145
- inputSchema: operation.inputSchema,
146
- uiSchema: operation.uiSchema,
147
- execute: operation.execute,
148
- refresh: operation.refresh,
149
- });
150
- }
151
138
  const WORKFLOW_APP_ACTION_DISABLED_REASON = '应用动作由应用页面负责';
152
139
  function standardWorkflowOperations(surface) {
153
- if (!surface.commandToken ||
154
- !surface.commandTokenExpiresAt ||
155
- new Date(surface.commandTokenExpiresAt).getTime() <= Date.now()) {
156
- return [];
157
- }
158
140
  return surface.operations
159
141
  .filter((operation) => operation.visible)
160
142
  .map((operation) => {
@@ -322,7 +304,7 @@ export function WorkflowTimelineSection({ timeline, }) {
322
304
  const operations = item.operations || [];
323
305
  const visiblePeople = visibleWorkflowTimelinePeople(item, operations);
324
306
  const businessStep = item.nodeKind === 'action' ? item.result.businessStep : undefined;
325
- return (_jsxs("div", { className: timelineTone(item.status), children: [_jsx("span", { className: "oxa-workflow-timeline-dot", children: _jsx(WorkflowStatusIcon, { status: item.status }) }), _jsxs("div", { children: [_jsxs("div", { className: "oxa-workflow-timeline-title", children: [_jsx("strong", { children: item.title }), businessStep?.status === 'waiting' ? _jsx(Tag, { color: "processing", children: "\u7B49\u5F85\u4E1A\u52A1\u7ED3\u679C" }) : businessStep?.status === 'result_ready' ? _jsx(Tag, { color: "warning", children: "\u63A8\u8FDB\u53D7\u963B" }) : _jsx(StatusTag, { status: item.status })] }), businessStep?.status === 'result_ready' && _jsx(Typography.Text, { type: "secondary", children: "\u8BA1\u7B97\u7ED3\u679C\u5DF2\u6536\u5230\uFF0C\u540E\u7EED\u6D41\u8F6C\u7B49\u5F85\u4FEE\u590D\u3002" }), visiblePeople.length > 0 && (_jsx("div", { className: "oxa-workflow-timeline-assignees", children: visiblePeople.map((person, index) => (_jsxs("div", { children: [_jsx(PlatformAvatar, { avatarUrl: person.avatarUrl, size: 20 }), _jsxs("span", { children: [_jsx(Typography.Text, { children: person.displayName }), person.departmentDisplayName && (_jsx("small", { children: person.departmentDisplayName }))] })] }, `${person.userId || person.displayName}:${index}`))) })), operations.length > 0 && (_jsx("div", { className: "oxa-workflow-timeline-operations", children: operations.map((operation) => (_jsxs("div", { children: [_jsx(PlatformAvatar, { avatarUrl: operation.actor.avatarUrl, size: 20 }), _jsxs("span", { className: "oxa-workflow-operation-content", children: [_jsxs("span", { children: [_jsx(Typography.Text, { children: operation.actor.displayName }), _jsx("strong", { children: operation.operationLabel })] }), operation.reason && (_jsxs("span", { className: "oxa-workflow-operation-opinion", children: [_jsx(Typography.Text, { type: "secondary", children: "\u610F\u89C1" }), _jsx(Typography.Text, { children: operation.reason })] }))] })] }, operation.id))) })), item.terminalReason && !operations.some(operation => operation.reason) && (_jsxs(Typography.Text, { type: "secondary", children: ["\u539F\u56E0\uFF1A", item.terminalReason] })), item.primaryDisplayTime && (_jsx("time", { className: "oxa-workflow-primary-time", children: formatTime(item.primaryDisplayTime) }))] })] }, item.key));
307
+ return (_jsxs("div", { className: timelineTone(item.status), children: [_jsx("span", { className: "oxa-workflow-timeline-dot", children: _jsx(WorkflowStatusIcon, { status: item.status }) }), _jsxs("div", { children: [_jsxs("div", { className: "oxa-workflow-timeline-title", children: [_jsx("strong", { children: item.title }), businessStep?.status === 'waiting' ? _jsx(Tag, { color: "processing", children: "\u7B49\u5F85\u4E1A\u52A1\u7ED3\u679C" }) : businessStep?.status === 'result_ready' ? _jsx(Tag, { color: "warning", children: "\u63A8\u8FDB\u53D7\u963B" }) : _jsx(StatusTag, { status: item.status })] }), item.status === 'skipped' && _jsx(Typography.Text, { type: "secondary", children: "\u65E0\u5BA1\u6279\u4EBA\uFF0C\u6309\u6B64\u8282\u70B9\u7684\u89C4\u5219\u81EA\u52A8\u7EE7\u7EED\u3002" }), businessStep?.status === 'result_ready' && _jsx(Typography.Text, { type: "secondary", children: "\u8BA1\u7B97\u7ED3\u679C\u5DF2\u6536\u5230\uFF0C\u540E\u7EED\u6D41\u8F6C\u7B49\u5F85\u4FEE\u590D\u3002" }), visiblePeople.length > 0 && (_jsx("div", { className: "oxa-workflow-timeline-assignees", children: visiblePeople.map((person, index) => (_jsxs("div", { children: [_jsx(PlatformAvatar, { avatarUrl: person.avatarUrl, size: 20 }), _jsxs("span", { children: [_jsx(Typography.Text, { children: person.displayName }), person.departmentDisplayName && (_jsx("small", { children: person.departmentDisplayName }))] })] }, `${person.userId || person.displayName}:${index}`))) })), operations.length > 0 && (_jsx("div", { className: "oxa-workflow-timeline-operations", children: operations.map((operation) => (_jsxs("div", { children: [_jsx(PlatformAvatar, { avatarUrl: operation.actor.avatarUrl, size: 20 }), _jsxs("span", { className: "oxa-workflow-operation-content", children: [_jsxs("span", { children: [_jsx(Typography.Text, { children: operation.actor.displayName }), _jsx("strong", { children: operation.operationLabel })] }), operation.reason && (_jsxs("span", { className: "oxa-workflow-operation-opinion", children: [_jsx(Typography.Text, { type: "secondary", children: "\u610F\u89C1" }), _jsx(Typography.Text, { children: operation.reason })] }))] })] }, operation.id))) })), item.terminalReason && !operations.some(operation => operation.reason) && (_jsxs(Typography.Text, { type: "secondary", children: ["\u539F\u56E0\uFF1A", item.terminalReason] })), item.primaryDisplayTime && (_jsx("time", { className: "oxa-workflow-primary-time", children: formatTime(item.primaryDisplayTime) }))] })] }, item.key));
326
308
  }) })) : (_jsx(Empty, { description: "\u6682\u65E0\u6D41\u7A0B\u8F68\u8FF9", image: Empty.PRESENTED_IMAGE_SIMPLE })) }));
327
309
  }
328
310
  function WorkflowMemberPicker({ id, placeholder, value, onChange, multiple = false, variant }) {
@@ -349,6 +331,11 @@ function OperationFields({ operation, variant, }) {
349
331
  return (_jsx(_Fragment, { children: schemaProperties(operation).map(({ key, property, required, ui }) => {
350
332
  const rules = [
351
333
  ...(required ? [{ required: true, message: `请填写${property.title || key}` }] : []),
334
+ ...(property.type === 'string' ? [{ validator: async (_rule, value) => {
335
+ const error = workflowOperationStringError(property, value, required, property.title || key);
336
+ if (error)
337
+ throw new Error(error);
338
+ } }] : []),
352
339
  ...(property.type === 'array' ? [{ validator: async (_rule, value) => {
353
340
  if (value == null && !required)
354
341
  return;
@@ -372,7 +359,7 @@ function OperationFields({ operation, variant, }) {
372
359
  else if (property.format === 'date-time') {
373
360
  control = _jsx(Input, { type: "datetime-local" });
374
361
  }
375
- return (_jsx(Form.Item, { initialValue: property.default, label: property.title || key, name: key, rules: rules, children: control }, key));
362
+ return (_jsx(Form.Item, { initialValue: property.default, label: property.title || key, name: key, rules: rules, validateFirst: true, children: control }, key));
376
363
  }) }));
377
364
  }
378
365
  function OperationDialog({ error, operation, submitting, variant, onCancel, onSubmit, }) {
@@ -394,6 +381,7 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
394
381
  const [selectedState, setSelectedState] = useState(null);
395
382
  const [moreOpen, setMoreOpen] = useState(false);
396
383
  const [operationError, setOperationError] = useState('');
384
+ const [retainRefusedInput, setRetainRefusedInput] = useState(false);
397
385
  const [submitting, setSubmitting] = useState(false);
398
386
  const [draftLocked, setDraftLocked] = useState(false);
399
387
  const [fileLocked, setFileLocked] = useState(false);
@@ -414,16 +402,31 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
414
402
  setSelectedState(null);
415
403
  }, [settlement]);
416
404
  const operations = standardWorkflowOperations(surface);
417
- const selected = selectedState?.surface === surface
418
- ? operations.find((operation) => operation.key === selectedState.operation.key &&
419
- workflowOperationSignature(operation) ===
420
- selectedState.operationSignature) || null
421
- : null;
405
+ const [, setCommandClock] = useState(0);
406
+ const commandExpiresAt = Date.parse(surface.commandTokenExpiresAt || '');
407
+ const commandNeedsRefresh = operations.some(operation => operation.kind === 'workflow_command') &&
408
+ (!surface.commandToken || !Number.isFinite(commandExpiresAt) || commandExpiresAt <= Date.now());
409
+ useEffect(() => {
410
+ if (!surface.commandToken || !Number.isFinite(commandExpiresAt) || commandExpiresAt <= Date.now())
411
+ return;
412
+ let timer;
413
+ const tick = () => {
414
+ setCommandClock(value => value + 1);
415
+ const remaining = commandExpiresAt - Date.now();
416
+ if (remaining > 0)
417
+ timer = setTimeout(tick, Math.min(remaining, 2_147_483_647));
418
+ };
419
+ timer = setTimeout(tick, Math.min(commandExpiresAt - Date.now(), 2_147_483_647));
420
+ return () => clearTimeout(timer);
421
+ }, [surface.commandToken, commandExpiresAt]);
422
+ const selected = commandNeedsRefresh ? null
423
+ : retainedWorkflowOperation(selectedState, surface, operations, retainRefusedInput);
422
424
  useEffect(() => {
423
425
  if (selectedState && !selected && !submitting && !unknown)
424
426
  setSelectedState(null);
425
427
  }, [selected, selectedState, submitting, unknown]);
426
428
  const selectOperation = (operation) => {
429
+ setRetainRefusedInput(false);
427
430
  setOperationError('');
428
431
  setSelectedState({
429
432
  operation,
@@ -447,9 +450,9 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
447
450
  await onRefresh();
448
451
  throw new Error('WORKFLOW_FRESH_COMMAND_TOKEN_REQUIRED');
449
452
  }
450
- if (new Date(surface.commandTokenExpiresAt).getTime() <= Date.now()) {
453
+ if (!Number.isFinite(commandExpiresAt) || commandExpiresAt <= Date.now()) {
451
454
  await onRefresh();
452
- throw new Error('WORKFLOW_COMMAND_SURFACE_EXPIRED');
455
+ throw new Error('操作已刷新,请保留当前输入并重新确认。');
453
456
  }
454
457
  const input = { ...values };
455
458
  if (surface.taskForm && ['save_form', 'approve', 'resubmit'].includes(selected.key)) {
@@ -504,13 +507,13 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
504
507
  if (rejected) {
505
508
  clearLocator(wire.key);
506
509
  request.current = null;
507
- setSelectedState(null);
510
+ setRetainRefusedInput(true);
508
511
  }
509
512
  else {
510
513
  setUnknown(true);
511
514
  setSelectedState(null);
512
515
  }
513
- const failure = errorMessage(error, '任务操作尚未完成');
516
+ const failure = workflowOperationInputFailure(error) || errorMessage(error, '任务操作尚未完成');
514
517
  setOperationError(failure);
515
518
  if (rejected) {
516
519
  message.error(failure);
@@ -588,16 +591,16 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
588
591
  .sort((left, right) => {
589
592
  if (variant !== 'mobile')
590
593
  return 0;
591
- const order = { reject: 0, approve: 1 };
594
+ const order = { reject: 0, approve: 1, resubmit: 1 };
592
595
  return (order[left.key] ?? 10) - (order[right.key] ?? 10);
593
596
  });
594
597
  const secondary = operations.filter((operation) => operation.placement !== 'primary');
595
- const content = surface.taskForm || ((submitting || unknown) && !pendingLocator) || unknown || refreshFailure ? (_jsxs(_Fragment, { children: [surface.taskForm && _jsx(WorkflowTaskForm, { controller: taskForm, disabled: locked, variant: variant, taskId: surface.task?.id ? String(surface.task.id) : undefined, draftDisabled: commandLocked, onRefresh: onRefresh, onDraftBusyChange: busy => { setDraftLocked(busy); onBusyChange(busy || fileLocked || busyRef.current); }, onFileBusyChange: busy => { setFileLocked(busy); onBusyChange(busy || draftLocked || busyRef.current); }, resourceCode: surface.presentation.businessDetail.resourceCode || undefined, recordId: surface.presentation.businessDetail.recordId || undefined }), (submitting || unknown) && !pendingLocator && _jsx(WorkflowPendingCommandGuard, {}), unknown && _jsx(Alert, { type: "warning", showIcon: true, title: "\u4FDD\u7559\u4E86\u539F\u63D0\u4EA4\u8BF7\u6C42", description: operationError || '提交结果待确认,请重试原请求或查询原结果。', action: _jsx(Button, { disabled: submitting, loading: submitting, onClick: () => void sendRequest(true), children: "\u91CD\u8BD5\u539F\u8BF7\u6C42" }) }), refreshFailure && _jsx(Alert, { type: "warning", showIcon: true, title: refreshFailure.outcome === 'succeeded'
598
+ const content = surface.taskForm || commandNeedsRefresh || ((submitting || unknown) && !pendingLocator) || unknown || refreshFailure ? (_jsxs(_Fragment, { children: [commandNeedsRefresh && !unknown && !pendingLocator && !refreshFailure && _jsx(Alert, { type: "info", showIcon: true, title: "\u8BF7\u5237\u65B0\u64CD\u4F5C\u540E\u7EE7\u7EED\u529E\u7406", description: "\u9875\u9762\u505C\u7559\u8F83\u4E45\uFF0C\u9700\u91CD\u65B0\u786E\u8BA4\u5F53\u524D\u529E\u7406\u6743\u9650\u3002\u5237\u65B0\u4F1A\u4FDD\u7559\u5C1A\u672A\u4FDD\u5B58\u7684\u8F93\u5165\u3002", action: _jsx(Button, { disabled: locked, loading: submitting, onClick: () => void refreshConfirmed(), children: "\u5237\u65B0\u64CD\u4F5C" }) }), surface.taskForm && _jsx(WorkflowTaskForm, { controller: taskForm, disabled: locked, variant: variant, taskVersion: surface.task?.version ? Number(surface.task.version) : undefined, taskId: surface.task?.id ? String(surface.task.id) : undefined, draftDisabled: commandLocked, onRefresh: onRefresh, onDraftBusyChange: busy => { setDraftLocked(busy); onBusyChange(busy || fileLocked || busyRef.current); }, onFileBusyChange: busy => { setFileLocked(busy); onBusyChange(busy || draftLocked || busyRef.current); }, resourceCode: surface.presentation.businessDetail.resourceCode || undefined, recordId: surface.presentation.businessDetail.recordId || undefined }), (submitting || unknown) && !pendingLocator && _jsx(WorkflowPendingCommandGuard, {}), unknown && _jsx(Alert, { type: "warning", showIcon: true, title: "\u4FDD\u7559\u4E86\u539F\u63D0\u4EA4\u8BF7\u6C42", description: operationError || '提交结果待确认,请重试原请求或查询原结果。', action: _jsx(Button, { disabled: submitting, loading: submitting, onClick: () => void sendRequest(true), children: "\u91CD\u8BD5\u539F\u8BF7\u6C42" }) }), refreshFailure && _jsx(Alert, { type: "warning", showIcon: true, title: refreshFailure.outcome === 'succeeded'
596
599
  ? '任务操作已成功,但资料刷新失败' : '本次未提交,最新资料读取失败', description: refreshFailure.message, action: _jsx(Button, { disabled: submitting, onClick: () => void refreshConfirmed(), children: "\u5237\u65B0\u8D44\u6599" }) })] })) : null;
597
- const actions = (_jsxs(_Fragment, { children: [_jsxs("div", { className: `oxa-workflow-actions oxa-workflow-actions-${variant}`, children: [primary.map((operation) => (_jsx(Button, { danger: operation.emphasis === 'danger', disabled: locked || taskForm.stale || taskForm.draftNeedsSave || !operation.enabled, onClick: () => selectOperation(operation), title: operation.disabledReason, type: operation.emphasis === 'primary' ? 'primary' : 'default', children: operation.label }, operation.key))), secondary.length > 0 && (_jsx(Button, { className: "oxa-workflow-more-trigger", disabled: locked || taskForm.stale || taskForm.draftNeedsSave, icon: _jsx(EllipsisOutlined, {}), onClick: () => setMoreOpen((value) => !value), children: "\u66F4\u591A\u64CD\u4F5C" })), secondary.length > 0 && moreOpen && (_jsx("div", { className: "oxa-workflow-more-actions", children: secondary.map((operation) => (_jsx(Button, { disabled: locked || taskForm.stale || taskForm.draftNeedsSave || !operation.enabled, onClick: () => {
600
+ const actions = (_jsxs(_Fragment, { children: [_jsxs("div", { className: `oxa-workflow-actions oxa-workflow-actions-${variant}`, children: [primary.map((operation) => (_jsx(Button, { danger: operation.emphasis === 'danger', disabled: locked || commandNeedsRefresh || taskForm.stale || taskForm.draftNeedsSave || !operation.enabled, onClick: () => selectOperation(operation), title: operation.disabledReason, type: operation.emphasis === 'primary' ? 'primary' : 'default', children: operation.label }, operation.key))), secondary.length > 0 && (_jsx(Button, { className: "oxa-workflow-more-trigger", disabled: locked || commandNeedsRefresh || taskForm.stale || taskForm.draftNeedsSave, icon: _jsx(EllipsisOutlined, {}), onClick: () => setMoreOpen((value) => !value), children: "\u66F4\u591A\u64CD\u4F5C" })), secondary.length > 0 && moreOpen && (_jsx("div", { className: "oxa-workflow-more-actions", children: secondary.map((operation) => (_jsx(Button, { disabled: locked || commandNeedsRefresh || taskForm.stale || taskForm.draftNeedsSave || !operation.enabled, onClick: () => {
598
601
  setMoreOpen(false);
599
602
  selectOperation(operation);
600
- }, type: "text", title: operation.disabledReason, children: operation.label }, operation.key))) }))] }), _jsx(OperationDialog, { error: operationError, onCancel: () => setSelectedState(null), onSubmit: (values) => void submit(values), operation: selected, submitting: submitting, variant: variant })] }));
603
+ }, type: "text", title: operation.disabledReason, children: operation.label }, operation.key))) }))] }), _jsx(OperationDialog, { error: operationError, onCancel: () => { setRetainRefusedInput(false); setSelectedState(null); }, onSubmit: (values) => void submit(values), operation: selected, submitting: submitting, variant: variant })] }));
601
604
  return renderLayout({ content, actions });
602
605
  }
603
606
  /**
@@ -935,7 +938,8 @@ function StandardWorkflowDetailRenderer({ surface, timeline, warning, operations
935
938
  const titleField = workflowDetailGroups(business).flatMap(group => group.fields).find(field => field.type === 'text.short');
936
939
  const title = titleField && business.record[titleField.key] ? String(business.record[titleField.key]) : summary.title;
937
940
  const activeNode = timeline?.display?.entries.find(entry => entry.status === 'active');
938
- const people = activeNode?.people.map(person => person.displayName).filter(Boolean).join('、');
941
+ const activeFlow = activeNode && timeline?.flow.find(entry => entry.key === activeNode.key && entry.status === 'active');
942
+ const people = activeFlow?.assignees.filter(person => person.status === 'active').map(person => person.displayName).filter(Boolean).join('、');
939
943
  const statusTone = workflowStatus(instance.status).color;
940
944
  const bannerTone = statusTone === 'error' ? 'error' : 'active';
941
945
  const edit = workflowHasEnded(instance) ? onEdit : undefined;
@@ -1239,7 +1243,7 @@ async function workflowContextPrefillValue(field, rawValue, resources) {
1239
1243
  }
1240
1244
  return workflowContextScalarValue(field, value);
1241
1245
  }
1242
- export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWorkflowCode, variant = 'desktop', onDismiss, onCompleted, } = {}) {
1246
+ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWorkflowCode, variant = 'desktop', onDismiss, onCompleted, formOptions, } = {}) {
1243
1247
  const { workflowCode: routeWorkflowCode = '' } = useParams();
1244
1248
  const workflowCode = declaredWorkflowCode || routeWorkflowCode;
1245
1249
  const definition = useWorkflowDefinition(workflowCode);
@@ -1250,6 +1254,9 @@ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWor
1250
1254
  const { message } = App.useApp();
1251
1255
  const [subjectForm] = Form.useForm();
1252
1256
  const [requirementForm] = Form.useForm();
1257
+ const watchedFormValues = Form.useWatch([], { form: subjectForm, preserve: true });
1258
+ const [prefillError, setPrefillError] = useState(false);
1259
+ const prefill = useRef({ context: '', applied: new Set() });
1253
1260
  const [loading, setLoading] = useState(false);
1254
1261
  const [launchSurface, setLaunchSurface] = useState(null);
1255
1262
  const [launchError, setLaunchError] = useState(null);
@@ -1342,6 +1349,41 @@ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWor
1342
1349
  namedIntent,
1343
1350
  subjectDefinition,
1344
1351
  ]);
1352
+ const formProjection = useMemo(() => {
1353
+ try {
1354
+ const values = subjectDefinition ? normalizeFormValues(watchedFormValues || {}, subjectDefinition.surface) : {};
1355
+ return { ...workflowSubmissionFormProjection(fields, values, formOptions?.fieldState?.(values)), error: false };
1356
+ }
1357
+ catch {
1358
+ return { fields, values: {}, hiddenValues: {}, error: true };
1359
+ }
1360
+ }, [fields, formOptions?.fieldState, subjectDefinition, watchedFormValues]);
1361
+ const prefillContext = JSON.stringify([recoveryScope, identity.environment.activeAppVersionId, submissionMode, subjectId]);
1362
+ useEffect(() => {
1363
+ if (!launchSurface || commandId || pendingSubmission || formOptions?.preparation || mutationMode !== 'create' || !subjectDefinition ||
1364
+ launchSurface.environmentId !== identity.environment.id || (generatedNamedSubmission && !namedIntent))
1365
+ return;
1366
+ if (prefill.current.context !== prefillContext)
1367
+ prefill.current = { context: prefillContext, applied: new Set() };
1368
+ try {
1369
+ const values = workflowSubmissionPrefill(fields, formOptions?.initialValues || {}, prefill.current.applied, key => subjectForm.isFieldTouched(key));
1370
+ const normalized = normalizeRecordForForm(values, subjectDefinition.surface);
1371
+ subjectForm.setFields(Object.entries(normalized).map(([name, value]) => ({ name, value, touched: false })));
1372
+ setPrefillError(false);
1373
+ }
1374
+ catch {
1375
+ setPrefillError(true);
1376
+ }
1377
+ }, [commandId, fields, formOptions?.initialValues, formOptions?.preparation, generatedNamedSubmission, identity.environment.id,
1378
+ launchSurface, mutationMode, namedIntent, pendingSubmission, prefillContext, subjectDefinition, subjectForm]);
1379
+ useEffect(() => {
1380
+ if (loading || commandId || pendingSubmission || !launchSurface || formProjection.error || !subjectDefinition)
1381
+ return;
1382
+ const values = normalizeRecordForForm(formProjection.hiddenValues, subjectDefinition.surface);
1383
+ const changes = Object.entries(values).filter(([key, value]) => JSON.stringify(subjectForm.getFieldValue(key)) !== JSON.stringify(value));
1384
+ if (changes.length)
1385
+ subjectForm.setFields(changes.map(([name, value]) => ({ name, value, errors: [] })));
1386
+ }, [commandId, formProjection, launchSurface, loading, pendingSubmission, subjectDefinition, subjectForm]);
1345
1387
  useEffect(() => {
1346
1388
  let active = true;
1347
1389
  setLaunchSurface(null);
@@ -1676,6 +1718,8 @@ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWor
1676
1718
  : '当前部署版本未声明 launch 配置;请升级工具链后为 workflows.definitions[].launch 显式声明 mode' }));
1677
1719
  if (!subjectDefinition)
1678
1720
  return frame(_jsx(Result, { status: "500", title: "\u6807\u51C6\u6D41\u7A0B\u5408\u540C\u4E0D\u5B8C\u6574" }));
1721
+ if (!commandId && formOptions?.preparation)
1722
+ return frame(formOptions.preparation);
1679
1723
  if (launchError && !commandId)
1680
1724
  return frame(_jsx(Result, { status: "error", title: "\u53D1\u8D77\u9875\u9762\u5F53\u524D\u4E0D\u53EF\u7528", subTitle: launchError }));
1681
1725
  if (!launchSurface && !commandId)
@@ -1691,11 +1735,11 @@ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWor
1691
1735
  launchSurface?.submission.kind !== 'standard-process')) {
1692
1736
  return frame(_jsx(Result, { status: "500", title: "\u6807\u51C6\u6D41\u7A0B\u5408\u540C\u4E0D\u5B8C\u6574" }));
1693
1737
  }
1694
- if (!commandId && fields.some(field => field.type === 'subtable')) {
1738
+ if (!commandId && namedIntent && fields.some(field => field.type === 'subtable')) {
1695
1739
  return frame(_jsx(Result, { status: "error", title: "\u6807\u51C6\u6D41\u7A0B\u4E0D\u652F\u6301\u5305\u542B\u53EF\u5199\u5B50\u8868\u7684\u4E3B\u4F53\u8868\u5355", subTitle: "\u5F53\u524D\u6807\u51C6\u63D0\u4EA4 Surface \u5C1A\u672A\u58F0\u660E\u53EF\u5199\u5B50\u8868\u6E32\u67D3\u5668\u3002" }));
1696
1740
  }
1697
1741
  const submit = async (values) => {
1698
- if (submitInFlight.current || commandId || completion || !launchSurface)
1742
+ if (submitInFlight.current || commandId || completion || !launchSurface || formOptions?.preparation || prefillError || formProjection.error)
1699
1743
  return;
1700
1744
  const unresolved = readPendingWorkflowSubmission(submissionLocatorStorage(), recoveryScope);
1701
1745
  if (pendingSubmission || unresolved) {
@@ -1715,8 +1759,9 @@ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWor
1715
1759
  setRecoveryObservedAbsent(false);
1716
1760
  };
1717
1761
  try {
1718
- const encoded = normalizeFormValues(values, subjectDefinition.surface);
1719
- const data = Object.fromEntries(fields.filter(field => Object.hasOwn(encoded, field.key)).map(field => [field.key, encoded[field.key]]));
1762
+ const encoded = namedIntent ? normalizeFormValues(values, subjectDefinition.surface)
1763
+ : standardProcessFormValues(values, subjectDefinition.surface, resources, (field, mode) => fieldWritable(field, mode === 'create' ? 'create' : 'edit', hasCapability, identity.isAppSuperAdmin));
1764
+ const data = workflowSubmissionFormProjection(fields, encoded, formOptions?.fieldState?.(encoded)).values;
1720
1765
  const signature = JSON.stringify({ workflowCode, subjectId, environmentKey: identity.environment.key, submissionMode, data });
1721
1766
  if (submissionAttempt.current?.signature !== signature) {
1722
1767
  submissionAttempt.current = { signature, idempotencyKey: randomId(`process:${workflowCode}`), requestedAt: new Date().toISOString() };
@@ -1904,6 +1949,7 @@ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWor
1904
1949
  const uploadOperationCode = namedIntent?.operationCode || definition.processOperationCode;
1905
1950
  const fieldRenderers = uploadOperationCode
1906
1951
  ? {
1952
+ ...(!namedIntent ? { renderSubtable: ({ field, disabled, operation, recordId }) => _jsx(SubtableField, { field: field, disabled: disabled, operation: operation, parentRecordId: recordId, mobile: variant === 'mobile' }) } : {}),
1907
1953
  ...(namedIntent ? { referenceLaunch: { workflowCode: definition.code, operationCode: namedIntent.operationCode } } : {}),
1908
1954
  upload: async (field, file) => await uploadOperationManagedFile({
1909
1955
  operationCode: uploadOperationCode,
@@ -1928,7 +1974,7 @@ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWor
1928
1974
  (namedIntent
1929
1975
  ? '业务操作将在服务端完成校验、幂等提交,并按规则决定是否进入审批'
1930
1976
  : '业务数据和流程发起意图将原子提交'),
1931
- fields,
1977
+ fields: formProjection.fields,
1932
1978
  subjectDefinition,
1933
1979
  subjectForm,
1934
1980
  requirementForm,
@@ -1942,7 +1988,10 @@ export function WorkflowSubmissionPage({ instancePath, workflowCode: declaredWor
1942
1988
  completion,
1943
1989
  embedded: Boolean(onDismiss),
1944
1990
  fieldRenderers,
1991
+ formIntro: formOptions?.intro,
1992
+ formError: prefillError || formProjection.error ? '表单规则暂不可用,请联系管理员。' : undefined,
1945
1993
  recordId: mutationMode === 'update' ? subjectId : undefined,
1994
+ expectedRevision: mutationMode === 'update' ? loadedSubjectRevision : undefined,
1946
1995
  onBack: onDismiss ? dismissDrawer : () => navigate(-1),
1947
1996
  onSubmit: submit,
1948
1997
  onAnswer: answer,
@@ -1971,7 +2020,7 @@ function StandardProcessSubmissionRenderer(props) {
1971
2020
  }, new Map())].map(([section, fields]) => ({ section, fields }));
1972
2021
  if (props.completion)
1973
2022
  return _jsx(Result, { status: "success", title: "\u63D0\u4EA4\u6210\u529F", extra: _jsx(Button, { onClick: props.onBack, children: "\u8FD4\u56DE" }) });
1974
- return _jsxs("div", { className: props.variant === 'mobile' ? 'oxa-mobile-page oxa-mobile-entry oxa-workflow-submission-mobile' : 'oxa-workflow-entry', children: [!props.embedded && _jsxs("header", { className: props.variant === 'mobile' ? 'oxa-mobile-header' : 'oxa-workflow-entry-header', children: [_jsx(Button, { type: "text", "aria-label": "\u8FD4\u56DE", icon: _jsx(ArrowLeftOutlined, {}), disabled: props.processing, onClick: props.onBack }), _jsx("h3", { children: props.title }), _jsx("span", {})] }), _jsx(ResourceFormContent, { variant: props.variant, mode: props.mutationMode === 'update' ? 'edit' : 'create', resourceCode: props.subjectDefinition.code, recordId: props.recordId, groups: groups, form: props.subjectForm, busy: props.loading || props.submitted, pending: props.loading || props.processing, submitDisabled: props.submitted, submitLabel: "\u63D0\u4EA4\u5BA1\u6279", canWriteField: () => true, renderers: props.fieldRenderers, feedback: _jsxs(_Fragment, { children: [props.launchControls, props.processing && _jsx(Alert, { type: "info", showIcon: true, title: "\u6B63\u5728\u63D0\u4EA4\u7533\u8BF7\uFF0C\u8BF7\u7A0D\u5019\u2026" })] }), onSubmit: values => void props.onSubmit(values) }), _jsx(ProcessCommandPanel, { error: props.processError, form: props.requirementForm, loading: props.loading, onAnswer: props.onAnswer, onRetry: props.onRetry, onRefresh: props.onRefresh, surface: props.processSurface })] });
2023
+ return _jsxs("div", { className: props.variant === 'mobile' ? 'oxa-mobile-page oxa-mobile-entry oxa-workflow-submission-mobile' : 'oxa-workflow-entry', children: [!props.embedded && _jsxs("header", { className: props.variant === 'mobile' ? 'oxa-mobile-header' : 'oxa-workflow-entry-header', children: [_jsx(Button, { type: "text", "aria-label": "\u8FD4\u56DE", icon: _jsx(ArrowLeftOutlined, {}), disabled: props.processing, onClick: props.onBack }), _jsx("h3", { children: props.title }), _jsx("span", {})] }), _jsx(ResourceFormContent, { variant: props.variant, mode: props.mutationMode === 'update' ? 'edit' : 'create', resourceCode: props.subjectDefinition.code, recordId: props.recordId, groups: groups, expectedRevision: props.expectedRevision, initialValues: props.mutationMode === 'update' ? undefined : Object.fromEntries(props.fields.filter(field => field.type === 'user.multiple').map(field => [field.key, []])), form: props.subjectForm, busy: props.loading || props.submitted, pending: props.loading || props.processing, submitDisabled: props.submitted || Boolean(props.formError), submitLabel: "\u63D0\u4EA4\u5BA1\u6279", canWriteField: () => true, renderers: props.fieldRenderers, feedback: _jsxs(_Fragment, { children: [props.formIntro, props.launchControls, props.formError && _jsx(Alert, { type: "error", showIcon: true, title: props.formError }), props.processing && _jsx(Alert, { type: "info", showIcon: true, title: "\u6B63\u5728\u63D0\u4EA4\u7533\u8BF7\uFF0C\u8BF7\u7A0D\u5019\u2026" })] }), onSubmit: values => void props.onSubmit(values) }), _jsx(ProcessCommandPanel, { error: props.processError, form: props.requirementForm, loading: props.loading, onAnswer: props.onAnswer, onRetry: props.onRetry, onRefresh: props.onRefresh, surface: props.processSurface })] });
1975
2024
  }
1976
2025
  function DesktopProcessSubmissionRenderer(props) { return _jsx(StandardProcessSubmissionRenderer, { ...props, variant: "desktop" }); }
1977
2026
  function MobileProcessSubmissionRenderer(props) { return _jsx(StandardProcessSubmissionRenderer, { ...props, variant: "mobile" }); }