From cedc81224c5cceab3674a42f0641349c30301d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?zhaobing=E2=80=99?= Date: Tue, 5 Dec 2023 13:38:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E7=BB=84=E7=BD=91=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network/containers/device-monitor.js | 115 +++--- .../sections/network/containers/tableShow.js | 341 ++++++++++++++++++ web-network/package.json | 2 +- 3 files changed, 385 insertions(+), 73 deletions(-) create mode 100644 web-network/client/src/sections/network/containers/tableShow.js diff --git a/web-network/client/src/sections/network/containers/device-monitor.js b/web-network/client/src/sections/network/containers/device-monitor.js index 3b85dbe..f858806 100644 --- a/web-network/client/src/sections/network/containers/device-monitor.js +++ b/web-network/client/src/sections/network/containers/device-monitor.js @@ -14,12 +14,12 @@ import { DeviceTypes } from '../constant'; import qs from "qs"; import '../style.less'; - -function DeviceMonitor ({ ...props }) { - const { - dispatch, actions, user, clientWidth, clientHeight, loading, - myStructList, deviceMetasWithFollow, devices, dimensions, deviceListAlarms, factorStations, - } = props; +import TableShow from './tableShow' +function DeviceMonitor({ ...props }) { + const { + dispatch, actions, user, clientWidth, clientHeight, loading, + myStructList, deviceMetasWithFollow, devices, dimensions, deviceListAlarms, factorStations, + } = props; const [params, setParams] = useState({}); @@ -190,72 +190,43 @@ function DeviceMonitor ({ ...props }) { return ( //
div
// - - - - { - extraType === 'tree' - ? (myStructList.find((v) => v.id === selectStructure) - && deviceMetasWithFollow?.devices?.length > 0 - && devices.instances) - ? ( - v.id === selectStructure)} - clientHeight={clientHeight} - clientWidth={clientWidth} - /> - ) : - : ( - { - setParams(params); - return { - data: [], - success: true, - }; - }} - pagination={{}} - options={{ - search: false, - reload: false, - }} - search={{ - className: 'device-monitor-search', - }} - toolBarRender={() => { - const node = []; - node.push(); - return node; - }} - // scroll={{ y: Func.getContentHeight(clientHeight) - 421 }} - dateFormatter="string" - headerTitle="设备列表" - dataSource={data} - /> - ) - } - - + + + + { + extraType === 'tree' + ? (myStructList.find((v) => v.id === selectStructure) + && deviceMetasWithFollow?.devices?.length > 0 + && devices.instances) + ? ( + v.id === selectStructure)} + clientHeight={clientHeight} + clientWidth={clientWidth} + /> + ) : + : ( + + ) + } + + // ); } diff --git a/web-network/client/src/sections/network/containers/tableShow.js b/web-network/client/src/sections/network/containers/tableShow.js new file mode 100644 index 0000000..375f376 --- /dev/null +++ b/web-network/client/src/sections/network/containers/tableShow.js @@ -0,0 +1,341 @@ +import React, { useEffect, useState, useRef, useMemo } from 'react' +import { connect } from 'react-redux' +import { Spin, Card, CardGroup, Form, Button, Table, Pagination, Tooltip } from '@douyinfe/semi-ui' + import { ExportData } from '@peace/components'; +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 }), []) + //名称回调事件 + const inputChange = e => { + setSearchName(e) + } + //选择设备类型下拉框回调 + const selectChange = e => { + let rslt=typeList.find(f => f.value == e) + setSearchType(rslt?rslt.label:undefined) + } + + //查询事件回调 + const searchHandler = () => { + setLastData( + lastDataCopy.filter(f => + (searchName === undefined || f.sensorName.includes(searchName)) && + (searchType === undefined || f.deviceType===searchType) + ) + ) + } + + const columns = [ + { + title: '设备名称', + dataIndex: 'sensorName', + width: '20%', + key: 'sensorName', + render: (_, r) => { + return ( + <> + +
{r.sensorName.length > 7 ? `${r.sensorName.substr(0, 7)}...` : r.sensorName}
+
+ + ) + }, + }, + { + title: '设备类型', + dataIndex: 'deviceType', + width: '15%', + key: 'deviceType', + }, + { + title: '最后采集时间', + dataIndex: 'collectTime', + width: '15%', + key: 'collectTime', + }, + { + title: '数据', + dataIndex: 'data', + width: '20%', + key: 'data', + render: (_, r) => { + return ( + <> + +
{r.data.length > 6 ? `${r.data.substr(0, 6)}...` : r.data}
+
+ + ) + }, + }, + { + title: '物联网卡状态', + width: '15%', + dataIndex: 'iotCardStatus', + key: 'iotCardStatus', + }, + { + title: '状态', + width: '10%', + dataIndex: 'status', + key: 'status', + }, + { + title: '操作', + width: '10%', + dataIndex: 'option', + key: 'option', + }, + ] + return ( + <> +
+
+
+ } + field='name' + pure + showClear + label='名称' + style={{ width: 260, marginRight: 12 }} + placeholder='请输入设备名称' + onChange={inputChange} + /> + + + +
+
+ {' '} + {lastData.length ? ( + + ) : ( + '' + )} +
+
+
+ + ) +} + +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) diff --git a/web-network/package.json b/web-network/package.json index 7d26451..2dd1cb5 100644 --- a/web-network/package.json +++ b/web-network/package.json @@ -67,7 +67,7 @@ "@ant-design/pro-table": "^2.48.0", "@antv/g6": "^4.2.5", "@fs/attachment": "^1.0.0", - "@peace/components": "0.0.35", + "@peace/components": "0.0.76", "@peace/utils": "0.0.66", "ahooks": "^3.7.8", "antd": "^4.19.2",