'use client';
import * as React from 'react';
import { IconStarFilled, IconBuilding, IconPlus, IconDownload, IconSearch, IconChevronLeft, IconChevronRight, IconChevronsLeft, IconChevronsRight } from '@tabler/icons-react';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@nice/ui/components/table';
import { Button } from '@nice/ui/components/button';
import { Badge } from '@nice/ui/components/badge';
import { Input } from '@nice/ui/components/input';
import { Label } from '@nice/ui/components/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@nice/ui/components/select';
import { MultipleProfessionSelector, MultipleStationSelector, MultipleDutyLevelSelector } from '@/components/selector';
import { DutyLevel } from '@fenghuo/common';
import { useTranslation } from '@nice/i18n';
import { EliteFormData } from '@fenghuo/common';
const DUTY_LEVEL_OPTIONS = [
{ value: 3, label: DutyLevel.HIGH },
{ value: 2, label: DutyLevel.MIDDLE },
{ value: 1, label: DutyLevel.PRIMARY },
];
// 职务等级星星显示组件
function DutyLevelStars({ level }: { level: number }) {
const stars = Array.from({ length: level }, (_, index) => (
));
if (level === 0) {
return null;
}
return
{stars}
;
}
function DutyLevelText({ level }: { level: number }) {
const option = DUTY_LEVEL_OPTIONS.find(option => option.value === level);
return {option?.label}
;
}
// 人员信息显示组件
function PersonInfo({
person,
onViewDetail
}: {
person: {
id: string;
name: string;
dutyName: string;
dutyCode: string;
dutyLevel: number;
};
onViewDetail: (id: string) => void;
}) {
const hasStars = person.dutyLevel > 0;
return (
onViewDetail(person.id)}
className="flex flex-row justify-center break-words min-h-[35px] items-center p-1 bg-muted rounded-lg"
>
{person.name}
(#{person.dutyCode})
{hasStars && }
);
}
// 人员列表显示组件
function PersonList({
persons,
onViewDetail
}: {
persons: Array<{
id: string;
name: string;
dutyName: string;
dutyCode: string;
dutyLevel: number;
}>;
onViewDetail: (id: string) => void;
}) {
if (!persons || persons.length === 0) {
return null
}
return (
{persons.sort((a, b) => b.dutyLevel - a.dutyLevel).map((person) => (
))}
);
}
interface EliteDataTableProps {
data: EliteFormData[];
isLoading?: boolean;
onViewDetail?: (personId: string) => void;
onProfessionClick?: (professionName: string, professionId: string) => void; // 修改为传递专业ID
onStationClick?: (stationName: string, stationId: string, professionId: string) => void; // 新增台站点击处理
onAddEmployee?: () => void;
onExportTable?: () => void;
onExportFilteredTable?: () => void;
isExporting?: boolean;
// 筛选相关props
selectedProfessionIds?: string[];
onProfessionIdsChange?: (ids: string[]) => void;
selectedStationIds?: string[];
onStationIdsChange?: (ids: string[]) => void;
selectedDutyLevels?: number[];
onDutyLevelsChange?: (levels: number[]) => void;
// 搜索相关props
searchKeyword?: string;
onSearchKeywordChange?: (keyword: string) => void;
// 新增分页相关props
currentPage?: number;
totalPages?: number;
totalCount?: number;
pageSize?: number;
hasNextPage?: boolean;
hasPreviousPage?: boolean;
onPageChange?: (page: number) => void;
onPageSizeChange?: (pageSize: number) => void;
}
export function EliteDataTable({
data,
isLoading = false,
onViewDetail = () => { },
onProfessionClick = () => { },
onStationClick = () => { }, // 新增台站点击处理
onAddEmployee = () => { },
onExportTable = () => { },
onExportFilteredTable = () => { },
isExporting = false,
selectedProfessionIds = [],
onProfessionIdsChange = () => { },
selectedStationIds = [],
onStationIdsChange = () => { },
selectedDutyLevels = [],
onDutyLevelsChange = () => { },
searchKeyword = '',
onSearchKeywordChange = () => { },
// 新增分页相关props
currentPage = 1,
totalPages = 1,
totalCount = 0,
pageSize = 10,
hasNextPage = false,
hasPreviousPage = false,
onPageChange = () => { },
onPageSizeChange = () => { },
}: EliteDataTableProps) {
const { t } = useTranslation();
// 防抖处理搜索输入
const [localSearchKeyword, setLocalSearchKeyword] = React.useState(searchKeyword);
React.useEffect(() => {
setLocalSearchKeyword(searchKeyword);
}, [searchKeyword]);
React.useEffect(() => {
const timer = setTimeout(() => {
onSearchKeywordChange(localSearchKeyword);
}, 300); // 300ms 防抖
return () => clearTimeout(timer);
}, [localSearchKeyword, onSearchKeywordChange]);
// 按专业分组数据(用于显示)
const groupedData = React.useMemo(() => {
const groups: Record = {};
data.forEach((item) => {
const profession = item.profession || '';
if (!groups[profession]) {
groups[profession] = [];
}
groups[profession].push(item);
});
return groups;
}, [data]);
return (
{/* 筛选器和操作按钮栏 */}
{/* 标题和操作按钮 */}
{t('profile.elite_table.title')}
{isLoading ? t('common.loading') : t('common.count_items', { count: totalCount || 0 })}
{/* 筛选状态显示 */}
{(selectedProfessionIds.length > 0 || selectedStationIds.length > 0 || selectedDutyLevels.length > 0 || searchKeyword.trim()) && (
{t('common.filtered')}
)}
{/* 筛选器区域 */}
{t('common.filter_conditions')}
{/* 搜索框 */}
{/* 表格 */}
{t('profile.elite_table.column.profession')}
{t('profile.elite_table.column.stations')}
{t('profile.elite_table.column.technician')}
{t('profile.elite_table.column.leader')}
{t('profile.elite_table.column.operator')}
{isLoading ? (
{t('common.loading')}
) : Object.keys(groupedData).length > 0 ? (
Object.entries(groupedData).map(([profession, items]) => (
{items.map((item, index) => (
{index === 0 ? (
onProfessionClick(profession, item.professionId)}
>
{profession}
) : null}
onStationClick(item.profession, item.stationId, item.professionId)}
>
{item.station && (
<>
{item.parentOrganization ? `${item.parentOrganization}/${item.station}` : item.station}
>
)}
))}
))
) : (
{searchKeyword.trim() || selectedDutyLevels.length > 0 ? t('common.no_records_found') : t('common.no_data')}
)}
{/* 分页控制 */}
{t('pagination.page_display', { current: currentPage, total: totalPages, count: totalCount })}
{t('pagination.items_per_page')}
{t('pagination.page_info_simple', { current: currentPage, total: totalPages })}
);
}