生产管理系统 - 全领域数据感知中心开发

This commit is contained in:
2025-10-30 20:20:24 +08:00
parent 5d5a24ac89
commit 8b7e86b8bf
21 changed files with 11093 additions and 1329 deletions

View File

@@ -523,7 +523,7 @@ export function AIDataCenter({ activePath }: AIDataCenterProps) {
return (
<div className="space-y-6">
<div>
<h2></h2>
<h2></h2>
<p className="text-sm text-muted-foreground mt-1">
</p>
@@ -1246,118 +1246,269 @@ export function AIDataCenter({ activePath }: AIDataCenterProps) {
{/* 设备配置对话框 */}
<Dialog open={showDeviceDialog} onOpenChange={setShowDeviceDialog}>
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>{selectedDevice ? '编辑设备' : '添加设备'}</DialogTitle>
<DialogTitle className="flex items-center gap-2">
<Settings className="w-5 h-5" />
{selectedDevice ? '编辑设备配置' : '添加新设备'}
</DialogTitle>
<DialogDescription>
IoT设备的基本信息
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div>
<Label></Label>
<Input placeholder="自动生成或手动输入" defaultValue={selectedDevice?.code} />
<div className="space-y-6">
{/* 基本信息 */}
<div className="space-y-4">
<h4 className="text-lg font-medium flex items-center gap-2">
<Settings className="w-4 h-4" />
</h4>
<div className="grid grid-cols-3 gap-4">
<div>
<Label></Label>
<Input placeholder="如: WS-2024-001" defaultValue={selectedDevice?.code} />
</div>
<div>
<Label></Label>
<Input placeholder="如: 1号气象站" defaultValue={selectedDevice?.name} />
</div>
<div>
<Label></Label>
{deviceTypes.length > 0 ? (
<Select defaultValue={selectedDevice?.deviceTypeId}>
<SelectTrigger>
<SelectValue placeholder="选择设备类型" />
</SelectTrigger>
<SelectContent>
{deviceTypes.map(type => (
<SelectItem key={type.id} value={type.id}>
{type.name}
</SelectItem>
))}
</SelectContent>
</Select>
) : (
<Select>
<SelectTrigger>
<SelectValue placeholder="选择设备类型" />
</SelectTrigger>
<SelectContent>
<SelectItem value="weather_station"></SelectItem>
<SelectItem value="soil_sensor"></SelectItem>
<SelectItem value="camera"></SelectItem>
<SelectItem value="water_sensor"></SelectItem>
<SelectItem value="env_station"></SelectItem>
</SelectContent>
</Select>
)}
</div>
</div>
<div>
<Label></Label>
<Input placeholder="输入设备名称" defaultValue={selectedDevice?.name} />
<div className="grid grid-cols-2 gap-4">
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.manufacturer}>
<SelectTrigger>
<SelectValue placeholder="选择制造商" />
</SelectTrigger>
<SelectContent>
<SelectItem value="华为"></SelectItem>
<SelectItem value="中科院"></SelectItem>
<SelectItem value="海康威视"></SelectItem>
<SelectItem value="绿盟科技">绿</SelectItem>
<SelectItem value="其他"></SelectItem>
</SelectContent>
</Select>
</div>
<div>
<Label></Label>
<Input placeholder="如: HW-WS-Pro" defaultValue={selectedDevice?.model} />
</div>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.deviceTypeId}>
<SelectTrigger>
<SelectValue placeholder="选择设备类型" />
</SelectTrigger>
<SelectContent>
{deviceTypes.length > 0 ? (
deviceTypes.map(type => (
<SelectItem key={type.id} value={type.id}>
{type.name}
{/* 位置信息 */}
<div className="space-y-4">
<h4 className="text-lg font-medium flex items-center gap-2">
<MapPin className="w-4 h-4" />
</h4>
<div className="grid grid-cols-2 gap-4">
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.fieldId}>
<SelectTrigger>
<SelectValue placeholder="选择所属地块" />
</SelectTrigger>
<SelectContent>
{fieldsList.map(field => (
<SelectItem key={field.id} value={field.id}>
{field.name} ({field.cropType} · {field.area})
</SelectItem>
))
) : (
<SelectItem value="" disabled></SelectItem>
)}
</SelectContent>
</Select>
</div>
<div>
<Label></Label>
<Input placeholder="输入设备型号" defaultValue={selectedDevice?.model} />
))}
</SelectContent>
</Select>
<p className="text-xs text-muted-foreground mt-1">
</p>
</div>
<div>
<Label></Label>
<Input placeholder="如: 1号大棚北侧" defaultValue={selectedDevice?.location} />
</div>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<Label></Label>
<Input placeholder="输入厂家名称" defaultValue={selectedDevice?.manufacturer} />
{/* 通信配置 */}
<div className="space-y-4">
<h4 className="text-lg font-medium flex items-center gap-2">
<Wifi className="w-4 h-4" />
</h4>
<div className="grid grid-cols-2 gap-4">
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.protocol}>
<SelectTrigger>
<SelectValue placeholder="选择通信协议" />
</SelectTrigger>
<SelectContent>
<SelectItem value="MQTT">MQTT</SelectItem>
<SelectItem value="HTTP">HTTP</SelectItem>
<SelectItem value="CoAP">CoAP</SelectItem>
<SelectItem value="WebSocket">WebSocket</SelectItem>
</SelectContent>
</Select>
</div>
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.dataFrequency}>
<SelectTrigger>
<SelectValue placeholder="选择数据频率" />
</SelectTrigger>
<SelectContent>
<SelectItem value="实时"></SelectItem>
<SelectItem value="每1分钟">1</SelectItem>
<SelectItem value="每5分钟">5</SelectItem>
<SelectItem value="每10分钟">10</SelectItem>
<SelectItem value="每30分钟">30</SelectItem>
<SelectItem value="每小时"></SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.fieldId}>
<SelectTrigger>
<SelectValue placeholder="选择地块" />
</SelectTrigger>
<SelectContent>
{fieldsList.map(field => (
<SelectItem key={field.id} value={field.id}>
{field.name} ({field.cropType} · {field.area})
</SelectItem>
))}
</SelectContent>
</Select>
<p className="text-xs text-muted-foreground mt-1">
</p>
<div className="grid grid-cols-2 gap-4">
<div>
<Label>IP地址</Label>
<Input placeholder="如: 192.168.1.100" defaultValue={selectedDevice?.ipAddress} />
</div>
<div>
<Label>MQTT主题</Label>
<Input placeholder="如: farm/weather/station01" defaultValue={selectedDevice?.mqttTopic} />
</div>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.protocol}>
<SelectTrigger>
<SelectValue placeholder="选择协议" />
</SelectTrigger>
<SelectContent>
<SelectItem value="MQTT">MQTT</SelectItem>
<SelectItem value="HTTP">HTTP</SelectItem>
<SelectItem value="CoAP">CoAP</SelectItem>
<SelectItem value="WebSocket">WebSocket</SelectItem>
</SelectContent>
</Select>
{/* 传感器配置 */}
<div className="space-y-4">
<h4 className="text-lg font-medium flex items-center gap-2">
<Gauge className="w-4 h-4" />
</h4>
<div className="space-y-3">
<div className="grid grid-cols-4 gap-4 text-sm font-medium text-muted-foreground">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
{/* 默认传感器配置 */}
<div className="grid grid-cols-4 gap-4 items-center">
<Input placeholder="温度" defaultValue="温度" />
<Input placeholder="℃" defaultValue="℃" />
<Input placeholder="-10~40" defaultValue="-10~40" />
<Switch defaultChecked />
</div>
<div className="grid grid-cols-4 gap-4 items-center">
<Input placeholder="湿度" defaultValue="湿度" />
<Input placeholder="%" defaultValue="%" />
<Input placeholder="0~100" defaultValue="0~100" />
<Switch defaultChecked />
</div>
<div className="grid grid-cols-4 gap-4 items-center">
<Input placeholder="气压" defaultValue="气压" />
<Input placeholder="hPa" defaultValue="hPa" />
<Input placeholder="950~1050" defaultValue="950~1050" />
<Switch defaultChecked />
</div>
</div>
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.dataFrequency}>
<SelectTrigger>
<SelectValue placeholder="选择上报频率" />
</SelectTrigger>
<SelectContent>
<SelectItem value="实时"></SelectItem>
<SelectItem value="每分钟"></SelectItem>
<SelectItem value="每5分钟">5</SelectItem>
<SelectItem value="每10分钟">10</SelectItem>
<SelectItem value="每30分钟">30</SelectItem>
</SelectContent>
</Select>
<Button variant="outline" className="w-full">
<Plus className="w-4 h-4 mr-2" />
</Button>
</div>
{/* 绑定配置 */}
<div className="space-y-4">
<h4 className="text-lg font-medium flex items-center gap-2">
<Link className="w-4 h-4" />
</h4>
<div className="grid grid-cols-2 gap-4">
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.bindingStatus}>
<SelectTrigger>
<SelectValue placeholder="选择绑定状态" />
</SelectTrigger>
<SelectContent>
<SelectItem value="未绑定"></SelectItem>
<SelectItem value="已绑定"></SelectItem>
</SelectContent>
</Select>
</div>
<div>
<Label></Label>
<Select defaultValue={selectedDevice?.bindingSystem}>
<SelectTrigger>
<SelectValue placeholder="选择绑定系统" />
</SelectTrigger>
<SelectContent>
<SelectItem value="智能灌溉控制系统"></SelectItem>
<SelectItem value="视频监控系统"></SelectItem>
<SelectItem value="环境监测系统"></SelectItem>
<SelectItem value="生产管理系统"></SelectItem>
</SelectContent>
</Select>
</div>
</div>
</div>
<div>
<Label>MQTT主题/IP地址</Label>
<Input placeholder="输入MQTT主题或IP地址" defaultValue={selectedDevice?.mqttTopic || selectedDevice?.ipAddress} />
{/* 备注信息 */}
<div className="space-y-4">
<h4 className="text-lg font-medium flex items-center gap-2">
<FileText className="w-4 h-4" />
</h4>
<div>
<Label></Label>
<Textarea
placeholder="请输入设备的详细描述信息,包括功能特点、安装要求等"
className="resize-none"
rows={3}
defaultValue={selectedDevice ? `${selectedDevice.manufacturer} ${selectedDevice.model}${selectedDevice.sensors.length}个传感器` : ''}
/>
</div>
</div>
<div className="flex items-center justify-between p-4 bg-success/10 rounded-lg">
{/* 启用和测试 */}
<div className="flex items-center justify-between p-4 bg-green-50 dark:bg-green-950/30 rounded-lg border border-green-200 dark:border-green-800">
<div className="flex items-center gap-2">
<Switch defaultChecked />
<span className="text-sm"></span>
<span className="text-sm font-medium"></span>
</div>
<Button size="sm" variant="outline" onClick={handleTestConnection}>
<Link className="w-3 h-3 mr-1" />
@@ -1366,14 +1517,14 @@ export function AIDataCenter({ activePath }: AIDataCenterProps) {
</div>
</div>
<DialogFooter>
<div className="flex justify-end gap-3 pt-4 border-t">
<Button variant="outline" onClick={() => setShowDeviceDialog(false)}>
</Button>
<Button className="bg-success hover:bg-success/90" onClick={handleSaveDevice}>
<Button className="bg-green-600 hover:bg-green-700" onClick={handleSaveDevice}>
{selectedDevice ? '保存配置' : '添加设备'}
</Button>
</DialogFooter>
</div>
</DialogContent>
</Dialog>