增加审批组件

This commit is contained in:
dengqichen 2025-10-24 23:17:07 +08:00
parent 114d549a5c
commit 50c8b4240b
3 changed files with 136 additions and 1 deletions

View File

@ -0,0 +1,75 @@
/**
*
*
*/
import React from 'react';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { FormRenderer } from '@/components/FormDesigner';
import type { FormDefinitionResponse } from '@/pages/Form/Definition/types';
interface FormPreviewModalProps {
open: boolean;
onClose: () => void;
formDefinition: FormDefinitionResponse | null;
}
const FormPreviewModal: React.FC<FormPreviewModalProps> = ({
open,
onClose,
formDefinition
}) => {
if (!formDefinition) {
return null;
}
return (
<Dialog open={open} onOpenChange={onClose}>
<DialogContent className="max-w-5xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>
{formDefinition.name}
{formDefinition.description && (
<span className="text-sm font-normal text-muted-foreground ml-2">
{formDefinition.description}
</span>
)}
</DialogTitle>
</DialogHeader>
<div className="py-4">
<FormRenderer
schema={formDefinition.schema}
readonly={false}
showSubmit={false}
showCancel={false}
/>
</div>
<div className="text-xs text-muted-foreground border-t pt-3 space-y-1">
<div>{formDefinition.key}</div>
<div>v{formDefinition.formVersion}</div>
<div>
<span className={`ml-1 ${
formDefinition.status === 'PUBLISHED' ? 'text-green-600' :
formDefinition.status === 'DRAFT' ? 'text-yellow-600' :
'text-gray-600'
}`}>
{formDefinition.status === 'PUBLISHED' ? '已发布' :
formDefinition.status === 'DRAFT' ? '草稿' :
formDefinition.status}
</span>
</div>
</div>
</DialogContent>
</Dialog>
);
};
export default FormPreviewModal;

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Save, Undo, Redo, ZoomIn, ZoomOut, Maximize2, ArrowLeft } from 'lucide-react';
import { Save, Undo, Redo, ZoomIn, ZoomOut, Maximize2, ArrowLeft, Eye } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Separator } from '@/components/ui/separator';
import {
@ -12,6 +12,8 @@ import {
interface WorkflowToolbarProps {
title?: string;
onSave?: () => void;
onPreviewForm?: () => void;
hasFormDefinition?: boolean;
onUndo?: () => void;
onRedo?: () => void;
onZoomIn?: () => void;
@ -27,6 +29,8 @@ interface WorkflowToolbarProps {
const WorkflowToolbar: React.FC<WorkflowToolbarProps> = ({
title = '工作流设计器',
onSave,
onPreviewForm,
hasFormDefinition = false,
onUndo,
onRedo,
onZoomIn,
@ -146,6 +150,23 @@ const WorkflowToolbar: React.FC<WorkflowToolbarProps> = ({
<Separator orientation="vertical" className="h-6 mx-2" />
{/* 预览表单按钮 */}
{hasFormDefinition && (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
onClick={onPreviewForm}
className="gap-1.5"
>
<Eye className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent></TooltipContent>
</Tooltip>
)}
{/* 保存按钮(最右侧) */}
<Button
onClick={onSave}

View File

@ -8,6 +8,7 @@ import NodePanel from './components/NodePanel';
import FlowCanvas from './components/FlowCanvas';
import NodeConfigModal from './components/NodeConfigModal';
import EdgeConfigModal, { type EdgeCondition } from './components/EdgeConfigModal';
import FormPreviewModal from './components/FormPreviewModal';
import type { FlowNode, FlowEdge, FlowNodeData } from './types';
import type { WorkflowNodeDefinition } from './nodes/types';
import { isConfigurableNode } from './nodes/types';
@ -15,6 +16,8 @@ import { useWorkflowSave } from './hooks/useWorkflowSave';
import { useWorkflowLoad } from './hooks/useWorkflowLoad';
import { useHistory } from './hooks/useHistory';
import { generateNodeId, generateEdgeId } from './utils/idGenerator';
import { getDefinitionById as getFormDefinitionById } from '@/pages/Form/Definition/service';
import type { FormDefinitionResponse } from '@/pages/Form/Definition/types';
// 样式
import '@xyflow/react/dist/style.css';
@ -50,6 +53,10 @@ const WorkflowDesignInner: React.FC = () => {
const [edgeConfigModalVisible, setEdgeConfigModalVisible] = useState(false);
const [configEdge, setConfigEdge] = useState<FlowEdge | null>(null);
// 表单定义数据和预览弹窗状态
const [formDefinition, setFormDefinition] = useState<FormDefinitionResponse | null>(null);
const [formPreviewVisible, setFormPreviewVisible] = useState(false);
// 保存和加载hooks
const { hasUnsavedChanges, saveWorkflow, markUnsaved } = useWorkflowSave();
const { workflowDefinition, loadWorkflow } = useWorkflowLoad();
@ -69,6 +76,19 @@ const WorkflowDesignInner: React.FC = () => {
setNodes(data.nodes);
setEdges(data.edges);
setWorkflowTitle(data.definition?.name || '未命名工作流');
// 如果工作流关联了表单,加载表单定义数据
if (data.definition?.formDefinitionId) {
try {
const formDef = await getFormDefinitionById(data.definition.formDefinitionId);
setFormDefinition(formDef);
console.log('表单定义数据已加载:', formDef);
} catch (error) {
console.error('加载表单定义失败:', error);
}
} else {
setFormDefinition(null);
}
}
}
};
@ -125,6 +145,16 @@ const WorkflowDesignInner: React.FC = () => {
navigate('/workflow/definition');
}, [navigate]);
// 预览表单
const handlePreviewForm = useCallback(() => {
if (!formDefinition) {
message.warning('当前工作流未关联启动表单');
return;
}
setFormPreviewVisible(true);
}, [formDefinition]);
// 撤销操作
const handleUndo = useCallback(() => {
const state = history.undo();
@ -494,6 +524,8 @@ const WorkflowDesignInner: React.FC = () => {
title={`${workflowTitle}${hasUnsavedChanges ? ' *' : ''}`}
onSave={handleSave}
onBack={handleBack}
onPreviewForm={handlePreviewForm}
hasFormDefinition={!!formDefinition}
onUndo={handleUndo}
onRedo={handleRedo}
onZoomIn={handleZoomIn}
@ -545,6 +577,13 @@ const WorkflowDesignInner: React.FC = () => {
onOk={handleEdgeConditionUpdate}
onCancel={handleCloseEdgeConfigModal}
/>
{/* 表单预览弹窗 */}
<FormPreviewModal
open={formPreviewVisible}
onClose={() => setFormPreviewVisible(false)}
formDefinition={formDefinition}
/>
</div>
);
};