feat: UI优化和功能完善
- 添加公共分页组件,支持上边显示、分页大小10 - 侧边栏/Header按Liner风格优化,添加动画效果 - 异常处理列表支持分页和明细弹窗 - 任务结果页面支持已匹配列表分页 - 修复Dialog弹窗背景透明问题 - 新增dropdown-menu组件 - 添加parsed_file_record模型和回填脚本 - 前端枚举中文化
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
"use client";
|
||||
|
||||
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
export interface PaginationProps {
|
||||
/** 当前页码(从 1 开始) */
|
||||
page: number;
|
||||
/** 每页条数 */
|
||||
pageSize: number;
|
||||
/** 总条数 */
|
||||
total: number;
|
||||
/** 页码或每页条数变化时的回调 */
|
||||
onChange: (page: number, pageSize: number) => void;
|
||||
/** 可选的每页条数选项,默认 [10, 20, 50] */
|
||||
pageSizeOptions?: number[];
|
||||
/** 是否显示每页条数选择器,默认 true */
|
||||
showPageSizeSelector?: boolean;
|
||||
}
|
||||
|
||||
export function Pagination({
|
||||
page,
|
||||
pageSize,
|
||||
total,
|
||||
onChange,
|
||||
pageSizeOptions = [10, 20, 50],
|
||||
showPageSizeSelector = true,
|
||||
}: PaginationProps) {
|
||||
const totalPages = Math.ceil(total / pageSize);
|
||||
const start = total > 0 ? (page - 1) * pageSize + 1 : 0;
|
||||
const end = Math.min(page * pageSize, total);
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-between px-4 py-3 border-t">
|
||||
<div className="flex items-center gap-4">
|
||||
{showPageSizeSelector && (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm text-muted-foreground">每页</span>
|
||||
<Select
|
||||
value={String(pageSize)}
|
||||
onValueChange={(val) => onChange(1, Number(val))}
|
||||
>
|
||||
<SelectTrigger className="h-8 w-[70px]">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent side="top">
|
||||
{pageSizeOptions.map((size) => (
|
||||
<SelectItem key={size} value={String(size)}>
|
||||
{size}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<span className="text-sm text-muted-foreground">条</span>
|
||||
</div>
|
||||
)}
|
||||
{total > 0 && (
|
||||
<span className="text-sm text-muted-foreground">
|
||||
显示 {start}-{end},共 {total} 条
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="h-8 w-8"
|
||||
onClick={() => onChange(1, pageSize)}
|
||||
disabled={page <= 1}
|
||||
>
|
||||
<ChevronsLeft className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="h-8 w-8"
|
||||
onClick={() => onChange(page - 1, pageSize)}
|
||||
disabled={page <= 1}
|
||||
>
|
||||
<ChevronLeft className="h-4 w-4" />
|
||||
</Button>
|
||||
|
||||
<div className="flex items-center gap-1 mx-1">
|
||||
{Array.from({ length: Math.min(totalPages, 5) }, (_, i) => {
|
||||
let pageNum: number;
|
||||
if (totalPages <= 5) {
|
||||
pageNum = i + 1;
|
||||
} else if (page <= 3) {
|
||||
pageNum = i + 1;
|
||||
} else if (page >= totalPages - 2) {
|
||||
pageNum = totalPages - 4 + i;
|
||||
} else {
|
||||
pageNum = page - 2 + i;
|
||||
}
|
||||
return (
|
||||
<Button
|
||||
key={pageNum}
|
||||
variant={pageNum === page ? "default" : "outline"}
|
||||
size="sm"
|
||||
className="h-8 w-9"
|
||||
onClick={() => onChange(pageNum, pageSize)}
|
||||
>
|
||||
{pageNum}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="h-8 w-8"
|
||||
onClick={() => onChange(page + 1, pageSize)}
|
||||
disabled={page >= totalPages}
|
||||
>
|
||||
<ChevronRight className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="icon"
|
||||
className="h-8 w-8"
|
||||
onClick={() => onChange(totalPages, pageSize)}
|
||||
disabled={page >= totalPages}
|
||||
>
|
||||
<ChevronsRight className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user