清洗优化

This commit is contained in:
mmc
2026-05-07 22:04:27 +08:00
parent 1554af83d3
commit 9645c2b651
6 changed files with 539 additions and 43 deletions

View File

@@ -250,7 +250,7 @@ export default function AlarmCenterPage() {
>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
<div>
<Typography.Text strong style={{ fontSize: 16, color: '#0837A8' }}>告警列表(共8条)</Typography.Text><br />
<Typography.Text strong style={{ fontSize: 16, color: '#0837A8', fontWeight: 800 }}>告警列表(共8条)</Typography.Text><br />
<Text type="secondary" style={{ fontSize: 12 }}>点击告警查看详情</Text>
</div>
</div>

View File

@@ -37,7 +37,8 @@
.custom-scrollbar::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.2); }
.ant-card-head-title{
color:#0837A8
color:#0837A8;
font-weight: 800 !important;
}
.ant-statistic-content-suffix{
font-size: 14px;

View File

@@ -196,7 +196,7 @@ export default function AIDiagnosisPage() {
<Row gutter={16} style={{ marginBottom: 24 }}>
<Col span={12}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>热成像分析(无人机巡检)</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>热成像分析(无人机巡检)</span>}
bordered={false}
style={{ borderRadius: 8 }}
extra={<Text type="secondary" style={{ fontSize: 12 }}>巡检时间:2026-05-06 09:30</Text>}
@@ -209,7 +209,7 @@ export default function AIDiagnosisPage() {
{item.title}
</div>
<div style={{ position: 'absolute', bottom: 8, left: 8 }}>
<div style={{ fontSize: 14, fontWeight: 600 }}>{item.name}</div>
<div style={{ fontSize: 14, fontWeight: 800 }}>{item.name}</div>
<div style={{ fontSize: 12, color: '#666' }}>{item.temp}</div>
</div>
</div>
@@ -227,7 +227,7 @@ export default function AIDiagnosisPage() {
</Col>
<Col span={12}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>组串异常定位</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>组串异常定位</span>}
bordered={false}
style={{ borderRadius: 8, height: "100%" }}
extra={<div style={{ display: 'flex', alignItems: 'center' }}><Text type="secondary" style={{ fontSize: 12 }}>20列 × 8排二维矩阵,点击点位查看详情</Text><Tag color="red" style={{ marginLeft: 8 }}>异常组串:8</Tag></div>}
@@ -276,7 +276,7 @@ export default function AIDiagnosisPage() {
</div>
<div style={{ width: 180, borderLeft: '1px solid #f0f0f0', paddingLeft: 16 }}>
<div style={{ marginBottom: 12 }}>
<div style={{ fontWeight: 600, marginBottom: 4 }}>A-03</div>
<div style={{ fontWeight: 800, marginBottom: 4 }}>A-03</div>
<div style={{ fontSize: 12, color: '#999', marginBottom: 2 }}>温度 <span style={{ color: '#ff4d4f' }}>75℃</span></div>
<div style={{ fontSize: 12, color: '#999', marginBottom: 2 }}>发电偏差 <span style={{ color: '#ff4d4f' }}>-18.6%</span></div>
<div style={{ fontSize: 12, color: '#999', marginBottom: 2 }}>历史异常 3 次</div>
@@ -293,7 +293,7 @@ export default function AIDiagnosisPage() {
<Row gutter={16} style={{ marginBottom: 24, height: '285px' }}>
<Col span={8}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>组件衰减分析</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>组件衰减分析</span>}
bordered={false}
style={{ borderRadius: 8 }}
>
@@ -302,7 +302,7 @@ export default function AIDiagnosisPage() {
</Col>
<Col span={8}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>发电表现分析</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>发电表现分析</span>}
bordered={false}
style={{ borderRadius: 8 }}
>
@@ -311,13 +311,17 @@ export default function AIDiagnosisPage() {
</Col>
<Col span={8} style={{ height: '100%' }}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>AI诊断总结</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>AI诊断总结</span>}
bordered={false}
style={{ borderRadius: 8, height: '100%' }}
extra={<Text type="secondary" style={{ fontSize: 12 }}>模型置信度与影响程度</Text>}
>
{/* 关键:给 Table 设置固定高度 + 滚动 */}
<div style={{ height: "200px", overflow: "auto" }}>
{/* 👇 加了灰色透明滚动条 */}
<div style={{
height: "200px",
overflow: "auto",
scrollbarWidth: 'thin', scrollbarColor: '#ccc transparent'
}}>
<Table
columns={[
{ title: '诊断项', dataIndex: 'diagnosis', width: 100 },
@@ -340,7 +344,7 @@ export default function AIDiagnosisPage() {
<Row gutter={16} style={{ marginTop: 16 }}>
<Col span={12}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>数据来源状态</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>数据来源状态</span>}
bordered={false}
style={{ borderRadius: 8, height: '100%' }}
extra={<Text type="secondary" style={{ fontSize: 12 }}>多源数据融合质量</Text>}
@@ -348,14 +352,14 @@ export default function AIDiagnosisPage() {
<Row gutter={16}>
<Col span={12}>
<div style={{ textAlign: 'center', padding: 12, background: '#f5f7fa', borderRadius: 8 }}>
<div style={{ fontSize: 16, fontWeight: 600, color: '#1890ff' }}>UAV</div>
<div style={{ fontSize: 16, fontWeight: 800, color: '#1890ff' }}>UAV</div>
<div style={{ fontSize: 12, marginTop: 4 }}>无人机</div>
<div style={{ fontSize: 10, color: '#52c41a' }}>数据状态:正常</div>
</div>
</Col>
<Col span={12}>
<div style={{ textAlign: 'center', padding: 12, background: '#f5f7fa', borderRadius: 8 }}>
<div style={{ fontSize: 16, fontWeight: 600, color: '#1890ff' }}>DB</div>
<div style={{ fontSize: 16, fontWeight: 800, color: '#1890ff' }}>DB</div>
<div style={{ fontSize: 12, marginTop: 4 }}>SCA</div>
<div style={{ fontSize: 10, color: '#52c41a' }}>数据状态:正常</div>
</div>
@@ -365,14 +369,14 @@ export default function AIDiagnosisPage() {
<Row gutter={16} style={{ marginTop: 16 }}>
<Col span={12}>
<div style={{ textAlign: 'center', padding: 12, background: '#f5f7fa', borderRadius: 8 }}>
<div style={{ fontSize: 16, fontWeight: 600, color: '#1890ff' }}>UAV</div>
<div style={{ fontSize: 16, fontWeight: 800, color: '#1890ff' }}>UAV</div>
<div style={{ fontSize: 12, marginTop: 4 }}>无人机</div>
<div style={{ fontSize: 10, color: '#52c41a' }}>数据状态:正常</div>
</div>
</Col>
<Col span={12}>
<div style={{ textAlign: 'center', padding: 12, background: '#f5f7fa', borderRadius: 8 }}>
<div style={{ fontSize: 16, fontWeight: 600, color: '#1890ff' }}>UAV</div>
<div style={{ fontSize: 16, fontWeight: 800, color: '#1890ff' }}>UAV</div>
<div style={{ fontSize: 12, marginTop: 4 }}>无人机</div>
<div style={{ fontSize: 10, color: '#52c41a' }}>数据状态:正常</div>
</div>
@@ -383,13 +387,17 @@ export default function AIDiagnosisPage() {
</Col>
<Col span={12}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>AI建议与处置</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>AI建议与处置</span>}
bordered={false}
style={{ borderRadius: 8 }}
extra={<Text type="secondary" style={{ fontSize: 12 }}>按收益、优先级与置信度排序</Text>}
>
{/* 👇 关键:外层包一层 div,设置高度 + 滚动 */}
<div style={{ height: 220, overflow: "auto" }}>
{/* 👇 加了灰色透明滚动条 */}
<div style={{
height: 220,
overflow: "auto",
scrollbarWidth: 'thin', scrollbarColor: '#ccc transparent'
}}>
<Table
columns={[
{ title: '建议措施', dataIndex: 'measure' },
@@ -433,7 +441,7 @@ export default function AIDiagnosisPage() {
{/* 抽屉详情 */}
<Drawer
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>AI诊断详情</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>AI诊断详情</span>}
placement="right"
onClose={() => setDrawerVisible(false)}
open={drawerVisible}

View File

@@ -0,0 +1,488 @@
import React, { useState } from 'react';
import {
Row, Col, Card, Button, Table, Tag, Typography, Space, Statistic, DatePicker,
Divider,
Flex
} from 'antd';
import {
ReloadOutlined, PlusOutlined, ArrowUpOutlined, CheckCircleOutlined,
CloudOutlined, SunOutlined, MoneyCollectOutlined, CalendarOutlined, DropOutlined
} from '@ant-design/icons';
import { Line, Pie, Bar } from '@ant-design/charts';
import he from '@/dist/assets/Organization-irk1gmLc';
const { Title, Text } = Typography;
// 模拟数据
const smartCleanPlanData = [
{ id: 'plan01', priority: '高', area: '区域15, 01', boost: '4,250 kWh', weather: 88 },
{ id: 'plan02', priority: '高', area: '区域06, 02', boost: '3,180 kWh', weather: 86 },
{ id: 'plan03', priority: '中', area: '区域07, 09', boost: '2,210 kWh', weather: 84 },
];
const workOrderPreviewData = [
{
area: 'A区北侧组件清洗区',
priority: '高',
duration: '2.5 h',
handler: '运维工程师',
planTime: '2026-04-30T20:26:05',
status: '已审批'
},
{
area: 'B区沙尘沉积区',
priority: '中',
duration: '2.5 h',
handler: '清洗班组',
planTime: '2026-05-02T20:26:05',
status: '待确认'
}
];
// 图表配置
const pollutionTrendConfig = {
data: [
{ date: '04-23', 污染指数: 45, 阈值: 50 },
{ date: '04-24', 污染指数: 48, 阈值: 50 },
{ date: '04-26', 污染指数: 52, 阈值: 50 },
{ date: '04-28', 污染指数: 50, 阈值: 50 },
{ date: '04-29', 污染指数: 54, 阈值: 50 },
],
xField: 'date',
yField: ['污染指数', '阈值'],
color: ['#1890ff', '#faad14'],
smooth: true,
legend: { position: 'top-left' },
};
const lossPieConfig = {
data: [
{ type: '灰尘积累', value: 50 },
{ type: '鸟粪遮挡', value: 30 },
{ type: '沙尘污染', value: 15 },
{ type: '其他', value: 5 },
],
angleField: 'value',
colorField: 'type',
color: ['#1890ff', '#ff4d4f', '#faad14', '#d9d9d9'],
radius: 0.8,
innerRadius: 0.6,
label: { type: 'outer' },
};
const compareBarConfig = {
data: [
{ date: 'D-7', 清洗前: 800, 清洗后: 1200, 提升率: 50 },
{ date: 'D-5', 清洗前: 850, 清洗后: 1200, 提升率: 41 },
{ date: 'D-3', 清洗前: 900, 清洗后: 1200, 提升率: 33 },
{ date: 'D-1', 清洗前: 950, 清洗后: 1200, 提升率: 26 },
],
xField: 'date',
yField: ['清洗前', '清洗后'],
color: ['#1890ff', '#52c41a'],
isGroup: true,
};
export default function CleanOptimizationPage() {
const [mapTooltip, setMapTooltip] = useState<any>(null);
const renderPriorityTag = (priority: string) => {
const colorMap: Record<string, string> = { '高': 'red', '中': 'orange', '低': 'green' };
return <Tag color={colorMap[priority]}>{priority}</Tag>;
};
const renderStatusTag = (status: string) => {
const colorMap: Record<string, string> = { '已审批': 'green', '待确认': 'orange' };
return <Tag color={colorMap[status]}>{status}</Tag>;
};
return (
<div style={{ background: '#f5f7fa', minHeight: '100vh', padding: 24 }}>
{/* 顶部标题与操作 */}
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
<div>
<Title level={4} style={{ margin: 0, }}>清洗优化管理</Title>
<Text type="secondary">污染热力分布、AI推荐计划、天气资源联动与清洗收益评估</Text>
</div>
<Space>
<Text type="secondary" style={{ marginRight: 16 }}>更新时间: 2026-05-06 09:30</Text>
<Button icon={<ReloadOutlined />}>刷新</Button>
<Button type="primary">生成清洗建议</Button>
<Button>新增计划</Button>
</Space>
</div>
{/* 顶部指标卡片 */}
<Row gutter={16} style={{ marginBottom: 24 }}>
<Col span={4}>
<Card bordered={false} style={{ borderRadius: 8, height: '100%' }}>
<Statistic
title="污染指数"
value={54.0}
precision={1}
prefix={
<div style={{ background: '#fff7e6', borderRadius: '50%', width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<SunOutlined style={{ color: '#faad14', fontSize: 18 }} />
</div>
}
valueStyle={{ fontSize: 28, fontWeight: 700 }}
/>
<div style={{ fontSize: 12, color: '#999' }}>较昨日 <span style={{ color: '#ff4d4f' }}>▼ 5.3</span></div>
</Card>
</Col>
<Col span={4}>
<Card bordered={false} style={{ borderRadius: 8, height: '100%' }}>
<Statistic
title="建议清洗区域数"
value={9}
suffix="/ 22"
prefix={
<div style={{ background: '#e6f7ff', borderRadius: '50%', width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<span style={{ color: '#1890ff', fontSize: 18 }}>▦</span>
</div>
}
valueStyle={{ fontSize: 28, fontWeight: 700 }}
/>
<div style={{ fontSize: 12, color: '#999' }}>占比 40%</div>
</Card>
</Col>
<Col span={4}>
<Card bordered={false} style={{ borderRadius: 8, height: '100%' }}>
<Statistic
title="预计发电提升"
value={12850}
suffix="kWh"
prefix={
<div style={{ background: '#f6ffed', borderRadius: '50%', width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<ArrowUpOutlined style={{ color: '#52c41a', fontSize: 18 }} />
</div>
}
valueStyle={{ fontSize: 28, fontWeight: 700, color: '#52c41a' }}
/>
<div style={{ fontSize: 12, color: '#999' }}>占昨日发电量 14.2%</div>
</Card>
</Col>
<Col span={4}>
<Card bordered={false} style={{ borderRadius: 8, height: '100%' }}>
<Statistic
title="预计收益提升"
value={8278}
prefix="¥"
prefix={
<div style={{ background: '#f9f0ff', borderRadius: '50%', width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<span style={{ color: '#722ed1', fontSize: 18 }}>¥</span>
</div>
}
valueStyle={{ fontSize: 28, fontWeight: 700 }}
/>
<div style={{ fontSize: 12, color: '#999' }}>按电价 0.568 元/kWh 计算</div>
</Card>
</Col>
<Col span={4}>
<Card bordered={false} style={{ borderRadius: 8, height: '100%' }}>
<Statistic
title="上次清洗时间"
value="2025-05-12"
prefix={
<div style={{ background: '#e6f7ff', borderRadius: '50%', width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<CalendarOutlined style={{ color: '#1890ff', fontSize: 18 }} />
</div>
}
valueStyle={{ fontSize: 20, fontWeight: 700 }}
/>
<div style={{ fontSize: 12, color: '#999' }}>距今 24 天</div>
</Card>
</Col>
<Col span={4}>
<Card bordered={false} style={{ borderRadius: 8, height: '100%' }}>
<Statistic
title="清洗成本预估"
value={5050}
prefix={
<div style={{ background: '#f9f0ff', borderRadius: '50%', width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<span style={{ color: '#722ed1', fontSize: 18 }}>¥</span>
</div>
}
suffix=""
valueStyle={{ fontSize: 28, fontWeight: 700 }}
/>
<div style={{ fontSize: 12, color: '#999' }}>预计单次清洗总成本</div>
</Card>
</Col>
</Row>
{/* 左侧图表区域 */}
<Row gutter={16} style={{ marginBottom: 24, height: '500px' }}>
<Col span={6} style={{
display: 'flex', flexDirection: 'column', gap: 16, height: '100%', overflowY: 'auto', overflowX: 'hidden', scrollbarWidth: 'thin', scrollbarColor: '#ccc transparent'
}}>
<Card
title={<div style={{ padding: '8px' }}>
<p style={{ color: '#0837A8', margin: 0 }}>污染趋势</p>
<Text type="secondary" style={{ fontSize: 10 }}>近30天污染指数与清洗阈值</Text>
</div>}
bordered={false}
style={{ borderRadius: 8 }}
>
<Line {...pollutionTrendConfig} height={140} />
</Card>
<Card
title={<div style={{ padding: '8px' }}>
<p style={{ color: '#0837A8', margin: 0 }}>发电损失分析</p>
<Text type="secondary" style={{ fontSize: 10 }}>污染类型造成的发电损失占比</Text>
</div>}
bordered={false}
style={{ borderRadius: 8 }}
>
{/* 👇 关键:给图表外层套一层固定宽度 + 居中,防止溢出 */}
<div style={{
width: '100%',
height: 140,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
}}>
<Pie
{...lossPieConfig}
height={140}
//width="100%" /* 强制宽度100% */
/>
<div style={{ position: 'absolute', textAlign: 'center' }}>
<div style={{ fontSize: 12, color: '#666' }}>发电损失</div>
<div style={{ fontSize: 18, fontWeight: 700 }}>9,320 kWh</div>
</div>
</div>
</Card>
<Card
title={<div style={{ padding: '8px' }}>
<p style={{ color: '#0837A8', margin: 0 }}>清洗前后对比</p>
<Text type="secondary" style={{ fontSize: 10 }}>近一次建议清洗区域发电恢复测算</Text>
</div>}
bordered={false}
style={{ borderRadius: 8 }}
>
<Bar {...compareBarConfig} height={140} />
</Card>
</Col>
{/* 中间地图区域 */}
<Col span={12} style={{
display: 'flex', flexDirection: 'column', gap: 16, height: '100%',
}}>
<Card
title={<div style={{ padding: '8px' }}>
<p style={{ color: '#0837A8', margin: 0 }}>电站污染分布与建议清洗区块</p>
<div style={{ display: 'flex', alignItems: 'center' }}>
<Text type="secondary" style={{ fontSize: 12 }}>真实正射底图 · 污染热力叠加 · AI调度优先级</Text>
<div style={{ display: 'flex', gap: 16, marginLeft: 16 }}>
<span style={{ display: 'flex', alignItems: 'center' }}><span style={{ width: 10, height: 10, background: '#52c41a', borderRadius: '50%', marginRight: 4 }}></span>低污染</span>
<span style={{ display: 'flex', alignItems: 'center' }}><span style={{ width: 10, height: 10, background: '#faad14', borderRadius: '50%', marginRight: 4 }}></span>中污染</span>
<span style={{ display: 'flex', alignItems: 'center' }}><span style={{ width: 10, height: 10, background: '#ff4d4f', borderRadius: '50%', marginRight: 4 }}></span>重污染</span>
</div>
</div>
</div>}
bordered={false}
style={{ borderRadius: 8, height: '100%' }}
>
<div style={{ position: 'relative', height: 380, background: '#f0f2f5', borderRadius: 8, overflow: 'hidden' }}>
{/* 模拟地图区域 */}
<div style={{
width: '100%', height: '100%',
display: 'flex', alignItems: 'center', justifyContent: 'center',
backgroundImage: 'url(https://via.placeholder.com/800x400)',
backgroundSize: 'cover',
backgroundPosition: 'center'
}}>
<div style={{ position: 'absolute', top: 20, left: 80, background: '#ff4d4f', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域01<br />82.3</div>
<div style={{ position: 'absolute', top: 20, left: 160, background: '#ff4d4f', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域02<br />76.8</div>
<div style={{ position: 'absolute', top: 40, left: 240, background: '#faad14', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域03<br />63.2</div>
<div style={{ position: 'absolute', top: 60, left: 320, background: '#52c41a', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域04<br />33.6</div>
<div style={{ position: 'absolute', top: 60, left: 400, background: '#52c41a', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域05<br />19.7</div>
<div style={{ position: 'absolute', top: 120, left: 80, background: '#ff4d4f', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域06<br />88.1</div>
<div style={{ position: 'absolute', top: 120, left: 160, background: '#faad14', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域07<br />68.7</div>
<div style={{ position: 'absolute', top: 120, left: 240, background: '#faad14', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域08<br />51.2</div>
<div style={{ position: 'absolute', top: 120, left: 320, background: '#faad14', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域09<br />72.9</div>
<div style={{ position: 'absolute', top: 120, left: 400, background: '#52c41a', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域10<br />36.8</div>
<div style={{ position: 'absolute', top: 180, left: 80, background: '#52c41a', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域11<br />44.6</div>
<div style={{ position: 'absolute', top: 180, left: 160, background: '#faad14', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域12<br />57.5</div>
<div style={{ position: 'absolute', top: 180, left: 240, background: '#faad14', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域13<br />61.8</div>
<div style={{ position: 'absolute', top: 180, left: 320, background: '#52c41a', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域14<br />42.1</div>
<div style={{ position: 'absolute', top: 240, left: 80, background: '#ff4d4f', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域15<br />85.6</div>
<div style={{ position: 'absolute', top: 240, left: 160, background: '#faad14', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域16<br />49.8</div>
<div style={{ position: 'absolute', top: 240, left: 240, background: '#52c41a', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域17<br />24.5</div>
<div style={{ position: 'absolute', top: 240, left: 320, background: '#52c41a', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域18<br />13.7</div>
<div style={{ position: 'absolute', top: 240, left: 400, background: '#52c41a', color: '#fff', padding: '4px 8px', borderRadius: 4, fontSize: 12 }}>区域19<br />36.3</div>
{/* 模拟 tooltip */}
{mapTooltip && (
<div style={{ position: 'absolute', bottom: 40, left: 80, background: 'rgba(0,0,0,0.7)', color: '#fff', padding: '8px 12px', borderRadius: 8, fontSize: 14 }}>
<div style={{ fontWeight: 700 }}>{mapTooltip.name}</div>
<div style={{ fontSize: 12 }}>{mapTooltip.desc}</div>
</div>
)}
</div>
{/* 地图控制 */}
<div style={{ position: 'absolute', top: 16, left: '50%', transform: 'translateX(-50%)', display: 'flex', alignItems: 'center', gap: 16 }}>
<Text type="secondary" style={{ fontSize: 12 }}>底图缩放</Text>
<Button size="small">适应</Button>
<Button size="small">-</Button>
<Button size="small">+</Button>
<Button size="small">重置</Button>
<div style={{ marginLeft: 16 }}>90%</div>
</div>
</div>
</Card>
</Col>
{/* 右侧面板 */}
<Col span={6} style={{
display: 'flex', flexDirection: 'column', gap: 16, height: '100%', overflowY: 'auto', overflowX: 'hidden', scrollbarWidth: 'thin', scrollbarColor: '#ccc transparent'
}}>
<Card
title={<span style={{ color: '#0837A8', }}>智能清洗建议</span>}
bordered={false}
style={{ borderRadius: 8, marginBottom: 16, flex: 1, display: "flex", flexDirection: "column" }}
extra={<div style={{ display: 'flex', alignItems: 'center' }}><Text type="secondary" style={{ fontSize: 12 }}>优先级、天气适宜度与收益提升联动排序</Text><Tag color="blue" style={{ marginLeft: 8 }}>AI推荐</Tag></div>}
>
{/* 👇 关键:填满卡片 + 超长滚动 */}
<div style={{
flex: 1,
overflow: "auto",
// 滚动条样式 #ccc + 透明
"&::-webkit-scrollbar": { width: "6px" },
"&::-webkit-scrollbar-thumb": { backgroundColor: "#ccc", borderRadius: "3px" },
"&::-webkit-scrollbar-track": { backgroundColor: "transparent" },
}}>
<Table
columns={[
{ title: '计划', dataIndex: 'id', width: 80 },
{ title: '优先级', dataIndex: 'priority', render: renderPriorityTag, width: 80 },
{ title: '建议区域', dataIndex: 'area', width: 100 },
{ title: '预计提升', dataIndex: 'boost', width: 100 },
{ title: '天气', dataIndex: 'weather', width: 80 },
]}
dataSource={smartCleanPlanData}
pagination={false}
size="small"
scroll={{ y: undefined }}
/>
</div>
</Card>
<Card
title={<span style={{ color: '#0837A8', flex: 1 }}>天气与资源参考</span>}
bordered={false}
style={{ borderRadius: 8, marginBottom: 16 }}
extra={<Text type="secondary" style={{ fontSize: 12 }}>未来7天作业窗口、风速、湿度、降水概率</Text>}
>
<div style={{ display: 'flex', gap: 8 }}>
{['05-06', '05-07', '05-08', '05-09'].map((day, idx) => (
<Button key={idx} size="small" style={{ flex: 1 }}>{day}</Button>
))}
</div>
</Card>
<Card
title={<span style={{ color: '#0837A8', flex: 1 }}>清洗方案建议</span>}
bordered={false}
style={{ borderRadius: 8 }}
extra={<Text type="secondary" style={{ fontSize: 12 }}>机器人清洗与人工清洗资源对比</Text>}
>
<div style={{ display: 'flex', gap: 8 }}>
<Button size="small" style={{ flex: 1 }} icon={<span>🤖</span>}>清洗机器人方案</Button>
<Button size="small" style={{ flex: 1 }} icon={<span>👷</span>}>人工清洗方案</Button>
</div>
</Card>
</Col>
</Row>
{/* 工单预览区域 */}
<Card
title={<span style={{ color: '#0837A8', }}>清洗工单预览</span>}
bordered={false}
style={{ borderRadius: 8, marginBottom: 24 }}
extra={<div style={{ display: 'flex', alignItems: 'center' }}><Text type="secondary" style={{ fontSize: 12 }}>AI推荐计划转工单、转任务仍保留现有接口</Text><Button type="link" size="small">新增</Button></div>}
>
<Table
columns={[
{ title: '区域', dataIndex: 'area' },
{ title: '优先级', dataIndex: 'priority', render: renderPriorityTag, width: 100 },
{ title: '预计工时', dataIndex: 'duration', width: 100 },
{ title: '负责人', dataIndex: 'handler', width: 120 },
{ title: '计划时间', dataIndex: 'planTime', width: 180 },
{ title: '状态', dataIndex: 'status', render: renderStatusTag, width: 100 },
{
title: '操作', width: 120, render: () => (
<Space>
<Button type="link" size="small">编辑</Button>
<Button type="link" size="small">生成</Button>
</Space>
)
}
]}
dataSource={workOrderPreviewData}
pagination={false}
/>
</Card>
{/* 清洗影响评估 */}
<Card
title={<span style={{ color: '#0837A8', }}>清洗影响评估</span>}
bordered={false}
style={{ borderRadius: 8, marginBottom: 24 }}
extra={<Text type="secondary" style={{ fontSize: 12 }}>预计用水、耗时、碳减排与作业风险综合判断</Text>}
>
<Row gutter={16}>
<Col span={6}>
<div style={{ padding: 16, background: '#f5f7fa', borderRadius: 8 }}>
<div style={{ fontSize: 12, color: '#666' }}>预计用水量</div>
<div style={{ fontSize: 24, fontWeight: 700, marginTop: 4 }}>18 吨</div>
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>节水率 30%(机器人)</div>
</div>
</Col>
<Col span={6}>
<div style={{ padding: 16, background: '#f5f7fa', borderRadius: 8 }}>
<div style={{ fontSize: 12, color: '#666' }}>预计耗时</div>
<div style={{ fontSize: 24, fontWeight: 700, marginTop: 4 }}>12 小时</div>
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>并行作业 2 组</div>
</div>
</Col>
<Col span={6}>
<div style={{ padding: 16, background: '#f5f7fa', borderRadius: 8 }}>
<div style={{ fontSize: 12, color: '#666' }}>碳减排量</div>
<div style={{ fontSize: 24, fontWeight: 700, marginTop: 4 }}>6.85 吨</div>
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>CO₂ 减排量</div>
</div>
</Col>
<Col span={6}>
<div style={{ padding: 16, background: '#f5f7fa', borderRadius: 8 }}>
<div style={{ fontSize: 12, color: '#666' }}>作业风险</div>
<div style={{ fontSize: 24, fontWeight: 700, marginTop: 4 }}>低风险</div>
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>天气和通道安全可控</div>
</div>
</Col>
</Row>
</Card>
{/* 业务入口 */}
<Card bordered={false} style={{ borderRadius: 8 }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div>
<Title level={5} style={{ margin: 0, color: '#0837A8' }}>业务入口</Title>
<Text type="secondary" style={{ fontSize: 12 }}>区域维护、计划审批、任务完成与效果评估仍使用现有接口和权限。</Text>
</div>
<Space>
<Button>新增区域</Button>
<Button>新增计划</Button>
<Button>新增</Button>
</Space>
</div>
</Card>
</div>
);
}

View File

@@ -121,42 +121,42 @@ export default function StationDashboard() {
>
<Col flex="1 1 16.666%">
<Card bordered={false} style={cardStyle}>
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 600 }}>今日发电量</span>}
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 800 }}>今日发电量</span>}
value={stationOverview.todayEnergy} precision={1} valueStyle={{ color: '#1890ff', fontSize: 24, fontWeight: 800 }} prefix={<CloudOutlined style={{ fontSize: 20 }} />} suffix="kWh" />
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>日发电实时累计</div>
</Card>
</Col>
<Col flex="1 1 16.666%">
<Card bordered={false} style={cardStyle}>
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 600 }}>当前功率</span>}
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 800 }}>当前功率</span>}
value={stationOverview.currentPower} precision={1} valueStyle={{ color: '#1890ff', fontSize: 24, fontWeight: 800 }} prefix={<ThunderboltOutlined style={{ fontSize: 20 }} />} suffix="kW" />
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>装机容量 100.0 MWp</div>
</Card>
</Col>
<Col flex="1 1 16.666%">
<Card bordered={false} style={cardStyle}>
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 600 }}>系统效率 PR</span>}
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 800 }}>系统效率 PR</span>}
value={stationOverview.systemEfficiency} precision={1} valueStyle={{ color: '#52c41a', fontSize: 24, fontWeight: 800 }} prefix={<BarChartOutlined style={{ fontSize: 20 }} />} suffix="%" />
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>昨日 {stationOverview.yesterdayEfficiency}% +1.3%</div>
</Card>
</Col>
<Col flex="1 1 16.666%">
<Card bordered={false} style={cardStyle}>
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 600 }}>系统可用率</span>}
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 800 }}>系统可用率</span>}
value={stationOverview.systemAvailability} precision={2} valueStyle={{ color: '#faad14', fontSize: 24, fontWeight: 800 }} prefix={<RiseOutlined style={{ fontSize: 20 }} />} suffix="%" />
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>在线设备 {stationOverview.onlineDevices}</div>
</Card>
</Col>
<Col flex="1 1 16.666%">
<Card bordered={false} style={cardStyle}>
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 600 }}>告警数量</span>}
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 800 }}>告警数量</span>}
value={stationOverview.alarmCount} valueStyle={{ color: '#ff4d4f', fontSize: 24, fontWeight: 800 }} prefix={<BellOutlined style={{ fontSize: 20 }} />} suffix="条" />
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>今日新增 0 条</div>
</Card>
</Col>
<Col flex="1 1 16.666%">
<Card bordered={false} style={cardStyle}>
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 600 }}>节省运维成本</span>}
<Statistic title={<span style={{ color: '#000', fontSize: 14, fontWeight: 800 }}>节省运维成本</span>}
value={stationOverview.costSaved} valueStyle={{ color: '#1890ff', fontSize: 24, fontWeight: 800 }} prefix="¥" />
<div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>清洗收益 + 工单闭环估算</div>
</Card>
@@ -176,7 +176,7 @@ export default function StationDashboard() {
{/* 左侧图表列 - 最终完美版:不溢出 + 一定可见 */}
<Col xs={24} lg={6} style={{ flex: '0 0 25%', padding: '0 8px', display: 'flex', flexDirection: 'column', height: '100%', gap: "8px", overflowX: 'hidden', overflowY: 'auto', scrollbarWidth: 'thin', scrollbarColor: '#ccc transparent' }}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>发电趋势</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>发电趋势</span>}
bordered={false}
style={{
...cardStyle,
@@ -197,7 +197,7 @@ export default function StationDashboard() {
</Card>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>辐照度与温度</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>辐照度与温度</span>}
bordered={false}
style={{
...cardStyle,
@@ -218,7 +218,7 @@ export default function StationDashboard() {
</Card>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>逆变器效率</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>逆变器效率</span>}
bordered={false}
style={{
...cardStyle,
@@ -239,7 +239,7 @@ export default function StationDashboard() {
</Card>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>运维任务进度</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>运维任务进度</span>}
bordered={false}
style={{
...cardStyle,
@@ -266,7 +266,7 @@ export default function StationDashboard() {
title={
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<div>
<div style={{ fontWeight: 500, color: '#0837A8' }}>电站概览</div>
<div style={{ fontWeight: 800, color: '#0837A8' }}>电站概览</div>
<div style={{ fontSize: 12, color: '#999' }}>GeoTIFF 正射底图 · 设备点位叠加</div>
</div>
@@ -318,7 +318,7 @@ export default function StationDashboard() {
<Card
title={
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ fontWeight: 600, fontSize: 14, color: '#0837A8' }}>实时告警</span>
<span style={{ fontWeight: 800, fontSize: 14, color: '#0837A8' }}>实时告警</span>
<Button type="link" style={{ padding: 0, fontSize: 12 }}>更多</Button>
</div>
}
@@ -366,7 +366,7 @@ export default function StationDashboard() {
{/* 设备在线状态 */}
<Card
title={<span style={{ fontWeight: 600, fontSize: 14, color: '#0837A8' }}>设备在线状态</span>}
title={<span style={{ fontWeight: 800, fontSize: 14, color: '#0837A8' }}>设备在线状态</span>}
bordered={false}
style={{
borderRadius: 8,
@@ -399,7 +399,7 @@ export default function StationDashboard() {
{/* 天气信息 */}
<Card
title={<span style={{ fontWeight: 600, fontSize: 14, color: '#0837A8' }}>天气信息</span>}
title={<span style={{ fontWeight: 800, fontSize: 14, color: '#0837A8' }}>天气信息</span>}
bordered={false}
style={{
borderRadius: 8,
@@ -412,7 +412,7 @@ export default function StationDashboard() {
<CloudOutlined style={{ fontSize: 32, color: '#1890ff', marginRight: 12 }} />
<div style={{ display: 'flex', flexDirection: 'row', gap: 12, alignItems: 'center' }}>
<div>
<div style={{ fontSize: 24, fontWeight: 600, color: '#1890ff' }}>22℃</div>
<div style={{ fontSize: 24, fontWeight: 800, color: '#1890ff' }}>22℃</div>
<div style={{ fontSize: 14, color: '#666', marginBottom: 2 }}>阴天</div>
</div>
<div>
@@ -428,7 +428,7 @@ export default function StationDashboard() {
<Card
title={
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span style={{ fontWeight: 600, fontSize: 14, color: '#0837A8' }}>清洗建议</span>
<span style={{ fontWeight: 800, fontSize: 14, color: '#0837A8' }}>清洗建议</span>
<Button type="link" style={{ padding: 0, fontSize: 12 }}>详情</Button>
</div>
}
@@ -453,7 +453,7 @@ export default function StationDashboard() {
autoFit={true}
/>
<div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', textAlign: 'center' }}>
<div style={{ fontSize: 24, fontWeight: 600, color: '#1890ff' }}>46</div>
<div style={{ fontSize: 24, fontWeight: 800, color: '#1890ff' }}>46</div>
<div style={{ fontSize: 12, color: '#666' }}>分</div>
</div>
</div>
@@ -469,7 +469,7 @@ export default function StationDashboard() {
<Row gutter={16} style={{ height: '25%' }} >
<Col xs={12} style={{ height: '100%' }}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>近期巡检记录</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>近期巡检记录</span>}
bordered={false}
style={{ ...cardStyle, height: '100%' }}
bodyStyle={{ padding: 12, height: '66%', overflow: 'auto', scrollbarWidth: 'thin', scrollbarColor: '#ccc transparent' }}
@@ -489,7 +489,7 @@ export default function StationDashboard() {
</Col>
<Col xs={12} style={{ height: '100%', }}>
<Card
title={<span style={{ color: '#0837A8', fontWeight: 600 }}>AI分析摘要</span>}
title={<span style={{ color: '#0837A8', fontWeight: 800 }}>AI分析摘要</span>}
bordered={false}
style={{ ...cardStyle, height: '100%' }}
bodyStyle={{ padding: 12, height: '66%', overflow: 'auto', scrollbarWidth: 'thin', scrollbarColor: '#ccc transparent' }}

View File

@@ -3,6 +3,7 @@ import { createBrowserRouter } from 'react-router-dom';
import type { RouteObject } from 'react-router-dom';
import VideoMonitorPage from '../pages/VideoMonitorPage';
import AIDiagnosisPage from '../pages/AIAnalysis';
import CleanOptimizationPage from '../pages/CleanOptimization';
const Layout = lazy(() => import('../components/Layout'));
const ProtectedRoute = lazy(() => import('../components/ProtectedRoute'));
@@ -83,10 +84,8 @@ const routes: RouteObject[] = [
{ path: 'video', element: <Video /> },
{ path: 'monitor', element: <VideoMonitorPage /> },
{ path: 'alerts', element: <Alerts /> },
{
path: 'AIanalysis', element: <AIDiagnosisPage />
},
{ path: 'clean', element: <div>清洗优化</div> },
{ path: 'AIanalysis', element: <AIDiagnosisPage /> },
{ path: 'clean', element: <CleanOptimizationPage /> },
{ path: 'task', element: <div>工单任务</div> },
{ path: 'table', element: <div>报表中心</div> },
{ path: 'systemSetting', element: <SystemSetting /> },