From 1c166c255943cb46dbae2ca5df396e7e791e8eed Mon Sep 17 00:00:00 2001 From: asp_ly Date: Mon, 30 Dec 2024 20:49:04 +0800 Subject: [PATCH] 1 --- .../src/pages/Workflow/NodeDesign/index.tsx | 421 ++++++++++++++---- .../src/pages/Workflow/NodeDesign/service.ts | 7 + 2 files changed, 334 insertions(+), 94 deletions(-) diff --git a/frontend/src/pages/Workflow/NodeDesign/index.tsx b/frontend/src/pages/Workflow/NodeDesign/index.tsx index d6ee1ddc..47e46a28 100644 --- a/frontend/src/pages/Workflow/NodeDesign/index.tsx +++ b/frontend/src/pages/Workflow/NodeDesign/index.tsx @@ -1,135 +1,368 @@ -import React, { useState } from 'react'; -import { ProTable } from '@ant-design/pro-components'; -import type { ProColumns } from '@ant-design/pro-components'; -import { Tag, Space, Button, Modal } from 'antd'; -import { PlusOutlined } from '@ant-design/icons'; +import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; +import { PageContainer } from '@/components/ui/page-container'; +import { PlusOutlined, DeleteOutlined } from '@ant-design/icons'; import { NodeTypeEnum, type NodeDesignDataResponse } from './types'; import * as service from './service'; +import { + Table, + TableHeader, + TableBody, + TableHead, + TableRow, + TableCell, +} from "@/components/ui/table"; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { useToast } from "@/components/ui/use-toast"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@/components/ui/alert-dialog"; +import { DataTablePagination } from "@/components/ui/pagination"; -// 节点类型标签颜色映射 -const nodeTypeColors = { - [NodeTypeEnum.START_EVENT]: 'green', - [NodeTypeEnum.END_EVENT]: 'red', - [NodeTypeEnum.SCRIPT_TASK]: 'blue', +// 节点类型标签样式映射 +const nodeTypeStyles = { + [NodeTypeEnum.START_EVENT]: { + variant: 'success' as const, + label: '开始事件' + }, + [NodeTypeEnum.END_EVENT]: { + variant: 'destructive' as const, + label: '结束事件' + }, + [NodeTypeEnum.SCRIPT_TASK]: { + variant: 'default' as const, + label: '脚本任务' + }, }; +interface Column { + accessorKey?: keyof NodeDesignDataResponse; + id?: string; + header: string; + size: number; + cell?: (props: { row: { original: NodeDesignDataResponse } }) => React.ReactNode; +} + const NodeDesignList: React.FC = () => { const navigate = useNavigate(); const [detailVisible, setDetailVisible] = useState(false); const [currentNode, setCurrentNode] = useState(); + const [list, setList] = useState([]); + const [loading, setLoading] = useState(false); + const [pagination, setPagination] = useState({ + pageNum: 1, + pageSize: 10, + totalElements: 0, + }); + const { toast } = useToast(); - // 表格列定义 - const columns: ProColumns[] = [ + const loadData = async () => { + setLoading(true); + try { + const response = await service.getNodeDefinitions({ + current: pagination.pageNum, + pageSize: pagination.pageSize, + }); + setList(response.content || []); + setPagination({ + ...pagination, + totalElements: response.totalElements, + }); + } catch (error) { + toast({ + variant: "destructive", + title: "获取节点列表失败", + duration: 3000, + }); + } finally { + setLoading(false); + } + }; + + const handlePageChange = (page: number) => { + setPagination({ + ...pagination, + pageNum: page, + }); + }; + + const handleDelete = async (id: number) => { + try { + await service.deleteNodeDefinition(id); + toast({ + title: "删除成功", + duration: 3000, + }); + loadData(); + } catch (error) { + toast({ + variant: "destructive", + title: "删除失败", + duration: 3000, + }); + } + }; + + useEffect(() => { + loadData(); + }, [pagination.pageNum, pagination.pageSize]); + + const columns: Column[] = [ { - title: '节点编码', - dataIndex: 'nodeCode', - width: 180, - copyable: true, - ellipsis: true, - }, - { - title: '节点名称', - dataIndex: 'nodeName', - width: 150, - }, - { - title: '节点类型', - dataIndex: 'nodeCode', - width: 120, - render: (_, record) => ( - - {record.nodeCode} - + accessorKey: 'nodeCode', + header: '节点编码', + size: 180, + cell: ({ row }) => ( +
{row.original.nodeCode}
), }, { - title: '面板变量', - dataIndex: 'panelVariablesSchema', - width: 100, - render: (val) => (val ? 已配置 : 未配置), + accessorKey: 'nodeName', + header: '节点名称', + size: 150, }, { - title: '本地变量', - dataIndex: 'localVariablesSchema', - width: 100, - render: (val) => (val ? 已配置 : 未配置), + accessorKey: 'nodeType', + header: '节点类型', + size: 120, + cell: ({ row }) => { + const style = nodeTypeStyles[row.original.nodeType as NodeTypeEnum] || { + variant: 'secondary' as const, + label: row.original.nodeType || '未知类型' + }; + return ( + + {style.label} + + ); + }, }, { - title: '表单变量', - dataIndex: 'formVariablesSchema', - width: 100, - render: (val) => (val ? 已配置 : 未配置), + accessorKey: 'panelVariablesSchema', + header: '面板变量', + size: 100, + cell: ({ row }) => ( + + {row.original.panelVariablesSchema ? '已配置' : '未配置'} + + ), }, { - title: '操作', - width: 180, - valueType: 'option', - fixed: 'right', - render: (_, record) => ( - + accessorKey: 'localVariablesSchema', + header: '本地变量', + size: 100, + cell: ({ row }) => ( + + {row.original.localVariablesSchema ? '已配置' : '未配置'} + + ), + }, + { + accessorKey: 'formVariablesSchema', + header: '表单变量', + size: 100, + cell: ({ row }) => ( + + {row.original.formVariablesSchema ? '已配置' : '未配置'} + + ), + }, + { + id: 'actions', + header: '操作', + size: 180, + cell: ({ row }) => ( +
- + + + + + + + 确定要删除该节点吗? + + 此操作将永久删除该节点,且不可恢复。 + + + + 取消 + handleDelete(row.original.id)} + className="bg-destructive text-destructive-foreground hover:bg-destructive/90" + > + 删除 + + + + +
), }, ]; return ( - <> - - columns={columns} - request={async (params) => { - const { current, pageSize, ...rest } = params; - const response = await service.getNodeDefinitions({ - current, - pageSize, - ...rest, - }); - return { - data: response.content, - success: true, - total: response.totalElements - }; - }} - rowKey="nodeCode" - search={false} - toolBarRender={() => [ - , - ]} - /> + +
+

节点管理

+ +
- setDetailVisible(false)} - width={800} - footer={null} - > - {/* TODO: 实现详情展示组件 */} -
节点详情内容
-
- + + + 节点列表 + + +
+ + + + {columns.map((column) => ( + + {column.header} + + ))} + + + + {list.map((item) => ( + + {columns.map((column) => ( + + {column.cell + ? column.cell({ row: { original: item } }) + : item[column.accessorKey!]} + + ))} + + ))} + +
+
+ +
+
+
+
+ + {/* 节点详情弹窗 */} + + + + 节点详情 + +
+
+
+
节点编码
+
{currentNode?.nodeCode}
+
+
+
节点名称
+
{currentNode?.nodeName}
+
+
+
节点类型
+
+ {currentNode?.nodeType && ( + + {(nodeTypeStyles[currentNode.nodeType as NodeTypeEnum] || {}).label || currentNode.nodeType} + + )} +
+
+
+
节点分类
+
{currentNode?.category}
+
+
+
+
描述
+
{currentNode?.description || '-'}
+
+
+
变量配置
+
+
+ 面板变量: + + {currentNode?.panelVariablesSchema ? '已配置' : '未配置'} + +
+
+ 本地变量: + + {currentNode?.localVariablesSchema ? '已配置' : '未配置'} + +
+
+ 表单变量: + + {currentNode?.formVariablesSchema ? '已配置' : '未配置'} + +
+
+
+
+
+
+ + setDetailVisible(false)}>关闭 + +
+
+
); }; diff --git a/frontend/src/pages/Workflow/NodeDesign/service.ts b/frontend/src/pages/Workflow/NodeDesign/service.ts index f4cc7b64..c99d78ec 100644 --- a/frontend/src/pages/Workflow/NodeDesign/service.ts +++ b/frontend/src/pages/Workflow/NodeDesign/service.ts @@ -24,3 +24,10 @@ export const saveNodeDefinition = (data: NodeDesignDataResponse) => export const updateNodeDefinition = (id: number, data: NodeDesignDataResponse) => request.put(`${BASE_URL}/${id}`, data); + +/** + * 删除节点定义 + * @param id 节点ID + */ +export const deleteNodeDefinition = (id: number) => + request.delete(`${BASE_URL}/${id}`);