|
|
|
|
@ -1,9 +1,502 @@
|
|
|
|
|
import {Button, Col, Form, Row, Select, DatePicker, Input} from "antd";
|
|
|
|
|
import Title from "@/pages/homepage/compontent/title";
|
|
|
|
|
import {PlusOutlined, SearchOutlined, SyncOutlined} from "@ant-design/icons";
|
|
|
|
|
import styles from "./InspectionRecords.less";
|
|
|
|
|
import TableWithPagination from "@/components/assetmangement/table";
|
|
|
|
|
import {useRef,useEffect} from "react";
|
|
|
|
|
import * as echarts from "echarts";
|
|
|
|
|
const {RangePicker} = DatePicker;
|
|
|
|
|
const Search = Input;
|
|
|
|
|
const InspectionRecords = () => {
|
|
|
|
|
const lineChartRef=useRef(null)
|
|
|
|
|
const barChartRef=useRef(null)
|
|
|
|
|
const zhuChartRef=useRef(null)
|
|
|
|
|
|
|
|
|
|
useEffect(()=>{
|
|
|
|
|
if(lineChartRef.current){
|
|
|
|
|
const lineChart =echarts.init(lineChartRef.current)
|
|
|
|
|
const options={
|
|
|
|
|
grid:{
|
|
|
|
|
top: '10%',
|
|
|
|
|
bottom: '10%',
|
|
|
|
|
left: '10%',
|
|
|
|
|
right: '10%',
|
|
|
|
|
},
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'category',
|
|
|
|
|
data: ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'],
|
|
|
|
|
boundaryGap: false,
|
|
|
|
|
splitLine:{
|
|
|
|
|
show: true,
|
|
|
|
|
type:'dashed',
|
|
|
|
|
lineStyle:{
|
|
|
|
|
color:'#CCCCCC',
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
splitLine:{
|
|
|
|
|
show:false,
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
series: [{
|
|
|
|
|
data: [150, 230, 224, 218, 135, 147, 260],
|
|
|
|
|
type: 'line',
|
|
|
|
|
lineStyle: {
|
|
|
|
|
color: '#2C9E9D',
|
|
|
|
|
width: 2,
|
|
|
|
|
},
|
|
|
|
|
itemStyle:{
|
|
|
|
|
color: '#2C9E9D',
|
|
|
|
|
},
|
|
|
|
|
areaStyle: {
|
|
|
|
|
color: '#E0ECE8',
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
}],
|
|
|
|
|
}
|
|
|
|
|
lineChart.setOption(options)
|
|
|
|
|
window.addEventListener('resize',()=>{
|
|
|
|
|
lineChart.resize()
|
|
|
|
|
})
|
|
|
|
|
return ()=>{
|
|
|
|
|
lineChart.dispose()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},[])
|
|
|
|
|
useEffect(()=>{
|
|
|
|
|
if(barChartRef.current){
|
|
|
|
|
const barChart =echarts.init(barChartRef.current)
|
|
|
|
|
const data = [
|
|
|
|
|
{ value: 40, name: '传感器' ,itemStyle:{color: '#006665',}},
|
|
|
|
|
{ value: 30, name: '网关' ,itemStyle:{color: '#999999',}},
|
|
|
|
|
{ value: 20, name: '摄像头' ,itemStyle:{color: '#FF826D',}},
|
|
|
|
|
{ value: 10, name: '其他' ,itemStyle:{color: '#FFBC00',}}
|
|
|
|
|
];
|
|
|
|
|
const total = data.reduce((sum, item) => sum + item.value, 0);
|
|
|
|
|
const option = {
|
|
|
|
|
legend: {
|
|
|
|
|
orient: 'vertical', // 水平排列
|
|
|
|
|
top: 10,
|
|
|
|
|
left:0,
|
|
|
|
|
// icon:'none'
|
|
|
|
|
itemGap:20,
|
|
|
|
|
itemWidth: 0,
|
|
|
|
|
// useHTML: true,
|
|
|
|
|
// 关键2:清空富文本,避免冲突
|
|
|
|
|
|
|
|
|
|
formatter: function (name) {
|
|
|
|
|
const item = data.find(d => d.name === name);
|
|
|
|
|
if (item) {
|
|
|
|
|
const percent = ((item.value / total) * 100).toFixed(1);
|
|
|
|
|
// 使用对应的 rich 标签
|
|
|
|
|
return `${name} ${percent}%`;
|
|
|
|
|
}
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
grid:{
|
|
|
|
|
top: '10%',
|
|
|
|
|
bottom: '10%',
|
|
|
|
|
left: 0,
|
|
|
|
|
right: '10%',
|
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: '销售额',
|
|
|
|
|
type: 'pie',
|
|
|
|
|
radius: ['0%', '45%'], // 环形图
|
|
|
|
|
center: ['70%', '40%'],
|
|
|
|
|
avoidLabelOverlap: true, // 防止标签重叠
|
|
|
|
|
labelLine: {
|
|
|
|
|
show: false // 设置为 false 即可
|
|
|
|
|
},
|
|
|
|
|
label:{
|
|
|
|
|
show:false
|
|
|
|
|
},
|
|
|
|
|
data:data,
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
barChart.setOption(option)
|
|
|
|
|
window.addEventListener('resize',()=>{
|
|
|
|
|
barChart.resize()
|
|
|
|
|
})
|
|
|
|
|
return ()=>{
|
|
|
|
|
barChart.dispose()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},[])
|
|
|
|
|
useEffect(()=>{
|
|
|
|
|
if(zhuChartRef.current){
|
|
|
|
|
const Chart =echarts.init(zhuChartRef.current)
|
|
|
|
|
const option = {
|
|
|
|
|
|
|
|
|
|
// 提示框配置
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'shadow' // 阴影指示器
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 网格配置
|
|
|
|
|
grid: {
|
|
|
|
|
left: '3%',
|
|
|
|
|
right: '4%',
|
|
|
|
|
bottom: '3%',
|
|
|
|
|
top: '20%',
|
|
|
|
|
containLabel: true
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// X轴配置
|
|
|
|
|
xAxis: {
|
|
|
|
|
type: 'category',
|
|
|
|
|
data: ['硬件故障', '软件故障', '网络故障', '环境异常'],
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: true
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: true
|
|
|
|
|
},
|
|
|
|
|
axisLabel:{
|
|
|
|
|
interval:0,
|
|
|
|
|
width: 40,
|
|
|
|
|
overflow:'break',
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
splitLine:{
|
|
|
|
|
show: true,
|
|
|
|
|
type: 'dashed' // 虚线网格
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Y轴配置
|
|
|
|
|
yAxis: {
|
|
|
|
|
type: 'value',
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: true
|
|
|
|
|
},
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: true
|
|
|
|
|
},
|
|
|
|
|
splitLine: {
|
|
|
|
|
lineStyle: {
|
|
|
|
|
type: 'dashed' // 虚线网格
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 系列配置
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: '销售量',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
data: [{value:120,itemStyle:{color: '#92C2DD'}}, {value:200,itemStyle:{color: '#BAD4DB'}}, {value:150,itemStyle:{color: '#5E949B'}}, {value:80,itemStyle:{color: '#10758E'}}],
|
|
|
|
|
barWidth: '40%' ,// 柱条宽度
|
|
|
|
|
label:{
|
|
|
|
|
show: true,
|
|
|
|
|
position: 'top',
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
Chart.setOption(option)
|
|
|
|
|
window.addEventListener('resize',()=>{
|
|
|
|
|
Chart.resize()
|
|
|
|
|
})
|
|
|
|
|
return ()=>{
|
|
|
|
|
Chart.dispose()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},[])
|
|
|
|
|
|
|
|
|
|
const columns = [
|
|
|
|
|
{
|
|
|
|
|
title: '记录 ID',
|
|
|
|
|
dataIndex: 'recordId',
|
|
|
|
|
key: 'recordId',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '任务名称',
|
|
|
|
|
dataIndex: 'taskName',
|
|
|
|
|
key: 'taskName',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '关联模板',
|
|
|
|
|
dataIndex: 'template',
|
|
|
|
|
key: 'template',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '巡检时间',
|
|
|
|
|
dataIndex: 'inspectionTime',
|
|
|
|
|
key: 'inspectionTime',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '涉及设备数',
|
|
|
|
|
dataIndex: 'deviceCount',
|
|
|
|
|
key: 'deviceCount',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '异常设备数',
|
|
|
|
|
dataIndex: 'abnormalCount',
|
|
|
|
|
key: 'abnormalCount',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '巡检结果',
|
|
|
|
|
dataIndex: 'result',
|
|
|
|
|
key: 'result',
|
|
|
|
|
// render: (text) => {
|
|
|
|
|
// const color = text === '正常' ? 'green' : 'red';
|
|
|
|
|
// return <span style={{ color }}>{text}</span>;
|
|
|
|
|
// },
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '操作',
|
|
|
|
|
key: 'actions',
|
|
|
|
|
render: () => (
|
|
|
|
|
<div>
|
|
|
|
|
<Button type="link" size="small" style={{ color: '#2C9E9D' }}>查看详情</Button>
|
|
|
|
|
<Button type="link" size="small" style={{ color: '#006665' }}>生成报告</Button>
|
|
|
|
|
</div>
|
|
|
|
|
),
|
|
|
|
|
align: 'center',
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
const dataSource = [
|
|
|
|
|
{
|
|
|
|
|
key: '1',
|
|
|
|
|
recordId: 'REC-001',
|
|
|
|
|
taskName: '核心设备日检任务',
|
|
|
|
|
template: '核心设备日检',
|
|
|
|
|
inspectionTime: '2025-10-30',
|
|
|
|
|
deviceCount: 10,
|
|
|
|
|
abnormalCount: 0,
|
|
|
|
|
result: '异常',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: '2',
|
|
|
|
|
recordId: 'REC-002',
|
|
|
|
|
taskName: '车间环境周检任务',
|
|
|
|
|
template: '车间环境周检',
|
|
|
|
|
inspectionTime: '2025-10-29',
|
|
|
|
|
deviceCount: 20,
|
|
|
|
|
abnormalCount: 0,
|
|
|
|
|
result: '正常',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: '3',
|
|
|
|
|
recordId: 'REC-003',
|
|
|
|
|
taskName: '传感器月检任务',
|
|
|
|
|
template: '传感器月检',
|
|
|
|
|
inspectionTime: '2025-10-28',
|
|
|
|
|
deviceCount: 8,
|
|
|
|
|
abnormalCount: 0,
|
|
|
|
|
result: '异常',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: '4',
|
|
|
|
|
recordId: 'REC-004',
|
|
|
|
|
taskName: '网关异常巡检任务',
|
|
|
|
|
template: '网关异常巡检',
|
|
|
|
|
inspectionTime: '2025-10-27',
|
|
|
|
|
deviceCount: 3,
|
|
|
|
|
abnormalCount: 0,
|
|
|
|
|
result: '异常',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: '5',
|
|
|
|
|
recordId: 'REC-005',
|
|
|
|
|
taskName: '仓库温湿度检任务',
|
|
|
|
|
template: '仓库温湿度检',
|
|
|
|
|
inspectionTime: '2025-10-26',
|
|
|
|
|
deviceCount: 15,
|
|
|
|
|
abnormalCount: 0,
|
|
|
|
|
result: '正常',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: '6',
|
|
|
|
|
recordId: 'REC-006',
|
|
|
|
|
taskName: '综合设备巡检任务',
|
|
|
|
|
template: '综合设备巡检',
|
|
|
|
|
inspectionTime: '2025-10-25',
|
|
|
|
|
deviceCount: 6,
|
|
|
|
|
abnormalCount: 0,
|
|
|
|
|
result: '异常',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: '7',
|
|
|
|
|
recordId: 'REC-007',
|
|
|
|
|
taskName: '边缘节点巡检任务',
|
|
|
|
|
template: '边缘节点巡检',
|
|
|
|
|
inspectionTime: '2025-10-24',
|
|
|
|
|
deviceCount: 2,
|
|
|
|
|
abnormalCount: 0,
|
|
|
|
|
result: '正常',
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<h1 >InspectionRecords</h1>
|
|
|
|
|
<div style={{padding: 20}}>
|
|
|
|
|
<div style={{paddingBottom: 20, borderBottom: '1px solid #eeeeee'}}>
|
|
|
|
|
<Row justify={'space-between'} align={'middle'}>
|
|
|
|
|
<Col>
|
|
|
|
|
<Title title="查询条件"></Title>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col>
|
|
|
|
|
<Button icon={<SearchOutlined/>} className={styles['search-button']}
|
|
|
|
|
style={{marginRight: '30px'}}>查询</Button>
|
|
|
|
|
<Button icon={<SyncOutlined/>} className={styles['reset-button']}>重置</Button>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
<Form layout={"inline"} style={{marginTop: '20px'}}>
|
|
|
|
|
<Row gutter={24}>
|
|
|
|
|
<Col>
|
|
|
|
|
<Form.Item label={'任务维度'} name="taskName">
|
|
|
|
|
<Select style={{width: 132}} placeholder="全部" options={[{
|
|
|
|
|
value: '1',
|
|
|
|
|
label: '待执行',
|
|
|
|
|
}, {
|
|
|
|
|
value: '2',
|
|
|
|
|
label: '执行中',
|
|
|
|
|
}, {
|
|
|
|
|
value: '3',
|
|
|
|
|
label: '已完成',
|
|
|
|
|
}]}/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col>
|
|
|
|
|
<Form.Item label={'设备维度'} name="taskStatus">
|
|
|
|
|
<Select style={{width: 132}} placeholder="全部" options={[{
|
|
|
|
|
value: '1',
|
|
|
|
|
label: '待执行',
|
|
|
|
|
}, {
|
|
|
|
|
value: '2',
|
|
|
|
|
label: '执行中',
|
|
|
|
|
}, {
|
|
|
|
|
value: '3',
|
|
|
|
|
label: '已完成',
|
|
|
|
|
}]}/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col>
|
|
|
|
|
<Form.Item label={'结果维度'} name="inspectionStatus">
|
|
|
|
|
<Select style={{width: 132}} placeholder="全部" options={[{
|
|
|
|
|
value: '1',
|
|
|
|
|
label: '待执行',
|
|
|
|
|
}, {
|
|
|
|
|
value: '2',
|
|
|
|
|
label: '执行中',
|
|
|
|
|
}, {
|
|
|
|
|
value: '3',
|
|
|
|
|
label: '已完成',
|
|
|
|
|
}]}/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col>
|
|
|
|
|
<Form.Item label={'时间维度'} name="executionTime">
|
|
|
|
|
<RangePicker/>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
</Form>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{marginTop: 20}}>
|
|
|
|
|
<Row gutter={20}>
|
|
|
|
|
<Col span={16}>
|
|
|
|
|
<Title title="任务列表"></Title>
|
|
|
|
|
<Row style={{margin: '20px 0'}} justify={'space-between'} align={'middle'}>
|
|
|
|
|
<Col>
|
|
|
|
|
<Button className={styles['search-button']} style={{marginRight: '30px'}}>导入任务</Button>
|
|
|
|
|
<Button className={styles['reset-button']} style={{marginRight: '30px'}}>导出任务</Button>
|
|
|
|
|
<Button className={styles['del-button']} style={{marginRight: '30px'}}>删除</Button>
|
|
|
|
|
<Button className={styles['reset-button']}>启动任务</Button>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col>
|
|
|
|
|
<Button icon={<PlusOutlined/>} className={styles['search-button']}>新建任务</Button>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
<TableWithPagination columns={columns} dataSource={dataSource} rowSelection={true}></TableWithPagination>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Title title="AI智能分析区"></Title>
|
|
|
|
|
<div className={styles.content}>
|
|
|
|
|
<div style={{display: 'flex', alignItems: 'center', marginBottom: 10, fontSize: 20}}>
|
|
|
|
|
<span style={{
|
|
|
|
|
width: 5,
|
|
|
|
|
height: 5,
|
|
|
|
|
backgroundColor: '#006665',
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
marginRight: 10
|
|
|
|
|
}}></span><span>巡检异常趋势折线图</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{height: 187, width: '100%'}} ref={lineChartRef}></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.content}>
|
|
|
|
|
<Row gutter={16}>
|
|
|
|
|
<Col span={12}>
|
|
|
|
|
<div style={{display: 'flex', alignItems: 'center', marginBottom: 10, fontSize: 20}}>
|
|
|
|
|
<span style={{
|
|
|
|
|
width: 5,
|
|
|
|
|
height: 5,
|
|
|
|
|
backgroundColor: '#006665',
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
marginRight: 10
|
|
|
|
|
}}></span><span>设备类型异常占比</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{height: 187, width: '100%'}} ref={barChartRef}></div>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={12}>
|
|
|
|
|
<div style={{display: 'flex', alignItems: 'center', marginBottom: 10, fontSize: 20}}>
|
|
|
|
|
<span style={{
|
|
|
|
|
width: 5,
|
|
|
|
|
height: 5,
|
|
|
|
|
backgroundColor: '#006665',
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
marginRight: 10
|
|
|
|
|
}}></span><span>问题类型趋势柱状图</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div style={{height: 187, width: '100%'}} ref={zhuChartRef}></div>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.content}>
|
|
|
|
|
<Row justify={'space-between'} align={'middle'}>
|
|
|
|
|
<Col>
|
|
|
|
|
<div style={{display: 'flex', alignItems: 'center', marginBottom: 10, fontSize: 20}}>
|
|
|
|
|
<span style={{
|
|
|
|
|
width: 5,
|
|
|
|
|
height: 5,
|
|
|
|
|
backgroundColor: '#006665',
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
marginRight: 10
|
|
|
|
|
}}></span><span>AI 智能建议</span>
|
|
|
|
|
</div>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col>
|
|
|
|
|
<Button className={styles['search-button']} style={{marginRight: '30px'}}>采纳建议</Button>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
<div className={styles.text}>
|
|
|
|
|
建议 1:“传感器设备异常率连续 3 周高于均值,建议将其巡检周期从‘月’调整为‘周’,并优先排查硬件批次问题”;
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.text}>
|
|
|
|
|
建议 2:“车间 B 的温湿度异常占比达 60%,建议增加环境传感器密度,或优化通风系统”;
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
export default InspectionRecords;
|
|
|
|
|
|