Files
users/components/data-integration/data-field-mapping.tsx
v0 2408d50cb0 refactor: overhaul UI for streamlined user experience
Redesign navigation, home overview, user portrait, and valuation pages
with improved functionality and responsive design.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2025-07-18 13:47:12 +00:00

322 lines
12 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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 { Badge } from "@/components/ui/badge"
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"
import { ArrowRight, Plus, Save, Trash2, HelpCircle } from "lucide-react"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
interface FieldMapping {
id: string
sourceField: string
targetField: string
dataType: string
required: boolean
transformation: string
primaryKey: boolean
}
export function DataFieldMapping() {
// 模拟数据
const [mappings, setMappings] = useState<FieldMapping[]>([
{
id: "1",
sourceField: "user_id",
targetField: "userId",
dataType: "string",
required: true,
transformation: "none",
primaryKey: true,
},
{
id: "2",
sourceField: "phone",
targetField: "phoneNumber",
dataType: "string",
required: true,
transformation: "formatPhoneNumber",
primaryKey: false,
},
{
id: "3",
sourceField: "id_card",
targetField: "identityNumber",
dataType: "string",
required: true,
transformation: "mask",
primaryKey: false,
},
{
id: "4",
sourceField: "imei",
targetField: "deviceImei",
dataType: "string",
required: false,
transformation: "none",
primaryKey: false,
},
{
id: "5",
sourceField: "name",
targetField: "fullName",
dataType: "string",
required: true,
transformation: "none",
primaryKey: false,
},
{
id: "6",
sourceField: "register_time",
targetField: "registrationDate",
dataType: "datetime",
required: true,
transformation: "parseDateTime",
primaryKey: false,
},
{
id: "7",
sourceField: "last_login",
targetField: "lastActiveTime",
dataType: "datetime",
required: false,
transformation: "parseDateTime",
primaryKey: false,
},
])
const addNewMapping = () => {
const newMapping: FieldMapping = {
id: `new-${Date.now()}`,
sourceField: "",
targetField: "",
dataType: "string",
required: false,
transformation: "none",
primaryKey: false,
}
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">
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription>
IDIMEI设备号为标准整合客户数据
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex justify-between items-center">
<div className="flex items-center gap-2">
<Badge className="bg-blue-100 text-blue-800"></Badge>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="ghost" size="icon">
<HelpCircle className="h-4 w-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p className="max-w-xs">
便
IDIMEI设备号
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<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></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>
<div className="flex items-center justify-center">
<Switch
checked={mapping.primaryKey}
onCheckedChange={(checked) => updateMapping(mapping.id, "primaryKey", 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>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle></CardTitle>
<CardDescription></CardDescription>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell className="font-medium">userId</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">phoneNumber</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">identityNumber</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">deviceImei</TableCell>
<TableCell></TableCell>
<TableCell>IMEI号码</TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">fullName</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">registrationDate</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
<TableRow>
<TableCell className="font-medium">lastActiveTime</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
</TableBody>
</Table>
</CardContent>
</Card>
</div>
)
}