import React, { useState } from 'react'; import {Button, Image, 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 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', }, { title: '分类图标', dataIndex: 'icon', valueType: 'image', fieldProps: { action: '/product/category/upload', mode: 'single', maxCount: 1, changeType: "id" }, render: (_, record: IProductCategory) => { const url = record.icon_url if (!url) return '-'; return ( ); }, align: 'center', hideInSearch: true, }, { title: '创建时间', dataIndex: 'updated_at', hideInForm: true, hideInSearch: true, align: 'center', }, { title: '创建时间', dataIndex: 'created_at', hideInForm: true, hideInSearch: true, 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[]), }, actionBarRender: (dom) => [ dom.add, , dom.keywordSearch, ], formProps: { grid: true, colProps: { span: 12 }, rowProps: { gutter: 20 }, layout: 'vertical', }, modalProps: { width: 640 }, }; return ( <>
商品分类 多级分类(如蔬菜/水果/其他),采购单导出与对账筛选按分类归组;有子分类或挂载商品时不可删除。
{...tableProps} /> ); }; export default ProductCategoryPage;