"use client"; import { useState } from "react"; import { motion, AnimatePresence } from "motion/react"; import { ChevronDown, ChevronRight, Eye, Check } from "lucide-react"; import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; import { ConfidenceBadge } from "./ConfidenceBadge"; import type { FieldMappingResponse } from "@/lib/api/types"; interface FieldMappingTableProps { mappings: FieldMappingResponse[]; fileName: string; fileType: string; onUpdate?: (mappingId: number, standardField: string) => void; onSkip?: (mappingId: number) => void; onConfirm?: (mappingId: number) => void; onConfirmAll?: (mappingIds: number[]) => void; readOnly?: boolean; } const STANDARD_FIELDS = [ { value: "员工姓名", label: "员工姓名" }, { value: "工号", label: "工号" }, { value: "部门", label: "部门" }, { value: "岗位", label: "岗位" }, { value: "基本工资", label: "基本工资" }, { value: "奖金", label: "奖金" }, { value: "补贴", label: "补贴" }, { value: "加班费", label: "加班费" }, { value: "扣款", label: "扣款" }, { value: "应发工资", label: "应发工资" }, { value: "实发工资", label: "实发工资" }, { value: "银行账号", label: "银行账号" }, { value: "身份证号", label: "身份证号" }, { value: "社保基数", label: "社保基数" }, { value: "养老保险", label: "养老保险" }, { value: "医疗保险", label: "医疗保险" }, { value: "失业保险", label: "失业保险" }, { value: "公积金", label: "公积金" }, { value: "个税", label: "个税" }, { value: "应税收入", label: "应税收入" }, { value: "税后收入", label: "税后收入" }, ]; export function FieldMappingTable({ mappings, fileName, fileType, onUpdate, onSkip, onConfirm, onConfirmAll, readOnly = false, }: FieldMappingTableProps) { const [expandedRows, setExpandedRows] = useState>(new Set()); const [editingId, setEditingId] = useState(null); const [editValue, setEditValue] = useState(""); const toggleExpand = (id: number) => { const newExpanded = new Set(expandedRows); if (newExpanded.has(id)) { newExpanded.delete(id); } else { newExpanded.add(id); } setExpandedRows(newExpanded); }; const startEdit = (id: number, currentValue: string) => { setEditingId(id); setEditValue(currentValue); }; const saveEdit = (id: number) => { if (onUpdate && editValue) { onUpdate(id, editValue); } setEditingId(null); setEditValue(""); }; const handleConfirmAll = () => { if (onConfirmAll) { const unconfirmedIds = mappings .filter((m) => !m.confirmed && !m.is_skipped && m.standard_field) .map((m) => m.id); onConfirmAll(unconfirmedIds); } }; const confirmedCount = mappings.filter((m) => m.confirmed).length; const unconfirmedCount = mappings.length - confirmedCount; return ( {/* 表头 */}
{fileName}
{fileType}
已确认: {confirmedCount} 待确认: {unconfirmedCount} {!readOnly && unconfirmedCount > 0 && ( )}
{/* 表格 */}
{mappings.map((mapping, index) => ( ))}
源字段 标准字段 置信度 状态 操作
{mapping.source_field} {editingId === mapping.id ? (
) : mapping.standard_field ? ( {mapping.standard_field} ) : ( 未识别 )}
{mapping.is_skipped ? ( 已跳过 ) : mapping.confirmed ? ( 已确认 ) : ( 待确认 )} {!readOnly && ( {editingId !== mapping.id && ( <> {!mapping.confirmed && ( )} )} )}
{mappings.length === 0 && (

暂无字段映射数据

)}
{/* 展开详情 */} {Array.from(expandedRows).map((id) => { const mapping = mappings.find((m) => m.id === id); if (!mapping || !mapping.sample_values) return null; return (
{mapping.reasoning && (
判断依据: {mapping.reasoning}
)}
样例值:
{(mapping.sample_values as unknown as string[]).slice(0, 5).map((value, idx) => ( {String(value)} ))}
); })}
); } export default FieldMappingTable;