Files
users/components/data-integration/data-mapping-config.tsx

211 lines
7.0 KiB
TypeScript
Raw Normal View History

"use client"
import { useState } from "react"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
import { ArrowRight, Plus, Save, Trash2 } from "lucide-react"
interface FieldMapping {
id: string
sourceField: string
targetField: string
dataType: string
required: boolean
transformation: string
}
export function DataMappingConfig() {
// 模拟数据
const [mappings, setMappings] = useState<FieldMapping[]>([
{
id: "1",
sourceField: "phone",
targetField: "phoneNumber",
dataType: "string",
required: true,
transformation: "formatPhoneNumber",
},
{
id: "2",
sourceField: "id_card",
targetField: "identityNumber",
dataType: "string",
required: true,
transformation: "mask",
},
{
id: "3",
sourceField: "imei",
targetField: "deviceImei",
dataType: "string",
required: false,
transformation: "none",
},
{
id: "4",
sourceField: "address",
targetField: "userAddress",
dataType: "string",
required: false,
transformation: "none",
},
{
id: "5",
sourceField: "name",
targetField: "fullName",
dataType: "string",
required: true,
transformation: "none",
},
{
id: "6",
sourceField: "register_time",
targetField: "registrationDate",
dataType: "datetime",
required: true,
transformation: "parseDateTime",
},
{
id: "7",
sourceField: "last_login",
targetField: "lastActiveTime",
dataType: "datetime",
required: false,
transformation: "parseDateTime",
},
])
const addNewMapping = () => {
const newMapping: FieldMapping = {
id: `new-${Date.now()}`,
sourceField: "",
targetField: "",
dataType: "string",
required: false,
transformation: "none",
}
setMappings([...mappings, newMapping])
}
const updateMapping = (id: string, field: keyof FieldMapping, value: any) => {
setMappings(mappings.map((mapping) => (mapping.id === id ? { ...mapping, [field]: value } : mapping)))
}
const deleteMapping = (id: string) => {
setMappings(mappings.filter((mapping) => mapping.id !== id))
}
return (
<div className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-medium"></h3>
<Button onClick={addNewMapping}>
<Plus className="mr-2 h-4 w-4" />
</Button>
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead className="text-right"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{mappings.map((mapping) => (
<TableRow key={mapping.id}>
<TableCell>
<Input
value={mapping.sourceField}
onChange={(e) => updateMapping(mapping.id, "sourceField", e.target.value)}
placeholder="源字段名"
/>
</TableCell>
<TableCell>
<ArrowRight className="h-4 w-4 text-muted-foreground" />
</TableCell>
<TableCell>
<Input
value={mapping.targetField}
onChange={(e) => updateMapping(mapping.id, "targetField", e.target.value)}
placeholder="目标字段名"
/>
</TableCell>
<TableCell>
<Select
value={mapping.dataType}
onValueChange={(value) => updateMapping(mapping.id, "dataType", value)}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="选择数据类型" />
</SelectTrigger>
<SelectContent>
<SelectItem value="string"></SelectItem>
<SelectItem value="number"></SelectItem>
<SelectItem value="boolean"></SelectItem>
<SelectItem value="datetime"></SelectItem>
<SelectItem value="array"></SelectItem>
<SelectItem value="object"></SelectItem>
</SelectContent>
</Select>
</TableCell>
<TableCell>
<div className="flex items-center justify-center">
<Switch
checked={mapping.required}
onCheckedChange={(checked) => updateMapping(mapping.id, "required", checked)}
/>
</div>
</TableCell>
<TableCell>
<Select
value={mapping.transformation}
onValueChange={(value) => updateMapping(mapping.id, "transformation", value)}
>
<SelectTrigger className="w-full">
<SelectValue placeholder="选择转换方式" />
</SelectTrigger>
<SelectContent>
<SelectItem value="none"></SelectItem>
<SelectItem value="formatPhoneNumber"></SelectItem>
<SelectItem value="mask"></SelectItem>
<SelectItem value="parseDateTime"></SelectItem>
<SelectItem value="uppercase"></SelectItem>
<SelectItem value="lowercase"></SelectItem>
<SelectItem value="trim"></SelectItem>
<SelectItem value="custom"></SelectItem>
</SelectContent>
</Select>
</TableCell>
<TableCell className="text-right">
<Button variant="ghost" size="icon" onClick={() => deleteMapping(mapping.id)}>
<Trash2 className="h-4 w-4 text-red-500" />
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
<div className="flex justify-end space-x-2">
<Button variant="outline"></Button>
<Button>
<Save className="mr-2 h-4 w-4" />
</Button>
</div>
</div>
)
}