首页添加二级路由

This commit is contained in:
Eamon
2026-08-03 10:53:12 +08:00
parent 0d5e28c785
commit 038e66d0cc
18 changed files with 1240 additions and 59 deletions

View File

@@ -5,6 +5,8 @@ import {
useReactTable,
} from "@tanstack/react-table"
import { Loader } from "lucide-react"
import { useMemo } from "react"
import { Checkbox } from "@/components/ui/checkbox"
import { Pagination, type PaginationProps } from "@/components/ui/pagination"
import {
TableBody,
@@ -25,29 +27,87 @@ export type DataTableProps<T> = {
headRow?: string
dataRow?: string
}
/** 是否开启行选择复选框 */
enableSelection?: boolean
/** 受控选中状态 */
rowSelection?: Record<string, boolean>
/** 选中状态变化回调 */
onSelectionChange?: (selection: Record<string, boolean>) => void
/** 行唯一ID生成函数 */
getRowId?: (row: T, index: number) => string
}
export default function DataTable<T extends Record<string, unknown>>(
props: DataTableProps<T>,
) {
// 动态注入复选框列
const finalColumns = useMemo<ColumnDef<T>[]>(() => {
if (!props.enableSelection) return props.columns
const selectColumn: ColumnDef<T> = {
id: "select",
size: 40,
enableSorting: false,
enableHiding: false,
header: ({ table }) => (
<Checkbox
checked={
table.getIsAllPageRowsSelected()
? true
: table.getIsSomePageRowsSelected()
? "indeterminate"
: false
}
onCheckedChange={value => table.toggleAllPageRowsSelected(!!value)}
aria-label="全选当前页"
className="rounded-none translate-y-0.5"
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={value => row.toggleSelected(!!value)}
aria-label="选择行"
className="rounded-none translate-y-0.5"
/>
),
}
return [selectColumn, ...props.columns]
}, [props.enableSelection, props.columns])
const table = useReactTable({
data: props.data,
columns: props.columns,
columns: finalColumns,
getCoreRowModel: getCoreRowModel(),
manualPagination: true,
rowCount: props.pagination?.total ?? props.data.length,
// 行选择核心配置
enableRowSelection: props.enableSelection ?? false,
getRowId: props.getRowId,
onRowSelectionChange: updaterOrValue => {
if (!props.onSelectionChange) return
const newSelection =
typeof updaterOrValue === "function"
? updaterOrValue(props.rowSelection ?? {})
: updaterOrValue
props.onSelectionChange(newSelection)
},
state: {
pagination: {
pageIndex: props.pagination?.page ?? 0,
pageSize: props.pagination?.size ?? props.data.length,
},
columnFilters: [],
...(props.rowSelection !== undefined && {
rowSelection: props.rowSelection,
}),
},
autoResetPageIndex: false,
})
console.log("data length:", props.data.length)
console.log("pageSize:", props.pagination?.size ?? props.data.length)
console.log("rows:", table.getRowModel().rows.length)
return (
<>
{/* 数据表 */}
@@ -55,7 +115,7 @@ export default function DataTable<T extends Record<string, unknown>>(
<TableRoot>
<TableHeader>
{table.getHeaderGroups().map(group => (
<TableRow key={group.id}>
<TableRow key={group.id} className={props.classNames?.headRow}>
{group.headers.map(header => (
<TableHead key={header.id} colSpan={header.colSpan}>
{header.isPlaceholder
@@ -73,7 +133,7 @@ export default function DataTable<T extends Record<string, unknown>>(
{props.status === "fail" ? (
<TableRow>
<TableCell
colSpan={props.columns.length}
colSpan={finalColumns.length}
className="text-center text-fail"
>
@@ -82,7 +142,7 @@ export default function DataTable<T extends Record<string, unknown>>(
) : !props.data?.length ? (
<TableRow>
<TableCell
colSpan={props.columns.length}
colSpan={finalColumns.length}
className="text-center"
>