Browse Source

feat:一图统揽更改

dev
zhaobing’ 1 year ago
parent
commit
266659a66d
  1. 560
      web-network/client/src/sections/network/components/export-data.js
  2. 5
      web-network/client/src/sections/network/containers/device-monitor.js
  3. 332
      web-network/client/src/sections/network/containers/tableShow.js

560
web-network/client/src/sections/network/components/export-data.js

@ -0,0 +1,560 @@
'use strict';
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Button, message } from "antd";
import moment from 'moment';
import XLSX from 'xlsx';
import { fromJS } from 'immutable';
import { Request } from '@peace/utils';
import FileSaver from 'file-saver';
import { DownOutlined } from '@ant-design/icons';
//通用前端导出组件 使用方法查看底部propTypes
const ExportData = ({...props}) => {
//const [form] = Form.useForm();
const [exportLoading, setExportLoading] = useState(false);
const { customRender, title, exportType, style, showIcon } = props;
const loop = (data, keypath, values) => { // deal with array
let dkey = keypath.slice(0, 1)[0];
if (dkey) {
let dvalue = data[dkey];
let otherKeypath = keypath.slice(1);
if (Array.isArray(dvalue)) {
if (otherKeypath.length) {
let immutableData = fromJS(data);
for (let index = 0; index < dvalue.length; index++) {
let tmp = immutableData.getIn([dkey, index]).toJS();
loop(tmp, otherKeypath, values);
}
}
} else {
values.push(dvalue);
}
}
return values;
};
const getColumnData = (opts) => {
const { data, keypath, render, spliter, rawdata, valueEnum } = opts;
let v = null;
let outer = data[keypath[0]];
if (Array.isArray(outer)) {
let values = loop(data, keypath, []);
v = rawdata ? values : values.join(spliter || ',');
} else {
v = fromJS(data).getIn(keypath);
}
//处理proTable 枚举
if(valueEnum && valueEnum[v]?.text){
v = valueEnum[v]?.text;
}
//处理render
// if (render && typeof render === 'function') {
// v = render(outer, data);
// }
return v;
};
const getDataSource = (attrs, filterData) => {
let dataSource = filterData.map(item => {
let record = {};
attrs.forEach(attr => {
const { key, dataIndex, render, child, valueEnum } = attr;
if (child) {
record[key] = getDataSource(child, item[key] || []);
} else {
let v = getColumnData({
data: item,
keypath: Array.isArray(dataIndex) ? dataIndex : [dataIndex],
render: render || null,
valueEnum: valueEnum
});
record[key] = v;
}
});
return record;
});
return dataSource;
};
const getNewColumns = (attrs) => {
return attrs.filter(f=> f.dataIndex).map(v=>{
const { dataIndex } = v;
return {
...v,
key: Array.isArray(dataIndex) ? dataIndex.reduce((p,c)=>{
p = `${p}${c.trim().replace(c[0], c[0].toUpperCase())}`;
return p
},'') : dataIndex
}
})
}
//暂时只处理两层
const getFlatData = (attrs, filterData, dataToAoa, deep = 0) => {
filterData.map(item => {
let cur = dataToAoa[deep]
if (!cur) {
cur = dataToAoa[deep] = []
}
attrs.map((attr, index) => {
const { key, child } = attr;
if (child) {
if (Array.isArray(item[key])) {
//getFlatData(child,item[key],dataToAoa,deep)
item[key].map((s, i) => {
if (i == 0) {
child.map(c => {
cur.push(s[c.key]);
})
} else {
deep++
let childCur = dataToAoa[deep] = []
pushNull(childCur, index);
child.map(c => {
childCur.push(s[c.key]);
});
}
})
}
} else {
cur.push(item[key]);
}
});
deep++
});
};
const getHeader = (headers, excelHeader, deep, perOffset) => {
let offset = 0
let cur = excelHeader[deep]
if (!cur) {
cur = excelHeader[deep] = []
}
pushNull(cur, perOffset - cur.length)
for (let i = 0; i < headers.length; i++) {
let head = headers[i]
cur.push(head.name)
if (head.hasOwnProperty('child') && Array.isArray(head.child) && head.child.length > 0) {
let childOffset = getHeader(head.child, excelHeader, deep + 1, cur.length - 1)
pushNull(cur, childOffset - 1)
offset += childOffset
} else {
offset++
}
}
return offset;
}
const pushNull = (arr, count) => {
for (let i = 0; i < count; i++) {
arr.push(null)
}
}
const fillNull = (arr) => {
let max = Math.max(...(arr.map(a => a.length)))
arr.filter(e => e.length < max).forEach(e => pushNull(e, max - e.length))
}
const doMerges = (arr) => {
// 要么横向合并 要么纵向合并
let deep = arr.length;
let merges = [];
for (let y = 0; y < deep; y++) {
// 先处理横向合并
let row = arr[y];
let colSpan = 0
for (let x = 0; x < row.length; x++) {
if (row[x] === null) {
colSpan++
if (((x + 1) === row.length) && (colSpan > 0 && x > colSpan)) {
merges.push({ s: { r: y, c: x - colSpan }, e: { r: y, c: x } })
}
} else if (colSpan > 0 && x > colSpan) {
merges.push({ s: { r: y, c: x - colSpan - 1 }, e: { r: y, c: x - 1 } })
colSpan = 0
} else {
colSpan = 0
}
}
}
// 再处理纵向合并
let colLength = arr[0].length
for (let x = 0; x < colLength; x++) {
let rowSpan = 0
for (let y = 0; y < deep; y++) {
if (arr[y][x] != null) {
rowSpan = 0
} else {
rowSpan++;
}
}
if (rowSpan > 0) {
merges.push({ s: { r: deep - rowSpan - 1, c: x }, e: { r: deep - 1, c: x } })
}
}
return merges;
}
//内容暂只出了纵向合并
const doContetMerges = (arr, headerLength) => {
let deep = arr.length;
let merges = [];
//处理纵向合并
let colLength = arr[0].length
for (let x = 0; x < colLength; x++) {
let rowSpan = 0;
let mergY = 0;
for (let y = 0; y < deep; y++) {
if (rowSpan > 0) {
//如果还有null 继续加
if (arr[y][x] === null) {
rowSpan = rowSpan + 1
} else {
//不为null 增加merge
merges.push({ s: { r: headerLength + (y - rowSpan - 1), c: x }, e: { r: headerLength + y - 1, c: x } });
rowSpan = 0;
}
} else {
if (arr[y][x] === null) {
rowSpan = rowSpan + 1
}
}
}
if (rowSpan > 0) {
merges.push({ s: { r: headerLength + (deep - rowSpan - 1), c: x }, e: { r: headerLength + deep - 1, c: x } })
rowSpan = 0;
}
}
return merges;
}
//导出可以纵向合并单元格的数据 不建议使用
const exportMergeExcel = async () => {
setExportLoading(true)
const { columns, data, fileName, exportUrl, exportQuery, exportBody, requestType, header, showYearMouth } = props || {};
let resultData = [];
if (exportUrl) {
resultData = requestType == 'post' ? await Request.post(exportUrl, exportBody || {}, exportQuery || {}).then(data => {
//数据接口返回的结果 如果是对象 必须把返回数组放入rows
if (typeof data === 'object' && data.rows) {
return data.rows
} else {
return data;
}
}, err => {
message.error('获取数据失败,导出失败!');
}) : await Request.get(exportUrl, exportQuery || {}).then(data => {
if (typeof data === 'object' && data.rows) {
return data.rows
} else {
return data;
}
}, err => {
message.error('获取数据失败,导出失败!');
});
if (!resultData) {
return;
}
} else {
resultData = data
}
let excelHeader = [];
const newColumns = getNewColumns(columns);
getHeader(newColumns, excelHeader, 0, 0);
fillNull(excelHeader);
//console.log(excelHeader);
let loopData = getDataSource(newColumns, resultData);
//console.log(loopData)
let dataToAoa = [];
getFlatData(newColumns, loopData, dataToAoa, 0);
fillNull(dataToAoa);
//console.log(dataToAoa);
let aoa = [].concat(excelHeader, dataToAoa);
//console.log(aoa)
let headerMerges = doMerges(excelHeader);
let contentMerages = doContetMerges(dataToAoa, excelHeader.length);
let merges = [].concat(headerMerges, contentMerages);
// console.log(contentMerages)
// let opts = {
// defaultCellStyle: {
// font: { name: "宋体", sz: 11, color: { auto: 1 } },
// border: {
// color: { auto: 1 }
// },
// alignment: {
// /// 自动换行
// wrapText: 1,
// // 居中
// horizontal: "center",
// vertical: "center",
// indent: 0
// }
// }
// }
let sheet = XLSX.utils.aoa_to_sheet(aoa);
// let newSheet = {};
// for (let [key, value] of Object.entries(sheet)) {
// if(key == '!ref'){
// newSheet[key] = value
// }else if(typeof value === 'object'){
// newSheet[key] = {
// ...value,
// s: opts.defaultCellStyle
// }
// }
// }
const wpx = columns.map(c => {
return {
wpx: Number.parseInt(c.wpx) ? Number.parseInt(c.wpx) : 100
}
})
sheet['!cols'] = wpx;
sheet['!merges'] = merges;
// 构建 workbook 对象
const workbook = XLSX.utils.book_new();
const time = moment().format('YYYY-MM-DD');
XLSX.utils.book_append_sheet(workbook, sheet, 'mySheet');
// 导出 Excel
XLSX.writeFile(workbook, fileName ? `${fileName}-${time}.xlsx` : `导出数据-${time}.xlsx`);
setExportLoading(false);
message.success(`成功导出了 ${loopData.length || 0} 条数据`);
}
//FileSaver 方式导出可以自定义样式 columns可定义 headStyle, rowStyle
const exportFileSaver = async () => {
setExportLoading(true)
const { columns, data, fileName, exportUrl, exportQuery, exportBody, requestType } = props || {};
let resultData = [];
if (exportUrl) {
resultData = requestType == 'post' ? await Request.post(exportUrl, exportBody || {}, exportQuery || {}).then(data => {
//数据接口返回的结果 如果是对象 必须把返回数组放入rows
if (typeof data === 'object') {
return data.data ? data.data : data.rows
} else {
return data;
}
}, err => {
message.error('获取数据失败,导出失败!');
}) : await Request.get(exportUrl, exportQuery || {}).then(data => {
if (typeof data === 'object' && data.rows) {
return data.rows
} else {
return data;
}
}, err => {
message.error('获取数据失败,导出失败!');
});
if (!resultData) {
return;
}
} else {
resultData = data
}
const newColumns = getNewColumns(columns);
const loopData = getDataSource(newColumns, resultData);
let content = '';
let header = '<tr>';
//header += `<th><div>序号</div></th>`;
newColumns.map(colum => {
header += `<th style="${colum.headStyle || ''}"><div>${colum.title}</div></th>`
});
header += '</tr>';
loopData.map(data => {
content += `<tr>`;
newColumns.map(c => {
if (c.style) {
content += `<th style="${c.rowStyle || ''}"><div>${data[c.key] || ''}</div></th>`
} else {
content += `<th><div>${data[c.key] || ''}</div></th>`
}
});
content += `</tr>`;
})
let exportTable = `\uFEFF
<table style='text-alagin:center' border="1">
${header}
${content}
</table>
`;
const time = moment().format('YYYY-MM-DD');
let tempStrs = new Blob([exportTable], { type: 'text/xls' })
FileSaver.saveAs(tempStrs, fileName ? `${fileName}-${time}.xls` : `导出数据-${time}.xlsx`);
setExportLoading(false);
message.success(`成功导出了 ${loopData.length || 0} 条数据`);
}
//普通XLSX导出
const exportExcel = async () => {
setExportLoading(true)
const { columns, data, fileName, exportUrl, exportQuery, exportBody, requestType } = props || {};
const newColumns = getNewColumns(columns);
const _headers = newColumns
.map((item, i) => Object.assign({}, { key: item.key, title: item.title, position: String.fromCharCode(65 + i) + 1 }))
.reduce((prev, next) => Object.assign({}, prev, { [next.position]: { key: next.key, v: next.title } }), {});
let resultData = [];
if (exportUrl) {
resultData = requestType == 'post' ? await Request.post(exportUrl, exportBody || {}, exportQuery || {}).then(data => {
//数据接口返回的结果 如果是对象 必须把返回数组放入rows
if (typeof data === 'object' && (data.rows || data.data)) {
return data.data ? data.data : data.rows
} else {
return data;
}
}, err => {
message.error('获取数据失败,导出失败!');
}) : await Request.get(exportUrl, exportQuery || {}).then(data => {
if (typeof data === 'object' && data.rows) {
return data.rows
} else {
return data;
}
}, err => {
message.error('获取数据失败,导出失败!');
});
if (!resultData) {
return;
}
} else {
resultData = data
}
const loopData = getDataSource(newColumns, resultData);
const wpx = newColumns.map(c => {
return {
wpx: Number.parseInt(c.wpx) ? Number.parseInt(c.wpx) : 100
}
})
if (!(loopData.length > 0)) {
setExportLoading(false);
return;
}
const _data = loopData
.map((item, i) => newColumns.map((key, j) => Object.assign({}, { content: item[key.key], position: String.fromCharCode(65 + j) + (i + 2) })))
// 对刚才的结果进行降维处理(二维数组变成一维数组)
.reduce((prev, next) => prev.concat(next))
// 转换成 worksheet 需要的结构
.reduce((prev, next) => Object.assign({}, prev, { [next.position]: { v: next.content } }), {});
// 合并 columns 和 data
const output = Object.assign({}, _headers, _data);
// 获取所有单元格的位置
const outputPos = Object.keys(output);
// 计算出范围 ,["A1",..., "H2"]
const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`;
// 构建 workbook 对象
const workbook = {
SheetNames: ['mySheet'],
Sheets: {
mySheet: Object.assign(
{},
output,
{
'!ref': ref,
'!cols': wpx,
},
),
},
};
const time = moment().format('YYYY-MM-DD');
// 导出 Excel
XLSX.writeFile(workbook, fileName ? `${fileName}-${time}.xlsx` : `导出数据-${time}.xlsx`);
setExportLoading(false);
message.success(`成功导出了 ${loopData.length || 0} 条数据`);
}
const handleExport = async () => {
switch (exportType) {
case 'fileSaver':
await exportFileSaver();
break;
case 'xlsx':
await exportExcel();
break;
case 'merge':
await exportMergeExcel();
break;
default:
await exportExcel();
break;
}
}
return (
customRender ?
<span style={style} loading={exportLoading} onClick={handleExport}>
{customRender}
</span> :
<Button style={style} loading={exportLoading} onClick={handleExport}>
{title || '导出'}
{showIcon && <DownOutlined />}
</Button>
)
}
ExportData.propTypes = {
fileName: PropTypes.string, //导出文件名称前缀
showIcon: PropTypes.bool, //导出按钮是否显示icon,默认不显示
customRender: PropTypes.element, //自定义导出组件渲染 不传默认按钮样式
style: PropTypes.object,//透传style
title: PropTypes.string, //导出按钮文字
columns: PropTypes.array.isRequired, //导出显示的header数组 兼容antd columns 可直接拿table或者protable的columns使用 注:columns每列的属性wpx设置导出的execl每列的宽度值 默认 100
data: PropTypes.array.isRequired, //导出的数据 兼容antd table 数组嵌套处理,如果传入exportUrl 则从接口获取数据导出,此参数无效
exportUrl: PropTypes.string, //导出数据从接口获取的url地址 返回的数据1、数组必须支持columns的设置 ,2、如果是对象,数组需放在rows属性上
exportBody: PropTypes.object, //导出数据接口body参数
exportQuery: PropTypes.object, //导出数据从接口获取的url地址上的参数
requestType: PropTypes.string, //请求类型 get,post,默认get
exportType: PropTypes.string, //导出执行类型函数 'fileSaver','xlsx','merge'纵向单元格合并
};
export default ExportData;

5
web-network/client/src/sections/network/containers/device-monitor.js

@ -14,7 +14,7 @@ import { DeviceTypes } from '../constant';
import qs from "qs";
import '../style.less';
// import TableShow from './tableShow'
import TableShow from './tableShow'
function DeviceMonitor ({ ...props }) {
const {
dispatch, actions, user, clientWidth, clientHeight, loading,
@ -199,8 +199,7 @@ console.log(3213,actions);
/>
) : <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
: (
<div></div>
// <TableShow thingId={strucParam.thingId} project={strucParam.projectId}/>
<TableShow thingId={strucParam.thingId} project={strucParam.projectId}/>
)
}
</ProCard>

332
web-network/client/src/sections/network/containers/tableShow.js

@ -0,0 +1,332 @@
import React, { useEffect, useState, useRef, useMemo } from 'react'
import { connect } from 'react-redux'
import { Spin, Card, CardGroup, Form,Select ,Input, Button, Table, Pagination, Tooltip } from 'antd'
import ExportData from '../components/export-data'
import moment from 'moment'
const Network = props => {
const { dispatch, actions, user, clientHeight, thingId, deviceListAlarms, devicesCardStatusList, project } = props
const { analysis } = actions
const form = useRef() //表单
const [deployData, setDeployData] = useState([])
const [deviceData, setDeviceData] = useState([])
const [deviceMetasDeployed, setDeviceMetasDeployed] = useState([])
const [sensorId, setSensorId] = useState([])
const [sensorsDataItems, setSensorsDataItems] = useState({})
const [tableData, setTableData] = useState([]) //最新一次的数据
const [lastData, setLastData] = useState([]) //最终数据
const [lastDataCopy, setLastDataCopy] = useState([]) //最终数据
const [searchType, setSearchType] = useState('')
const [searchName, setSearchName] = useState('')
const [typeList, setTypeList] = useState([])
const [query, setQuery] = useState({ limit: 10, page: 0 }) //页码信息
const DeviceTypes = {
'DTU': 'DTU',
'gateway': '网关',
'sensor': '传感器',
'acqUnit': '采集单元',
'dau.gateway': '分布式智能云采集网关',
'dau.node': '分布式智能云采集节点',
'tcp.dtu': '工作站',
}
useEffect(() => {
setLastData([])
setLastDataCopy([])
}, [project])
useEffect(() => {
if (thingId) {
let dataList = []
dispatch(analysis.getThingsDeploy(thingId)).then(rs => {
if (rs.success) {
setDeployData(rs.payload.data)
dataList = rs.payload.data
//列表渲染数据
let da = []
if (dataList.instances) {
Object.keys(dataList.instances).forEach(i => {
if (dataList.instances[i].type == 's.d') {
da.push({
sensorId: i,
sensorName: dataList.instances[i]?.name,
deviceType: dataList?.instances[i]?.instance?.properties?.deviceType,
collectTime: '--',
data: '--',
iotCardStatus: '--',
status: '--',
option: '--',
})
}
})
}
dispatch(analysis.findDeviceMetaDeployed(thingId)).then(res => {
if (res.success) {
setDeviceMetasDeployed(res.payload.data)
const deviceMetaDeployed = res.payload.data
if (deviceMetaDeployed && dataList && deviceMetaDeployed.devices) {
const sensorsId = []
let alarmSensorId = [] //所有设备的id
const sensorsDataItems = {}
for (const id in dataList.instances) {
alarmSensorId.push(id)
const instances = dataList.instances[id]
if (instances.type == 's.d' && instances.instance.properties.deviceType == 'sensor') {
const meta = deviceMetaDeployed.devices.find(m => m.id == instances.instance.deviceMetaId)
sensorsDataItems[id] = {
items: {},
deviceName: instances.name,
}
if (meta) {
sensorsDataItems[id].items = meta.capabilities[0].properties.reduce((p, n) => {
if (n.category == 'Output') {
p[n.name] = { name: n.showName, unit: n.unit }
}
return p
}, {})
}
sensorsId.push(id)
}
}
dispatch(analysis.getDevicesAlarms({ deviceIds: alarmSensorId }, { limit: 5 }))
dispatch(analysis.findDevicesCardStatus({ deviceIds: alarmSensorId }))
setSensorsDataItems(sensorsDataItems)
setSensorId(sensorsId)
setDeviceData(da)
}
}
})
}
})
}
}, [thingId])
useEffect(async () => {
if (sensorId && sensorId.length && sensorsDataItems) {
const rs = await dispatch(analysis.findSensorLastData(sensorId))
const tableData = []
if (rs.success) {
rs.payload.data.forEach(sd => {
if (Object.keys(sensorsDataItems).length) {
let sensorDataItem = sensorsDataItems[sd.sensorId]
let sensorName = sensorDataItem && sensorDataItem.deviceName ? sensorDataItem.deviceName : ''
let msg = sd.data.length
? sd.data[0]
: {
collectTime: null,
sensorName: sensorName,
data: { noData: '暂无数据' },
}
let dataStr = ''
let dataKeys = Object.keys(msg.data)
dataKeys.forEach(k => {
let item = sensorDataItem && sensorDataItem.items ? sensorDataItem.items[k] : null
if (item) {
dataStr += `${item.name}${msg.data[k]}${item.unit}); `
} else if (k == 'noData') {
dataStr += msg.data[k]
} else {
dataStr += `${k}${msg.data[k]}`
}
})
let collectTime = msg.collectTime ? moment(msg.collectTime).format('YYYY-MM-DD HH:mm:ss') : '--'
tableData.push({
sensorId: sd.sensorId,
sensorName: sensorName,
collectTime: collectTime,
data: dataStr,
deviceType: 'sensor', //传感器
iotCardStatus: '--',
status: '--',
option: '--',
})
}
})
}
setTableData(tableData)
}
}, [sensorId])
useEffect(() => {
if (deviceData && deviceData.length ) {
const dataD = deviceData?.map(p => {
const objRslt = tableData?.find(q => q.sensorId == p.sensorId)
return {
sensorId: objRslt ? objRslt.sensorId : p.sensorId,
sensorName: objRslt ? objRslt.sensorName : p.sensorName,
collectTime: objRslt ? objRslt.collectTime : p.collectTime,
data: objRslt ? objRslt.data : p.data,
deviceType: DeviceTypes[objRslt ? objRslt.deviceType : p.deviceType],
iotCardStatus:
devicesCardStatusList && devicesCardStatusList.length
? devicesCardStatusList.find(v => v.deviceId == p.sensorId).status === 0
? '正常'
: devicesCardStatusList.find(v => v.deviceId == p.sensorId).status === 1
? '未激活'
: '停机'
: '--',
status:
deviceListAlarms && deviceListAlarms.length
? deviceListAlarms?.find(v => v.deviceId == p.sensorId)
? '异常'
: '正常'
: '--',
option: objRslt ? objRslt.option : p.option,
}
})
const typeList = dataD.reduce((p, c) => {
let isExist = p.some(q => q.label === c.deviceType)
if (!isExist) {
p.push({ label: c.deviceType, value: c.sensorId })
}
return p
}, [])
setTypeList(typeList)
setLastData(dataD)
setLastDataCopy(dataD)
}
}, [deviceData])
// const lastDataCopy=useMemo(()=>{
// return lastData
// },[thingId])
const scroll = useMemo(() => ({ y:clientHeight-600+175+175 }), [])
//名称回调事件
const inputChange = e => {
setSearchName(e.target.value)
}
//选择设备类型下拉框回调
const selectChange = e => {
let rslt=typeList.find(f => f.value == e)
setSearchType(rslt?rslt.label:undefined)
}
//查询事件回调
const searchHandler = () => {
setLastData(
lastDataCopy.filter(f =>
(!searchName || f.sensorName.includes(searchName)) &&
(!searchType|| f.deviceType===searchType)
)
)
}
const columns = [
{
title: '设备名称',
dataIndex: 'sensorName',
width: '20%',
key: 'sensorName',
render: (_, r) => {
return (
<>
<Tooltip title={r.sensorName}>
<div>{r.sensorName.length > 7 ? `${r.sensorName.substr(0, 7)}...` : r.sensorName}</div>
</Tooltip>
</>
)
},
},
{
title: '设备类型',
dataIndex: 'deviceType',
width: '15%',
key: 'deviceType',
},
{
title: '最后采集时间',
dataIndex: 'collectTime',
width: '15%',
key: 'collectTime',
},
{
title: '数据',
dataIndex: 'data',
width: '20%',
key: 'data',
render: (_, r) => {
return (
<>
<Tooltip title={r.data}>
<div>{r.data.length > 6 ? `${r.data.substr(0, 6)}...` : r.data}</div>
</Tooltip>
</>
)
},
},
{
title: '物联网卡状态',
width: '15%',
dataIndex: 'iotCardStatus',
key: 'iotCardStatus',
},
{
title: '状态',
width: '10%',
dataIndex: 'status',
key: 'status',
},
{
title: '操作',
width: '10%',
dataIndex: 'option',
key: 'option',
},
]
return (
<>
<div style={{ marginBottom: 12, display: 'flex' }}>
<div>
<Input // suffix={<IconSearch />}
label='名称'
placeholder='请输入设备名称'
pure
allowClear
style={{ width: 260, marginRight: 12 }}
onChange={inputChange}/>
<Select options={typeList} label='设备类型'
pure
allowClear
onChange={selectChange}
style={{ width: 260, marginLeft: 12, marginRight: 12 }}
placeholder='请选择设备类型'></Select>
<Button theme='solid' type='primary' htmlType='submit' onClick={searchHandler}>
查询
</Button>
</div>
<div style={{ marginLeft: 10 }}>
{' '}
{lastData.length ? (
<ExportData
// showIcon
fileName='设备列表'
exportType='fileSaver'
data={lastData}
columns={columns}
key='export'
/>
) : (
''
)}
</div>
</div>
<Table
// scroll={scroll}
columns={columns}
dataSource={lastData}></Table>
</>
)
}
function mapStateToProps(state) {
const { auth, global, members, webSocket, deviceListAlarms, devicesCardStatus } = state
return {
user: auth.user,
actions: global.actions,
clientHeight: global.clientHeight,
deviceListAlarms: deviceListAlarms?.data || [],
devicesCardStatusList: devicesCardStatus?.data || [],
}
}
export default connect(mapStateToProps)(Network)
Loading…
Cancel
Save