/* eslint-disable */ import React, { useState, useEffect, useRef, useContext } from 'react'; import classNames from 'classnames'; import moment from 'moment'; import sha1 from 'sha1'; import Empty from '@wisdom-components/empty'; import LoadBox from '@wisdom-components/loadbox'; import VideoSliderModal from '@wisdom-components/videoslidermodal'; import { Input, message, Modal, Form, ConfigProvider, Button } from 'antd'; import { ExclamationCircleOutlined, DoubleLeftOutlined, LeftOutlined, RightOutlined, DoubleRightOutlined, } from '@ant-design/icons'; import MqttView from '@wisdom-components/mqttview'; import PropTypes from 'prop-types'; import HistoryView from '@wisdom-components/ec_historyview'; import * as go from './js/go'; import GuidedDraggingTool from './js/GuidedDraggingTool'; import TopRotatingTool from './js/RotatingTool'; import BarLink from './js/BarLink'; import WaterFlowControlView from './js/WaterFlowControlView'; import ConfigurationDetail from './js/ConfigurationDetail'; import DragModal from './js/DragModal'; import { getSketchPadList, getSketchPadContent, getPointAddress, getDeviceRealInfo, getVideoDetail, } from './apis'; import { isNumber, createGuid, deepCopy, hexToRgba, addNumMethod, hexSwitch, textStyle, querySkipUrl, isJson, stationData, getVideoUrl, } from './js/utils'; import './index.less'; const goJS = go.GraphObject.make; let online = false; let imgUrl = null; let modalComponent = null; // 点击节点展示的模态框内容 let modalConfirmFn = null; // 点击节点展示的模态框的确定事件 let auModalConfirmFn = null; // 登录模态框的确定事件 let jumpModalProps = null; let modalProps = {}; let modalWidth = 520; let historyInfoParams = []; let nodeData = null; // 选中节点的数据 let twoID = ''; const waterFlow = new WaterFlowControlView(); const ConfigurationView = (props) => { let myDiagram = null; let mqttView = null; let editionArr = []; const guidAggre = {}; const bindData = []; const stationList = []; const { getPrefixCls } = useContext(ConfigProvider.ConfigContext); const prefixCls = getPrefixCls('ec-configuration-view'); const componentPrefix = getPrefixCls(''); const [isModalVisible, setIsModalVisible] = useState(false); const [isAuModalVisible, setIsAuModalVisible] = useState(false); // 登录模态框 const [isHIModalVisible, setIsHIModalVisible] = useState(false); // 历史曲线模态框 const [isJumpModalVisible, setIsJumpModalVisible] = useState(false); // 画板跳转模态框 const [spinning, setSpinning] = useState(true); // 画板loading const [isEmpty, setIsEmpty] = useState(false); // 画板无数据状态 const [description, setDescription] = useState(''); // 画板无数据描述 const [first, setFirst] = useState(true); // 第一次加载 const [isVideoVisible, setIsVideoVisible] = useState(false); const [videoData, setVideoData] = useState([]); const [videoTitle, setVideoTitle] = useState(''); twoID = `TDG${Date.now().toString(36)}`; const AdjustControlInput = useRef(); const AuthorFrom = useRef(); const ConfigurationRef = useRef(); const customBack = props.customBack ? props.customBack : () => {}; const { devices = [], config, isZoom = false, flowShow = true, deviceName = [] } = props; let devicesCode = []; const globalConfig = window.globalConfig || config; let isClose = false; const _JessibucaObj = { operateBtns: { screenshot: false, }, loadingText: '视频加载中', decoder: '/JessibucaVideo/decoder.js', }; /** **********************************获取工艺图画板信息*********************** */ const getConfiguraList = async () => { const url = globalConfig.mainserver ? globalConfig.mainserver : 'https://panda-water.cn/'; imgUrl = online ? `${url}PandaMonitor/Monitor/` : `/PandaMonitor/Monitor/`; // 获取画板信息 const drawInfo = await getSketchPadList({ name: props.name, siteCode: globalConfig.userInfo && globalConfig.userInfo.LocalSite ? globalConfig.userInfo.LocalSite : '', version: '全部', _site: globalConfig.userInfo && globalConfig.userInfo.LocalSite ? globalConfig.userInfo.LocalSite : '', }); if (drawInfo.code === 0) { const data = drawInfo.data ? (drawInfo.data.list ? drawInfo.data.list : []) : []; if (data.length > 0) { const num = data.length ? (data[0].num ? data[0].num * 1 : 0) : 0; const siteInfo = data.length ? (data[0].siteInfo ? JSON.parse(data[0].siteInfo) : {}) : {}; for (let i = 0; i < num; i++) { const round = parseInt(i / 26); const remain = i % 26; if (round) { stationList.push(stationData[remain] + round); } else { stationList.push(stationData[remain]); } } const siteInfoArr = Object.getOwnPropertyNames(siteInfo); devicesCode = []; siteInfoArr.forEach((name, index) => { const deviceList = devices[index] || (siteInfo && siteInfo[name] ? siteInfo[name].Code || '' : ''); bindData.push({ code: deviceList, name, type: siteInfo && siteInfo[name] ? siteInfo[name].Type : '', }); devicesCode.push(deviceList); }); getDiagramJson(data[0], siteInfo); } else { setDescription('咦~未查询到工艺图画板信息哦~'); setIsEmpty(true); setSpinning(false); return false; } } else { setDescription('咦~工艺图画板信息报错啦~'); setIsEmpty(true); setSpinning(false); return message.error(drawInfo.msg); } // 获取点表信息 const pointInfo = devicesCode.length ? await getPointAddress({ code: devicesCode.join(','), _site: globalConfig.userInfo && globalConfig.userInfo.LocalSite ? globalConfig.userInfo.LocalSite : '', }) : null; editionArr = deepCopy(pointInfo && pointInfo.data ? pointInfo.data : [], []); }; /** *********************************节点展示逻辑****************************** */ const showNodeMethod = (node, list) => { const realVal = list.Value * 1; let switchState; myDiagram.model.setDataProperty(node, 'realVal', realVal); if (node.switch === '是') { switchState = openValState(node.openVal, realVal) ? '开' : '关'; myDiagram.model.setDataProperty(node, 'switchState', switchState); } if (!node.shType) return false; const patt = /[><=]/gi; let shRule = []; try { switch (node.category) { case 'svgCase': // 图片模型 shRule = ruleOperation(node, realVal); if (node.shType === '模型切换') { myDiagram.model.setDataProperty(node, 'imgSrc', shRule ? shRule.attr : node.dtImgSrc); } else if (node.shType === '显隐展示') { myDiagram.model.setDataProperty(node, 'visible', shRule ? shRule.visible : true); } break; case 'nameCase': // 名称模型 if (node.shType === '文本变化') { shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty( node, 'fontStroke', shRule ? shRule.attr : node.dtFontStroke, ); myDiagram.model.setDataProperty(node, 'text', shRule ? shRule.text : node.dtText); } else { shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty( node, 'fillColor', hexToRgba(shRule ? shRule.attr : node.fill, node.opacity), ); } break; case 'valCase': // 实时值模型 const division = node.division || false; if (node.shType === '值显示') { myDiagram.model.setDataProperty( node, 'showVal', realVal < 0 ? 0 : division ? realVal.toLocaleString() : realVal, ); } else { myDiagram.model.setDataProperty( node, 'showVal', division ? realVal.toLocaleString() : realVal, ); } // 颜色规则 if (node.stateName) return false; shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty( node, 'fontStroke', node.realType === '在线' ? shRule ? shRule.attr : node.fontStroke : node.oflColor || '#999999', ); myDiagram.model.setDataProperty(node, 'dtStroke', shRule ? shRule.attr : node.fontStroke); break; case 'waterCase': // 水池模型 const height = node.height - node.strokeWidth * 2; let waterHight = (realVal * height) / node.poolHight; waterHight = waterHight >= height ? height : waterHight; myDiagram.model.setDataProperty(node, 'waterHight', waterHight); shRule = JSON.parse(node.shRule); shRule.forEach((item) => { const min = item.min && !isNaN(item.min * 1) ? item.min * 1 : 0; const max = item.max && !isNaN(item.max * 1) ? item.max * 1 : 0; if (realVal >= min && realVal < max) myDiagram.model.setDataProperty( node, 'fillColor', hexToRgba(item.attr ? item.attr : node.fill, node.fillAlpha), ); }); break; case 'switchCase': // 开关模型 shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty( node, 'fillColor', hexToRgba(shRule ? shRule.attr : node.fill, node.opacity), ); myDiagram.model.setDataProperty(node, 'switch', shRule ? '是' : '否'); break; case 'rotateCase': // 状态模型 shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty(node, 'imgSrc', shRule ? shRule.attr : node.dtImgSrc); break; case 'pointCase': // 点状态模型 shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty( node, 'fillColor', hexToRgba(shRule ? shRule.attr : node.fill, node.opacity), ); break; case 'blenderCase': // 搅拌机模型 break; case 'HBar': // 合管模型 shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty(node, 'stroke', shRule ? shRule.attr : node.stroke); myDiagram.model.setDataProperty( node, 'waterStroke', shRule ? shRule.text : node.waterStroke, ); break; case 'speedCase': // 进度条模型 shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty( node, 'fillColor', hexToRgba(shRule ? shRule.attr : node.fill, node.opacity), ); const { width } = node; let speedWidth = (realVal * width) / node.speedWidth; speedWidth = speedWidth >= width ? width : speedWidth; myDiagram.model.setDataProperty(node, 'lineWidth', speedWidth); break; case 'modelCase': // 模板块模型 shRule = ruleOperation(node, realVal); if (node.shType === '层级展示') { myDiagram.model.setDataProperty( node, 'zOrder', shRule ? shRule.text * 1 || node.dtzOrder : node.dtzOrder, ); } else if (node.shType === '显隐展示') { myDiagram.model.setDataProperty(node, 'visible', shRule ? shRule.visible : true); } break; case 'ellipseCase': // 圆形模型 shRule = ruleOperation(node, realVal); if (node.shType === '层级展示') { myDiagram.model.setDataProperty( node, 'zOrder', shRule ? shRule.text * 1 || node.dtzOrder : node.dtzOrder, ); } else if (node.shType === '显隐展示') { myDiagram.model.setDataProperty(node, 'visible', shRule ? shRule.visible : true); } break; case 'imgCase': // 图片模型 shRule = ruleOperation(node, realVal); if (node.shType === '层级展示') { myDiagram.model.setDataProperty( node, 'zOrder', shRule ? shRule.text * 1 || node.dtzOrder : node.dtzOrder, ); } else if (node.shType === '显隐展示') { myDiagram.model.setDataProperty(node, 'visible', shRule ? shRule.visible : true); } break; default: break; } } catch (e) { // console.log(e); } }; /** *********************************节点状态展示逻辑****************************** */ const stateMethod = (node, list) => { const realVal = list.Value * 1; if (!node.shType) return false; let shRule = []; try { switch (node.category) { case 'valCase': // 实时值模型 // 颜色规则 shRule = ruleOperation(node, realVal); myDiagram.model.setDataProperty( node, 'fontStroke', node.realType === '在线' ? shRule ? shRule.attr : node.fontStroke : node.oflColor || '#999999', ); myDiagram.model.setDataProperty(node, 'dtStroke', shRule ? shRule.attr : node.fontStroke); break; default: break; } } catch (e) { // console.log(e); } }; /** ***********************************展示规则运算********************************* */ const ruleOperation = (node, realVal) => { const patt = /[><=]/gi; const shRule = JSON.parse(node.shRule).find((rule) => { if (rule.val.toString().match(patt)) { const ruleStr = 'if(' + rule.val + '){ return true } else { return false }'; try { return new Function('x', 'X', ruleStr)(realVal, realVal); } catch (err) { return false; } } else { return rule.val.toString().split(',').indexOf(realVal.toString()) > -1; } }); return shRule; }; /** ***********************************运行值规则运算********************************* */ const openValState = (openVal, realVal) => { const patt = /[><=]/gi; if (openVal.toString().match(patt)) { const ruleStr = 'if(' + openVal + '){ return true } else { return false }'; try { return new Function('x', 'X', ruleStr)(realVal, realVal); } catch (err) { return false; } } else { return openVal.toString().split(',').indexOf(realVal.toString()) > -1; } }; /** ***********************************MQTT控制结果回调********************************* */ const controlData = (mqttDatas, code) => { const controlInfo = JSON.parse(mqttDatas); if (guidAggre[code]) { const guid = guidAggre[code]; if (!controlInfo.result) { message.warning(`${guid.tag}控制失败,${controlInfo.message}!`); } else { message.success(`${guid.tag}控制下发成功。`); } delete guidAggre[code]; } }; /** *********************************MQTT请求数据回调****************************** */ const refreshData = (mqttDatas, code) => { const bindList = bindData.find((item) => { return item.code === code; }); const name = bindList ? bindList.name : ''; const mqttData = JSON.parse(mqttDatas)[code]; const editionList = editionArr.find((item) => { return item.code === code; }); if (!mqttData) return false; const json = JSON.parse(myDiagram.model.toJson()); const jsonCopy = JSON.parse(JSON.stringify(json)); const oldJson = deepCopy(jsonCopy, {}); try { myDiagram.model.linkDataArray.forEach((item) => { if (!item.shName || item.stationName !== name || item.shType !== '线条展示') return false; mqttData.forEach((list) => { const itemID = list.ItemID; const num = itemID.lastIndexOf('.'); const ptName = itemID.substring(0, num); const shName = itemID.substring(num + 1, Infinity); if (editionList && `${editionList.name}.${editionList.version}` !== ptName) return false; if (list.Value == null || shName !== item.shName || item.realVal === list.Value) return false; item.realVal = list.Value * 1; const shRule = ruleOperation(item, item.realVal); if (shRule) { myDiagram.model.setDataProperty(item, 'stroke', shRule.attr); myDiagram.model.setDataProperty(item, 'waterStroke', shRule.text); } else { myDiagram.model.setDataProperty(item, 'stroke', item.stroke); myDiagram.model.setDataProperty(item, 'waterStroke', item.waterStroke); } }); }); } catch (e) { // 水流样式 } try { jsonCopy.nodeDataArray.forEach((item) => { if (!(item.shName || item.figure === 'updateTime') || item.stationName !== name) return false; const node = myDiagram.model.findNodeDataForKey(item.key); const onlineList = onLineDataMethod(mqttData); if (onlineList) { node.realType = onlineList.Value ? '在线' : '离线'; myDiagram.model.setDataProperty(node, 'realType', onlineList.Value ? '在线' : '离线'); onlineColorMethod(node); } mqttData.forEach((list) => { if (node.figure === 'updateTime') { myDiagram.model.setDataProperty( node, 'text', moment(list.Time).format('yyyy-MM-DD hh:mm:ss'), ); return false; } const itemID = list.ItemID; const num = itemID.lastIndexOf('.'); const ptName = itemID.substring(0, num); const shName = itemID.substring(num + 1, Infinity); if (editionList && `${editionList.name}.${editionList.version}` !== ptName) return false; if ( (list.Value == null || shName !== item.shName || item.realVal === list.Value) && shName !== item.stateName ) return false; if (shName === item.shName) showNodeMethod(node, list); if (shName === item.stateName) stateMethod(node, list); }); }); } catch (e) { // 节点展示 } try { const jsonModel = waterFlow.waterFlowControlByDiagramJson(oldJson, myDiagram); if (!jsonModel) return false; const oldLink = myDiagram.model.linkDataArray; const dataLink = []; jsonModel.linkDataArray.forEach((item, index) => { const list = { ...oldLink[index] }; list.isHavingDash = item.isHavingDash; dataLink.push(list); }); jsonModel.nodeDataArray.forEach((item) => { if (item.category === 'HBar') { const node = myDiagram.model.findNodeDataForKey(item.key); const waterStroke = item.typeDash ? 'transparent' : item.hBarClolor; if (item.typeDash !== node.typeDash) { myDiagram.model.setDataProperty(node, 'waterStroke', waterStroke); myDiagram.model.setDataProperty(node, 'typeDash', item.typeDash); } } }); dataLink.forEach((item) => { const node = myDiagram.findLinkForData(item); if (item.isHavingDash !== node.data.isHavingDash) myDiagram.model.setDataProperty(node.data, 'isHavingDash', item.isHavingDash); }); } catch (e) { // 水流展示 } }; /** **************************************是否在线数据获取****************************************** */ const onLineDataMethod = (data) => { const onlineList = data.find((list) => { const itemID = list.ItemID; const num = itemID.lastIndexOf('.'); const shName = itemID.substring(num + 1, Infinity); return shName === '是否在线'; }); return onlineList; }; /** **************************************是否在线颜色变化****************************************** */ const onlineColorMethod = (node) => { if (node.realVal === '--' || !node.shName) return false; try { switch (node.category) { case 'valCase': // 实时值模型 myDiagram.model.setDataProperty( node, 'fontStroke', node.realType === '在线' ? node.dtStroke : node.oflColor || '#999999', ); break; default: break; } } catch (e) { // console.log(e) } }; /** **************************************合管****************************************** */ const changLinkRouting = (e) => { const link = e.subject; if (link.toNode == null || link.fromNode == null) { return false; } if (link.fromNode.category === 'HBar' || link.toNode.category === 'HBar') { e.subject.routing = go.Link.Normal; } }; /** ************************************创建连接点*********************************** */ // 创建一个port,ID为name,spot控制其怎么被连接,放置于node的什么位置,output/input决定其哪里可以from和to const makePort = (name, spot, output, input) => { // the port is basically just a small transparent square return goJS(go.Shape, 'Circle', { fill: null, // not seen, by default; set to a translucent gray by showSmallPorts, defined below stroke: null, desiredSize: new go.Size(7, 7), alignment: spot, // align the port on the main Shape alignmentFocus: spot, // just inside the Shape portId: name, // declare this object to be a "port" fromSpot: spot, toSpot: spot, // declare where links may connect at this port fromLinkable: output, toLinkable: input, // declare whether the user may draw links to/from here cursor: 'pointer', // show a different cursor to indicate potential link point }); }; /** 动画设置*********************************************** */ const animationSvg = () => { const diagram = myDiagram; const oldskips = diagram.skipsUndoManager; diagram.skipsUndoManager = true; diagram.nodes.map((node) => { const shape = node.findObject('animateSvg'); if (!shape) return false; const gpRule = JSON.parse(node.data.gpRule || '[]').concat(); const amTime = node.data.amTime || 0; if (!amTime) return false; gpRule.map((item) => { mySetInterval(() => { const { time = 0, fill = 100, scale = 1, angle = 0 } = item; myTimeout(() => { shape.opacity = (fill || 100) / 100; shape.scale = (scale || 1) * 1; shape.angle = (angle || 0) * 1; }, 0.01 * amTime * time); }, amTime * 1); }); }); diagram.skipsUndoManager = oldskips; }; const myTimeout = (fn, delay) => { let timer; const stime = +new Date(); const myLoop = () => { if (isClose) return timer && cancelAnimationFrame(timer); const etime = +new Date(); if (stime + delay <= etime) { fn(); return; } timer = requestAnimationFrame(myLoop); }; timer = requestAnimationFrame(myLoop); return () => { cancelAnimationFrame(timer); }; }; const mySetInterval = (fn, interval) => { let timer; let stime = +new Date(); let etime; let myLoop = () => { etime = +new Date(); if (isClose) return timer && cancelAnimationFrame(timer); timer = requestAnimationFrame(myLoop); if (etime - stime >= interval) { stime = etime = +new Date(); fn(); } }; return requestAnimationFrame(myLoop); }; /** ******************************************水池效果****************************** */ const waterSvg = () => { const diagram = myDiagram; // poolWater = setInterval(() => { mySetInterval(() => { const oldskips = diagram.skipsUndoManager; diagram.skipsUndoManager = true; diagram.nodes.each((node) => { const shape = node.findObject('waterSvg'); if (!shape) return false; const range = (shape.range ? shape.range : 0) + 0.5; shape.range = range >= 5 ? 0 : range; shape.geometryString = `F M0 ${shape.range} L${shape.width} ${5 - shape.range} L${ shape.width } ${shape.height} L0 ${shape.height}z`; }); diagram.skipsUndoManager = oldskips; }, 100); }; /** ***********************************水流效果********************************** */ const loop = () => { const diagram = myDiagram; // tubeWater = setInterval(() => { mySetInterval(() => { const oldskips = diagram.skipsUndoManager; diagram.skipsUndoManager = true; diagram.links.each((link) => { const shape = link.findObject('PIPE'); if (!shape) return false; if (link.data.isHavingDash) { link.zOrder = 1; shape.strokeWidth = link.data.defaultWidth || 3; const off = shape.strokeDashOffset - 3; shape.strokeDashOffset = off <= 0 ? 60 : off; } else { link.zOrder = 0; shape.strokeWidth = 0; shape.strokeDashOffset = 0; } }); diagram.skipsUndoManager = oldskips; }, 60); }; /** **************************************泵状态效果*************************** */ const rotateSvg = () => { const diagram = myDiagram; // pumpType = setInterval(() => { mySetInterval(() => { const oldskips = diagram.skipsUndoManager; diagram.skipsUndoManager = true; diagram.nodes.each((node) => { const shape = node.findObject('rotateSvg'); if (!shape) return false; const _node = node.data; if (_node.switchState !== '开' || _node.realVal === '--' || _node.switch !== '是') return false; const off = shape.angle + 60; shape.angle = off <= 360 ? off : 0; }); diagram.skipsUndoManager = oldskips; }, 60); }; /** *********************************搅拌机状态效果************************* */ const blenderSvg = () => { const diagram = myDiagram; // blenderType = setInterval(() => { mySetInterval(() => { const oldskips = diagram.skipsUndoManager; diagram.skipsUndoManager = true; diagram.nodes.each((node) => { const shape = node.findObject('blenderSvg'); if (!shape) return false; const _node = node.data; const srcStr = _node.dtImgSrc.split('/').pop(); if (_node.switchState !== '开' || _node.realVal === '--' || _node.switch !== '是') { shape.source = require(`./images/组态/状态/${srcStr.replace(/[0-9]/gi, 1)}`); return false; } shape.flag = shape.flag || 1; const num = shape.source.match(/\d/)[0] * 1; let _num = 1; if (shape.flag === 1) { _num = num < 5 ? num + 1 : 4; if (num >= 5) shape.flag = 2; } else { _num = num > 1 ? num - 1 : 2; if (num <= 1) shape.flag = 1; } shape.source = require(`./images/组态/状态/${srcStr.replace(/[0-9]/gi, _num)}`); }); diagram.skipsUndoManager = oldskips; }, 100); }; /** *******************将myDiagram.model中的信息展示在画板上*********************** */ const loadDiagramProperties = (e) => { const pos = myDiagram.model.modelData.position; if (pos) myDiagram.initialPosition = go.Point.parse(pos); }; /** *******************绑定角色可见*************************** */ const roleVisibleBinding = () => { return new go.Binding('visible', '', function (data) { if (!data.roles) return true; const roles = data.roles.split(','); const curRoleMap = {}; globalConfig && globalConfig.userInfo && globalConfig.userInfo.roles && globalConfig.userInfo.roles.forEach(function (role) { curRoleMap[role.OID] = role; }); const samerole = roles.filter(function (roleID) { return !!curRoleMap[roleID]; }); return samerole.length > 0; }); }; /** ***********************************节点样式********************************** */ const nodeStyle = () => { return [ new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), { locationSpot: go.Spot.Center, }, ]; }; /** ************************************联网判断******************************* */ const onlineMethod = (pathImg, url) => { if (!first) return getConfiguraList(); const ImgObj = new Image(); ImgObj.src = pathImg; ImgObj.onload = () => { online = ImgObj.fileSize > 0 || (ImgObj.width > 0 && ImgObj.height > 0); setFirst(false); getConfiguraList(); }; ImgObj.onerror = () => { online = false; setFirst(false); getConfiguraList(); }; }; useEffect(() => { if (!props.name) { setDescription('咦~工艺图配置信息不全哦~'); setIsEmpty(true); setSpinning(false); return false; } const url = globalConfig.mainserver ? globalConfig.mainserver : 'https://panda-water.cn/'; onlineMethod(`${url}civweb4/assets/images/bootPage/熊猫图标.png`, url); return () => { isClose = true; mqttView && mqttView.disSaveWaconnect(); mqttView = null; if (myDiagram) { myDiagram.div = null; myDiagram = null; } }; }, [props.name]); useEffect(() => { if (!isModalVisible) { modalConfirmFn = null; modalComponent = null; modalProps = {}; } }, [isModalVisible]); useEffect(() => { if (!isAuModalVisible) { auModalConfirmFn = null; } }, [isAuModalVisible]); /** ************************************获取画板JSON******************************* */ const getDiagramJson = async (list, siteInfo) => { const response = await getSketchPadContent({ dimension: list.dimension, siteCode: list.siteCode, fileName: list.deployURL.split('\\').pop(), _site: globalConfig.userInfo && globalConfig.userInfo.LocalSite ? globalConfig.userInfo.LocalSite : '', }); if (response.code === 0) { if (isClose) return false; const fromJson = response.data ? response.data : { linkFromPortIdProperty: 'fromPort', linkToPortIdProperty: 'toPort', nodeDataArray: [], linkDataArray: [], }; // devices.forEach((item, index) => { // const name = `设备${stationList[index]}`; // bindData.push({ // code: item, // name, // type: siteInfo && siteInfo[name] ? siteInfo[name].Type : '', // }); // }); mqttView = devicesCode.length ? new MqttView({ mqttIP: globalConfig.mqtt_iotIP, mqttPath: globalConfig.mqtt_path, mqttSsl: globalConfig.mqtt_IsSSL, siteCode: globalConfig.mqtt_mess.site_code, devices: devicesCode, callback: refreshData, controlback: controlData, }) : null; diagramRender(typeof fromJson === 'string' ? fromJson : JSON.stringify(fromJson), list); try { mqttView && mqttView.saveWaterMqtt(); } catch (e) { // 获取实时数据 getRealData(siteInfo); } } else { message.error(response.msg); } }; /** ************************************实时数据获取******************************* */ const getRealData = async (siteInfo) => { try { if (!siteInfo) return false; const accountFieldParams = []; for (let i in siteInfo) { accountFieldParams.push({ aName: siteInfo[i].Type, }); } const params = { equipmentCode: devicesCode.join(','), accountFieldParams, }; const results = await getDeviceRealInfo(params); const realData = results && results.data && results.data.list ? results.data.list : []; chartDataRender(flatten(realData)); } catch (err) {} }; // 实时数据父子级平铺 const flatten = (arr) => { return [].concat( ...arr.map((item) => item.child ? [].concat(item, ...flatten(item.child)) : [].concat(item), ), ); }; /** ************************************图表数据处理******************************* */ const chartDataRender = (mqttData) => { const json = JSON.parse(myDiagram.model.toJson()); const jsonCopy = JSON.parse(JSON.stringify(json)); const oldJson = deepCopy(jsonCopy); try { jsonCopy.linkDataArray.forEach((item) => { if (!item.shName || item.shType !== '线条展示') return false; mqttData.forEach((list) => { const bindList = bindData.find((arr) => { return arr.code === list.code; }); const pvList = list.dataList.find((arr) => { return arr.dName === item.shName; }); if (!bindList || item.stationName !== bindList.name) return false; if ( !pvList || pvList.pv === null || pvList.dName !== item.shName || item.realVal === pvList.pv ) return false; item.realVal = pvList.pv * 1; const shRule = ruleOperation(item, item.realVal); if (shRule) { myDiagram.model.setDataProperty(item, 'stroke', shRule.attr); myDiagram.model.setDataProperty(item, 'waterStroke', shRule.text); } else { myDiagram.model.setDataProperty(item, 'stroke', item.stroke); myDiagram.model.setDataProperty(item, 'waterStroke', item.waterStroke); } }); }); } catch (e) { // 水流样式 } try { jsonCopy.nodeDataArray.forEach((item) => { if (!(item.shName || item.figure === 'updateTime')) return false; const node = myDiagram.model.findNodeDataForKey(item.key); mqttData.forEach((list) => { if (node.figure === 'updateTime') { myDiagram.model.setDataProperty( node, 'text', new Date(list.PT).format('yyyy-MM-dd hh:mm:ss'), ); return false; } const bindList = bindData.find((arr) => { return arr.code === list.code; }); const pvList = list.dataList.find((arr) => { return arr.dName === item.shName; }); if (!bindList || item.stationName !== bindList.name) return false; if ( (!pvList || pvList.pv === null || pvList.dName !== item.shName || item.realVal === pvList.pv) && pvList.dName !== item.stateName ) return false; pvList.Value = pvList.pv; if (pvList.dName === item.shName) showNodeMethod(node, pvList); if (pvList.dName === item.stateName) stateMethod(node, list); }); }); } catch (e) { // 节点展示 } try { const jsonModel = waterFlow.waterFlowControlByDiagramJson(oldJson, myDiagram); if (!jsonModel) return false; const oldLink = myDiagram.model.linkDataArray; const dataLink = []; jsonModel.linkDataArray.forEach((item, index) => { const list = Object.assign({}, oldLink[index]); list.isHavingDash = item.isHavingDash; dataLink.push(list); }); jsonModel.nodeDataArray.forEach((item) => { if (item.category == 'HBar') { const node = myDiagram.model.findNodeDataForKey(item.key); const waterStroke = item.typeDash ? 'transparent' : item.hBarClolor; if (item.typeDash != node.typeDash) { myDiagram.model.setDataProperty(node, 'waterStroke', waterStroke); myDiagram.model.setDataProperty(node, 'typeDash', item.typeDash); } } }); dataLink.forEach((item) => { const node = myDiagram.findLinkForData(item); if (item.isHavingDash != node.data.isHavingDash) myDiagram.model.setDataProperty(node.data, 'isHavingDash', item.isHavingDash); }); } catch (e) { // 水流展示 } }; /** **************************************历史模态渲染****************************************** */ const historyModalRender = (data, list) => { historyInfoParams = [ { deviceCode: list.code, sensors: data.shName, deviceType: list.type, }, ]; setIsHIModalVisible(true); }; /** **************************************渲染按钮控制****************************************** */ const renderSwitchControlModal = () => { return ( <div className={classNames('switchControlContent')}> <ExclamationCircleOutlined /> {`确定要${nodeData.text}${nodeData.ctName}?`} </div> ); }; /** **************************************渲染输入控制****************************************** */ const renderAdjustControlModal = () => { const ctRule = nodeData.ctRule ? JSON.parse(nodeData.ctRule) : []; const step = ctRule.length ? ctRule[0].step || 0.1 : 0.1; return ( <div className={classNames('adjustControlContent')}> <div className={classNames('label')}>设置</div> <Input placeholder="请输入设置值" ref={AdjustControlInput} defaultValue={nodeData.realVal} onChange={() => {}} suffix={ctRule.length ? ctRule[0].text : ''} /> <div className={classNames('adjustControlGroup')}> <Button type="primary" ghost={true} icon={<DoubleLeftOutlined />} onClick={() => adjustControlStep(step * -10)} /> <Button type="primary" ghost={true} icon={<LeftOutlined />} onClick={() => adjustControlStep(step * -1)} /> <Button type="primary" ghost={true} icon={<RightOutlined />} onClick={() => adjustControlStep(step)} /> <Button type="primary" ghost={true} icon={<DoubleRightOutlined />} onClick={() => adjustControlStep(step * 10)} /> </div> </div> ); }; const adjustControlStep = (step) => { const value = AdjustControlInput.current.state ? AdjustControlInput.current.state.value : AdjustControlInput.current.input.value; if (!isNaN(value * 1)) { if (AdjustControlInput.current.state) { AdjustControlInput.current.setState({ value: addNumMethod(value * 1, step * 1) }); } else { AdjustControlInput.current.input.value = addNumMethod(value * 1, step * 1); } } }; /** **************************************权限控制确认****************************************** */ const defineAutho = (code, tag, node, guid, value) => { const { userName, password } = AuthorFrom.current.getFieldsValue(true); if (!userName || !password) { message.warning('用户名或密码不能为空!'); return false; } setIsAuModalVisible(false); guidAggre[guid] = { tag, code, }; const flag = isNumber(value); mqttView && mqttView.onSendWaMessageArrived( userName, sha1(password).toUpperCase(), guid, code, tag, value, flag ? value * 1 : '', ); }; /** **************************************权限控制方法****************************************** */ const authoMethod = (code, tag, node, guid, value) => { setIsAuModalVisible(true); auModalConfirmFn = () => defineAutho(code, tag, node, guid, value); }; /** **************************************开关控制确定****************************************** */ const defineSwitch = (code, tag, node) => { const guid = createGuid(); setIsModalVisible(false); const ctRule = JSON.parse(node.ctRule); if (node.isControl === '是') { authoMethod(code, tag, node, guid, ctRule[0].val); return false; } guidAggre[guid] = { tag, code }; const { val } = ctRule[0]; const flag = isNumber(val); mqttView && mqttView.onSendWaMessageArrived( globalConfig.token || '', '', guid, code, tag, val, flag ? val * 1 : '', ); }; /** **************************************控制方法****************************************** */ const controlMethod = (code, tag, node) => { const ctRule = JSON.parse(node.ctRule); const min = ctRule.length ? ctRule[0].min : ''; const max = ctRule.length ? ctRule[0].max : ''; const hexfrom = ctRule.length ? ctRule[0].hexfrom : ''; const hexto = ctRule.length ? ctRule[0].hexto : ''; let value = AdjustControlInput.current.state ? AdjustControlInput.current.state.value : AdjustControlInput.current.input.value; if (value != 0 && !value) { message.warning('设置值不能为空!'); return false; } if (isNaN(value * 1)) { message.warning('设置值不合理!'); return false; } if (value < 0) { message.warning('设置值不合理!'); return false; } if (min !== '' && !isNaN(min * 1) && value < min * 1) { message.warning(`设置值不能小于${min}!`); return false; } if (max !== '' && !isNaN(max * 1) && value > max * 1) { message.warning(`设置值不能大于${max}!`); return false; } if (hexfrom && hexto) value = hexSwitch(value, hexfrom, hexto); const guid = createGuid(); setIsModalVisible(false); if (node.isControl === '是') { authoMethod(code, tag, node, guid, value); return false; } guidAggre[guid] = { tag, code }; mqttView && mqttView.onSendWaMessageArrived( globalConfig.token || '', '', guid, code, tag, node.switchType, value * 1, ); }; const moreControlMethod = (code, tag, node, value) => { const guid = createGuid(); setIsModalVisible(false); if (node.isControl === '是') { authoMethod(code, tag, node, guid, value); return false; } guidAggre[guid] = { tag, code }; const flag = isNumber(value); mqttView && mqttView.onSendWaMessageArrived( globalConfig.token || '', '', guid, code, tag, value, flag ? value * 1 : '', ); }; /** **************************************渲染多选控制****************************************** */ const renderMoreControlModal = () => { const ctRule = nodeData.ctRule ? JSON.parse(nodeData.ctRule) : []; const list = bindData.find((item) => { return item.name === nodeData.stationName; }); return ( <div className={classNames('moreControlContent')}> {ctRule.length > 0 && ctRule.map((rule, index) => { if (rule.val !== '' && rule.text !== '') { return ( <div key={index} className={classNames('moreControlList')}> <span>状态设置</span> <div onClick={(e) => moreControlMethod(list.code, nodeData.ctName, nodeData, rule.val) } > {rule.text} </div> </div> ); } })} </div> ); }; /** **************************************控制模态渲染****************************************** */ const controlModalRender = (data, list) => { const ctRule = data && data.ctRule ? JSON.parse(data.ctRule) : ''; switch (data.ctType) { case '按钮控制': if (data.switch === '是') message.warning(`当前设备已是${data.text}状态,请勿重复操作!`); if ( data.realVal === '--' || data.switch === '是' || !data.ctName || !data.ctName.length || ctRule[0].val === '' ) return false; modalComponent = renderSwitchControlModal; modalConfirmFn = () => defineSwitch(list.code, data.ctName, data); modalProps = { title: '状态控制' }; modalWidth = 520; setIsModalVisible(true); break; case '输入控制': if (data.realVal === '--' || !data.ctName) return false; modalComponent = renderAdjustControlModal; modalConfirmFn = () => controlMethod(list.code, data.ctName, data); modalProps = { title: `${data.ctName}设置` }; modalWidth = 520; setIsModalVisible(true); break; case '多选控制': if (!data.ctName) return false; modalComponent = renderMoreControlModal; modalProps = { footer: null, title: `${data.ctName}设置` }; modalWidth = 'auto'; setIsModalVisible(true); break; default: break; } }; /** **************************************视频查看****************************************** */ const videoScanMethod = async (data) => { try { const opRule = JSON.parse(data.opRule); const video = opRule && opRule.video ? opRule.video : ''; if (!video) return false; const detail = await getVideoDetail({ id: video, _site: globalConfig.userInfo && globalConfig.userInfo.LocalSite ? globalConfig.userInfo.LocalSite : '', }); const dataList = detail?.data; if (!dataList) return setVideoData([]); const videoChannels = detail?.data?.videoChannels || []; const detailList = []; videoChannels.forEach((item, index) => { detailList.push({ id: item.id, name: item.channelName, protocol: item.protocol, username: item.username, password: item.password, dataRate: 'Sub', pandavmsHost: getVideoUrl(), address: item.address, }); }); setVideoTitle(dataList?.deviceName || '视频查看'); setVideoData(detailList); setIsVideoVisible(true); } catch (e) { // console.log(e) } }; /** **************************************交互脚本****************************************** */ const interactiveScript = (data) => { try { const opRule = JSON.parse(data.opRule); const script = opRule && opRule.script ? opRule.script : ''; new Function('diagram', 'list', 'props', script)(myDiagram, data, props); } catch (e) { // console.log(e) } }; /** **************************************跳转方法****************************************** */ const menuJumpMethod = (data) => { const opRule = JSON.parse(data.opRule); const widget = opRule && opRule.widget ? opRule.widget : ''; const params = opRule && opRule.params ? (isJson(opRule.params) && JSON.parse(opRule.params)) || {} : {}; const list = querySkipUrl(globalConfig?.widgets || [], widget); if (!list || !widget) return false; window.history.pushState(params, null, `/civbase/${list.product || 'civweb4'}/${list.url}`); }; /** **************************************跳转方法****************************************** */ const drawBoardMethod = (data) => { const opRule = JSON.parse(data.opRule); const name = opRule && opRule.name ? opRule.name : ''; const title = opRule && opRule.title ? opRule.title : ''; const device = opRule && opRule.device ? opRule.device : []; const width = opRule && opRule.width ? opRule.width : ''; const height = opRule && opRule.height ? opRule.height : ''; const color = opRule && opRule.color ? opRule.color : '#282d3b'; if (!name) return false; const deviceArr = []; device.forEach((item) => { const list = bindData.find((item1) => { return item1.name === item; }); deviceArr.push(list ? list.code : item); }); jumpModalProps = { width, height, title, name, device: deviceArr, color, }; setIsJumpModalVisible(true); }; const handleOk = (e) => { e.stopPropagation(); modalConfirmFn && modalConfirmFn(); }; const handleCancel = () => { setIsModalVisible(false); }; const handleAuOk = (e) => { e.stopPropagation(); auModalConfirmFn && auModalConfirmFn(); }; const renderModalContent = () => { return modalComponent && nodeData ? modalComponent() : null; }; /** **********************************画布渲染************************************ */ const diagramRender = (jsonStr, chartInfo) => { myDiagram = goJS( go.Diagram, twoID, // must name or refer to the DIV HTML element { initialContentAlignment: go.Spot.Center, contentAlignment: go.Spot.Center, allowDrop: false, // must be true to accept drops from the Palette 右边的面板允许防止图形 draggingTool: new GuidedDraggingTool(), allowZoom: isZoom ? true : false, allowSelect: false, 'draggingTool.dragsLink': true, isReadOnly: true, autoScale: isZoom ? go.Diagram.None : go.Diagram.Uniform, // 自适应,默认不自适应 initialAutoScale: go.Diagram.Uniform, // 自适应,默认不自适应 'draggingTool.isGridSnapEnabled': true, 'linkingTool.isUnconnectedLinkValid': true, 'animationManager.duration': 100, allowHorizontalScroll: isZoom ? true : false, // padding: 20, allowVerticalScroll: isZoom ? true : false, 'linkingTool.portGravity': 20, 'relinkingTool.isUnconnectedLinkValid': true, 'relinkingTool.portGravity': 20, 'draggingTool.horizontalGuidelineColor': 'blue', 'draggingTool.verticalGuidelineColor': 'blue', 'draggingTool.centerGuidelineColor': 'green', rotatingTool: goJS(TopRotatingTool), // defined below 'rotatingTool.snapAngleMultiple': 15, 'rotatingTool.snapAngleEpsilon': 15, 'undoManager.isEnabled': true, LinkDrawn: changLinkRouting, // LinkReshaped: (e) => { // e.subject.routing = go.Link.Orthogonal; // }, 'linkingTool.direction': go.LinkingTool.ForwardsOnly, }, ); /** **********************************分组模型************************************* */ myDiagram.groupTemplate = ('groupCase', goJS( go.Group, 'Auto', { ungroupable: true, zOrder: 1 }, { // 设置其可选择 selectable: false, layerName: 'Background', }, goJS( go.Shape, 'RoundedRectangle', // surrounds everything { parameter1: 10, fill: 'transparent', strokeWidth: 0, stroke: 'transparent', }, ), goJS( go.Panel, 'Auto', // position header above the subgraph goJS( go.Placeholder, // represents area for all member parts { background: 'transparent' }, ), ), )); // 自定义矩形 go.Shape.defineFigureGenerator('RoundedRectanglePlus', (shape, w, h) => { // this figure takes one parameter, the size of the corner let p1 = Infinity; // default corner size if (shape !== null) { const param1 = shape.parameter1; if (!isNaN(param1) && param1 >= 0) p1 = param1; // can't be negative or NaN } p1 = Math.min(p1, w / 2); p1 = Math.min(p1, h / 2); // limit by whole height or by half height? const geo = new go.Geometry(); // a single figure consisting of straight lines and quarter-circle arcs geo.add( new go.PathFigure(0, p1) .add(new go.PathSegment(go.PathSegment.Arc, 180, 90, p1, p1, p1, p1)) .add(new go.PathSegment(go.PathSegment.Line, w - p1, 0)) .add(new go.PathSegment(go.PathSegment.Arc, 270, 90, w - p1, p1, p1, p1)) .add(new go.PathSegment(go.PathSegment.Arc, 0, 90, w - p1, h - p1, p1, p1)) .add(new go.PathSegment(go.PathSegment.Arc, 90, 90, p1, h - p1, p1, p1).close()), ); // don't intersect with two top corners when used in an "Auto" Panel geo.spot1 = new go.Spot(0, 0, 0.3 * p1, 0.3 * p1); geo.spot2 = new go.Spot(1, 1, -0.3 * p1, 0); return geo; }); /** *********************************节点模板************************************* */ // 背景模板定义 myDiagram.nodeTemplateMap.add( 'bgCase', goJS( go.Node, 'Spot', { locationSpot: go.Spot.Center, zOrder: 0 }, // new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('visible', 'visible').makeTwoWay(), new go.Binding('angle').makeTwoWay(), { // 设置其可选择 selectable: false, layerName: 'Background', }, // the main object is a Panel that surrounds a TextBlock with a Shape ~图形:Panel包围着TextBlock goJS( go.Panel, 'Auto', { name: 'PANEL', }, new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), goJS( go.Picture, { width: 56, height: 56, scale: 1, source: '', background: '#2e3343' }, new go.Binding('source', 'imgSrc', function (v) { const own = myDiagram ? myDiagram.model.findNodeDataForKey('bgCase') : {}; props.bgMethod && props.bgMethod(own); return v ? `/PandaMonitor/Monitor/SketchPad/PreviewResource?name=${v}&_site=${ globalConfig?.userInfo?.LocalSite || '' }` : ''; }).makeTwoWay(), new go.Binding('scale', 'scale').makeTwoWay(), new go.Binding('width', 'width').makeTwoWay(), new go.Binding('height', 'height').makeTwoWay(), new go.Binding('background', 'background').makeTwoWay(), ), ), ), ); // img节点定义 myDiagram.nodeTemplateMap.add( 'imgCase', goJS( go.Node, 'Spot', { locationSpot: go.Spot.Center, zOrder: 1, cursor: 'default' }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('cursor', 'cursor').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 // the main object is a Panel that surrounds a TextBlock with a Shape ~图形:Panel包围着TextBlock goJS( go.Panel, 'Auto', { name: 'PANEL', }, new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding('visible', 'visible').makeTwoWay(), goJS( go.Picture, { name: 'animateSvg', width: 56, height: 56, column: 0, scale: 1, source: require('./images/组态/默认.png'), }, new go.Binding('source', 'imgSrc', function (v) { return !v ? require('./images/组态/默认.png') : `/PandaMonitor/Monitor/SketchPad/PreviewResource?name=${v}&_site=${ globalConfig?.userInfo?.LocalSite || '' }`; }).makeTwoWay(), new go.Binding('scale', 'scale').makeTwoWay(), new go.Binding('width', 'width').makeTwoWay(), new go.Binding('height', 'height').makeTwoWay(), ), ), { click(e, node) { const { data } = node; nodeData = data; const list = bindData.find((item) => { return item.name === data.stationName; }); if (!list) return false; // 画板跳转 switch (data.opType) { case '画板跳转': // 图片模型 drawBoardMethod(data); break; case '功能跳转': // 功能模型 menuJumpMethod(data); break; case '视频查看': // 视频查看 videoScanMethod(data); break; case '自定义交互': // 自定义交互 customBack(data); interactiveScript(data); break; default: break; } }, }, ), ); // svg节点定义 myDiagram.nodeTemplateMap.add( 'svgCase', goJS( go.Node, 'Spot', { locationSpot: go.Spot.Center, zOrder: 1, cursor: 'default' }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('cursor', 'cursor').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Panel, 'Auto', { name: 'PANEL', }, new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding('visible', 'visible').makeTwoWay(), goJS( go.Picture, { name: 'animateSvg', width: 56, height: 56, column: 0, scale: 1, source: '' }, new go.Binding('source', 'imgSrc', (v) => { return `${imgUrl}Model/Preview/${encodeURIComponent(v)}`; }), new go.Binding('scale', 'scale').makeTwoWay(), new go.Binding('width', 'width').makeTwoWay(), new go.Binding('height', 'height').makeTwoWay(), ), ), { click(e, node) { const { data } = node; nodeData = data; const list = bindData.find((item) => { return item.name === data.stationName; }); if (!list) return false; // 控制方法 if (data.ctName && data.ctType) { controlModalRender(data, list); return false; } // 画板跳转 switch (data.opType) { case '画板跳转': // 图片模型 drawBoardMethod(data); break; case '功能跳转': // 功能模型 menuJumpMethod(data); break; case '视频查看': // 视频查看 videoScanMethod(data); break; case '自定义交互': // 自定义交互 customBack(data); interactiveScript(data); break; default: break; } }, }, ), ); // 模板块定义 myDiagram.nodeTemplateMap.add( 'modelCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 1 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), { // 设置其可改变大小 resizeObjectName: 'SHAPE', }, new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'RoundedRectanglePlus', { name: 'SHAPE', fill: 'rgba(128,128,128,0.2)', stroke: 'gray', parameter1: 0 }, new go.Binding('visible', 'visible').makeTwoWay(), new go.Binding('parameter1', 'radius').makeTwoWay(), new go.Binding('fill', 'fillColor').makeTwoWay(), new go.Binding('stroke').makeTwoWay(), new go.Binding('strokeWidth').makeTwoWay(), new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), ), ), ); // 圆形定义 myDiagram.nodeTemplateMap.add( 'ellipseCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 1 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), { // 设置其可改变大小 resizeObjectName: 'SHAPE', }, new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'Ellipse', { name: 'SHAPE', fill: 'rgba(128,128,128,0.2)', stroke: 'gray' }, new go.Binding('visible', 'visible').makeTwoWay(), new go.Binding('fill', 'fillColor').makeTwoWay(), new go.Binding('stroke').makeTwoWay(), new go.Binding('strokeWidth').makeTwoWay(), new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), ), ), ); // 设备名称定义 myDiagram.nodeTemplateMap.add( 'deviceCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 3, cursor: 'default' }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('cursor', 'cursor').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'RoundedRectanglePlus', { name: 'SHAPE', strokeWidth: 10, stroke: '#000000', parameter1: 0 }, new go.Binding('fill', 'fillColor').makeTwoWay(), new go.Binding('stroke').makeTwoWay(), new go.Binding('strokeWidth').makeTwoWay(), new go.Binding('parameter1', 'radius').makeTwoWay(), new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), ), goJS( go.TextBlock, textStyle(), { margin: 5, maxSize: new go.Size(NaN, NaN), minSize: new go.Size(NaN, 1), wrap: go.TextBlock.WrapFit, textAlign: 'center', editable: true, font: 'bold 12px Helvetica, Arial, sans-serif', stroke: '#454545', }, new go.Binding('text').makeTwoWay(), new go.Binding('font', 'fontStyle'), new go.Binding('stroke', 'fontStroke').makeTwoWay(), new go.Binding('textAlign', 'fontAlign'), new go.Binding('maxSize', 'textSize'), new go.Binding('minSize', 'textSize'), ), { click(e, node) { const { data } = node; nodeData = data; const list = bindData.find((item) => { return item.name === data.stationName; }); if (!list) return false; switch (data.opType) { case '画板跳转': // 图片模型 drawBoardMethod(data); break; case '功能跳转': // 功能模型 menuJumpMethod(data); break; case '视频查看': // 视频查看 videoScanMethod(data); break; case '自定义交互': // 自定义交互 customBack(data); interactiveScript(data); break; default: break; } }, }, ), ); // 名称定义 myDiagram.nodeTemplateMap.add( 'nameCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 3, cursor: 'default' }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('cursor', 'cursor').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'RoundedRectanglePlus', { name: 'SHAPE', strokeWidth: 10, stroke: '#000000', parameter1: 0 }, new go.Binding('fill', 'fillColor').makeTwoWay(), new go.Binding('stroke').makeTwoWay(), new go.Binding('strokeWidth').makeTwoWay(), new go.Binding('parameter1', 'radius').makeTwoWay(), new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), ), goJS( go.TextBlock, textStyle(), { margin: 5, maxSize: new go.Size(NaN, NaN), minSize: new go.Size(NaN, 1), wrap: go.TextBlock.WrapFit, textAlign: 'center', editable: true, font: 'bold 12px Helvetica, Arial, sans-serif', stroke: '#454545', }, new go.Binding('text').makeTwoWay(), new go.Binding('font', 'fontStyle'), new go.Binding('stroke', 'fontStroke').makeTwoWay(), new go.Binding('textAlign', 'fontAlign'), new go.Binding('maxSize', 'textSize'), new go.Binding('minSize', 'textSize'), ), { click(e, node) { const { data } = node; nodeData = data; const list = bindData.find((item) => { return item.name === data.stationName; }); if (!list) return false; // 控制方法 if (data.ctName && data.ctType) { controlModalRender(data, list); return false; } switch (data.opType) { case '画板跳转': // 图片模型 drawBoardMethod(data); break; case '功能跳转': // 功能模型 menuJumpMethod(data); break; case '视频查看': // 视频查看 videoScanMethod(data); break; case '自定义交互': // 自定义交互 customBack(data); interactiveScript(data); break; default: break; } }, }, ), ); // 公用管定义 myDiagram.nodeTemplateMap.add( 'HBar', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 1 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), { // 设置其可改变大小 resizable: false, layerName: 'Background', }, roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'Rectangle', { name: 'SHAPE', height: 0, width: 120, fill: '#41BFEC', stroke: null, strokeWidth: 0, minSize: new go.Size(20, 0), maxSize: new go.Size(Infinity, 0), }, new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding('minSize', 'minSize').makeTwoWay(), new go.Binding('maxSize', 'maxSize').makeTwoWay(), new go.Binding('stroke', 'stroke').makeTwoWay(), new go.Binding('strokeWidth', 'strokeWidth').makeTwoWay(), ), goJS( go.Shape, { isPanelMain: true, stroke: 'white', strokeWidth: 3, height: 0, width: 100, name: 'PIPE', strokeDashArray: [20, 40], }, new go.Binding('width').makeTwoWay(), new go.Binding('stroke', 'waterStroke').makeTwoWay(), new go.Binding('strokeWidth', 'waterWidth').makeTwoWay(), new go.Binding('strokeDashArray', 'strokeDashArray').makeTwoWay(), { portId: '', toLinkable: true, fromLinkable: true, }, ), ), ); // 值定义 myDiagram.nodeTemplateMap.add( 'valCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 2, cursor: 'default' }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('cursor', 'cursor').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'RoundedRectanglePlus', { name: 'SHAPE', strokeWidth: 10, stroke: '#000000', parameter1: 0 }, new go.Binding('fill', 'fillColor'), new go.Binding('stroke'), new go.Binding('strokeWidth'), new go.Binding('parameter1', 'radius').makeTwoWay(), new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), ), goJS( go.TextBlock, textStyle(), { maxSize: new go.Size(NaN, NaN), minSize: new go.Size(NaN, 1), wrap: go.TextBlock.WrapFit, textAlign: 'center', editable: true, font: 'bold 12px Helvetica, Arial, sans-serif', stroke: '#454545', }, new go.Binding('text', 'showVal'), new go.Binding('font', 'fontStyle'), new go.Binding('stroke', 'fontStroke'), new go.Binding('textAlign', 'fontAlign'), new go.Binding('maxSize', 'textSize'), new go.Binding('minSize', 'textSize'), ), { click(e, node) { const { data } = node; nodeData = data; const list = bindData.find((item) => { return item.name === data.stationName; }); if (!list) return false; // 控制方法 if (data.ctName && data.ctType) { controlModalRender(data, list); return false; } // 历史查看 if (data.opType && data.shName) historyModalRender(data, list); }, }, ), ); // 连接点定义 myDiagram.nodeTemplateMap.add( 'linkPort', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 1 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色 goJS( go.Panel, 'Auto', { name: 'PANEL', }, goJS(go.Shape, 'Rectangle', { fill: 'transparent', strokeWidth: 0, width: 8, height: 8, minSize: new go.Size(5, 5), }), ), ), ); // 水池动效 go.Shape.defineFigureGenerator('Pool', (shape, w, h) => { const geo = new go.Geometry(); const fig = new go.PathFigure(0, 0, true); // starting point geo.add(fig); fig.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0)); fig.add(new go.PathSegment(go.PathSegment.Line, w, 0.25 * h)); fig.add(new go.PathSegment(go.PathSegment.Line, w, h)); fig.add(new go.PathSegment(go.PathSegment.Line, 0, h).close()); return geo; }); // 定义水池 myDiagram.nodeTemplateMap.add( 'waterCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 1 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'Rectangle', { name: 'SHAPE', alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Bottom, fill: 'transparent', strokeWidth: 10, stroke: 'red', desiredSize: new go.Size(NaN, 26), }, new go.Binding('width').makeTwoWay(), new go.Binding('height').makeTwoWay(), new go.Binding('stroke', 'stroke').makeTwoWay(), new go.Binding('strokeWidth', 'strokeWidth').makeTwoWay(), ), goJS( go.Shape, 'Rectangle', { name: 'SHAPE', alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Bottom, fill: '#ccc', strokeWidth: 10, stroke: 'transparent', desiredSize: new go.Size(NaN, 26), }, new go.Binding('width').makeTwoWay(), new go.Binding('height').makeTwoWay(), new go.Binding('fill', 'waterColor').makeTwoWay(), new go.Binding('strokeWidth', 'strokeWidth').makeTwoWay(), ), goJS( go.Shape, 'Pool', { name: 'waterSvg', alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Bottom, fill: '#DEE0A3', stroke: 'transparent', strokeWidth: 10, minSize: new go.Size(NaN, 5), desiredSize: new go.Size(NaN, 20), }, new go.Binding('width').makeTwoWay(), new go.Binding('height', 'waterHight').makeTwoWay(), new go.Binding('fill', 'fillColor').makeTwoWay(), new go.Binding('strokeWidth', 'strokeWidth').makeTwoWay(), ), ), ); // 定义进度条 myDiagram.nodeTemplateMap.add( 'speedCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 1 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'RoundedRectanglePlus', { name: 'SHAPE', alignment: go.Spot.Left, alignmentFocus: go.Spot.Left, strokeWidth: 2, stroke: '#FFFFFF', desiredSize: new go.Size(NaN, 26), fill: 'transparent', parameter1: 5, }, new go.Binding('width').makeTwoWay(), new go.Binding('height').makeTwoWay(), new go.Binding('strokeWidth', 'strokeWidth').makeTwoWay(), new go.Binding('parameter1', 'radius').makeTwoWay(), new go.Binding('stroke', 'stroke').makeTwoWay(), ), goJS( go.Shape, 'RoundedRectanglePlus', { name: 'SHAPE', alignment: go.Spot.Left, alignmentFocus: go.Spot.Left, fill: '#CCCCCC', strokeWidth: 2, stroke: 'transparent', desiredSize: new go.Size(NaN, 26), parameter1: 5, }, new go.Binding('width').makeTwoWay(), new go.Binding('height').makeTwoWay(), new go.Binding('fill', 'waterColor').makeTwoWay(), new go.Binding('parameter1', 'radius').makeTwoWay(), new go.Binding('strokeWidth', 'strokeWidth').makeTwoWay(), ), goJS( go.Shape, 'RoundedRectanglePlus', { name: 'speedSvg', alignment: go.Spot.Left, alignmentFocus: go.Spot.Left, fill: '#DEE0A3', stroke: 'transparent', strokeWidth: 2, minSize: new go.Size(NaN, 5), desiredSize: new go.Size(NaN, 20), parameter1: 5, }, new go.Binding('width', 'lineWidth').makeTwoWay(), new go.Binding('height', 'height').makeTwoWay(), new go.Binding('parameter1', 'radius').makeTwoWay(), new go.Binding('fill', 'fillColor').makeTwoWay(), new go.Binding('strokeWidth', 'strokeWidth'), ), ), ); // 泵状态设置 myDiagram.nodeTemplateMap.add( 'rotateCase', goJS( go.Node, 'Table', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 2 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), { // 设置其可改变大小 resizeObjectName: 'SHAPE', rotatable: true, }, roleVisibleBinding(), // 绑定角色可见 goJS( go.Panel, 'Table', { name: 'PANEL', }, goJS( go.Shape, 'Ellipse', // 定义形状 { width: 37, height: 37, fill: 'transparent', stroke: 'transparent', strokeWidth: 1 }, new go.Binding('width', 'widthBox').makeTwoWay(), new go.Binding('height', 'heightBox').makeTwoWay(), ), new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), goJS( go.Picture, { name: 'rotateSvg', width: 26, height: 26, column: 0, scale: 1, source: require('./images/组态/状态/泵离线.svg'), angle: 0, }, new go.Binding('source', 'imgSrc', (v) => { return require(`./images/组态/状态/${v.split('/').pop()}`); }).makeTwoWay(), new go.Binding('scale', 'scale').makeTwoWay(), new go.Binding('width', 'width').makeTwoWay(), new go.Binding('angle', 'angle').makeTwoWay(), new go.Binding('height', 'height').makeTwoWay(), ), ), ), ); // 点状态设置 myDiagram.nodeTemplateMap.add( 'pointCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 2 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'Ellipse', { width: 14, height: 14, name: 'SHAPE', fill: 'rgba(109, 122, 151, 1)', stroke: '#ffffff', }, new go.Binding('fill', 'fillColor').makeTwoWay(), new go.Binding('stroke').makeTwoWay(), new go.Binding('strokeWidth').makeTwoWay(), new go.Binding('height', 'height').makeTwoWay(), new go.Binding('width', 'height').makeTwoWay(), ), ), ); // 开关开设置 myDiagram.nodeTemplateMap.add( 'switchCase', goJS( go.Node, 'Auto', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 2, cursor: 'default' }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('cursor', 'cursor').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, 'RoundedRectanglePlus', { name: 'SHAPE', strokeWidth: 10, stroke: '#000000', parameter1: 5 }, new go.Binding('fill', 'fillColor'), new go.Binding('stroke'), new go.Binding('strokeWidth'), new go.Binding('parameter1', 'radius').makeTwoWay(), new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), ), goJS( go.TextBlock, textStyle(), { maxSize: new go.Size(NaN, NaN), minSize: new go.Size(NaN, 1), wrap: go.TextBlock.WrapFit, textAlign: 'center', editable: true, font: 'bold 12px Helvetica, Arial, sans-serif', stroke: '#454545', }, new go.Binding('text'), new go.Binding('font', 'fontStyle'), new go.Binding('stroke', 'fontStroke'), new go.Binding('textAlign', 'fontAlign'), new go.Binding('maxSize', 'textSize'), new go.Binding('minSize', 'textSize'), ), { click(e, node) { const { data } = node; nodeData = data; const list = bindData.find((item) => { return item.name === data.stationName; }); if (!list) return false; // 控制方法 controlModalRender(data, list); }, }, ), ); // 搅拌机状态设置 myDiagram.nodeTemplateMap.add( 'blenderCase', goJS( go.Node, 'Table', nodeStyle(), 'Spot', { locationSpot: go.Spot.Center, zOrder: 2 }, new go.Binding('zOrder', 'zOrder').makeTwoWay(), new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), { // 设置其可改变大小 resizeObjectName: 'SHAPE', rotatable: true, }, new go.Binding('angle').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Panel, 'Auto', { name: 'PANEL', }, new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify), goJS( go.Picture, { name: 'blenderSvg', width: 42.5, height: 56, column: 0, scale: 1, source: require('./images/组态/状态/搅拌机双头1.svg'), angle: 0, }, new go.Binding('source', 'imgSrc', (v) => { return require(`./images/组态/状态/${v.split('/').pop()}`); }).makeTwoWay(), new go.Binding('scale', 'scale').makeTwoWay(), new go.Binding('width', 'width').makeTwoWay(), new go.Binding('angle', 'angle').makeTwoWay(), new go.Binding('height', 'height').makeTwoWay(), ), ), ), ); // 连接线装饰模板 const linkSelectionAdornmentTemplate = goJS( go.Adornment, 'Link', goJS(go.Shape, { isPanelMain: true, fill: null, stroke: 'deepskyblue', strokeWidth: 0, }), ); /** *******************************单管连接方式****************************** */ myDiagram.linkTemplate = goJS( BarLink, { curve: go.Link.JumpOver, toShortLength: 0, fromShortLength: 0, layerName: 'Background', routing: go.Link.Orthogonal, // 不同的位置进行不同的routing corner: 2, reshapable: true, resegmentable: true, relinkableFrom: true, relinkableTo: true, zOrder: 1, }, new go.Binding('fromSpot', 'fromPort', (d) => { return spotConverter(d); }), new go.Binding('toSpot', 'toPort', (d) => { return spotConverter(d); }), new go.Binding('points').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 goJS( go.Shape, { isPanelMain: true, stroke: '#41BFEC' /* blue */, strokeWidth: 6, name: 'changecolor' }, new go.Binding('stroke', 'stroke'), new go.Binding('strokeWidth', 'strokeWidth'), ), goJS( go.Shape, { isPanelMain: true, stroke: 'white', strokeWidth: 3, name: 'PIPE', strokeDashArray: [20, 40], }, new go.Binding('strokeWidth', 'waterWidth'), new go.Binding('stroke', 'waterStroke'), ), ); /** *******************************sharpLine线条****************************** */ myDiagram.linkTemplateMap.add( 'sharpLine', goJS( BarLink, { curve: go.Link.JumpOver, resegmentable: true, adjusting: go.Link.Stretch, routing: go.Link.Normal, layerName: 'Background', routing: go.Link.Normal, //不同的位置进行不同的routing corner: 0, reshapable: true, resegmentable: true, relinkableFrom: true, relinkableTo: true, relinkableFrom: true, relinkableTo: true, zOrder: 1, }, new go.Binding('fromSpot', 'fromPort', function (d) { return spotConverter(d); }), new go.Binding('toSpot', 'toPort', function (d) { return spotConverter(d); }), new go.Binding('points').makeTwoWay(), roleVisibleBinding(), // 绑定角色可见 // mark each Shape to get the link geometry with isPanelMain: true goJS( go.Shape, { isPanelMain: true, stroke: '#41BFEC' /* blue*/, strokeWidth: 6, name: 'changecolor', }, new go.Binding('stroke', 'stroke'), new go.Binding('strokeWidth', 'strokeWidth'), ), goJS( go.Shape, { isPanelMain: true, stroke: 'white', strokeWidth: 3, name: 'PIPE', strokeDashArray: [20, 40], }, new go.Binding('strokeWidth', 'waterWidth'), new go.Binding('stroke', 'waterStroke'), ), ), ); /** **************************************合管连接方式****************************************** */ // myDiagram.linkTemplateMap.add( // 'linkToLink', // goJS( // 'Link', // { relinkableFrom: true, relinkableTo: true }, // goJS('Shape', { // stroke: '#2D9945', // strokeWidth: 2, // }), // ), // ); const fromJson = JSON.parse(jsonStr); myTimeout(() => { loop(); waterSvg(); rotateSvg(); blenderSvg(); animationSvg(); }, 100); const json = JSON.parse(JSON.stringify(fromJson)); json.linkDataArray.forEach((item) => { item.isHavingDash = flowShow; item.realVal = '--'; item.defaultWidth = item.waterWidth; }); json.nodeDataArray.forEach((item) => { item.showVal = '--'; item.realVal = '--'; item.realType = '在线'; item.Unit = ''; item.switchState = '开'; item.dtImgSrc = item.imgSrc || ''; if (item.category === 'HBar') { item.hBarClolor = item.waterStroke; item.typeDash = false; } if (item.category === 'valCase') { if (item.shType === '') item.showVal = item.text; item.dtStroke = item.fontStroke; } if (item.category === 'nameCase') { item.dtFillColor = item.fillColor; item.dtStroke = item.stroke; item.dtFontStroke = item.fontStroke; item.dtText = item.text; } if (item.category === 'modelCase' || item.category === 'ellipseCase') { item.dtzOrder = item.zOrder; } if (item.category == 'deviceCase' && item.shType && deviceName && deviceName.length) { var device = deviceName.find(function (arr, index) { return '设备' + stationList[index] == item.stationName; }); if (device) item.text = device; } // 兼容V1之前版本(部分展示可支持) if (chartInfo.version === 'V1') return false; item.shName = item.showName || ''; item.hbControl = item.authoControl || '否'; if (item.controlType === '开关展示') item.switch = '是'; if (item.category === 'valCase') item.shType = '值显示'; }); myDiagram.model = go.Model.fromJson(json); }; return ( <div className={classNames(prefixCls)} ref={ConfigurationRef}> <div id={twoID} className={classNames('configurationView')}> <LoadBox spinning={spinning} /> {isEmpty && <Empty theme={'dark'} description={description} />} </div> {/* 远程控制 */} {isModalVisible && ( <Modal centered okText={'确定'} width={modalWidth} cancelText={'取消'} open={isModalVisible} onOk={handleOk} onCancel={handleCancel} wrapClassName={classNames(`${prefixCls}-baseModal`)} getContainer={ConfigurationRef.current} {...modalProps} > {renderModalContent()} </Modal> )} {/* 权限登录 */} {isAuModalVisible && ( <Modal centered title={'权限认证'} okText={'确定'} cancelText={'取消'} open={isAuModalVisible} onOk={handleAuOk} onCancel={() => setIsAuModalVisible(false)} getContainer={ConfigurationRef.current} width={520} wrapClassName={classNames(`${prefixCls}-baseModal`)} > <Form className={classNames('authorizeControlContent')} ref={AuthorFrom} name="loginForm"> <Form.Item className={classNames('authorizeControlItem')} name="userName" label="账户"> <Input placeholder="请输入用户名" /> </Form.Item> <Form.Item className={classNames('authorizeControlItem')} name="password" label="密码"> <Input.Password placeholder="请输入密码" /> </Form.Item> </Form> </Modal> )} {/* 历史曲线 */} {isHIModalVisible && ( <Modal centered width={1200} footer={null} open={isHIModalVisible} onOk={() => setIsHIModalVisible(false)} onCancel={() => setIsHIModalVisible(false)} getContainer={ConfigurationRef.current} wrapClassName={classNames(`${prefixCls}-historyInfoModal`)} > <HistoryView deviceParams={historyInfoParams} /> </Modal> )} {/* 画板跳转 */} {isJumpModalVisible && jumpModalProps && ( <DragModal centered width={jumpModalProps.width ? `${jumpModalProps.width}px` : '100vw'} title={jumpModalProps.title} footer={null} visible={isJumpModalVisible} limit={true} onCancel={() => setIsJumpModalVisible(false)} wrapClassName={classNames(`${prefixCls}-jumpModal`)} getContainer={ConfigurationRef.current} componentPrefix={componentPrefix} destroyOnClose={true} style={{ height: jumpModalProps.height ? `${Number(jumpModalProps.height) + 103}px` : '100vh', left: `calc(50% - ${jumpModalProps.width ? jumpModalProps.width / 2 + 'px' : '50%'})`, top: `calc(50% - ${ jumpModalProps.height ? (Number(jumpModalProps.height) + 103) / 2 + 'px' : '50%' })`, }} > <ConfigurationDetail {...props} name={jumpModalProps.name} devices={jumpModalProps.device} /> </DragModal> )} {isVideoVisible && ( <VideoSliderModal modalInfo={{ title: videoTitle, open: isVideoVisible, onCancel: () => { setIsVideoVisible(false); }, }} videoInfos={videoData} JessibucaObj={_JessibucaObj} /> )} </div> ); }; ConfigurationView.defaultProps = { name: '', devices: [], deviceName: [], config: {}, isZoom: false, flowShow: true, customBack: () => {}, }; ConfigurationView.propTypes = { name: PropTypes.string, devices: PropTypes.array, deviceName: PropTypes.array, config: PropTypes.object, isZoom: PropTypes.bool, flowShow: PropTypes.bool, customBack: PropTypes.func, }; export default ConfigurationView;