import { DeleteOutlined, EditOutlined, PlusOutlined, SortAscendingOutlined } from '@ant-design/icons'; import { ModalForm, PageContainer, ProFormDigit, ProFormText, ProFormTreeSelect, ProTable, type ActionType, type ProColumns } from '@ant-design/pro-components'; import { useBoolean } from 'ahooks'; import { Button, Form, message } from 'antd'; import { useMemo, useRef, useState } from 'react'; import type { CategoryForm, CategoryQuery, CategoryVO } from '@/api/workflow/category/types'; import { addCategory, delCategory, getCategory, listCategory, updateCategory } from '@/api/workflow/category'; import RowActions from '@/components/common/RowActions'; import { useTreeTableExpand } from '@/hooks/useTreeTableExpand'; import { useTableScroll } from '@/hooks/useTableScroll'; import { useUserStore } from '@/stores/userStore'; import { hasPermi } from '@/utils/permission'; import { handleTree } from '@/utils/ruoyi'; const defaultCategoryForm: CategoryForm = { orderNum: 0 }; interface CategorySelectNode { title: string; value: string | number; children?: CategorySelectNode[]; } function toTreeSelectData(nodes: CategoryVO[]): CategorySelectNode[] { return nodes.map(node => ({ title: node.categoryName, value: node.categoryId, children: node.children ? toTreeSelectData(node.children) : undefined })); } export default function WorkflowCategoryPage() { const actionRef = useRef(undefined); const { tableScroll } = useTableScroll(900); const [form] = Form.useForm(); const userInfo = useUserStore(state => state.userInfo); const [categoryOptions, setCategoryOptions] = useState([]); const [tableRows, setTableRows] = useState([]); const { expandAll, expandedRowKeys, onExpandedRowsChange, syncExpandedRows, toggleExpandAll } = useTreeTableExpand(row => row.categoryId); const [modalOpen, { setTrue: openModal, setFalse: closeModal }] = useBoolean(false); const [modalTitle, setModalTitle] = useState(''); const canAdd = hasPermi(userInfo, ['workflow:category:add']); const canEdit = hasPermi(userInfo, ['workflow:category:edit']); const canRemove = hasPermi(userInfo, ['workflow:category:remove']); const treeSelectData = useMemo(() => toTreeSelectData(categoryOptions), [categoryOptions]); const loadCategoryOptions = async () => { const res = await listCategory(); setCategoryOptions(handleTree(res.data || [], 'categoryId', 'parentId')); }; const openAdd = async (row?: CategoryVO) => { await loadCategoryOptions(); form.resetFields(); form.setFieldsValue({ ...defaultCategoryForm, parentId: row?.categoryId }); setModalTitle('添加流程分类'); openModal(); }; const openEdit = async (row: CategoryVO) => { await loadCategoryOptions(); const res = await getCategory(row.categoryId); form.resetFields(); form.setFieldsValue(res.data); setModalTitle('修改流程分类'); openModal(); }; const submitForm = async (values: CategoryForm) => { values.categoryId ? await updateCategory(values) : await addCategory(values); message.success('操作成功'); form.resetFields(); actionRef.current?.reload(); return true; }; const remove = async (row: CategoryVO) => { await delCategory(row.categoryId); message.success('删除成功'); actionRef.current?.reload(); }; const columns: ProColumns[] = [ { title: '分类名称', dataIndex: 'categoryName', width: 260 }, { title: '显示顺序', dataIndex: 'orderNum', search: false, width: 120 }, { title: '创建时间', dataIndex: 'createTime', valueType: 'dateTime', search: false, width: 170 }, { title: '操作', valueType: 'option', width: 130, fixed: 'right', render: (_, row) => ( , onClick: () => openEdit(row) }, canAdd && { key: 'add', label: '新增', icon: , onClick: () => openAdd(row) }, canRemove && { key: 'delete', label: '删除', icon: , danger: true, confirm: `是否确认删除"${row.categoryName}"的分类?`, onClick: () => remove(row) } ]} /> ) } ]; return ( actionRef={actionRef} rowKey="categoryId" columns={columns} scroll={tableScroll} pagination={false} search={{ labelWidth: 90 }} expandable={{ expandedRowKeys, onExpandedRowsChange }} request={async params => { const res = await listCategory({ categoryName: params.categoryName }); const rows = handleTree(res.data || [], 'categoryId', 'parentId'); setTableRows(rows); syncExpandedRows(rows, expandAll); return { data: rows, total: rows.length, success: true }; }} toolbar={{ title: '流程分类列表' }} toolBarRender={() => [ canAdd && ( ), ]} /> title={modalTitle} open={modalOpen} width={520} form={form} layout="vertical" initialValues={defaultCategoryForm} modalProps={{ destroyOnHidden: true, onCancel: closeModal }} onOpenChange={open => !open && closeModal()} onFinish={submitForm} > ); }