import React, { useEffect, useState } from 'react'; import { Button, Space, Tag, Typography } from 'antd'; import { NodeExpandOutlined } from '@ant-design/icons'; import XinTable from '@/components/XinTable'; import type { XinTableColumn, XinTableProps } from '@/components/XinTable/typings.ts'; import type IProductCategory from '@/domain/iProductCategory.ts'; import { CATEGORY_STATUS_MAP } from '@/domain/iProductCategory.ts'; import { getCategoryTable } from '@/api/product/category.ts'; const { Title, Text } = Typography; /** * 递归收集全部节点 id(用于展开整棵树) */ function collectAllIds(nodes: IProductCategory[]): number[] { const ids: number[] = []; const walk = (list: IProductCategory[]) => { list.forEach((node) => { if (node.id !== undefined) { ids.push(node.id); } if (node.children?.length) { walk(node.children); } }); }; walk(nodes); return ids; } /** * 商品分类管理(多级分类树表) */ const ProductCategoryPage: React.FC = () => { const [expandedKeys, setExpandedKeys] = useState([]); const [allIds, setAllIds] = useState([]); const [categoryTree, setCategoryTree] = useState([]); const loadTree = async () => { const res = await getCategoryTable(); const tree = res.data.data ?? []; setCategoryTree(tree); setAllIds(collectAllIds(tree)); }; useEffect(() => { loadTree(); }, []); const columns: XinTableColumn[] = [ { title: '分类名称', dataIndex: 'name', valueType: 'text', required: true, rules: [{ required: true, message: '请输入分类名称' }], }, { title: '上级分类', dataIndex: 'parent_id', valueType: 'treeSelect', hideInTable: true, hideInSearch: true, initialValue: 0, fieldProps: { treeData: [{ id: 0, name: '顶级分类', children: categoryTree }], fieldNames: { label: 'name', value: 'id', children: 'children' }, placeholder: '默认顶级分类', treeDefaultExpandAll: true, }, }, { title: '排序', dataIndex: 'sort', valueType: 'digit', hideInSearch: true, fieldProps: { min: 0 }, align: 'center', }, { title: '状态', dataIndex: 'status', valueType: 'radioButton', initialValue: 1, hideInSearch: true, fieldProps: { options: [ { value: 1, label: '正常' }, { value: 0, label: '停用' }, ], }, render: (_, record) => { const item = CATEGORY_STATUS_MAP[record.status ?? 1]; return {item?.text}; }, align: 'center', }, ]; const tableProps: XinTableProps = { api: '/product/category', columns, rowKey: 'id', accessName: 'product.category', // 后端直接返回分类树,不走分页接口 handleRequest: async () => { const res = await getCategoryTable(); const tree = res.data.data ?? []; setCategoryTree(tree); setAllIds(collectAllIds(tree)); return { data: tree, total: tree.length }; }, pagination: { pageSize: 200 }, expandable: { expandedRowKeys: expandedKeys, onExpandedRowsChange: (keys) => setExpandedKeys([...keys] as number[]), }, formProps: { grid: true, colProps: { span: 12 }, layout: 'vertical', }, modalProps: { width: 640 }, }; return ( <>
商品分类 多级分类(如蔬菜/水果/其他),采购单导出与对账筛选按分类归组;有子分类或挂载商品时不可删除。
{...tableProps} /> ); }; export default ProductCategoryPage;