248 lines
6.3 KiB
TypeScript
248 lines
6.3 KiB
TypeScript
'use client'
|
|
|
|
import { ColumnDef } from '@tanstack/react-table'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Edit, Trash2, MoreHorizontal } from 'lucide-react'
|
|
import { formatDate } from '@/lib/format'
|
|
import { Checkbox } from '@/components/ui/checkbox'
|
|
import { DataTableColumnHeader } from '@/components/data-table/column-header'
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
} from '@/components/ui/dropdown-menu'
|
|
import type { DeptAdmin } from '@/server/routers/dept-admin'
|
|
|
|
// 操作回调类型
|
|
export type DeptAdminActions = {
|
|
onEdit: (id: number) => void
|
|
onDelete: (id: number) => void
|
|
}
|
|
|
|
// 列定义选项类型
|
|
export type DeptAdminColumnsOptions = {
|
|
depts?: Array<{ code: string; name: string; fullName: string }>
|
|
}
|
|
|
|
// 创建院系管理员表格列定义
|
|
export const createDeptAdminColumns = (
|
|
actions: DeptAdminActions,
|
|
options: DeptAdminColumnsOptions = {}
|
|
): ColumnDef<DeptAdmin>[] => [
|
|
{
|
|
id: "select",
|
|
header: ({ table }) => (
|
|
<Checkbox
|
|
checked={
|
|
table.getIsAllPageRowsSelected() ||
|
|
(table.getIsSomePageRowsSelected() && "indeterminate")
|
|
}
|
|
onCheckedChange={(value) =>
|
|
table.toggleAllPageRowsSelected(!!value)
|
|
}
|
|
aria-label="Select all"
|
|
/>
|
|
),
|
|
cell: ({ row }) => (
|
|
<Checkbox
|
|
checked={row.getIsSelected()}
|
|
onCheckedChange={(value) => row.toggleSelected(!!value)}
|
|
aria-label="Select row"
|
|
/>
|
|
),
|
|
size: 32,
|
|
enableSorting: false,
|
|
enableHiding: false,
|
|
},
|
|
{
|
|
id: 'id',
|
|
accessorKey: 'id',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="ID" />
|
|
),
|
|
cell: ({ row }) => <div className="font-medium">{row.original.id}</div>,
|
|
meta: {
|
|
label: 'ID',
|
|
},
|
|
},
|
|
{
|
|
id: 'uid',
|
|
accessorKey: 'uid',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="用户ID" />
|
|
),
|
|
cell: ({ row }) => <div className="font-medium">{row.original.uid}</div>,
|
|
enableColumnFilter: true,
|
|
meta: {
|
|
label: '用户ID',
|
|
filter: {
|
|
placeholder: '请输入用户ID',
|
|
variant: 'text',
|
|
}
|
|
},
|
|
},
|
|
{
|
|
id: 'userName',
|
|
accessorKey: 'user.name',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="姓名" />
|
|
),
|
|
cell: ({ row }) => <div>{row.original.user?.name || '-'}</div>,
|
|
enableColumnFilter: true,
|
|
meta: {
|
|
label: '姓名',
|
|
filter: {
|
|
placeholder: '请输入姓名',
|
|
variant: 'text',
|
|
}
|
|
},
|
|
},
|
|
{
|
|
id: 'deptCode',
|
|
accessorKey: 'deptCode',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="院系" />
|
|
),
|
|
cell: ({ row }) => (
|
|
<div>
|
|
<div className="font-medium">{row.original.dept?.name || '-'}</div>
|
|
<div className="text-xs text-muted-foreground">{row.original.deptCode}</div>
|
|
</div>
|
|
),
|
|
enableColumnFilter: true,
|
|
meta: {
|
|
label: '院系',
|
|
filter: {
|
|
variant: 'multiSelect',
|
|
options: options.depts?.map(dept => ({
|
|
id: dept.code,
|
|
name: dept.fullName,
|
|
})) || [],
|
|
}
|
|
},
|
|
},
|
|
{
|
|
id: 'adminEmail',
|
|
accessorKey: 'adminEmail',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="邮箱" />
|
|
),
|
|
cell: ({ row }) => <div>{row.original.adminEmail || '-'}</div>,
|
|
enableColumnFilter: true,
|
|
meta: {
|
|
label: '邮箱',
|
|
filter: {
|
|
placeholder: '请输入邮箱',
|
|
variant: 'text',
|
|
}
|
|
},
|
|
},
|
|
{
|
|
id: 'adminLinePhone',
|
|
accessorKey: 'adminLinePhone',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="座机" />
|
|
),
|
|
cell: ({ row }) => <div>{row.original.adminLinePhone || '-'}</div>,
|
|
enableColumnFilter: true,
|
|
meta: {
|
|
label: '座机',
|
|
filter: {
|
|
placeholder: '请输入座机',
|
|
variant: 'text',
|
|
}
|
|
},
|
|
},
|
|
{
|
|
id: 'adminMobilePhone',
|
|
accessorKey: 'adminMobilePhone',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="手机" />
|
|
),
|
|
cell: ({ row }) => <div>{row.original.adminMobilePhone || '-'}</div>,
|
|
enableColumnFilter: true,
|
|
meta: {
|
|
label: '手机',
|
|
filter: {
|
|
placeholder: '请输入手机',
|
|
variant: 'text',
|
|
}
|
|
},
|
|
},
|
|
{
|
|
id: 'note',
|
|
accessorKey: 'note',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="备注" />
|
|
),
|
|
cell: ({ row }) => (
|
|
<div className="max-w-[200px] truncate" title={row.original.note || ''}>
|
|
{row.original.note || '-'}
|
|
</div>
|
|
),
|
|
enableSorting: false,
|
|
meta: {
|
|
label: '备注',
|
|
},
|
|
},
|
|
{
|
|
id: 'createdAt',
|
|
accessorKey: 'createdAt',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="创建时间" />
|
|
),
|
|
cell: ({ row }) => {
|
|
return <div>{formatDate(row.original.createdAt) || '-'}</div>
|
|
},
|
|
meta: {
|
|
label: '创建时间',
|
|
}
|
|
},
|
|
{
|
|
id: 'updatedAt',
|
|
accessorKey: 'updatedAt',
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="更新时间" />
|
|
),
|
|
cell: ({ row }) => {
|
|
return <div>{formatDate(row.original.updatedAt) || '-'}</div>
|
|
},
|
|
meta: {
|
|
label: '更新时间',
|
|
}
|
|
},
|
|
{
|
|
id: 'actions',
|
|
cell: ({ row }) => {
|
|
const deptAdmin = row.original
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="ghost" size="icon" className="h-6 w-6 md:w-9">
|
|
<MoreHorizontal className="h-4 w-4" />
|
|
<span className="sr-only">打开菜单</span>
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end">
|
|
<DropdownMenuItem onClick={() => actions.onEdit(deptAdmin.id)}>
|
|
<Edit className="h-4 w-4" />
|
|
编辑
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem
|
|
variant="destructive"
|
|
onClick={() => actions.onDelete(deptAdmin.id)}
|
|
>
|
|
<Trash2 className="h-4 w-4" />
|
|
删除
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)
|
|
},
|
|
size: 32,
|
|
enableSorting: false,
|
|
enableHiding: false,
|
|
},
|
|
]
|