Files
web-Iot/src/pages/AIAnalysis.tsx
2026-09-02 15:54:49 +08:00

600 lines
28 KiB
TypeScript

import React, { useState } from 'react';
import {
Row, Col, Card, Button, Tag, Table, Typography, Space, Statistic, message, Divider, Tooltip, Avatar, Empty
} from 'antd';
import {
ReloadOutlined, InfoCircleOutlined, ThunderboltOutlined,
LineChartOutlined, AppstoreOutlined, BellOutlined,
CheckCircleOutlined, CalendarOutlined, ArrowUpOutlined,
ArrowDownOutlined, RiseOutlined, FallOutlined, ScanOutlined,
DatabaseOutlined, CloudOutlined, RestOutlined, AimOutlined,
SelectOutlined, FireOutlined, WarningOutlined, ExclamationCircleOutlined
} from '@ant-design/icons';
import { Line, Area } from '@ant-design/charts';
import { useTranslation } from 'react-i18next';
import { UniversalLineChart } from "../components/recharts"
const { Title, Text } = Typography;
const degradationData = [
{
date: '2024-01',
average: 0,
best: 0,
worst: -1.0,
},
{
date: '2024-04',
average: -1.2,
best: -0.5,
worst: -2.5,
},
{
date: '2024-07',
average: -2.5,
best: -1.0,
worst: -4.0,
},
{
date: '2024-10',
average: -3.8,
best: -1.5,
worst: -6.5,
},
{
date: '2025-01',
average: -4.5,
best: -2.0,
worst: -8.0,
},
{
date: '2025-05',
average: -5.32,
best: -2.5,
worst: -10.2,
},
];
const generationPerformanceData = [
{
time: '00:00',
actual: 0,
predict: 0,
theory: 0,
},
{
time: '03:00',
actual: 0,
predict: 0,
theory: 0,
},
{
time: '06:00',
actual: 100,
predict: 150,
theory: 200,
},
{
time: '09:00',
actual: 800,
predict: 950,
theory: 1100,
},
{
time: '12:00',
actual: 1400,
predict: 1650,
theory: 1800,
},
{
time: '15:00',
actual: 1200,
predict: 1350,
theory: 1500,
},
{
time: '18:00',
actual: 400,
predict: 550,
theory: 650,
},
{
time: '21:00',
actual: 0,
predict: 0,
theory: 0,
},
{
time: '24:00',
actual: 0,
predict: 0,
theory: 0,
},
];
export default function AIDiagnosisPage() {
const { t } = useTranslation();
const cardStyle = {
borderRadius: 12,
border: '1px solid #f0f0f0',
boxShadow: '0 4px 12px rgba(0,0,0,0.05)',
overflow: 'hidden'
};
const aiRecommendations = [
{ key: '1', measure: t('aiAnalysis.handleHotspotComponents'), priority: t('workOrder.high'), expectedGain: '+2.15%', confidence: '92%' },
{ key: '2', measure: t('aiAnalysis.checkAbnormalStrings'), priority: t('workOrder.high'), expectedGain: '+1.85%', confidence: '90%' },
{ key: '3', measure: t('aiAnalysis.cleanShadedAreas'), priority: t('workOrder.medium'), expectedGain: '+0.45%', confidence: '78%' },
{ key: '4', measure: t('aiAnalysis.trackDegradedComponents'), priority: t('workOrder.medium'), expectedGain: '+0.35%', confidence: '86%' },
{ key: '5', measure: t('aiAnalysis.monitorInverterEfficiency'), priority: t('workOrder.low'), expectedGain: '+0.10%', confidence: '93%' },
];
const thermalImagingData = [
{ name: t('aiAnalysis.arrayLabel', { name: 'A-05' }), temp: '71.5℃', id: 'A05', status: 'serious' },
{ name: t('aiAnalysis.arrayLabel', { name: 'A-12' }), temp: '68.3℃', id: 'A12', status: 'warning' },
{ name: t('aiAnalysis.arrayLabel', { name: 'B-03' }), temp: '64.8℃', id: 'B03', status: 'warning' },
{ name: t('aiAnalysis.arrayLabel', { name: 'C-07' }), temp: '67.2℃', id: 'C07', status: 'warning' },
];
const renderStatusTag = (status: string) => {
let color = '';
if (status === t('home.abnormal')) color = '#ff4d4f';
else if (status === t('aiAnalysis.minor')) color = '#1677ff';
else if (status === t('roles.normal')) color = '#52c41a';
return <Tag color={color} style={{ margin: 0, fontWeight: 600 }}>{status}</Tag>;
};
// 影响程度标签渲染
const renderImpactTag = (impact: string) => {
let color = '';
if (impact === t('workOrder.high')) color = '#ff4d4f';
else if (impact === t('workOrder.medium')) color = '#fa8c16';
else if (impact === t('workOrder.low')) color = '#52c41a';
return <Tag color={color} style={{ margin: 0, fontWeight: 600 }}>{impact}</Tag>;
};
// 优先级标签渲染(建议措施用)
const renderPriorityTag = (priority: string) => {
let color = '';
if (priority === t('workOrder.high')) color = '#ff4d4f';
else if (priority === t('workOrder.medium')) color = '#fa8c16';
else if (priority === t('workOrder.low')) color = '#52c41a';
return <Tag color={color} style={{ margin: 0, fontWeight: 600 }}>{priority}</Tag>;
};
return (
<div style={{ background: '#f5f7fa', minHeight: '100vh', padding: '8px 0px', boxSizing: 'border-box', overflowX: 'hidden' }}>
<style>
{`
.compact-table .ant-table-thead > tr > th {
background: #f8fafc;
padding: 8px 12px !important;
font-size: 12px;
color: #4E5969;
}
.compact-table .ant-table-tbody > tr > td {
padding: 8px 12px !important;
font-size: 12px;
}
.thermal-card:hover {
transform: translateY(-2px);
transition: all 0.3s;
}
.grid-item:hover {
filter: brightness(0.9);
cursor: pointer;
}
`}
</style>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingBottom: "16px" }}>
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(18px, 1.5vw, 24px)', color: '#1D2129' }}>{t('aiAnalysis.fixed2Ai2')}</Typography.Title>
<Space>
<Button icon={<ReloadOutlined />}>{t('aiAnalysis.fixed2Refresh')}</Button>
<Button type="primary">{t('aiAnalysis.fixed2Export')}</Button>
</Space>
</div>
{/* 第一排:顶部统计卡片 */}
<Row gutter={[8, 8]} style={{ marginBottom: 8 }}>
{[
{ title: t('aiAnalysis.prValue'), value: '82.6%', trend: t('devices.vsYesterday', { value: '-1.3%' }), icon: <RiseOutlined />, color: '#00B42A', bg: '#E8FFEA', trendColor: '#F53F3F', direction: 'down' },
{ title: t('aiAnalysis.fixed2GenerationDeviation'), value: '-4.35%', trend: t('devices.vsYesterday', { value: '-1.02%' }), icon: <FallOutlined />, color: '#F53F3F', bg: '#FFF1F0', trendColor: '#F53F3F', direction: 'down' },
{ title: t('aiAnalysis.fixed2AbnormalStringFixed2QuantityFixed2'), value: '8', trend: t('devices.vsYesterday', { value: '+2 ↑' }), icon: <AppstoreOutlined />, color: '#1D2129', bg: '#F5F7FA', trendColor: '#F53F3F', direction: 'up' },
{ title: t('aiAnalysis.fixed2HotspotSuspectFixed2QuantityFixed2'), value: '36', trend: t('devices.vsYesterday', { value: '+5 ↑' }), icon: <BellOutlined />, color: '#F53F3F', bg: '#FFF1F0', trendColor: '#F53F3F', direction: 'up' },
{ title: t('aiAnalysis.s25'), value: '86.3', unit: t('aiAnalysis.scoreUnit'), trend: t('devices.vsYesterday', { value: '-1.7' }), icon: <CheckCircleOutlined />, color: '#00B42A', bg: '#E8FFEA', trendColor: '#F53F3F', direction: 'down' },
{ title: t('aiAnalysis.fixed2PredictedGeneration'), value: '4,821', unit: t('home.kWh'), trend: t('devices.vsYesterday', { value: '+2.6% ↑' }), icon: <ThunderboltOutlined />, color: '#165DFF', bg: '#E8F3FF', trendColor: '#00B42A', direction: 'up' },
].map((item, index) => (
<Col key={index} xs={24} sm={12} md={8} xl={4}>
<Card
variant="borderless"
styles={{ body: { padding: '20px 16px' } }}
style={{ ...cardStyle, height: '100%' }}
>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
<div style={{ flex: 1 }}>
<div style={{ fontSize: 'clamp(12px, 0.8vw, 13px)', color: '#86909C', marginBottom: 8, whiteSpace: 'nowrap' }}>{item.title}</div>
<div style={{ fontSize: 'clamp(20px, 1.4vw, 24px)', fontWeight: 800, color: item.color, display: 'flex', alignItems: 'baseline', gap: 4 }}>
{item.value}
{item.unit && <span style={{ fontSize: 13, fontWeight: 400, color: '#86909C' }}>{item.unit}</span>}
</div>
<div style={{ fontSize: 11, color: '#86909C', marginTop: 10, display: 'flex', alignItems: 'center', gap: 4 }}>
<span style={{ color: item.trendColor }}>{item.trend}</span>
{item.direction === 'up' ? <ArrowUpOutlined style={{ color: item.trendColor }} /> : <ArrowDownOutlined style={{ color: item.trendColor }} />}
</div>
</div>
<div style={{
width: 44, height: 44, background: item.bg, borderRadius: '12px',
display: 'flex', justifyContent: 'center', alignItems: 'center', flexShrink: 0,
boxShadow: `0 4px 10px ${item.bg}80`
}}>
{React.cloneElement(item.icon as React.ReactElement, { style: { fontSize: 22, color: item.color === '#1D2129' ? '#4E5969' : item.color } })}
</div>
</div>
</Card>
</Col>
))}
</Row>
{/* 第二排:热成像分析 和 组串异常定位 */}
<Row gutter={[12, 12]} style={{ marginBottom: 8 }}>
<Col xs={24} lg={10}>
<Card
title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>{t('aiAnalysis.fixed2UavInspection')}<InfoCircleOutlined style={{ marginLeft: 6, color: '#86909C', fontSize: 13 }} /></span>}
extra={<Text type="secondary" style={{ fontSize: 12 }}>{t('aiAnalysis.fixed2Inspection202505200930')}<CalendarOutlined style={{ marginLeft: 4 }} /></Text>}
variant="borderless"
styles={{ body: { padding: '16px 20px' } }}
style={{ ...cardStyle, height: '100%' }}
>
<Row gutter={[12, 12]}>
{thermalImagingData.map((item, idx) => (
<Col span={6} key={idx}>
<div className="thermal-card" style={{ background: '#000', borderRadius: 8, height: 'clamp(90px, 9vw, 120px)', position: 'relative', overflow: 'hidden', border: '1px solid #333', cursor: 'pointer' }}>
<div style={{ width: '100%', height: '100%', background: 'linear-gradient(135deg, #1a0000 0%, #7a0000 30%, #ff4d4f 60%, #ffec3d 100%)', opacity: 0.9 }} />
{/* 模拟热斑点 */}
<div style={{ position: 'absolute', top: '25%', left: '35%', width: 14, height: 14, border: '2px solid #fff', borderRadius: '50%', boxShadow: '0 0 12px #ff4d4f', animation: 'pulse 2s infinite' }} />
<div style={{ position: 'absolute', bottom: 6, right: 6, background: 'rgba(0,0,0,0.7)', color: '#fff', padding: '2px 6px', borderRadius: 4, fontSize: 10, fontWeight: 600, letterSpacing: 0.5 }}>
{item.temp}
</div>
<div style={{ position: 'absolute', top: 6, left: 6 }}>
<Tag color={item.status === 'serious' ? 'error' : 'warning'} style={{ margin: 0, fontSize: 9, padding: '0 4px', lineHeight: '14px' }}>
{item.status === 'serious' ? t('aiAnalysis.highDanger') : t('aiAnalysis.attention')}
</Tag>
</div>
</div>
<div style={{ textAlign: 'center', marginTop: 10, fontSize: 12, fontWeight: 500, color: '#4E5969' }}>{item.name}</div>
</Col>
))}
</Row>
<div style={{ background: '#f8fafc', padding: '12px 16px', borderRadius: 8, marginTop: 20, display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12 }}>
<div style={{ display: 'flex', gap: 16, fontSize: 12 }}>
<span style={{ display: 'flex', alignItems: 'center', color: '#1D2129' }}><AimOutlined style={{ color: '#F53F3F', marginRight: 6 }} />{t('aiAnalysis.fixed2HotspotSuspect')}</span>
<span style={{ display: 'flex', alignItems: 'center', color: '#1D2129' }}><div style={{ width: 14, height: 10, border: '1.5px dashed #F53F3F', borderRadius: 2, marginRight: 6 }}></div>{t('aiAnalysis.areaFixed2')}</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
<span style={{ fontSize: 12, color: '#86909C' }}>{t('aiAnalysis.fixed2Temperature2585')}</span>
<div style={{ width: 120, height: 8, background: 'linear-gradient(to right, #000080, #0000ff, #00ff00, #ffff00, #ff0000)', borderRadius: 4 }} />
</div>
</div>
</Card>
</Col>
<Col xs={24} lg={14}>
<Card
title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>{t('aiAnalysis.status')}<InfoCircleOutlined style={{ marginLeft: 6, color: '#86909C', fontSize: 13 }} /></span>}
extra={<Space split={<Divider type="vertical" />} style={{ fontSize: 12, color: '#86909C' }}>
<span>{t('aiAnalysis.s9')}<b style={{ color: '#1D2129' }}>160</b></span>
<span>{t('aiAnalysis.fixed2Abnormal')}<b style={{ color: '#F53F3F' }}>8</b></span>
</Space>}
variant="borderless"
styles={{ body: { padding: '16px 20px' } }}
style={{ ...cardStyle, height: '100%' }}
>
<Row gutter={[20, 20]}>
<Col xs={24} md={18}>
<div style={{ overflowX: 'auto', paddingBottom: 8 }} className="custom-scrollbar">
<div style={{ minWidth: 500 }}>
<div style={{ display: 'grid', gridTemplateColumns: '40px repeat(20, 1fr)', gap: '4px' }}>
<div></div>
{Array.from({ length: 20 }).map((_, i) => (
<div key={i} style={{ fontSize: 11, color: '#86909C', textAlign: 'center', fontWeight: 500 }}>{String(i + 1).padStart(2, '0')}</div>
))}
{['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'].map((row) => (
<React.Fragment key={row}>
<div style={{ fontSize: 11, color: '#86909C', display: 'flex', alignItems: 'center', fontWeight: 600 }}>{row}{t('aiAnalysis.rowUnit')}</div>
{Array.from({ length: 20 }).map((_, col) => {
let color = '#E8F3FF';
let icon = null;
let statusKey = 'normal';
if (row === 'B' && col === 3) { color = '#F53F3F'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; statusKey = 'seriousHotspot'; }
if (row === 'B' && col === 17) { color = '#F53F3F'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; statusKey = 'seriousBreak'; }
if (row === 'C' && col === 15) { color = '#FF7D00'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; statusKey = 'abnormalPowerDeviation'; }
if (row === 'E' && col === 4) { color = '#FF7D00'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; statusKey = 'abnormalShading'; }
if (row === 'F' && col === 11) { color = '#F7BA1E'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; statusKey = 'minor'; }
if (row === 'G' && col === 1) { color = '#F7BA1E'; icon = <div style={{ width: 6, height: 6, background: '#fff', borderRadius: '50%' }} />; statusKey = 'minor'; }
if (row === 'H' && col === 10) { color = '#86909C'; statusKey = 'offline'; }
const tooltip = t('aiAnalysis.stringCellTooltip', { row, col: col + 1, status: t(`aiAnalysis.stringStatus.${statusKey}`) });
return (
<Tooltip title={tooltip} key={`${row}-${col}`}>
<div className="grid-item" style={{ width: '100%', height: 18, background: color, borderRadius: 3, display: 'flex', justifyContent: 'center', alignItems: 'center', transition: 'all 0.2s' }}>
{icon}
</div>
</Tooltip>
);
})}
</React.Fragment>
))}
</div>
</div>
</div>
<div style={{ display: 'flex', gap: 16, marginTop: 20, fontSize: 11, flexWrap: 'wrap', background: '#f8fafc', padding: '8px 12px', borderRadius: 6 }}>
{[
{ color: '#E8F3FF', label: t('aiAnalysis.normalFixed2') },
{ color: '#F7BA1E', label: t('aiAnalysis.abnormalFixed22') },
{ color: '#FF7D00', label: t('aiAnalysis.abnormalFixed2') },
{ color: '#F53F3F', label: t('aiAnalysis.fixed2CriticalFixed2ErrorFixed2') },
{ color: '#86909C', label: t('aiAnalysis.fixed2DeviceFixed2OfflineFixed2') },
].map(item => (
<span key={item.label} style={{ display: 'flex', alignItems: 'center', color: '#4E5969' }}>
<span style={{ width: 10, height: 10, background: item.color, marginRight: 6, borderRadius: 2 }}></span>
{item.label}
</span>
))}
</div>
</Col>
<Col xs={24} md={6}>
<div style={{ background: '#f8fafc', padding: 16, borderRadius: 8, height: '100%' }}>
<div style={{ fontSize: 13, fontWeight: 700, color: '#1D2129', marginBottom: 16, display: 'flex', alignItems: 'center' }}>
<WarningOutlined style={{ marginRight: 8, color: '#F53F3F' }} />{t('aiAnalysis.fixed2AbnormalFixed2Type')}</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
{[
{ label: t('aiAnalysis.fixed2CriticalFixed2ErrorFixed2'), value: 2, color: '#F53F3F', percent: '25%' },
{ label: t('aiAnalysis.abnormalFixed2'), value: 4, color: '#FF7D00', percent: '50%' },
{ label: t('aiAnalysis.abnormalFixed22'), value: 2, color: '#F7BA1E', percent: '25%' },
{ label: t('aiAnalysis.fixed2Offline'), value: 0, color: '#86909C', percent: '0%' },
].map(item => (
<div key={item.label}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
<span style={{ fontSize: 12, color: '#4E5969' }}>{item.label}</span>
<span style={{ fontWeight: 700, color: item.color, fontSize: 13 }}>{item.value}</span>
</div>
<div style={{ width: '100%', height: 4, background: '#E5E6EB', borderRadius: 2 }}>
<div style={{ width: item.percent, height: '100%', background: item.color, borderRadius: 2 }}></div>
</div>
</div>
))}
</div>
<Divider style={{ margin: '16px 0' }} />
<Button block type="dashed" size="small" style={{ fontSize: 12 }}>{t('aiAnalysis.fixed2View')}</Button>
</div>
</Col>
</Row>
</Card>
</Col>
</Row>
{/* 第三排:三个主要分析区域 */}
<Row gutter={[12, 12]} style={{ marginBottom: 16 }}>
<Col xs={24} lg={7}>
<Card
title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>{t('aiAnalysis.s13')}<InfoCircleOutlined style={{ marginLeft: 6, color: '#86909C', fontSize: 13 }} /></span>}
variant="borderless"
styles={{ body: { padding: '16px 20px' } }}
style={{ ...cardStyle, height: '100%' }}
>
<div style={{ fontSize: 12, color: '#86909C', marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
<span>{t('aiAnalysis.degradationTrend')}</span>
<span style={{ color: '#F53F3F', fontWeight: 600 }}>{t('aiAnalysis.fixed2Current532')}</span>
</div>
<UniversalLineChart
data={degradationData}
xKey="date"
height={240}
smooth
dot
showGrid
showLegend
series={[
{
key: 'average',
name: t('aiAnalysis.averageDegradationRate'),
color: '#165DFF',
strokeWidth: 3,
},
{
key: 'best',
name: t('aiAnalysis.bestComponent'),
color: '#00B42A',
strokeWidth: 2,
},
{
key: 'worst',
name: t('aiAnalysis.worstComponent'),
color: '#F53F3F',
strokeWidth: 2,
},
]}
/> <div style={{ marginTop: 16, padding: '12px', background: '#FFF7E8', borderRadius: 8, border: '1px solid #FFE4BA' }}>
<div style={{ fontSize: 12, color: '#86909C', display: 'flex', alignItems: 'center' }}>
<ExclamationCircleOutlined style={{ color: '#FF7D00', marginRight: 6 }} />
<span style={{ color: '#1D2129', fontWeight: 600 }}>{t('aiAnalysis.s15')}</span>
<span style={{ marginLeft: 4 }}>{t('aiAnalysis.12')}</span>
</div>
</div>
</Card>
</Col>
<Col xs={24} lg={10}>
<Card
title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>{t('aiAnalysis.generation')}<InfoCircleOutlined style={{ marginLeft: 6, color: '#86909C', fontSize: 13 }} /></span>}
variant="borderless"
styles={{ body: { padding: '16px 20px' } }}
style={{ ...cardStyle, height: '100%' }}
>
<div style={{ display: 'flex', gap: 20 }}>
<div style={{ flex: 1 }}>
<div style={{ fontSize: 12, color: '#86909C', marginBottom: 16 }}>{t('aiAnalysis.generationComparison')}</div>
<UniversalLineChart
data={generationPerformanceData}
xKey="time"
height={240}
smooth
dot={false}
showGrid
showLegend
series={[
{
key: 'actual',
name: t('aiAnalysis.actualGeneration'),
color: '#165DFF',
strokeWidth: 3,
},
{
key: 'predict',
name: t('aiAnalysis.predictedGeneration'),
color: '#00B42A',
strokeWidth: 2,
},
{
key: 'theory',
name: t('aiAnalysis.theoreticalGeneration'),
color: '#86909C',
strokeWidth: 2,
},
]}
/> </div>
<div style={{ width: 120, display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 16, flexShrink: 0, paddingLeft: 16, borderLeft: '1px solid #f0f0f0' }}>
{[
{ label: t('aiAnalysis.actualFixed2GenerationFixed2'), value: '4,752', unit: t('home.kWh'), color: '#165DFF' },
{ label: t('aiAnalysis.predictedGenerationFixed2'), value: '4,960', unit: t('home.kWh'), color: '#00B42A' },
{ label: t('aiAnalysis.fixed2GenerationDeviation'), value: '-4.35%', unit: '', color: '#F53F3F' },
{ label: t('aiAnalysis.pr'), value: '82.6%', unit: '', color: '#1D2129' },
].map(item => (
<div key={item.label}>
<div style={{ color: '#86909C', marginBottom: 4, fontSize: 11 }}>{item.label}</div>
<div style={{ fontWeight: 800, color: item.color, fontSize: 15 }}>{item.value} <span style={{ fontSize: 10, fontWeight: 400, color: '#86909C' }}>{item.unit}</span></div>
</div>
))}
</div>
</div>
</Card>
</Col>
<Col xs={24} lg={7}>
<Card
variant="borderless"
styles={{ body: { padding: 0 } }}
style={{ ...cardStyle, height: '100%' }}
>
{/* AI诊断总结 */}
<div style={{ padding: '12px 14px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
<span style={{ fontSize: 14, fontWeight: 700, color: '#1D2129' }}>{t('aiAnalysis.fixed2Ai2')}</span>
<span style={{ fontSize: 12, color: '#86909C' }}>{t('aiAnalysis.fixed2UpdatedAt202505200945')}</span>
</div>
<Table
rowKey="key"
columns={[
{ title: t('aiAnalysis.s36'), dataIndex: 'diagnosis', width: 78 },
{ title: t('roles.status'), dataIndex: 'status', render: renderStatusTag, },
{ title: t('aiAnalysis.confidence'), dataIndex: 'confidence', },
{ title: t('aiAnalysis.s37'), dataIndex: 'impact', render: renderImpactTag, width: 52 },
{ title: t('common.detail'), dataIndex: 'detail', ellipsis: true },
]}
dataSource={[
{ key: '1', diagnosis: t('aiAnalysis.hotspotDetection'), status: t('home.abnormal'), confidence: '92%', impact: t('workOrder.high'), detail: t('aiAnalysis.hotspotDetail') },
{ key: '2', diagnosis: t('aiAnalysis.stringMismatch'), status: t('home.abnormal'), confidence: '90%', impact: t('workOrder.high'), detail: t('aiAnalysis.stringMismatchDetail', { count: 8 }) },
{ key: '3', diagnosis: t('aiAnalysis.shadingRisk'), status: t('aiAnalysis.minor'), confidence: '78%', impact: t('workOrder.medium'), detail: t('aiAnalysis.shadingDetail') },
{ key: '4', diagnosis: t('aiAnalysis.componentDegradation'), status: t('home.abnormal'), confidence: '86%', impact: t('workOrder.medium'), detail: t('aiAnalysis.degradationDetail', { value: '-5.32%' }) },
{ key: '5', diagnosis: t('aiAnalysis.inverterAbnormal'), status: t('roles.normal'), confidence: '93%', impact: t('workOrder.low'), detail: t('aiAnalysis.inverterNormalDetail') },
]}
pagination={false}
size="small"
style={{ fontSize: 12 }}
/>
</div>
<Divider style={{ margin: 0 }} />
<div style={{ padding: '12px 14px' }}>
<div style={{ fontSize: 14, fontWeight: 700, color: '#1D2129', marginBottom: 10 }}>{t('aiAnalysis.fixed2Ai')}</div>
<Table
rowKey="key"
columns={[
{ title: t('aiAnalysis.s39'), dataIndex: 'measure', ellipsis: true },
{ title: t('workOrder.priority'), dataIndex: 'priority', render: renderPriorityTag, width: 58 },
{ title: t('aiAnalysis.s40'), dataIndex: 'gain', render: g => <span style={{ color: '#00B42A', fontWeight: 600 }}>{g}</span>, width: 68 },
{ title: t('aiAnalysis.confidence'), dataIndex: 'confidence', width: 60 },
{
title: t('roles.actions'),
key: 'action',
width: 76,
render: (_, record) => (
<Button
type="primary"
size="small"
style={{ fontSize: 11, borderRadius: 4, height: 22, padding: '0 6px' }}
>
{record.isView ? t('common.detail') : t('workOrder.dispatch')}
</Button>
)
},
]}
dataSource={[
{ key: '1', measure: t('aiAnalysis.handleHotspotComponents'), priority: t('workOrder.high'), gain: '+2.15%', confidence: '92%', isView: false },
{ key: '2', measure: t('aiAnalysis.checkAbnormalStrings'), priority: t('workOrder.high'), gain: '+1.85%', confidence: '90%', isView: false },
{ key: '3', measure: t('aiAnalysis.cleanShadedAreas'), priority: t('workOrder.medium'), gain: '+0.45%', confidence: '78%', isView: false },
{ key: '4', measure: t('aiAnalysis.trackDegradedComponents'), priority: t('workOrder.medium'), gain: '+0.35%', confidence: '86%', isView: false },
{ key: '5', measure: t('aiAnalysis.monitorInverterEfficiency'), priority: t('workOrder.low'), gain: '+0.10%', confidence: '93%', isView: true },
]}
pagination={false}
size="small"
style={{ fontSize: 12 }}
/>
</div>
</Card>
</Col>
</Row>
{/* 底部:数据来源 */}
<Card
title={<span style={{ fontSize: 15, fontWeight: 700, color: '#1D2129' }}>{t('aiAnalysis.sourceFixed2')}</span>}
variant="borderless"
styles={{ body: { padding: '16px 20px' } }}
style={cardStyle}
>
<Row gutter={[16, 16]}>
{[
{ title: t('aiAnalysis.fixed2Uav'), time: '2025-05-20 09:30', icon: <ScanOutlined />, status: t('aiAnalysis.syncing') },
{ title: t('aiAnalysis.scada'), time: '2025-05-20 09:45:12', icon: <DatabaseOutlined />, status: t('roles.normal') },
{ title: t('aiAnalysis.s43'), time: '2025-05-20 09:45:00', icon: <CloudOutlined />, status: t('roles.normal') },
{ title: t('aiAnalysis.oM'), time: t('aiAnalysis.lastUpdated', { value: '2025-05-18' }), icon: <RestOutlined />, status: t('roles.normal') },
].map((source, idx) => (
<Col xs={24} sm={12} md={6} key={idx}>
<div style={{ background: '#f8fafc', padding: '16px', borderRadius: 12, display: 'flex', alignItems: 'center', gap: 16, border: '1px solid #f0f0f0', transition: 'all 0.3s' }} className="thermal-card">
<div style={{ width: 48, height: 48, background: '#fff', borderRadius: 12, display: 'flex', justifyContent: 'center', alignItems: 'center', fontSize: 24, color: '#165DFF', boxShadow: '0 4px 10px rgba(0,0,0,0.05)' }}>
{source.icon}
</div>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ fontSize: 14, fontWeight: 700, color: '#1D2129' }}>{source.title}</div>
<div style={{ fontSize: 12, color: '#86909C', marginTop: 4, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{t('aiAnalysis.dataPoint', { time: source.time })}</div>
<div style={{ fontSize: 11, color: source.status === t('roles.normal') ? '#00B42A' : '#165DFF', marginTop: 6, display: 'flex', alignItems: 'center', gap: 6 }}>
<div style={{ width: 6, height: 6, background: source.status === t('roles.normal') ? '#00B42A' : '#165DFF', borderRadius: '50%' }}></div>
{t('aiAnalysis.statusLabel', { status: source.status })}
</div>
</div>
</div>
</Col>
))}
</Row>
</Card>
</div>
);
}