xx
This commit is contained in:
@@ -59,6 +59,10 @@
|
||||
.ant-select-selector{
|
||||
border-radius:8px !important;
|
||||
}
|
||||
.ant-btn{
|
||||
border-radius:8px !important;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@keyframes sunRotate {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,35 +1,47 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Layout, Card, Row, Col, Button, Table, Tag, Select, Input, Typography, Space,
|
||||
Statistic, message, Drawer, Descriptions, Timeline, Divider, Form, Modal
|
||||
Statistic, Modal, message, Empty, Drawer, Descriptions, Timeline, Divider, Form, Tabs, Progress, Badge, DatePicker, Pagination
|
||||
} from 'antd';
|
||||
import {
|
||||
PlusOutlined, SearchOutlined, EditOutlined, EyeOutlined,
|
||||
ClockCircleOutlined, CheckCircleOutlined, PlayCircleOutlined,
|
||||
CloseCircleOutlined, ThunderboltOutlined, SettingOutlined,
|
||||
SendOutlined, PauseOutlined, ArrowRightOutlined, FileDoneOutlined,
|
||||
RobotOutlined, CloudOutlined, RiseOutlined,
|
||||
BranchesOutlined
|
||||
CheckOutlined, ClockCircleOutlined, ControlOutlined,
|
||||
BarChartOutlined, RiseOutlined, ArrowUpOutlined,
|
||||
SearchOutlined, PlusOutlined, EditOutlined, DeleteOutlined,
|
||||
EyeOutlined, CommentOutlined, PauseOutlined, FormOutlined,
|
||||
ReloadOutlined, FilterOutlined, MoreOutlined,
|
||||
CheckCircleFilled, PlayCircleFilled, InfoCircleFilled,
|
||||
RobotOutlined, ThunderboltOutlined, AlertOutlined
|
||||
} from '@ant-design/icons';
|
||||
import { Pie, Line, Bar } from '@ant-design/charts';
|
||||
import dayjs from 'dayjs';
|
||||
import { Pie, Line } from '@ant-design/charts';
|
||||
import {
|
||||
ClipboardList,
|
||||
Clock,
|
||||
Play,
|
||||
CheckCircle,
|
||||
Timer,
|
||||
Cpu,
|
||||
Calendar as CalendarIcon,
|
||||
ChevronRight,
|
||||
History,
|
||||
ExternalLink
|
||||
} from 'lucide-react';
|
||||
|
||||
const { Option } = Select;
|
||||
const { Search } = Input;
|
||||
const { Text, Title } = Typography;
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
// 模拟数据(完全匹配参考图)
|
||||
const workOrderList = [
|
||||
// 模拟数据
|
||||
const workOrderData = [
|
||||
{
|
||||
id: 'WO20250524001',
|
||||
title: '逆变器 INV-05 告警排查',
|
||||
source: 'AI诊断',
|
||||
type: '检修',
|
||||
priority: 'high',
|
||||
status: 'pending',
|
||||
handler: '李工',
|
||||
deadline: '2025-05-24 14:30',
|
||||
status: 'pending',
|
||||
description: ''
|
||||
},
|
||||
{
|
||||
id: 'WO20250524002',
|
||||
@@ -37,10 +49,9 @@ const workOrderList = [
|
||||
source: '无人机巡检',
|
||||
type: '巡检',
|
||||
priority: 'high',
|
||||
status: 'processing',
|
||||
handler: '王工',
|
||||
deadline: '2025-05-24 15:00',
|
||||
status: 'processing',
|
||||
description: '对AI识别热斑区域进行复检与红外复核,确认是否需要更换组件。'
|
||||
},
|
||||
{
|
||||
id: 'WO20250524003',
|
||||
@@ -48,10 +59,9 @@ const workOrderList = [
|
||||
source: '清洗优化',
|
||||
type: '清洗',
|
||||
priority: 'medium',
|
||||
status: 'dispatched',
|
||||
handler: '赵工',
|
||||
deadline: '2025-05-24 16:00',
|
||||
status: 'dispatched',
|
||||
description: ''
|
||||
},
|
||||
{
|
||||
id: 'WO20250524004',
|
||||
@@ -59,10 +69,9 @@ const workOrderList = [
|
||||
source: '视频监控',
|
||||
type: '维修',
|
||||
priority: 'medium',
|
||||
status: 'processing',
|
||||
handler: '陈工',
|
||||
deadline: '2025-05-24 17:30',
|
||||
status: 'processing',
|
||||
description: ''
|
||||
},
|
||||
{
|
||||
id: 'WO20250524005',
|
||||
@@ -70,10 +79,9 @@ const workOrderList = [
|
||||
source: '装备控制',
|
||||
type: '运维',
|
||||
priority: 'low',
|
||||
status: 'pending',
|
||||
handler: '刘工',
|
||||
deadline: '2025-05-24 18:00',
|
||||
status: 'pending',
|
||||
description: ''
|
||||
},
|
||||
{
|
||||
id: 'WO20250524006',
|
||||
@@ -81,78 +89,46 @@ const workOrderList = [
|
||||
source: '人工创建',
|
||||
type: '巡检',
|
||||
priority: 'medium',
|
||||
status: 'completed',
|
||||
handler: '张运维',
|
||||
deadline: '2025-05-24 21:00',
|
||||
status: 'completed',
|
||||
description: ''
|
||||
}
|
||||
];
|
||||
|
||||
// 工单状态配置
|
||||
const statusConfig = {
|
||||
pending: { label: '待处理', color: '#1890ff', icon: <ClockCircleOutlined /> },
|
||||
dispatched: { label: '已派发', color: '#52c41a', icon: <SendOutlined /> },
|
||||
processing: { label: '执行中', color: '#2f54eb', icon: <PlayCircleOutlined /> },
|
||||
suspended: { label: '挂起', color: '#faad14', icon: <PauseOutlined /> },
|
||||
completed: { label: '已完成', color: '#52c41a', icon: <CheckCircleOutlined /> },
|
||||
closed: { label: '已关闭', color: '#8c8c8c', icon: <CloseCircleOutlined /> }
|
||||
pending: { label: '待处理', color: '#52c41a', textColor: '#1890ff', bg: '#e6f7ff', border: '#91d5ff' },
|
||||
dispatched: { label: '已派发', color: '#52c41a', textColor: '#52c41a', bg: '#f6ffed', border: '#b7eb8f' },
|
||||
processing: { label: '执行中', color: '#1890ff', textColor: '#1890ff', bg: '#e6f7ff', border: '#91d5ff' },
|
||||
completed: { label: '已完成', color: '#52c41a', textColor: '#52c41a', bg: '#f6ffed', border: '#b7eb8f' },
|
||||
suspended: { label: '已挂起', color: '#faad14', textColor: '#faad14', bg: '#fff7e6', border: '#ffe7ba' }
|
||||
};
|
||||
|
||||
// 优先级配置
|
||||
const priorityConfig = {
|
||||
low: { label: '低', color: '#52c41a' },
|
||||
medium: { label: '中', color: '#faad14' },
|
||||
high: { label: '高', color: '#ff4d4f' },
|
||||
urgent: { label: '紧急', color: '#f5222d' }
|
||||
low: { label: '低', color: '#52c41a', bg: '#f6ffed' },
|
||||
medium: { label: '中', color: '#faad14', bg: '#fff7e6' },
|
||||
high: { label: '高', color: '#ff4d4f', bg: '#fff1f0' }
|
||||
};
|
||||
|
||||
// 统计卡片数据
|
||||
const overviewCards = [
|
||||
{ title: '今日新增工单', value: 18, suffix: '单', desc: '较昨日 +3', color: '#1890ff', icon: <FileDoneOutlined /> },
|
||||
{ title: '待处理工单', value: 12, suffix: '单', desc: '高优先级 5', color: '#ff4d4f', icon: <ClockCircleOutlined /> },
|
||||
{ title: '执行中工单', value: 9, suffix: '单', desc: '按时率 92%', color: '#52c41a', icon: <PlayCircleOutlined /> },
|
||||
{ title: '已完成工单', value: 126, suffix: '单', desc: '本月累计', color: '#52c41a', icon: <CheckCircleOutlined /> },
|
||||
{ title: '平均处理时长', value: 4.3, suffix: '小时', desc: '较上周 -12% ↓', color: '#1890ff', icon: <ClockCircleOutlined /> },
|
||||
{ title: 'AI建议生成', value: 7, suffix: '单', desc: '今日自动生成', color: '#722ed1', icon: <RobotOutlined /> }
|
||||
];
|
||||
const WorkOrderPage = () => {
|
||||
const [activeTab, setActiveTab] = useState('1');
|
||||
const [selectedRowKey, setSelectedRowKey] = useState('WO20250524002');
|
||||
|
||||
// 任务排班数据
|
||||
const scheduleData = [
|
||||
{ handler: '李工', tasks: [{ title: 'INV-05 告警排查', time: '08:30 - 12:00', type: 'alarm' }] },
|
||||
{ handler: '王工', tasks: [{ title: 'B-12 热斑复检', time: '13:30 - 15:00', type: 'inspect' }] },
|
||||
{ handler: '赵工', tasks: [{ title: '组件清洗 C-05', time: '09:00 - 12:00', type: 'clean' }, { title: '清洗效果复检', time: '15:00 - 17:00', type: 'clean' }] },
|
||||
{ handler: '陈工', tasks: [{ title: '周界摄像头修复', time: '10:00 - 12:30', type: 'repair' }, { title: '设备巡检', time: '15:30 - 17:30', type: 'inspect' }] }
|
||||
];
|
||||
// 统计数据
|
||||
const stats = [
|
||||
{ title: '今日新增工单', value: 18, subValue: '+3', subText: '较昨日', icon: <ClipboardList size={24} color="#1890ff" />, bg: '#e6f7ff' },
|
||||
{ title: '待处理工单', value: 12, subValue: '5', subText: '高优先级', icon: <Clock size={24} color="#ff4d4f" />, bg: '#fff1f0' },
|
||||
{ title: '执行中工单', value: 9, subValue: '92%', subText: '按时率', icon: <Play size={24} color="#52c41a" />, bg: '#f6ffed' },
|
||||
{ title: '已完成工单', value: 126, subValue: '', subText: '本月累计', icon: <CheckCircle size={24} color="#52c41a" />, bg: '#f6ffed' },
|
||||
{ title: '平均处理时长', value: 4.3, unit: '小时', subValue: '-12%', subText: '较上周', icon: <Timer size={24} color="#1890ff" />, bg: '#e6f7ff' },
|
||||
{ title: 'AI建议生成', value: 7, unit: '单', subValue: '', subText: '今日自动生成', icon: <Cpu size={24} color="#722ed1" />, bg: '#f9f0ff' },
|
||||
];
|
||||
|
||||
// 告警趋势数据
|
||||
const alarmTrendData = [
|
||||
{ date: '05-18', count: 5 },
|
||||
{ date: '05-19', count: 10 },
|
||||
{ date: '05-20', count: 5 },
|
||||
{ date: '05-21', count: 5 },
|
||||
{ date: '05-22', count: 12 },
|
||||
{ date: '05-23', count: 10 },
|
||||
{ date: '05-24', count: 12 }
|
||||
];
|
||||
|
||||
// 告警列表数据
|
||||
const alarmList = [
|
||||
{ name: 'INV-05 逆变器告警', time: '05-24 10:24' },
|
||||
{ name: 'B-12 区块热斑告警', time: '05-24 09:56' },
|
||||
{ name: 'B-12 组件温度异常', time: '05-24 09:32' }
|
||||
];
|
||||
|
||||
export default function WorkOrderPage() {
|
||||
const [selectedOrder, setSelectedOrder] = useState(workOrderList[1]); // 默认选中执行中的工单
|
||||
const [drawerVisible, setDrawerVisible] = useState(false);
|
||||
const [editModalVisible, setEditModalVisible] = useState(false);
|
||||
const [editingOrder, setEditingOrder] = useState(null);
|
||||
const [editForm] = Form.useForm();
|
||||
|
||||
// 表格列定义
|
||||
// 表格列
|
||||
const columns = [
|
||||
{ title: '工单编号', dataIndex: 'id', key: 'id', width: 140 },
|
||||
{ title: '工单标题', dataIndex: 'title', key: 'title' },
|
||||
{ title: '工单编号', dataIndex: 'id', key: 'id', width: 130 },
|
||||
{ title: '工单标题', dataIndex: 'title', key: 'title', width: 180, ellipsis: true },
|
||||
{ title: '来源', dataIndex: 'source', key: 'source', width: 100 },
|
||||
{ title: '类型', dataIndex: 'type', key: 'type', width: 80 },
|
||||
{
|
||||
@@ -160,62 +136,89 @@ export default function WorkOrderPage() {
|
||||
dataIndex: 'priority',
|
||||
key: 'priority',
|
||||
width: 80,
|
||||
render: (priority) => (
|
||||
<Tag color={priorityConfig[priority]?.color} style={{ borderRadius: 4 }}>
|
||||
{priorityConfig[priority]?.label}
|
||||
render: (p) => (
|
||||
<Tag color={priorityConfig[p].bg} style={{ color: priorityConfig[p].color, border: `1px solid ${priorityConfig[p].color}`, borderRadius: 4 }}>
|
||||
{priorityConfig[p].label}
|
||||
</Tag>
|
||||
)
|
||||
},
|
||||
{ title: '负责人', dataIndex: 'handler', key: 'handler', width: 80 },
|
||||
{ title: '截止时间', dataIndex: 'deadline', key: 'deadline', width: 160 },
|
||||
{ title: '截止时间', dataIndex: 'deadline', key: 'deadline', width: 150 },
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
width: 100,
|
||||
render: (status) => (
|
||||
<Tag color={statusConfig[status]?.color} style={{ borderRadius: 4 }}>
|
||||
{statusConfig[status]?.label}
|
||||
</Tag>
|
||||
width: 90,
|
||||
render: (s) => (
|
||||
<span style={{ color: statusConfig[s].textColor }}>{statusConfig[s].label}</span>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 80,
|
||||
render: (_, record) => (
|
||||
<Button type="link" size="small" onClick={() => { setSelectedOrder(record); setDrawerVisible(true); }}>
|
||||
查看
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
width: 60,
|
||||
render: () => <Button type="link" size="small">查看</Button>
|
||||
},
|
||||
];
|
||||
|
||||
// 工单状态分布饼图数据
|
||||
// 图表数据
|
||||
const pieData = [
|
||||
{ type: '待处理', value: 12, color: '#1890ff' },
|
||||
{ type: '执行中', value: 9, color: '#2f54eb' },
|
||||
{ type: '已完成', value: 126, color: '#52c41a' },
|
||||
{ type: '已挂起', value: 4, color: '#faad14' }
|
||||
{ type: '待处理', value: 12 },
|
||||
{ type: '执行中', value: 9 },
|
||||
{ type: '已完成', value: 126 },
|
||||
{ type: '已挂起', value: 4 },
|
||||
];
|
||||
|
||||
const alarmTrendData = [
|
||||
{ date: '05-18', value: 5 },
|
||||
{ date: '05-19', value: 10 },
|
||||
{ date: '05-20', value: 7 },
|
||||
{ date: '05-21', value: 12 },
|
||||
{ date: '05-22', value: 8 },
|
||||
{ date: '05-23', value: 15 },
|
||||
{ date: '05-24', value: 11 },
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ padding: 20, background: '#f5f7fa', minHeight: '100vh' }}>
|
||||
{/* 顶部统计卡片 */}
|
||||
<Row gutter={16} style={{ marginBottom: 20 }}>
|
||||
{overviewCards.map((card, idx) => (
|
||||
<Col span={4} key={idx}>
|
||||
<Card bordered={false} style={{ borderRadius: 8, height: 120 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div style={{ padding: '16px 24px', background: '#f0f2f5', minHeight: '100vh' }}>
|
||||
{/* 顶部标题和页签 */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 16 }}>
|
||||
<Title level={4} style={{ margin: '0 32px 0 0' }}>工单任务</Title>
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
items={[
|
||||
{ key: '1', label: '工单总览' },
|
||||
{ key: '2', label: '待处理工单' },
|
||||
{ key: '3', label: '执行中' },
|
||||
{ key: '4', label: '已完成' },
|
||||
{ key: '5', label: '工单模板' },
|
||||
]}
|
||||
tabBarStyle={{ marginBottom: 0 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 统计卡片 */}
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
{stats.map((item, index) => (
|
||||
<Col span={4} key={index}>
|
||||
<Card bordered={false} bodyStyle={{ padding: '16px' }} style={{ borderRadius: 8 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div>
|
||||
<div style={{ fontSize: 14, color: '#666' }}>{card.title}</div>
|
||||
<div style={{ fontSize: 28, fontWeight: 700, color: card.color, margin: '8px 0' }}>
|
||||
{card.value} <span style={{ fontSize: 14, fontWeight: 400 }}>{card.suffix}</span>
|
||||
<Text type="secondary" style={{ fontSize: 13 }}>{item.title}</Text>
|
||||
<div style={{ margin: '4px 0' }}>
|
||||
<Text style={{ fontSize: 24, fontWeight: 'bold' }}>{item.value}</Text>
|
||||
{item.unit && <Text style={{ fontSize: 14, marginLeft: 4 }}>{item.unit}</Text>}
|
||||
</div>
|
||||
<div style={{ fontSize: 12 }}>
|
||||
<Text type="secondary">{item.subText}</Text>
|
||||
<Text style={{ marginLeft: 4, color: item.subValue.startsWith('+') ? '#52c41a' : item.subValue.startsWith('-') ? '#ff4d4f' : '#1890ff', fontWeight: 'bold' }}>
|
||||
{item.subValue}
|
||||
</Text>
|
||||
</div>
|
||||
<div style={{ fontSize: 12, color: '#999' }}>{card.desc}</div>
|
||||
</div>
|
||||
<div style={{ width: 48, height: 48, borderRadius: '50%', background: `${card.color}15`, display: 'flex', alignItems: 'center', justifyContent: 'center', color: card.color, fontSize: 20 }}>
|
||||
{card.icon}
|
||||
<div style={{ width: 48, height: 48, borderRadius: '50%', background: item.bg, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
{item.icon}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
@@ -224,109 +227,151 @@ export default function WorkOrderPage() {
|
||||
</Row>
|
||||
|
||||
{/* 筛选栏 */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 20, gap: 16, flexWrap: 'wrap' }}>
|
||||
<Select placeholder="工单类型" style={{ width: 120 }} defaultValue="all">
|
||||
<Option value="all">全部</Option>
|
||||
<Option value="inspect">巡检</Option>
|
||||
<Option value="repair">维修</Option>
|
||||
<Option value="clean">清洗</Option>
|
||||
</Select>
|
||||
<Select placeholder="优先级" style={{ width: 120 }} defaultValue="all">
|
||||
<Option value="all">全部</Option>
|
||||
<Option value="high">高</Option>
|
||||
<Option value="medium">中</Option>
|
||||
<Option value="low">低</Option>
|
||||
</Select>
|
||||
<Select placeholder="负责人" style={{ width: 120 }} defaultValue="all">
|
||||
<Option value="all">全部</Option>
|
||||
<Option value="李工">李工</Option>
|
||||
<Option value="王工">王工</Option>
|
||||
<Option value="赵工">赵工</Option>
|
||||
</Select>
|
||||
<Space>
|
||||
<span>时间范围</span>
|
||||
<Input style={{ width: 180 }} value="2025-05-24 ~ 2025-05-24" readOnly />
|
||||
</Space>
|
||||
<Select placeholder="状态" style={{ width: 120 }} defaultValue="all">
|
||||
<Option value="all">全部</Option>
|
||||
<Option value="pending">待处理</Option>
|
||||
<Option value="processing">执行中</Option>
|
||||
<Option value="completed">已完成</Option>
|
||||
</Select>
|
||||
<Input placeholder="请输入工单编号/标题" style={{ width: 240 }} prefix={<SearchOutlined />} />
|
||||
<Space>
|
||||
<Button>重置</Button>
|
||||
<Button type="primary">查询</Button>
|
||||
</Space>
|
||||
</div>
|
||||
<Card bordered={false} bodyStyle={{ padding: '12px 16px' }} style={{ borderRadius: 8, marginBottom: 16 }}>
|
||||
<Row gutter={16} align="middle">
|
||||
<Col span={3}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Text style={{ marginRight: 8, whiteSpace: 'nowrap' }}>工单类型</Text>
|
||||
<Select defaultValue="all" style={{ width: '100%' }}>
|
||||
<Option value="all">全部</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={3}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Text style={{ marginRight: 8, whiteSpace: 'nowrap' }}>优先级</Text>
|
||||
<Select defaultValue="all" style={{ width: '100%' }}>
|
||||
<Option value="all">全部</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={3}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Text style={{ marginRight: 8, whiteSpace: 'nowrap' }}>负责人</Text>
|
||||
<Select defaultValue="all" style={{ width: '100%' }}>
|
||||
<Option value="all">全部</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Text style={{ marginRight: 8, whiteSpace: 'nowrap' }}>时间范围</Text>
|
||||
<RangePicker style={{ width: '100%' }} />
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={3}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Text style={{ marginRight: 8, whiteSpace: 'nowrap' }}>状态</Text>
|
||||
<Select defaultValue="all" style={{ width: '100%' }}>
|
||||
<Option value="all">全部</Option>
|
||||
</Select>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Text style={{ marginRight: 8, whiteSpace: 'nowrap' }}>关键词</Text>
|
||||
<Input placeholder="请输入工单编号/标题" suffix={<SearchOutlined />} />
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={3} style={{ textAlign: 'right' }}>
|
||||
<Space>
|
||||
<Button>重置</Button>
|
||||
<Button type="primary">查询</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<Row gutter={16}>
|
||||
{/* 左侧工单列表 */}
|
||||
<Col span={14}>
|
||||
<Card bordered={false} style={{ borderRadius: 8, marginBottom: 20 }} title="工单列表(共 147 条)">
|
||||
{/* 左侧:列表 + 底部图表 */}
|
||||
<Col span={15}>
|
||||
<Card
|
||||
bordered={false}
|
||||
title={<div style={{ display: 'flex', alignItems: 'center' }}><Text strong style={{ fontSize: 16 }}>工单列表</Text><Text type="secondary" style={{ fontSize: 12, marginLeft: 8 }}>(共 147 条)</Text></div>}
|
||||
bodyStyle={{ padding: 0 }}
|
||||
style={{ borderRadius: 8, marginBottom: 16 }}
|
||||
>
|
||||
<Table
|
||||
rowKey="id"
|
||||
dataSource={workOrderData}
|
||||
columns={columns}
|
||||
dataSource={workOrderList}
|
||||
pagination={{ pageSize: 15, showSizeChanger: true, showTotal: (total) => `共 ${total} 条` }}
|
||||
pagination={false}
|
||||
size="middle"
|
||||
rowKey="id"
|
||||
scroll={{ x: 'max-content' }}
|
||||
rowClassName={(record) => record.id === selectedOrder?.id ? 'selected-row' : ''}
|
||||
onRow={(record) => ({ onClick: () => setSelectedOrder(record) })}
|
||||
rowSelection={{
|
||||
type: 'radio',
|
||||
selectedRowKeys: [selectedRowKey],
|
||||
onChange: (keys) => setSelectedRowKey(keys[0] as string)
|
||||
}}
|
||||
/>
|
||||
<style>{`
|
||||
.selected-row { background-color: #e6f7ff !important; }
|
||||
`}</style>
|
||||
<div style={{ padding: '16px', textAlign: 'right' }}>
|
||||
<Pagination size="small" total={147} showSizeChanger showQuickJumper />
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* 工单状态分布 + 任务排班 */}
|
||||
<Row gutter={16}>
|
||||
<Col span={8}>
|
||||
<Card bordered={false} style={{ borderRadius: 8 }} title="工单状态分布">
|
||||
<Pie
|
||||
data={pieData}
|
||||
angleField="value"
|
||||
colorField="type"
|
||||
color={['#1890ff', '#2f54eb', '#52c41a', '#faad14']}
|
||||
radius={0.8}
|
||||
innerRadius={0.6}
|
||||
height={180}
|
||||
label={{
|
||||
formatter: (datum) => `${datum.value} (${((datum.value / 147) * 100).toFixed(2)}%)`
|
||||
}}
|
||||
interactions={[{ type: 'pie-legend-active' }]}
|
||||
/>
|
||||
<div style={{ textAlign: 'center', marginTop: -120 }}>
|
||||
<div style={{ fontSize: 16, fontWeight: 600 }}>总数</div>
|
||||
<div style={{ fontSize: 24, fontWeight: 700 }}>147</div>
|
||||
<Col span={10}>
|
||||
<Card bordered={false} title="工单状态分布" style={{ borderRadius: 8, height: 360 }}>
|
||||
<div style={{ height: 280, position: 'relative' }}>
|
||||
<Pie
|
||||
data={pieData}
|
||||
angleField="value"
|
||||
colorField="type"
|
||||
radius={1}
|
||||
innerRadius={0.6}
|
||||
label={false}
|
||||
legend={{
|
||||
position: 'right',
|
||||
layout: 'vertical',
|
||||
itemValueLabel: {
|
||||
formatter: (text, item) => {
|
||||
const total = pieData.reduce((a, b) => a + b.value, 0);
|
||||
const percent = ((item.value / total) * 100).toFixed(2);
|
||||
return `${item.value} (${percent}%)`;
|
||||
}
|
||||
}
|
||||
}}
|
||||
height={240}
|
||||
/>
|
||||
<div style={{ position: 'absolute', top: '42%', left: '30%', textAlign: 'center', transform: 'translate(-50%, -50%)' }}>
|
||||
<div style={{ fontSize: 14, color: '#8c8c8c' }}>总数</div>
|
||||
<div style={{ fontSize: 24, fontWeight: 'bold' }}>147</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={16}>
|
||||
<Card bordered={false} style={{ borderRadius: 8 }} title={<div style={{ display: 'flex', justifyContent: 'space-between' }}><span>任务排班 / 日历视图</span><Button type="link">更多 </Button></div>}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 16 }}>
|
||||
<Button type="text" icon={<ArrowRightOutlined style={{ transform: 'rotate(180deg)' }} />} />
|
||||
<span style={{ margin: '0 16px' }}>2025-05-24 (今天)</span>
|
||||
<Button type="text" icon={<ArrowRightOutlined />} />
|
||||
<Col span={14}>
|
||||
<Card
|
||||
bordered={false}
|
||||
title="任务排班 / 日历视图"
|
||||
extra={<Button type="link" size="small">更多 <ChevronRight size={14} /></Button>}
|
||||
style={{ borderRadius: 8, height: 360 }}
|
||||
>
|
||||
<div style={{ marginBottom: 12 }}>
|
||||
<Space>
|
||||
<Button size="small" icon={<ChevronRight style={{ transform: 'rotate(180deg)' }} size={14} />} />
|
||||
<Text strong>2025-05-24 (今天)</Text>
|
||||
<Button size="small" icon={<ChevronRight size={14} />} />
|
||||
</Space>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
||||
{scheduleData.map((item, idx) => (
|
||||
<div key={idx} style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
<div style={{ width: 60, textAlign: 'right' }}>{item.handler}</div>
|
||||
<div style={{ flex: 1, display: 'flex', gap: 16, height: 40, alignItems: 'center', position: 'relative' }}>
|
||||
<div style={{ position: 'absolute', left: 0, right: 0, height: 1, background: '#e8e8e8', zIndex: 0 }} />
|
||||
{item.tasks.map((task, i) => (
|
||||
<div key={i} style={{
|
||||
background: task.type === 'alarm' ? '#e6ffed' : task.type === 'inspect' ? '#e6f7ff' : task.type === 'clean' ? '#f9f0ff' : '#fff7e6',
|
||||
border: '1px solid #d9d9d9',
|
||||
borderRadius: 4,
|
||||
padding: '4px 8px',
|
||||
fontSize: 12,
|
||||
zIndex: 1
|
||||
}}>
|
||||
<div>{task.title}</div>
|
||||
<div style={{ color: '#666' }}>{task.time}</div>
|
||||
</div>
|
||||
))}
|
||||
<div style={{ border: '1px solid #f0f0f0', borderRadius: 4, overflow: 'hidden' }}>
|
||||
<div style={{ display: 'flex', background: '#fafafa', borderBottom: '1px solid #f0f0f0' }}>
|
||||
<div style={{ width: 60, padding: '8px', borderRight: '1px solid #f0f0f0' }}></div>
|
||||
{['08:00', '10:00', '12:00', '14:00', '16:00', '18:00'].map(t => (
|
||||
<div key={t} style={{ flex: 1, padding: '8px', textAlign: 'center', fontSize: 12 }}>{t}</div>
|
||||
))}
|
||||
</div>
|
||||
{['李工', '王工', '赵工', '陈工'].map((name, idx) => (
|
||||
<div key={name} style={{ display: 'flex', borderBottom: idx === 3 ? 'none' : '1px solid #f0f0f0', height: 50, position: 'relative' }}>
|
||||
<div style={{ width: 60, padding: '8px', borderRight: '1px solid #f0f0f0', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12 }}>{name}</div>
|
||||
<div style={{ flex: 1, position: 'relative' }}>
|
||||
{idx === 0 && <div style={{ position: 'absolute', left: '10%', top: 5, width: '40%', height: 40, background: '#f6ffed', border: '1px solid #b7eb8f', borderRadius: 4, padding: '2px 8px', fontSize: 10 }}>INV-05 告警排查<br />08:30 - 12:00</div>}
|
||||
{idx === 1 && <div style={{ position: 'absolute', left: '55%', top: 5, width: '30%', height: 40, background: '#e6f7ff', border: '1px solid #91d5ff', borderRadius: 4, padding: '2px 8px', fontSize: 10 }}>B-12 热斑复检<br />13:30 - 15:00</div>}
|
||||
{idx === 1 && <div style={{ position: 'absolute', left: '86%', top: 5, width: '12%', height: 40, background: '#f0f5ff', border: '1px solid #adc6ff', borderRadius: 4, borderStyle: 'dashed', padding: '2px 4px', fontSize: 10 }}>无人机巡检<br />16:00-18:00</div>}
|
||||
{idx === 2 && <div style={{ position: 'absolute', left: '20%', top: 5, width: '35%', height: 40, background: '#f9f0ff', border: '1px solid #d3adf7', borderRadius: 4, padding: '2px 8px', fontSize: 10 }}>组件清洗 C-05<br />09:00 - 12:00</div>}
|
||||
{idx === 2 && <div style={{ position: 'absolute', left: '70%', top: 5, width: '25%', height: 40, background: '#fff7e6', border: '1px solid #ffe7ba', borderRadius: 4, padding: '2px 8px', fontSize: 10 }}>清洗效果复检<br />15:00 - 17:00</div>}
|
||||
{idx === 3 && <div style={{ position: 'absolute', left: '30%', top: 5, width: '30%', height: 40, background: '#fff2e8', border: '1px solid #ffbb96', borderRadius: 4, padding: '2px 8px', fontSize: 10 }}>周界摄像头修复<br />10:00 - 12:30</div>}
|
||||
{idx === 3 && <div style={{ position: 'absolute', left: '75%', top: 5, width: '20%', height: 40, background: '#fffbe6', border: '1px solid #ffe58f', borderRadius: 4, padding: '2px 8px', fontSize: 10 }}>设备巡检<br />15:30 - 17:30</div>}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
@@ -336,177 +381,145 @@ export default function WorkOrderPage() {
|
||||
</Row>
|
||||
</Col>
|
||||
|
||||
{/* 右侧工单详情面板 */}
|
||||
<Col span={10}>
|
||||
<Card bordered={false} style={{ borderRadius: 8, marginBottom: 16 }} title={
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div>
|
||||
<Title level={5} style={{ margin: 0 }}>{selectedOrder?.title}</Title>
|
||||
<Tag color="red" size="small">高优先级</Tag>
|
||||
</div>
|
||||
<Text type="secondary">工单编号: {selectedOrder?.id}</Text>
|
||||
</div>
|
||||
}>
|
||||
<Row gutter={16} style={{ marginBottom: 16 }}>
|
||||
<Col span={12}><div style={{ display: 'flex', justifyContent: 'space-between' }}><span>来源:</span><span>{selectedOrder?.source}</span></div></Col>
|
||||
<Col span={12}><div style={{ display: 'flex', justifyContent: 'space-between' }}><span>工单类型:</span><span>{selectedOrder?.type}</span></div></Col>
|
||||
<Col span={12}><div style={{ display: 'flex', justifyContent: 'space-between' }}><span>负责人:</span><span>{selectedOrder?.handler}</span></div></Col>
|
||||
<Col span={12}><div style={{ display: 'flex', justifyContent: 'space-between' }}><span>协同人员:</span><span>无人机A01 / 张运维</span></div></Col>
|
||||
<Col span={12}><div style={{ display: 'flex', justifyContent: 'space-between' }}><span>计划时间:</span><span>2025-05-24 13:30 ~ 15:00</span></div></Col>
|
||||
<Col span={12}><div style={{ display: 'flex', justifyContent: 'space-between' }}><span>关联区域:</span><span>B-12</span></div></Col>
|
||||
<Col span={12}><div style={{ display: 'flex', justifyContent: 'space-between' }}><span>关联设备:</span><span>UAV-A01</span></div></Col>
|
||||
<Col span={12}><div style={{ display: 'flex', justifyContent: 'space-between' }}><span>当前状态:</span><Tag color="blue">执行中</Tag></div></Col>
|
||||
</Row>
|
||||
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<div style={{ fontSize: 14, fontWeight: 500, marginBottom: 8 }}>任务描述</div>
|
||||
<div style={{ fontSize: 13, color: '#666', background: '#fafafa', padding: 12, borderRadius: 4 }}>
|
||||
{selectedOrder?.description}
|
||||
</div>
|
||||
{/* 右侧:详情 + AI + 告警 */}
|
||||
<Col span={9}>
|
||||
<Card
|
||||
bordered={false}
|
||||
style={{ borderRadius: 8, marginBottom: 16 }}
|
||||
bodyStyle={{ padding: '16px' }}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
|
||||
<Text strong style={{ fontSize: 16 }}>工单详情</Text>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>工单编号: WO20250524002</Text>
|
||||
</div>
|
||||
|
||||
{/* 流程步骤 */}
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24, padding: '0 20px' }}>
|
||||
{['已创建', '已派发', '执行中', '已完成'].map((step, idx) => (
|
||||
<div key={idx} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
||||
<div style={{
|
||||
width: 24, height: 24, borderRadius: '50%', background: idx < 3 ? '#1890ff' : '#d9d9d9',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontSize: 12
|
||||
}}>
|
||||
{idx + 1}
|
||||
</div>
|
||||
<div style={{ fontSize: 12, marginTop: 4 }}>{step}</div>
|
||||
<div style={{ marginBottom: 20 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 8 }}>
|
||||
<Title level={4} style={{ margin: '0 12px 0 0' }}>区块 B-12 热斑复检</Title>
|
||||
<Tag color="#fff1f0" style={{ color: '#ff4d4f', border: '1px solid #ff4d4f' }}>高优先级</Tag>
|
||||
</div>
|
||||
|
||||
<Row gutter={[0, 12]}>
|
||||
<Col span={12}><Text type="secondary">来源:</Text><Text>无人机巡检</Text></Col>
|
||||
<Col span={12}><Text type="secondary">工单类型:</Text><Text>巡检</Text></Col>
|
||||
<Col span={12}><Text type="secondary">负责人:</Text><Text>王工</Text></Col>
|
||||
<Col span={12}><Text type="secondary">协同人员:</Text><Text>无人机 A01 / 张运维</Text></Col>
|
||||
<Col span={24}><Text type="secondary">计划时间:</Text><Text>2025-05-24 13:30 - 15:00</Text></Col>
|
||||
<Col span={12}><Text type="secondary">关联设备:</Text><Text style={{ color: '#1890ff' }}>UAV-A01</Text></Col>
|
||||
<Col span={12}><Text type="secondary">关联区域:</Text><Text>B-12</Text></Col>
|
||||
<Col span={24}><Text type="secondary">当前状态:</Text><Tag color="blue" style={{ borderRadius: 10 }}>执行中</Tag></Col>
|
||||
<Col span={24}>
|
||||
<Text type="secondary">任务描述:</Text>
|
||||
<Text>对 AI 识别热斑区域进行复检与红外复核,确认是否需要更换组件。</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<div style={{ marginBottom: 24 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', padding: '0 10px', marginBottom: 8 }}>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<CheckCircleFilled style={{ color: '#52c41a', fontSize: 20 }} />
|
||||
<div style={{ fontSize: 12, marginTop: 4 }}>已创建</div>
|
||||
</div>
|
||||
))}
|
||||
<div style={{ position: 'absolute', width: 'calc(100% - 120px)', height: 2, background: '#e8e8e8', left: 60, top: 100, zIndex: 0 }} />
|
||||
<div style={{ flex: 1, height: 2, background: '#52c41a', marginTop: 10 }}></div>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<CheckCircleFilled style={{ color: '#52c41a', fontSize: 20 }} />
|
||||
<div style={{ fontSize: 12, marginTop: 4 }}>已派发</div>
|
||||
</div>
|
||||
<div style={{ flex: 1, height: 2, background: '#1890ff', marginTop: 10 }}></div>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{ width: 20, height: 20, borderRadius: '50%', background: '#1890ff', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12 }}>3</div>
|
||||
<div style={{ fontSize: 12, marginTop: 4 }}>执行中</div>
|
||||
</div>
|
||||
<div style={{ flex: 1, height: 2, background: '#f0f0f0', marginTop: 10 }}></div>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{ width: 20, height: 20, borderRadius: '50%', border: '1px solid #d9d9d9', color: '#d9d9d9', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12 }}>4</div>
|
||||
<div style={{ fontSize: 12, marginTop: 4, color: '#d9d9d9' }}>已完成</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
||||
<Button type="primary">派发文单</Button>
|
||||
<Button>转派</Button>
|
||||
<Button>挂起</Button>
|
||||
<Button type="primary" style={{ background: '#52c41a', borderColor: '#52c41a' }}>完成工单</Button>
|
||||
</div>
|
||||
<Row gutter={8}>
|
||||
<Col span={6}><Button type="primary" block>派发工单</Button></Col>
|
||||
<Col span={6}><Button icon={<ReloadOutlined />} block>转派</Button></Col>
|
||||
<Col span={6}><Button icon={<PauseOutlined />} danger ghost block>挂起</Button></Col>
|
||||
<Col span={6}><Button icon={<CheckOutlined />} style={{ background: '#52c41a', color: '#fff', border: 'none' }} block>完成工单</Button></Col>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
{/* AI建议与关联信息 */}
|
||||
<Card bordered={false} style={{ borderRadius: 8 }} title="AI建议与关联信息">
|
||||
<div style={{ display: 'flex', gap: 16, marginBottom: 16 }}>
|
||||
<div style={{ flex: 1, background: '#f0f5ff', padding: 12, borderRadius: 8 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
|
||||
<div style={{ width: 32, height: 32, borderRadius: 4, background: '#e6f7ff', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#1890ff' }}>
|
||||
<CloudOutlined />
|
||||
</div>
|
||||
<div style={{ fontSize: 13, fontWeight: 500 }}>建议携带红外热像设备</div>
|
||||
<Card
|
||||
bordered={false}
|
||||
title={<div style={{ display: 'flex', alignItems: 'center' }}><Text strong>AI 建议与关联信息</Text></div>}
|
||||
style={{ borderRadius: 8, marginBottom: 16 }}
|
||||
bodyStyle={{ padding: '12px' }}
|
||||
>
|
||||
<Row gutter={8}>
|
||||
<Col span={8}>
|
||||
<div style={{ background: '#f9f0ff', padding: '12px 8px', borderRadius: 8, textAlign: 'center' }}>
|
||||
<RobotOutlined style={{ fontSize: 20, color: '#722ed1', marginBottom: 8 }} />
|
||||
<div style={{ fontSize: 12 }}>建议携带</div>
|
||||
<div style={{ fontSize: 12, fontWeight: 'bold' }}>红外热像设备</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ flex: 1, background: '#f6ffed', padding: 12, borderRadius: 8 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
|
||||
<div style={{ width: 32, height: 32, borderRadius: 4, background: '#e6ffed', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#52c41a' }}>
|
||||
<BranchesOutlined />
|
||||
</div>
|
||||
<div style={{ fontSize: 13, fontWeight: 500 }}>优先复检组件 B-12-03 / B-12-05</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div style={{ background: '#f6ffed', padding: '12px 8px', borderRadius: 8, textAlign: 'center' }}>
|
||||
<ThunderboltOutlined style={{ fontSize: 20, color: '#52c41a', marginBottom: 8 }} />
|
||||
<div style={{ fontSize: 12 }}>优先复检组件</div>
|
||||
<div style={{ fontSize: 10, fontWeight: 'bold' }}>B-12-03 / B-12-05</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ flex: 1, background: '#fff7e6', padding: 12, borderRadius: 8 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
|
||||
<div style={{ width: 32, height: 32, borderRadius: 4, background: '#fff7e6', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fa8c16' }}>
|
||||
<ThunderboltOutlined />
|
||||
</div>
|
||||
<div style={{ fontSize: 13, fontWeight: 500 }}>预计影响发电 2.1%</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div style={{ background: '#fff7e6', padding: '12px 8px', borderRadius: 8, textAlign: 'center' }}>
|
||||
<RiseOutlined style={{ fontSize: 20, color: '#faad14', marginBottom: 8 }} />
|
||||
<div style={{ fontSize: 12 }}>预计影响发电</div>
|
||||
<div style={{ fontSize: 12, fontWeight: 'bold' }}>2.1%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<div style={{ fontSize: 14, fontWeight: 500, marginBottom: 8 }}>关联告警趋势(近7天)</div>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Card bordered={false} title="关联告警趋势 (近 7 天)" style={{ borderRadius: 8 }}>
|
||||
<Line
|
||||
data={alarmTrendData}
|
||||
xField="date"
|
||||
yField="count"
|
||||
color="#1890ff"
|
||||
point={{ size: 4 }}
|
||||
height={120}
|
||||
legend={false}
|
||||
yField="value"
|
||||
smooth
|
||||
point={{ size: 4, shape: 'circle' }}
|
||||
height={120}
|
||||
padding="auto"
|
||||
xAxis={{ label: { style: { fontSize: 10 } } }}
|
||||
yAxis={{ label: { style: { fontSize: 10 } } }}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
|
||||
<span style={{ fontSize: 14, fontWeight: 500 }}>关联告警列表(近3条)</span>
|
||||
<Button type="link" size="small">查看全部 </Button>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Card bordered={false} title="关联告警列表 (近 3 条)" extra={<Button type="link" size="small" style={{ fontSize: 12 }}>查看全部 <ChevronRight size={12} /></Button>} style={{ borderRadius: 8 }}>
|
||||
<div style={{ fontSize: 12 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 8 }}>
|
||||
<Badge status="error" style={{ marginRight: 8 }} />
|
||||
<Text ellipsis style={{ flex: 1 }}>INV-05 逆变器告警</Text>
|
||||
<Text type="secondary" style={{ fontSize: 10 }}>05-24 10:24</Text>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 8 }}>
|
||||
<Badge status="warning" style={{ marginRight: 8 }} />
|
||||
<Text ellipsis style={{ flex: 1 }}>B-12 区块热斑告警</Text>
|
||||
<Text type="secondary" style={{ fontSize: 10 }}>05-24 09:56</Text>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Badge status="warning" style={{ marginRight: 8 }} />
|
||||
<Text ellipsis style={{ flex: 1 }}>B-12 组件温度异常</Text>
|
||||
<Text type="secondary" style={{ fontSize: 10 }}>05-24 09:32</Text>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
||||
{alarmList.map((alarm, idx) => (
|
||||
<div key={idx} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '4px 8px', background: '#fafafa', borderRadius: 4 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<div style={{ width: 8, height: 8, borderRadius: '50%', background: idx === 0 ? '#ff4d4f' : idx === 1 ? '#fa8c16' : '#faad14' }} />
|
||||
<span style={{ fontSize: 13 }}>{alarm.name}</span>
|
||||
</div>
|
||||
<span style={{ fontSize: 12, color: '#999' }}>{alarm.time}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/* 工单详情抽屉 */}
|
||||
<Drawer
|
||||
title="工单详情"
|
||||
placement="right"
|
||||
width={600}
|
||||
onClose={() => setDrawerVisible(false)}
|
||||
open={drawerVisible}
|
||||
destroyOnClose
|
||||
>
|
||||
{selectedOrder && (
|
||||
<div>
|
||||
<Descriptions column={2} bordered size="small" title="基础信息">
|
||||
<Descriptions.Item label="工单编号">{selectedOrder.id}</Descriptions.Item>
|
||||
<Descriptions.Item label="状态">{statusConfig[selectedOrder.status]?.label}</Descriptions.Item>
|
||||
<Descriptions.Item label="标题">{selectedOrder.title}</Descriptions.Item>
|
||||
<Descriptions.Item label="优先级">
|
||||
<Tag color={priorityConfig[selectedOrder.priority]?.color}>{priorityConfig[selectedOrder.priority]?.label}</Tag>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="来源">{selectedOrder.source}</Descriptions.Item>
|
||||
<Descriptions.Item label="类型">{selectedOrder.type}</Descriptions.Item>
|
||||
<Descriptions.Item label="负责人">{selectedOrder.handler || '—'}</Descriptions.Item>
|
||||
<Descriptions.Item label="截止时间">{selectedOrder.deadline}</Descriptions.Item>
|
||||
<Descriptions.Item label="描述" span={2}>{selectedOrder.description || '—'}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</div>
|
||||
)}
|
||||
</Drawer>
|
||||
|
||||
{/* 编辑工单弹窗 */}
|
||||
<Modal
|
||||
title="编辑工单"
|
||||
open={editModalVisible}
|
||||
onCancel={() => setEditModalVisible(false)}
|
||||
onOk={() => { editForm.validateFields().then(values => { message.success('工单保存成功'); setEditModalVisible(false); }); }}
|
||||
okText="保存"
|
||||
cancelText="取消"
|
||||
width={600}
|
||||
destroyOnClose
|
||||
>
|
||||
<Form form={editForm} layout="vertical" initialValues={{ priority: 'low', source: '人工创建', type: '巡检' }}>
|
||||
<Form.Item label="标题" name="title" rules={[{ required: true, message: '请输入标题' }]}><Input /></Form.Item>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}><Form.Item label="来源" name="source"><Select><Option value="人工创建">人工创建</Option><Option value="告警">告警</Option><Option value="AI诊断">AI诊断</Option></Select></Form.Item></Col>
|
||||
<Col span={12}><Form.Item label="类型" name="type"><Select><Option value="巡检">巡检</Option><Option value="故障排查">故障排查</Option><Option value="维护">维护</Option><Option value="清洗">清洗</Option></Select></Form.Item></Col>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}><Form.Item label="优先级" name="priority"><Select><Option value="low">低</Option><Option value="medium">中</Option><Option value="high">高</Option></Select></Form.Item></Col>
|
||||
<Col span={12}><Form.Item label="负责人" name="handler"><Input /></Form.Item></Col>
|
||||
</Row>
|
||||
<Form.Item label="描述" name="description"><Input.TextArea rows={4} /></Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default WorkOrderPage;
|
||||
|
||||
Reference in New Issue
Block a user