openxiangda 2.62.0 → 2.63.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.
- package/dist/browser/AuthoritativeSelector.d.ts +4 -3
- package/dist/browser/AuthoritativeSelector.d.ts.map +1 -1
- package/dist/browser/AuthoritativeSelector.js +25 -16
- package/dist/browser/AuthoritativeSelector.js.map +1 -1
- package/dist/browser/admin-contributions.d.ts +26 -0
- package/dist/browser/admin-contributions.d.ts.map +1 -1
- package/dist/browser/admin-contributions.js +30 -0
- package/dist/browser/admin-contributions.js.map +1 -1
- package/dist/browser/components/administration/membership-batch-model.d.ts.map +1 -1
- package/dist/browser/components/administration/membership-batch-model.js +2 -1
- package/dist/browser/components/administration/membership-batch-model.js.map +1 -1
- package/dist/browser/components/platform-fields/AttachmentFileList.d.ts +2 -1
- package/dist/browser/components/platform-fields/AttachmentFileList.d.ts.map +1 -1
- package/dist/browser/components/platform-fields/AttachmentFileList.js +3 -3
- package/dist/browser/components/platform-fields/AttachmentFileList.js.map +1 -1
- package/dist/browser/components/platform-fields/MobileManagedFileField.d.ts.map +1 -1
- package/dist/browser/components/platform-fields/MobileManagedFileField.js +2 -1
- package/dist/browser/components/platform-fields/MobileManagedFileField.js.map +1 -1
- package/dist/browser/components/platform-fields/ResourceReferenceField.d.ts +4 -2
- package/dist/browser/components/platform-fields/ResourceReferenceField.d.ts.map +1 -1
- package/dist/browser/components/platform-fields/ResourceReferenceField.js +4 -4
- package/dist/browser/components/platform-fields/ResourceReferenceField.js.map +1 -1
- package/dist/browser/components/platform-fields/SubtableField.d.ts.map +1 -1
- package/dist/browser/components/platform-fields/SubtableField.js +3 -2
- package/dist/browser/components/platform-fields/SubtableField.js.map +1 -1
- package/dist/browser/components/platform-fields/address-value.d.ts +2 -12
- package/dist/browser/components/platform-fields/address-value.d.ts.map +1 -1
- package/dist/browser/components/platform-fields/address-value.js +1 -69
- package/dist/browser/components/platform-fields/address-value.js.map +1 -1
- package/dist/browser/components/platform-fields/cascade-value.d.ts +2 -5
- package/dist/browser/components/platform-fields/cascade-value.d.ts.map +1 -1
- package/dist/browser/components/platform-fields/cascade-value.js +1 -46
- package/dist/browser/components/platform-fields/cascade-value.js.map +1 -1
- package/dist/browser/components/platform-fields/resource-query.d.ts +3 -19
- package/dist/browser/components/platform-fields/resource-query.d.ts.map +1 -1
- package/dist/browser/components/platform-fields/resource-query.js +2 -153
- package/dist/browser/components/platform-fields/resource-query.js.map +1 -1
- package/dist/browser/components/resource/GeneratedResourceCrud.d.ts +393 -2
- package/dist/browser/components/resource/GeneratedResourceCrud.d.ts.map +1 -1
- package/dist/browser/components/resource/GeneratedResourceCrud.js +148 -71
- package/dist/browser/components/resource/GeneratedResourceCrud.js.map +1 -1
- package/dist/browser/components/resource/GeneratedResourceForm.d.ts.map +1 -1
- package/dist/browser/components/resource/GeneratedResourceForm.js +7 -1
- package/dist/browser/components/resource/GeneratedResourceForm.js.map +1 -1
- package/dist/browser/components/resource/RecordDetailFrame.d.ts +4 -1
- package/dist/browser/components/resource/RecordDetailFrame.d.ts.map +1 -1
- package/dist/browser/components/resource/RecordDetailFrame.js +4 -2
- package/dist/browser/components/resource/RecordDetailFrame.js.map +1 -1
- package/dist/browser/components/resource/ResourceBatchActions.d.ts.map +1 -1
- package/dist/browser/components/resource/ResourceBatchActions.js +7 -6
- package/dist/browser/components/resource/ResourceBatchActions.js.map +1 -1
- package/dist/browser/components/resource/SurfaceFields.d.ts +4 -1
- package/dist/browser/components/resource/SurfaceFields.d.ts.map +1 -1
- package/dist/browser/components/resource/SurfaceFields.js +8 -8
- package/dist/browser/components/resource/SurfaceFields.js.map +1 -1
- package/dist/browser/components/resource/record-comment-session.d.ts.map +1 -1
- package/dist/browser/components/resource/record-comment-session.js +2 -1
- package/dist/browser/components/resource/record-comment-session.js.map +1 -1
- package/dist/browser/components/resource/record-deletion-session.d.ts.map +1 -1
- package/dist/browser/components/resource/record-deletion-session.js +2 -1
- package/dist/browser/components/resource/record-deletion-session.js.map +1 -1
- package/dist/browser/components/resource/useResourceFormDrafts.d.ts.map +1 -1
- package/dist/browser/components/resource/useResourceFormDrafts.js +2 -9
- package/dist/browser/components/resource/useResourceFormDrafts.js.map +1 -1
- package/dist/browser/components/workflow/StandardWorkflowPages.d.ts +5 -2
- package/dist/browser/components/workflow/StandardWorkflowPages.d.ts.map +1 -1
- package/dist/browser/components/workflow/StandardWorkflowPages.js +107 -64
- package/dist/browser/components/workflow/StandardWorkflowPages.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowAssignmentRoutingEditor.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowAssignmentRoutingEditor.js +2 -1
- package/dist/browser/components/workflow/WorkflowAssignmentRoutingEditor.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowBusinessStepRecoveryPanel.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowBusinessStepRecoveryPanel.js +15 -9
- package/dist/browser/components/workflow/WorkflowBusinessStepRecoveryPanel.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowConditionConfigurationEditor.d.ts +18 -0
- package/dist/browser/components/workflow/WorkflowConditionConfigurationEditor.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowConditionConfigurationEditor.js +29 -0
- package/dist/browser/components/workflow/WorkflowConditionConfigurationEditor.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowConditionEditor.d.ts +9 -0
- package/dist/browser/components/workflow/WorkflowConditionEditor.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowConditionEditor.js +33 -0
- package/dist/browser/components/workflow/WorkflowConditionEditor.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowDelegationManager.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowDelegationManager.js +2 -1
- package/dist/browser/components/workflow/WorkflowDelegationManager.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowDesigner.d.ts +14 -0
- package/dist/browser/components/workflow/WorkflowDesigner.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowDesigner.js +510 -0
- package/dist/browser/components/workflow/WorkflowDesigner.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowDesignerAssistant.d.ts +15 -0
- package/dist/browser/components/workflow/WorkflowDesignerAssistant.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowDesignerAssistant.js +75 -0
- package/dist/browser/components/workflow/WorkflowDesignerAssistant.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowDiagram.d.ts +8 -2
- package/dist/browser/components/workflow/WorkflowDiagram.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowDiagram.js +6 -6
- package/dist/browser/components/workflow/WorkflowDiagram.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowDraftHandlingEditor.d.ts +13 -0
- package/dist/browser/components/workflow/WorkflowDraftHandlingEditor.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowDraftHandlingEditor.js +20 -0
- package/dist/browser/components/workflow/WorkflowDraftHandlingEditor.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowFlowCanvas.d.ts +7 -0
- package/dist/browser/components/workflow/WorkflowFlowCanvas.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowFlowCanvas.js +84 -23
- package/dist/browser/components/workflow/WorkflowFlowCanvas.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowNodeCard.d.ts +2 -1
- package/dist/browser/components/workflow/WorkflowNodeCard.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowNodeCard.js +12 -10
- package/dist/browser/components/workflow/WorkflowNodeCard.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.d.ts +13 -2
- package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.js +72 -24
- package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowNotificationEditor.d.ts +20 -0
- package/dist/browser/components/workflow/WorkflowNotificationEditor.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowNotificationEditor.js +18 -0
- package/dist/browser/components/workflow/WorkflowNotificationEditor.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowParallelConfigurationEditor.d.ts +10 -0
- package/dist/browser/components/workflow/WorkflowParallelConfigurationEditor.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowParallelConfigurationEditor.js +24 -0
- package/dist/browser/components/workflow/WorkflowParallelConfigurationEditor.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowRecordEditor.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowRecordEditor.js +2 -1
- package/dist/browser/components/workflow/WorkflowRecordEditor.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowReminderEditor.d.ts +7 -0
- package/dist/browser/components/workflow/WorkflowReminderEditor.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowReminderEditor.js +7 -0
- package/dist/browser/components/workflow/WorkflowReminderEditor.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowReturnPolicyEditor.d.ts +8 -0
- package/dist/browser/components/workflow/WorkflowReturnPolicyEditor.d.ts.map +1 -0
- package/dist/browser/components/workflow/WorkflowReturnPolicyEditor.js +33 -0
- package/dist/browser/components/workflow/WorkflowReturnPolicyEditor.js.map +1 -0
- package/dist/browser/components/workflow/WorkflowTaskDraftPanel.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowTaskDraftPanel.js +2 -1
- package/dist/browser/components/workflow/WorkflowTaskDraftPanel.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowTaskFiles.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowTaskFiles.js +2 -1
- package/dist/browser/components/workflow/WorkflowTaskFiles.js.map +1 -1
- package/dist/browser/components/workflow/WorkflowTaskForm.d.ts +1 -4
- package/dist/browser/components/workflow/WorkflowTaskForm.d.ts.map +1 -1
- package/dist/browser/components/workflow/WorkflowTaskForm.js +5 -6
- package/dist/browser/components/workflow/WorkflowTaskForm.js.map +1 -1
- package/dist/browser/components/workflow/workflow-approval-presentation.d.ts +13 -0
- package/dist/browser/components/workflow/workflow-approval-presentation.d.ts.map +1 -0
- package/dist/browser/components/workflow/workflow-approval-presentation.js +21 -0
- package/dist/browser/components/workflow/workflow-approval-presentation.js.map +1 -0
- package/dist/browser/components/workflow/workflow-designer-presentation.d.ts +13 -0
- package/dist/browser/components/workflow/workflow-designer-presentation.d.ts.map +1 -0
- package/dist/browser/components/workflow/workflow-designer-presentation.js +69 -0
- package/dist/browser/components/workflow/workflow-designer-presentation.js.map +1 -0
- package/dist/browser/components/workflow/workflow-flow-layout.d.ts +11 -2
- package/dist/browser/components/workflow/workflow-flow-layout.d.ts.map +1 -1
- package/dist/browser/components/workflow/workflow-flow-layout.js +44 -9
- package/dist/browser/components/workflow/workflow-flow-layout.js.map +1 -1
- package/dist/browser/components/workflow/workflow-operation-layout.d.ts +6 -0
- package/dist/browser/components/workflow/workflow-operation-layout.d.ts.map +1 -0
- package/dist/browser/components/workflow/workflow-operation-layout.js +17 -0
- package/dist/browser/components/workflow/workflow-operation-layout.js.map +1 -0
- package/dist/browser/durable-command.d.ts.map +1 -1
- package/dist/browser/durable-command.js +2 -1
- package/dist/browser/durable-command.js.map +1 -1
- package/dist/browser/managed-command.d.ts.map +1 -1
- package/dist/browser/managed-command.js +2 -1
- package/dist/browser/managed-command.js.map +1 -1
- package/dist/browser/platform-client.d.ts +71 -3
- package/dist/browser/platform-client.d.ts.map +1 -1
- package/dist/browser/platform-client.js +58 -9
- package/dist/browser/platform-client.js.map +1 -1
- package/dist/browser/record-detail.css +4 -3
- package/dist/browser/styles.css +355 -1
- package/dist/browser/uuid.d.ts +7 -0
- package/dist/browser/uuid.d.ts.map +1 -0
- package/dist/browser/uuid.js +19 -0
- package/dist/browser/uuid.js.map +1 -0
- package/dist/browser/workflow-approval.css +205 -0
- package/dist/browser/workflow-operation-input.d.ts.map +1 -1
- package/dist/browser/workflow-operation-input.js +1 -0
- package/dist/browser/workflow-operation-input.js.map +1 -1
- package/dist/core.d.ts +1 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +1 -0
- package/dist/core.js.map +1 -1
- package/dist/react.d.ts +1 -0
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +1 -0
- package/dist/react.js.map +1 -1
- package/dist/resource.d.ts +22 -0
- package/dist/resource.d.ts.map +1 -0
- package/dist/resource.js +18 -0
- package/dist/resource.js.map +1 -0
- package/documentation/AGENTS.md +1 -1
- package/documentation/application-templates.md +37 -0
- package/documentation/field-components.md +10 -1
- package/documentation/frontend.md +14 -4
- package/documentation/getting-started.md +9 -7
- package/documentation/manifest.json +13 -7
- package/documentation/reference/cli.md +2 -0
- package/documentation/reference/mcp.md +238 -0
- package/documentation/workflow-events.md +33 -0
- package/package.json +39 -29
- package/releases/2.63.0.json +45 -0
- package/releases/2.63.1.json +46 -0
- package/skills/manifest.json +1 -1
- package/skills/openxiangda-v2/SKILL.md +7 -7
- package/skills/openxiangda-v2/references/application-templates.md +37 -0
- package/skills/openxiangda-v2/references/cli.md +2 -0
- package/skills/openxiangda-v2/references/field-components.md +10 -1
- package/skills/openxiangda-v2/references/frontend.md +14 -4
- package/skills/openxiangda-v2/references/getting-started.md +9 -7
- package/skills/openxiangda-v2/references/mcp.md +238 -0
- package/skills/openxiangda-v2/references/workflow-events.md +33 -0
- package/releases/2.20.1.json +0 -30
- package/releases/2.20.2.json +0 -30
- package/releases/2.20.3.json +0 -29
- package/releases/2.20.4.json +0 -30
- package/releases/2.31.5.json +0 -33
- package/releases/2.59.3.json +0 -36
- package/releases/2.60.0.json +0 -38
- package/releases/2.61.0.json +0 -39
- package/releases/2.61.1.json +0 -37
- package/releases/2.61.2.json +0 -32
- package/releases/2.61.3.json +0 -33
- package/releases/2.62.0.json +0 -40
|
@@ -7,8 +7,8 @@ import { WorkflowTaskForm, useWorkflowTaskForm } from './WorkflowTaskForm';
|
|
|
7
7
|
import { retainedWorkflowOperation, workflowOperationSignature, workflowOperationStringError, workflowOperationInputFailure } from '../../workflow-operation-input';
|
|
8
8
|
import { WorkflowPendingCommandGuard, WorkflowTaskCommandReceipt } from './WorkflowTaskCommandReceipt';
|
|
9
9
|
import { PresentationTime, usePresentationTimeZone } from '../../presentation-time';
|
|
10
|
-
import { ArrowLeftOutlined,
|
|
11
|
-
import { Alert, App, Button, Card, Drawer, Empty, Form, Input, Modal, Result, Segmented, Select, Space, Spin, Table, Tabs, Tag, Tooltip, Typography, } from 'antd';
|
|
10
|
+
import { ArrowLeftOutlined, EllipsisOutlined, RightOutlined, EditOutlined, StopOutlined, SwapOutlined, UserAddOutlined, SaveOutlined, ReloadOutlined, CloseOutlined, ExpandOutlined, CompressOutlined, ExportOutlined, } from '@ant-design/icons';
|
|
11
|
+
import { Alert, App, Button, Card, Dropdown, Drawer, Empty, Form, Input, Modal, Result, Segmented, Select, Space, Spin, Table, Tabs, Tag, Tooltip, Typography, } from 'antd';
|
|
12
12
|
import { normalizeWorkflowBusinessDetail, } from 'openxiangda-contracts/browser';
|
|
13
13
|
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
14
14
|
import { Link, Navigate, useHref, useNavigate, useParams, useSearchParams, } from 'react-router-dom';
|
|
@@ -23,10 +23,12 @@ import { useRuntime, useOptionalRuntime } from '../../runtime';
|
|
|
23
23
|
import { SurfaceFieldValue, } from '../resource/SurfaceFields';
|
|
24
24
|
import { workflowContextScalarValue, processStatusReadRetryDelay, buildWorkflowNamedOperationInput, parseWorkflowNamedOperationResult, workflowLaunchContractJsonEqual, } from '../../workflow-launch';
|
|
25
25
|
import { normalizeFormValues, normalizeRecordForForm, } from '../platform-fields/field-form-codec';
|
|
26
|
-
import { RecordDetailFrame,
|
|
26
|
+
import { RecordDetailFrame, detailTime } from '../resource/RecordDetailFrame';
|
|
27
27
|
import { RecordChangeHistory } from '../resource/RecordChangeHistory';
|
|
28
28
|
import { ResourceFormContent } from '../resource/ResourceFormFrame';
|
|
29
29
|
import { WorkflowRecordEditor } from './WorkflowRecordEditor';
|
|
30
|
+
import { workflowOperationGroups } from './workflow-operation-layout';
|
|
31
|
+
import { workflowApprovalProgress, WorkflowApprovalParticipants } from './workflow-approval-presentation';
|
|
30
32
|
import { PlatformAvatar } from '../PlatformAvatar';
|
|
31
33
|
import { SubtableField } from '../platform-fields/SubtableField';
|
|
32
34
|
import { assertNamedSubtableReadonlyFields, namedProcessFormValues, standardProcessFormValues } from './standard-process-values';
|
|
@@ -79,7 +81,7 @@ function errorMessage(error, fallback) {
|
|
|
79
81
|
WORKFLOW_TASK_FORM_REVISION_CONFLICT: '业务资料已被其他处理人更新。请刷新并核对,当前输入会保留。',
|
|
80
82
|
WORKFLOW_TASK_FORM_RECOMPUTATION_REQUIRED: '这些资料会影响已完成的计算,请退回到计算前的节点重新办理。',
|
|
81
83
|
WORKFLOW_TASK_FORM_FIELD_NOT_EDITABLE: '页面规则已变化,请刷新资料后重新确认。',
|
|
82
|
-
WORKFLOW_TASK_FORM_COMMAND_FORBIDDEN: '
|
|
84
|
+
WORKFLOW_TASK_FORM_COMMAND_FORBIDDEN: '此操作不提交补填资料,请使用保存、同意或重新提交。',
|
|
83
85
|
};
|
|
84
86
|
if (code && taskPageMessages[code])
|
|
85
87
|
return taskPageMessages[code];
|
|
@@ -222,9 +224,18 @@ export function WorkflowBusinessDetailSections({ surface, variant, }) {
|
|
|
222
224
|
if (detail.status === 'unavailable' || !detail.surface) {
|
|
223
225
|
return _jsx(Result, { status: "warning", title: "\u4E1A\u52A1\u8BE6\u60C5\u6682\u65F6\u4E0D\u53EF\u7528" });
|
|
224
226
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
227
|
+
const renderValue = (field) => _jsx(SurfaceFieldValue, { field: field, presentation: "workflow-detail", mobile: variant === 'mobile', resourceCode: detail.resourceCode || undefined, value: detail.record[field.key], workflowFileBinding: { instanceId: instance.id, resourceCode: String(detail.resourceCode), recordId: String(detail.recordId), fieldCode: field.key } });
|
|
228
|
+
const attachmentFields = groups.flatMap(group => group.fields).filter(field => field.type === 'file');
|
|
229
|
+
const contentGroups = groups.map(group => ({ ...group, fields: group.fields.filter(field => field.type !== 'file') })).filter(group => group.fields.length);
|
|
230
|
+
return _jsxs("div", { className: "oxa-record-detail-sections oxa-workflow-business-sections", children: [contentGroups.map(group => _jsxs("section", { className: "oxa-workflow-business-section", children: [_jsx("h2", { children: ['default', '申请信息', '基本信息'].includes(group.section) ? '申请内容' : group.section }), _jsx("div", { className: "oxa-record-detail-card", children: _jsx("div", { className: "oxa-record-detail-fields", children: group.fields.map(field => field.type === 'subtable'
|
|
231
|
+
? _jsxs("details", { className: "is-wide oxa-workflow-subtable-disclosure", children: [_jsxs("summary", { children: [_jsx("span", { children: field.label }), _jsxs("span", { children: [detail.subtables[field.key]?.total ?? 0, " \u9879", _jsx(RightOutlined, {})] })] }), _jsx(WorkflowSubtableValue, { detail: detail, field: field, instanceId: instance.id, variant: variant })] }, field.key)
|
|
232
|
+
: _jsxs("div", { className: ['textarea', 'image', 'rich-text', 'address', 'location', 'signature', 'json'].includes(field.widget) ? 'is-wide' : undefined, children: [_jsx("div", { className: "oxa-record-detail-label", children: field.label }), _jsx("div", { className: `oxa-record-detail-value${field.widget === 'money' ? ' is-amount' : ''}`, children: field.type === 'text.long' && typeof detail.record[field.key] === 'string'
|
|
233
|
+
? _jsx(Typography.Paragraph, { ellipsis: { rows: 2, expandable: 'collapsible', symbol: expanded => expanded ? '收起' : '展开' }, children: String(detail.record[field.key]) })
|
|
234
|
+
: renderValue(field) })] }, field.key)) }) })] }, group.section)), attachmentFields.map(field => {
|
|
235
|
+
const value = detail.record[field.key];
|
|
236
|
+
const count = Array.isArray(value) ? value.length : value ? 1 : 0;
|
|
237
|
+
return _jsxs("section", { className: "oxa-workflow-business-section oxa-workflow-attachment-section", "aria-label": field.label, children: [_jsxs("h2", { children: [field.label, "\uFF08", count, "\uFF09"] }), _jsx("div", { className: "oxa-record-detail-card", children: renderValue(field) })] }, field.key);
|
|
238
|
+
})] });
|
|
228
239
|
}
|
|
229
240
|
function timelineTone(status) {
|
|
230
241
|
return `is-${status}`;
|
|
@@ -298,14 +309,30 @@ export function WorkflowStatusIcon({ status, }) {
|
|
|
298
309
|
}
|
|
299
310
|
return (_jsx("svg", { "aria-hidden": "true", className: `oxa-workflow-status-icon is-${status}`, viewBox: "0 0 24 24", children: glyph }));
|
|
300
311
|
}
|
|
301
|
-
export function WorkflowTimelineSection({ timeline, }) {
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
312
|
+
export function WorkflowTimelineSection({ timeline, compact = false, task, footer, }) {
|
|
313
|
+
const [expanded, setExpanded] = useState(false);
|
|
314
|
+
const runtime = useOptionalRuntime();
|
|
315
|
+
const allEntries = workflowTimelineEntries(timeline);
|
|
316
|
+
const activeIndex = allEntries.findIndex(entry => entry.status === 'active' || entry.status === 'waiting');
|
|
317
|
+
const start = Math.max(0, Math.min(activeIndex < 0 ? allEntries.length - 3 : activeIndex - 1, allEntries.length - 3));
|
|
318
|
+
const entries = compact ? allEntries.slice(start, start + 3) : allEntries;
|
|
319
|
+
const time = (value) => _jsx("time", { className: "oxa-workflow-primary-time", dateTime: value, children: _jsx(PresentationTime, { value: value, options: { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' } }) });
|
|
320
|
+
return (_jsxs(Card, { className: `oxa-workflow-timeline-card${compact ? ' oxa-workflow-timeline-compact' : ''}`, title: "\u5BA1\u6279\u8FDB\u5EA6", extra: compact && entries.length > 0 ? _jsxs(Button, { type: "link", onClick: () => setExpanded(true), children: ["\u67E5\u770B\u5168\u90E8", _jsx(RightOutlined, {})] }) : undefined, children: [entries.length ? _jsx("div", { className: "oxa-workflow-timeline", children: entries.map(item => {
|
|
321
|
+
const operations = item.operations || [];
|
|
322
|
+
const visiblePeople = visibleWorkflowTimelinePeople(item, operations);
|
|
323
|
+
const flow = timeline?.flow.find(visit => visit.key === item.key);
|
|
324
|
+
const progress = item.status === 'active' && task?.nodeId === item.nodeId ? workflowApprovalProgress(task) : null;
|
|
325
|
+
const businessStep = item.nodeKind === 'action' ? item.result.businessStep : undefined;
|
|
326
|
+
return _jsxs("div", { className: `${timelineTone(item.status)}${item.kind === 'planned_node' ? ' is-planned' : ''}`, 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 }), item.kind === 'planned_node' ? _jsx(Tag, { children: "\u9884\u8BA1" }) : progress
|
|
327
|
+
? _jsxs(Tag, { color: "processing", children: [progress.label, progress.total > 0 ? ` ${progress.approved}/${progress.total}` : ''] })
|
|
328
|
+
: businessStep?.status === 'waiting' ? _jsx(Tag, { color: "processing", children: "\u7B49\u5F85\u4E1A\u52A1\u7ED3\u679C" })
|
|
329
|
+
: businessStep?.status === 'result_ready' ? _jsx(Tag, { color: "warning", children: "\u63A8\u8FDB\u53D7\u963B" })
|
|
330
|
+
: !['completed', 'active', 'waiting'].includes(item.status) ? _jsx(StatusTag, { status: item.status }) : null, item.primaryDisplayTime && item.status !== 'active' && !compact && time(item.primaryDisplayTime)] }), !compact && progress && progress.total > 0 && _jsxs("div", { className: "oxa-workflow-quorum", "aria-label": `${progress.label}:${progress.approved}/${progress.total} 人${progress.verb}`, children: [_jsx("span", { children: _jsx("span", { style: { width: `${progress.approved / progress.total * 100}%` } }) }), _jsxs("small", { children: [progress.approved, "/", progress.total] })] }), item.status === 'skipped' && _jsx(Typography.Text, { type: "secondary", children: item.result.skipReason === 'return_resume' ? '重新提交后直接返回当前节点,已处理的阶段无需重复办理。' : '无审批人,按此节点的规则自动继续。' }), 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" }), operations.length > 0 && _jsx("div", { className: "oxa-workflow-timeline-operations", children: operations.map(operation => _jsxs("div", { children: [_jsxs("div", { className: "oxa-workflow-person-line", children: [_jsx(PlatformAvatar, { avatarUrl: operation.actor.avatarUrl, size: 24 }), _jsxs("span", { children: [operation.actor.displayName, operation.actor.userId === runtime?.identity.userId ? '(你)' : ''] }), _jsx(Tag, { color: operation.operation === 'approve' ? 'success' : operation.operation === 'reject' ? 'error' : 'default', children: operation.operationLabel }), operation.occurredAt && (compact || item.status === 'active' || operation.occurredAt !== item.primaryDisplayTime) && time(operation.occurredAt)] }), operation.reason && _jsxs("div", { className: "oxa-workflow-operation-opinion", children: ["\u201C", operation.reason, "\u201D"] })] }, operation.id)) }), visiblePeople.length > 0 && _jsx("div", { className: "oxa-workflow-timeline-assignees", children: visiblePeople.map((person, index) => {
|
|
331
|
+
const participant = flow?.assignees.find(assignee => assignee.userId === person.userId);
|
|
332
|
+
return _jsxs("div", { className: "oxa-workflow-person-line", children: [_jsx(PlatformAvatar, { avatarUrl: person.avatarUrl, size: 24 }), _jsxs("span", { children: [person.displayName, person.userId === runtime?.identity.userId ? '(你)' : ''] }), item.status === 'active' && participant?.status === 'active' ? _jsx(Tag, { color: "warning", children: "\u5F85\u5904\u7406" })
|
|
333
|
+
: person.departmentDisplayName && _jsx("small", { children: person.departmentDisplayName })] }, `${person.userId || person.displayName}:${index}`);
|
|
334
|
+
}) }), item.terminalReason && !operations.some(operation => operation.reason) && _jsxs(Typography.Text, { type: "secondary", children: ["\u539F\u56E0\uFF1A", item.terminalReason] }), compact && !operations.length && item.primaryDisplayTime && time(item.primaryDisplayTime)] })] }, item.key);
|
|
335
|
+
}) }) : _jsx(Empty, { description: "\u6682\u65E0\u6D41\u7A0B\u8F68\u8FF9", image: Empty.PRESENTED_IMAGE_SIMPLE }), footer, compact && _jsx(Drawer, { open: expanded, onClose: () => setExpanded(false), title: "\u5168\u90E8\u5BA1\u6279\u8FDB\u5EA6", placement: "bottom", size: "85dvh", rootClassName: "oxa-workflow-progress-drawer", destroyOnHidden: true, children: _jsx(WorkflowTimelineSection, { timeline: timeline, task: task }) })] }));
|
|
309
336
|
}
|
|
310
337
|
function WorkflowMemberPicker({ id, placeholder, value, onChange, multiple = false, variant }) {
|
|
311
338
|
const [snapshots, setSnapshots] = useState([]);
|
|
@@ -328,6 +355,16 @@ function schemaProperties(operation) {
|
|
|
328
355
|
}));
|
|
329
356
|
}
|
|
330
357
|
function OperationFields({ operation, variant, }) {
|
|
358
|
+
const form = Form.useFormInstance();
|
|
359
|
+
const targetNodeId = Form.useWatch('targetNodeId', form);
|
|
360
|
+
const returnRoutes = operation.uiSchema.returnRoutes;
|
|
361
|
+
const previousTarget = useRef(undefined);
|
|
362
|
+
useEffect(() => {
|
|
363
|
+
const policy = targetNodeId ? returnRoutes?.[targetNodeId] : undefined;
|
|
364
|
+
if (policy && (previousTarget.current !== targetNodeId || !policy.routes.includes(String(form.getFieldValue('resubmitMode')))))
|
|
365
|
+
form.setFieldsValue({ resubmitMode: policy.defaultRoute });
|
|
366
|
+
previousTarget.current = targetNodeId;
|
|
367
|
+
}, [form, targetNodeId, returnRoutes]);
|
|
331
368
|
return (_jsx(_Fragment, { children: schemaProperties(operation).map(({ key, property, required, ui }) => {
|
|
332
369
|
const rules = [
|
|
333
370
|
...(required ? [{ required: true, message: `请填写${property.title || key}` }] : []),
|
|
@@ -348,10 +385,10 @@ function OperationFields({ operation, variant, }) {
|
|
|
348
385
|
if (ui.component === 'user_select')
|
|
349
386
|
control = _jsx(WorkflowMemberPicker, { variant: variant, multiple: property.type === 'array' || ui.mode === 'multiple', placeholder: ui.placeholder || `请选择${property.title || '成员'}` });
|
|
350
387
|
else if (property.enum) {
|
|
351
|
-
control = (_jsx(Select, { options: property.enum.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
388
|
+
control = (_jsx(Select, { options: property.enum.flatMap((value, index) => key === 'resubmitMode' && targetNodeId && returnRoutes?.[targetNodeId] && !returnRoutes[targetNodeId].routes.includes(value) ? [] : [{
|
|
389
|
+
label: property.enumNames?.[index] || value,
|
|
390
|
+
value,
|
|
391
|
+
}]) }));
|
|
355
392
|
}
|
|
356
393
|
else if (property.format === 'textarea') {
|
|
357
394
|
control = (_jsx(Input.TextArea, { autoSize: { minRows: 4, maxRows: 8 }, maxLength: property.maxLength, showCount: true }));
|
|
@@ -370,11 +407,11 @@ function OperationDialog({ error, operation, submitting, variant, onCancel, onSu
|
|
|
370
407
|
if (!operation)
|
|
371
408
|
return null;
|
|
372
409
|
const ui = operation.uiSchema;
|
|
373
|
-
const formNode = (_jsxs(Form, { form: form, layout: "vertical", onFinish: onSubmit, disabled: submitting, children: [error && _jsx(Alert, { role: "alert", title: "\u5BA1\u6279\u5C1A\u672A\u5B8C\u6210", description: error, showIcon: true, type: "error" }), ui.confirmation?.description && (_jsx(Alert, { className: "oxa-workflow-operation-alert", description: ui.confirmation
|
|
410
|
+
const formNode = (_jsxs(Form, { form: form, layout: "vertical", onFinish: onSubmit, disabled: submitting, children: [error && _jsx(Alert, { role: "alert", title: "\u5BA1\u6279\u5C1A\u672A\u5B8C\u6210", description: error, showIcon: true, type: "error" }), (operation.consequence || ui.confirmation?.description) && (_jsx(Alert, { className: "oxa-workflow-operation-alert", description: operation.consequence || ui.confirmation?.description, showIcon: true, type: operation.emphasis === 'danger' ? 'warning' : 'info' })), _jsx(OperationFields, { operation: operation, variant: variant })] }));
|
|
374
411
|
if (variant === 'mobile') {
|
|
375
|
-
return (_jsx(Drawer, { extra: _jsx(Button, { loading: submitting, onClick: () => form.submit(), type: "primary", children: ui.confirmText || `确认${operation.label}` }), rootClassName: "oxa-workflow-operation-drawer", styles: { body: { overflowY: 'auto', minHeight: 0 } }, keyboard: !submitting, mask: { closable: !submitting }, closable: !submitting, onClose: submitting ? undefined : onCancel, open: true, placement: "bottom", size: "min(640px, 92dvh)", title: operation.label, children: formNode }));
|
|
412
|
+
return (_jsx(Drawer, { extra: _jsx(Button, { danger: operation.emphasis === 'danger', loading: submitting, onClick: () => form.submit(), type: "primary", children: ui.confirmText || `确认${operation.label}` }), rootClassName: "oxa-workflow-operation-drawer", styles: { body: { overflowY: 'auto', minHeight: 0 } }, keyboard: !submitting, mask: { closable: !submitting }, closable: !submitting, onClose: submitting ? undefined : onCancel, open: true, placement: "bottom", size: "min(640px, 92dvh)", title: operation.label, children: formNode }));
|
|
376
413
|
}
|
|
377
|
-
return (_jsx(Modal, { cancelText: "\u53D6\u6D88", confirmLoading: submitting, cancelButtonProps: { disabled: submitting }, okText: ui.confirmText || `确认${operation.label}`, onCancel: onCancel, onOk: () => form.submit(), open: true, title: operation.label, keyboard: !submitting, mask: { closable: !submitting }, closable: !submitting, children: formNode }));
|
|
414
|
+
return (_jsx(Modal, { cancelText: "\u53D6\u6D88", confirmLoading: submitting, cancelButtonProps: { disabled: submitting }, okButtonProps: { danger: operation.emphasis === 'danger' }, okText: ui.confirmText || `确认${operation.label}`, onCancel: onCancel, onOk: () => form.submit(), open: true, title: operation.label, keyboard: !submitting, mask: { closable: !submitting }, closable: !submitting, children: formNode }));
|
|
378
415
|
}
|
|
379
416
|
function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pendingLocator, persistLocator, clearLocator, onBusyChange, settlement, confirmedReadPending, renderLayout, }) {
|
|
380
417
|
const { message } = App.useApp();
|
|
@@ -383,7 +420,6 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
|
|
|
383
420
|
const [operationError, setOperationError] = useState('');
|
|
384
421
|
const [retainRefusedInput, setRetainRefusedInput] = useState(false);
|
|
385
422
|
const [submitting, setSubmitting] = useState(false);
|
|
386
|
-
const [draftLocked, setDraftLocked] = useState(false);
|
|
387
423
|
const [fileLocked, setFileLocked] = useState(false);
|
|
388
424
|
const [refreshFailure, setRefreshFailure] = useState(null);
|
|
389
425
|
const [unknown, setUnknown] = useState(false);
|
|
@@ -435,15 +471,15 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
|
|
|
435
471
|
surface,
|
|
436
472
|
});
|
|
437
473
|
};
|
|
438
|
-
const submit = async (values) => {
|
|
439
|
-
if (!
|
|
474
|
+
const submit = async (values, operation = selected) => {
|
|
475
|
+
if (!operation || busyRef.current || fileLocked || taskForm.draftNeedsSave || pendingLocator || unknown || refreshFailure || confirmedReadPending)
|
|
440
476
|
return;
|
|
441
477
|
setOperationError('');
|
|
442
478
|
setSubmitting(true);
|
|
443
479
|
busyRef.current = true;
|
|
444
480
|
onBusyChange(true);
|
|
445
481
|
try {
|
|
446
|
-
if (
|
|
482
|
+
if (operation.kind !== 'workflow_command') {
|
|
447
483
|
throw new Error('WORKFLOW_APP_ACTION_NOT_EXECUTABLE_IN_STANDARD_PANEL');
|
|
448
484
|
}
|
|
449
485
|
const commandToken = surface.commandToken;
|
|
@@ -456,16 +492,16 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
|
|
|
456
492
|
throw new Error('操作已刷新,请保留当前输入并重新确认。');
|
|
457
493
|
}
|
|
458
494
|
const input = { ...values };
|
|
459
|
-
if (surface.taskForm && ['save_form', 'approve', 'resubmit'].includes(
|
|
495
|
+
if (surface.taskForm && ['save_form', 'complete', 'approve', 'resubmit'].includes(operation.key)) {
|
|
460
496
|
if (taskForm.stale)
|
|
461
497
|
throw new Error('业务资料已更新,请先核对最新资料');
|
|
462
|
-
input.form = await taskForm.build(
|
|
498
|
+
input.form = await taskForm.build(operation.key !== 'save_form');
|
|
463
499
|
}
|
|
464
|
-
const key = randomId(`workflow:${
|
|
500
|
+
const key = randomId(`workflow:${operation.key}`);
|
|
465
501
|
if (surface.task?.id)
|
|
466
|
-
persistLocator({ taskId: String(surface.task.id), command:
|
|
502
|
+
persistLocator({ taskId: String(surface.task.id), command: operation.key,
|
|
467
503
|
idempotencyKey: key, requestedAt: new Date().toISOString(), tokenDigest: await workflowCommandTokenDigest(commandToken) });
|
|
468
|
-
request.current = { surface, operation
|
|
504
|
+
request.current = { surface, operation, input: JSON.parse(JSON.stringify(input)), key };
|
|
469
505
|
}
|
|
470
506
|
catch (error) {
|
|
471
507
|
const hasFreshSurface = Boolean(error?.data?.freshSurface);
|
|
@@ -477,7 +513,7 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
|
|
|
477
513
|
else {
|
|
478
514
|
const failure = error?.status === 403
|
|
479
515
|
? '当前审批资料或操作权限已变化,请刷新资料后重新确认。'
|
|
480
|
-
: errorMessage(error, `${
|
|
516
|
+
: errorMessage(error, `${operation.label}失败`);
|
|
481
517
|
setOperationError(failure);
|
|
482
518
|
message.error(failure);
|
|
483
519
|
}
|
|
@@ -543,7 +579,10 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
|
|
|
543
579
|
setSelectedState(null);
|
|
544
580
|
taskForm.committed(wire.input.form, Number(result.dataRevision) || undefined);
|
|
545
581
|
onBusyChange(false);
|
|
546
|
-
message.success(`${wire.operation.label}
|
|
582
|
+
message.success(`${wire.operation.label}成功`);
|
|
583
|
+
const resume = result.returnResume;
|
|
584
|
+
if (resume?.reason)
|
|
585
|
+
message.info(resume.reason);
|
|
547
586
|
// The write has succeeded. A callback or read failure can only affect refresh.
|
|
548
587
|
try {
|
|
549
588
|
await onCommandSuccess(result);
|
|
@@ -584,24 +623,30 @@ function WorkflowOperations({ surface, variant, onRefresh, onCommandSuccess, pen
|
|
|
584
623
|
}
|
|
585
624
|
};
|
|
586
625
|
const commandLocked = submitting || unknown || Boolean(pendingLocator) || Boolean(refreshFailure) || confirmedReadPending;
|
|
587
|
-
const locked = commandLocked ||
|
|
626
|
+
const locked = commandLocked || fileLocked;
|
|
588
627
|
if (!operations.length && !surface.taskForm && !unknown && !refreshFailure)
|
|
589
628
|
return renderLayout({ content: null, actions: null });
|
|
590
|
-
const primary = operations
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
if (
|
|
594
|
-
return
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
629
|
+
const { primary, secondary } = workflowOperationGroups(operations, variant);
|
|
630
|
+
const actionsDisabled = locked || commandNeedsRefresh || taskForm.stale || taskForm.draftNeedsSave;
|
|
631
|
+
const choose = (operation) => {
|
|
632
|
+
if (actionsDisabled || !operation.visible || !operation.enabled)
|
|
633
|
+
return;
|
|
634
|
+
setMoreOpen(false);
|
|
635
|
+
if (operation.uiSchema.presentation === 'direct') {
|
|
636
|
+
setRetainRefusedInput(false);
|
|
637
|
+
setSelectedState(null);
|
|
638
|
+
void submit({}, operation);
|
|
639
|
+
}
|
|
640
|
+
else
|
|
641
|
+
selectOperation(operation);
|
|
642
|
+
};
|
|
643
|
+
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, valueLinkage: taskFormBehavior?.valueLinkage, linkageContext: { workflowCode: String(surface.instance.workflowCode || ''), nodeId: String(surface.task?.nodeId || ''), pageCode: surface.taskForm.pageCode }, operationPending: submitting || unknown || Boolean(pendingLocator) || fileLocked, taskVersion: surface.task?.version ? Number(surface.task.version) : undefined, taskId: surface.task?.id ? String(surface.task.id) : undefined, onFileBusyChange: busy => { setFileLocked(busy); onBusyChange(busy || 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'
|
|
600
644
|
? '任务操作已成功,但资料刷新失败' : '本次未提交,最新资料读取失败', description: refreshFailure.message, action: _jsx(Button, { disabled: submitting, onClick: () => void refreshConfirmed(), children: "\u5237\u65B0\u8D44\u6599" }) })] })) : null;
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
645
|
+
const moreTrigger = _jsx(Button, { className: "oxa-workflow-more-trigger", disabled: actionsDisabled, icon: _jsx(EllipsisOutlined, {}), "aria-label": "\u66F4\u591A", "aria-expanded": moreOpen && !actionsDisabled, onClick: variant === 'mobile' ? () => setMoreOpen(true) : undefined, children: "\u66F4\u591A" });
|
|
646
|
+
const actions = operations.length ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: `oxa-workflow-actions oxa-workflow-actions-${variant}`, role: "group", "aria-label": "\u5BA1\u6279\u64CD\u4F5C", children: [secondary.length > 0 && (variant === 'mobile' ? moreTrigger : _jsx(Dropdown, { open: moreOpen && !actionsDisabled, onOpenChange: setMoreOpen, trigger: ['click'], placement: "topLeft", menu: { items: secondary.map(operation => ({ key: operation.key, danger: operation.emphasis === 'danger',
|
|
647
|
+
disabled: actionsDisabled || !operation.enabled,
|
|
648
|
+
label: _jsxs("span", { className: "oxa-workflow-more-label", children: [_jsx("strong", { children: operation.label }), _jsx("small", { children: operation.disabledReason || operation.consequence })] }),
|
|
649
|
+
onClick: () => choose(operation), })) }, children: moreTrigger })), primary.map(operation => _jsx(Button, { className: operation.emphasis === 'primary' ? 'oxa-workflow-approve-primary' : undefined, danger: operation.emphasis === 'danger', disabled: actionsDisabled || !operation.enabled, onClick: () => choose(operation), title: operation.disabledReason, type: operation.emphasis === 'primary' ? 'primary' : variant === 'desktop' && operation.emphasis === 'danger' ? 'text' : 'default', children: operation.label }, operation.key))] }), variant === 'mobile' && _jsx(Drawer, { title: "\u66F4\u591A\u64CD\u4F5C", open: moreOpen && !actionsDisabled && secondary.length > 0, onClose: () => setMoreOpen(false), closable: false, placement: "bottom", size: "auto", rootClassName: "oxa-workflow-more-drawer", destroyOnHidden: true, footer: _jsx(Button, { type: "text", block: true, onClick: () => setMoreOpen(false), children: "\u53D6\u6D88" }), children: _jsx("div", { className: "oxa-workflow-more-list", children: secondary.map(operation => _jsxs(Button, { type: "text", danger: operation.emphasis === 'danger', disabled: actionsDisabled || !operation.enabled, onClick: () => choose(operation), children: [_jsx("span", { className: "oxa-workflow-more-icon", "aria-hidden": "true", children: operation.emphasis === 'danger' ? _jsx(StopOutlined, {}) : operation.key === 'transfer' ? _jsx(SwapOutlined, {}) : operation.key === 'add_assignee' ? _jsx(UserAddOutlined, {}) : operation.key === 'save_form' ? _jsx(SaveOutlined, {}) : _jsx(EditOutlined, {}) }), _jsxs("span", { className: "oxa-workflow-more-label", children: [_jsx("strong", { children: operation.label }), _jsx("small", { children: operation.disabledReason || operation.consequence })] })] }, operation.key)) }) }), _jsx(OperationDialog, { error: operationError, onCancel: () => { setRetainRefusedInput(false); setSelectedState(null); }, onSubmit: values => void submit(values), operation: selected, submitting: submitting, variant: variant })] })) : null;
|
|
605
650
|
return renderLayout({ content, actions });
|
|
606
651
|
}
|
|
607
652
|
/**
|
|
@@ -942,30 +987,28 @@ export function WorkflowSummarySection({ surface }) {
|
|
|
942
987
|
function StandardWorkflowDetailRenderer({ surface, timeline, warning, operations, taskContent, variant, onClose, onEdit, drawer, drawerState, newPageHref, editing, busy, }) {
|
|
943
988
|
const navigate = useNavigate();
|
|
944
989
|
const timeZone = usePresentationTimeZone();
|
|
945
|
-
const [
|
|
990
|
+
const [auditInstance, setAuditInstance] = useState(null);
|
|
946
991
|
const instance = surfaceInstance(surface);
|
|
947
|
-
const
|
|
992
|
+
const task = surfaceTask(surface);
|
|
993
|
+
const definition = useWorkflowDefinition(instance.workflowCode);
|
|
994
|
+
const deadline = task?.completionDeadline;
|
|
948
995
|
const business = surfaceBusinessDetail(surface);
|
|
949
996
|
const summary = surface.presentation.summary;
|
|
950
|
-
const
|
|
951
|
-
const
|
|
952
|
-
const activeNode = timeline
|
|
997
|
+
const title = summary.title;
|
|
998
|
+
const pageTitle = business.resourceName || definition?.title || '申请详情';
|
|
999
|
+
const activeNode = workflowTimelineEntries(timeline).find(entry => entry.status === 'active');
|
|
953
1000
|
const activeFlow = activeNode && timeline?.flow.find(entry => entry.key === activeNode.key && entry.status === 'active');
|
|
954
1001
|
const people = activeFlow?.assignees.filter(person => person.status === 'active').map(person => person.displayName).filter(Boolean).join('、');
|
|
955
|
-
const
|
|
956
|
-
const bannerTone = statusTone === 'error' ? 'error' : 'active';
|
|
1002
|
+
const progress = activeNode?.nodeId === task?.nodeId ? workflowApprovalProgress(task) : null;
|
|
957
1003
|
const edit = workflowHasEnded(instance) ? onEdit : undefined;
|
|
958
|
-
const
|
|
1004
|
+
const visibleOperations = standardWorkflowOperations(surface);
|
|
1005
|
+
const needsYou = visibleOperations.some(operation => operation.enabled && operation.audience === 'participant' && operation.group === 'decision');
|
|
959
1006
|
const loadAudit = useCallback(() => loadWorkflowDataAudit(instance.id), [instance.id]);
|
|
960
1007
|
const back = onClose || (() => navigate(variant === 'mobile' ? '/m/work-center' : '/work-center'));
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
{ key: 'changes', label: '变更记录', children: tab === 'changes' && business.surface && business.resourceCode && business.recordId
|
|
966
|
-
? _jsx(RecordChangeHistory, { resourceCode: business.resourceCode, recordId: business.recordId, surface: business.surface, readable: () => true, loadPage: loadAudit })
|
|
967
|
-
: _jsx(Empty, { description: "\u6682\u65E0\u53D8\u66F4\u8BB0\u5F55" }) },
|
|
968
|
-
] }), taskContent && _jsx("div", { className: "oxa-workflow-task-content", children: taskContent })] });
|
|
1008
|
+
const audit = ['ready', 'stale'].includes(business.status) && business.surface && business.resourceCode && business.recordId &&
|
|
1009
|
+
_jsxs("details", { className: "oxa-workflow-audit-section", open: auditInstance === instance.id, onToggle: event => setAuditInstance(event.currentTarget.open ? instance.id : null), children: [_jsxs("summary", { children: [_jsx(EditOutlined, {}), _jsx("span", { children: "\u8D44\u6599\u53D8\u66F4" }), _jsx(RightOutlined, {})] }), auditInstance === instance.id && _jsx(RecordChangeHistory, { resourceCode: business.resourceCode, recordId: business.recordId, surface: business.surface, readable: () => true, loadPage: loadAudit })] });
|
|
1010
|
+
return _jsxs(RecordDetailFrame, { className: "oxa-workflow-approval-detail", variant: variant, summaryHeader: true, backLabel: "\u8FD4\u56DE\u5F85\u529E", title: pageTitle, heading: variant === 'desktop' && title !== pageTitle ? `${pageTitle} · ${title}` : title, status: _jsx(StatusTag, { status: instance.status }), metadata: [summary.initiator?.displayName || summary.initiatorDisplayName, summary.initiator?.departmentDisplayName || summary.departmentDisplayName,
|
|
1011
|
+
summary.submittedAt ? `${detailTime(summary.submittedAt, timeZone)}${variant === 'desktop' ? ' 提交' : ''}` : '', variant === 'desktop' ? summary.businessNumber : ''].filter(Boolean).join(' · '), onClose: back, onEdit: edit, editing: editing, busy: busy, drawer: drawer, drawerState: drawerState, newPageHref: newPageHref, footer: operations || visibleOperations.length || edit ? _jsxs(_Fragment, { children: [operations, edit && _jsx(Button, { onClick: edit, children: "\u7F16\u8F91" })] }) : null, children: [warning && _jsx(Alert, { description: warning, showIcon: true, type: "warning" }), _jsxs("div", { className: `oxa-workflow-detail-sections oxa-workflow-detail-sections-${variant}`, children: [_jsxs("div", { className: "oxa-workflow-main-column", children: [!workflowHasEnded(instance) && activeNode && _jsx("div", { className: "oxa-workflow-current-section", children: _jsxs("div", { className: "oxa-workflow-current-node is-active", role: "status", children: [_jsxs("strong", { children: [_jsx("span", { className: "oxa-workflow-current-dot" }), `${needsYou ? '需要你处理' : '当前节点'}:${activeNode.title}`] }), (progress || people) && _jsx("span", { children: progress ? `${progress.label}${progress.total > 0 ? ` · 已有 ${progress.approved}/${progress.total} 人${progress.verb}` : ''}` : `等待${people}处理` })] }) }), deadline && !workflowHasEnded(instance) && ['pending', 'failed'].includes(deadline.status) && _jsx(Alert, { showIcon: true, type: deadline.status === 'failed' ? 'warning' : 'info', title: deadline.status === 'failed' ? '到期自动处理未成功' : `未提前完成时,将于 ${detailTime(deadline.deadlineAt, timeZone)} 自动同意`, description: deadline.status === 'failed' ? '流程仍可人工办理。自动处理已停止,请联系流程管理员查看执行记录。' : '可以在此之前填写可选内容并手动提交;自动处理不会代替任何人记录审批意见。' }), _jsx("section", { "aria-label": "\u7533\u8BF7\u5185\u5BB9", className: "oxa-workflow-detail-section oxa-workflow-application-section", children: _jsx(WorkflowBusinessDetailSections, { surface: surface, variant: variant }) }), taskContent && _jsx("section", { "aria-label": "\u672C\u8282\u70B9\u9700\u586B\u5199", className: "oxa-workflow-task-content", children: taskContent })] }), _jsxs("aside", { className: "oxa-workflow-progress-rail", children: [_jsx("section", { "aria-label": "\u5BA1\u6279\u8FDB\u5EA6", className: "oxa-workflow-detail-section oxa-workflow-history-section", children: _jsx(WorkflowTimelineSection, { timeline: timeline, task: task, compact: variant === 'mobile', footer: audit }) }), variant === 'desktop' && _jsx(WorkflowApprovalParticipants, { surface: surface, timeline: timeline })] })] })] });
|
|
969
1012
|
}
|
|
970
1013
|
export function DesktopWorkflowDetailRenderer(props) {
|
|
971
1014
|
return _jsx(StandardWorkflowDetailRenderer, { ...props, variant: "desktop" });
|