Files
HTCloud/HT.Cloud.Web/Areas/DevicesManage/Views/DeviceMonitor/Index.cshtml
dell c15babafd3
Some checks failed
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
可视化修改
2025-10-17 09:15:31 +08:00

824 lines
30 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Index.cshtml";
}
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment env
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style>
/* 基本样式确保图表显示正确 */
.path {
background-color: transparent; /* 子元素背景透明,继承父元素背景 */
fill:transparent;
}
#svg-container {
width: 100%;
height: auto;
border: 1px solid #ccc;
overflow: auto;
}
.text-and-button {
display: flex;
align-items: center;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
height:30px;
}
.text-and-button .text-content {
/* 设置文本格式 */
font-family: Arial, sans-serif;
font-size: 16px;
color: #333;
margin-right: 20px; /* 文本与按钮之间的间隔 */
}
.text-and-button button {
/* 设置按钮样式 */
background-color:#4CAF50; /* 绿色背景 */
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
border-radius: 5px;
}
/* 初始样式定义 */
.defaultNode {
fill: #ffffff;
stroke: #000000;
stroke-width: 2px;
color: #000000;
}
/* 更新后的样式 */
.updatedNode {
fill: #add8e6; /* 浅蓝色作为底色 */
stroke: #333333;
stroke-width: 3px;
color: #ff0000; /* 红色作为文字颜色 */
}
.layui-card {
border: 1px solid #f2f2f2;
border-radius: 5px;
}
.icon {
margin-right: 10px;
color: #1aa094;
}
.icon-cray {
color: #ffb800 !important;
}
.icon-blue {
color: #1e9fff !important;
}
.icon-tip {
color: #ff5722 !important;
}
.layuimini-qiuck-module {
text-align: center;
margin-top: 10px
}
.layuimini-qiuck-module a i {
display: inline-block;
width: 100%;
height: 60px;
line-height: 60px;
text-align: center;
border-radius: 2px;
font-size: 30px;
background-color: #F8F8F8;
color: #333;
transition: all .3s;
-webkit-transition: all .3s;
}
.layuimini-qiuck-module a cite {
position: relative;
top: 2px;
display: block;
color: #666;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-size: 14px;
}
.welcome-module {
width: 100%;
height: 210px;
}
.panel {
background-color: #fff;
border: 1px solid transparent;
border-radius: 3px;
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);
box-shadow: 0 1px 1px rgba(0,0,0,.05)
}
.panel-body {
padding: 10px
}
.panel-title {
margin-top: 0;
margin-bottom: 0;
font-size: 12px;
color: inherit
}
.label {
display: inline;
padding: .2em .6em .3em;
font-size: 75%;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
margin-top: .3em;
}
.label {
display: inline;
padding: .2em .6em .3em;
font-size: 75%;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
margin-top: .3em;
}
.layui-red {
color: red
}
.main_btn > p {
height: 40px;
}
.layui-bg-number {
background-color: #F8F8F8;
}
.layuimini-notice:hover {
background: #f6f6f6;
}
.layuimini-notice {
padding: 7px 16px;
clear: both;
font-size: 12px !important;
cursor: pointer;
position: relative;
transition: background 0.2s ease-in-out;
}
.layuimini-notice-title, .layuimini-notice-label {
padding-right: 70px !important;
text-overflow: ellipsis !important;
overflow: hidden !important;
white-space: nowrap !important;
}
.layuimini-notice-title {
line-height: 28px;
font-size: 14px;
}
.layuimini-notice-extra {
position: absolute;
top: 50%;
margin-top: -8px;
right: 16px;
display: inline-block;
height: 16px;
color: #999;
}
</style>
<script>
layui.use(['layer', 'echarts', 'common', 'tree'], function () {
var $ = layui.jquery,
layer = layui.layer,
common = layui.common,
tree = layui.tree,
table = layui.table,
echarts = layui.echarts;
wcLoading.close();
// Initial table rendering
table.render({
elem: '#dynamicTable', // Table ID
cols: [[ // Table headers (unchanged)
// {field: 'id', title: '序号', width: 60},
// {field: 'isMet', title: '状态', width: 20},
{
field: 'isMet',
title: '状态',
width: 30,
templet: function(d) {
// SVG indicator light: green for "满足", red for "未满足"
var color = d.isMet === 'True' ? '#6495ED' : '#FFF143';
return `
<div style="display: flex; justify-content: center; align-items: center; height: 100%;">
<svg width="20" height="20">
<circle cx="10" cy="10" r="8" fill="${color}" />
</svg>
</div>
`;
}
},
{field: 'condition', title: '条件'},
// {field: 'isMet', title: '是否满足', width: 90}
]],
data: [], // Initially empty, will be populated by backend data
even: true, // Enable even row styling
done: function(res, curr, count) {
// Custom row styling based on 'status' field
var tableData = res.data;
layui.each(tableData, function(index, item){
var tr = $('tr[data-index="' + index + '"]');
if (item.status=="True") {
// tr.css('background-color', '#67E667'); // Green for true
// tr.css('color', 'black');
tr.css('color', '#6495ED');
} else {
// tr.css('background-color', '#FF7373'); // Red for false
// tr.css('color', 'black');
tr.css('color', '#D69646');
}
});
}
});
var GROUPSTATIC = "";
// Function to fetch data from backend and reload table
function fetchAndReload() {
$.ajax({
url: '/DevicesManage/DeviceMonitoring/GetRealTableData', // Replace with your actual backend API
method: 'Post',
dataType: 'json',
data:{grouptype : GROUPSTATIC},
success: function(response) {
table.reload('dynamicTable', {
data: response
});
},
error: function(err) {
console.error('Failed to fetch data:', err);
}
});
}
// Initial fetch
fetchAndReload();
// Refresh every 1 second
setInterval(fetchAndReload, 1000);
var menujson ;
var currID='';
var xhr = new XMLHttpRequest();
xhr.open('GET', '/sfc/sfcmenu.json?nocache=' + new Date().getTime(), true); // 替换为你的JSON文件路径
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
try {
var menudata = JSON.parse(xhr.responseText);
menujson = menudata;
console.log('Data loaded:', menudata);
// 在这里处理你的数据
tree.render({
elem: '#ID-tree-demo-onlyIconControl',
data: menudata,
onlyIconControl: true, // 是否仅允许节点左侧图标控制展开收缩
click: function(obj){
layer.msg('打开流程-'+(obj.data.title));
currID = obj.data.id;
drawsvg(obj.data.title,obj.data.group);
}
});
} catch (e) {
console.error('Failed to parse JSON:', e);
}
}
};
xhr.send();
//var data = JSON.parse(document.getElementById('sfcmenu').textContent); // 获取JSON数据假设JSON被嵌入到HTML中或以某种方式可用作全局变量。
// 模拟数据
// 渲染
//拖拽
const draggable_dev = true;
// //开发色彩
// const fill_backgroud = '#8d98a3';
// const fill_iobox = '#8d98a3';
// const stroke_iobox = '#494d52';;
// const stroke_iobox_line = '#42444a';
// const stroke_iobox_spiltline = '#474b58';
// const fill_top_name = '#f1f4f6';
// const fill_top_name_value = '#f1f4f6';
// const fill_rect = '#a4a9ab';
// const fill_rect_text_name = '#e5e9ec';
// const fill_rect_text_description = '#f3f6f8';
// const fill_rect_io_on = '#aaff00';
// const fill_rect_io_off = '#a3a6a9';
//新版色彩
const fill_backgroud = '#28333e';
//const fill_backgroud = '#2a0056';
// const fill_iobox = '#2492e9';//00
// const fill_iobox = '#345266';//001
const fill_iobox = '#345b87';//002
// const fill_iobox = '#50657a';//003
// const fill_iobox = '#334b64';//004
//const fill_iobox = '#3d5062';//005
const stroke_iobox = '#494d52';;
const stroke_iobox_line = '#42444a';
const stroke_iobox_spiltline = '#474b58';
const fill_top_name = '#ffffff';
const fill_top_name_value = '#ffffff';
const fill_rect = '#cecece';
const fill_rect_text_name = '#ffffff';
//const fill_rect_text_name = '#02f2e0';
const fill_rect_text_description = '#ffffff';
//const fill_rect_text_description = '#02f2e0';
const fill_rect_io_on = '#00ff55';//'#00ff7f'
//const fill_rect_io_on = '#00ff7f'
const fill_rect_io_off = '#cecece';
function findTitleById(jsonData, id) {
// 递归函数用于遍历JSON结构
function search(node) {
if (node.id === id) {
return node.title;
}
if (node.children) {
for (var i = 0; i < node.children.length; i++) {
var result = search(node.children[i]);
if (result !== undefined) {
return result;
}
}
}
return undefined;
}
// 从根节点开始搜索
for (var i = 0; i < jsonData.length; i++) {
var result = search(jsonData[i]);
if (result !== undefined) {
return result;
}
}
return "No title found for the given ID.";
}
function findGroupById(jsonData, id) {
// 递归函数用于遍历JSON结构
function search(node) {
if (node.id === id) {
return node.group;
}
if (node.children) {
for (var i = 0; i < node.children.length; i++) {
var result = search(node.children[i]);
if (result !== undefined) {
return result;
}
}
}
return undefined;
}
// 从根节点开始搜索
for (var i = 0; i < jsonData.length; i++) {
var result = search(jsonData[i]);
if (result !== undefined) {
return result;
}
}
return "No title found for the given ID.";
}
function drawTable(group){
$.ajax({
url: '/DevicesManage/DeviceMonitoring/GetRealTableData', // Replace with your actual backend API
method: 'Post',
dataType: 'json',
data:{grouptype : group},
success: function(response) {
// Assuming response is an array of objects like:
// [{id: 1, condition: "焦炉煤气压力>=2KPA", isMet: "满足", status: true}, ...]
table.reload('dynamicTable', {
data: response
});
},
error: function(err) {
console.error('Failed to fetch data:', err);
}
});
}
function drawsvg(svgname,group){
GROUPSTATIC = group;
var xhr = new XMLHttpRequest();
xhr.open('GET', '/sfc/' + svgname + '.svg?nocache=' + new Date().getTime(), true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var svgContainer = document.getElementById('svg-container');
svgContainer.innerHTML = xhr.responseText;
drawTable(group);
// 查找所有的矩形元素并添加双击事件监听器
var rectElements = svgContainer.getElementsByTagName('rect');
for (var i = 0; i < rectElements.length; i++) {
var rect = rectElements[i];
rect.addEventListener('dblclick', function(event) {
debugger;
console.log('Rectangle was double-clicked!');
// 获取rect的父节点的父节点
var parentOfParent = this.parentNode.parentNode;
var idToSearch = parentOfParent.childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].innerHTML;
//var menudata=menujson;
try {
//menudata = JSON.parse(xhr.responseText);
var svgnamenew = findTitleById(menujson, idToSearch);
var groupnew = findGroupById(menujson, idToSearch);
currID = idToSearch;
drawsvg(svgnamenew,groupnew);
} catch (e) {
console.error('Failed to parse JSON:', e);
}
// 改变矩形的颜色作为双击的反馈
//this.style.fill = 'red';
});
}
// 定义查找和修改元素背景色的函数
function changeElementColor(elementId, newColor) {
var element = document.getElementById(elementId);
if (element != null) {
element.style.fill = newColor;
} else {
console.log('Element not found:', elementId);
}
}
//_tfGcsZuRspaPDUqBOv4-14
//_tfGcsZuRspaPDUqBOv4-13
} else {
console.log('Failed to load SVG file:', xhr.statusText);
}
}
};
xhr.send();
var span = document.getElementById('mySpan');
span.textContent = svgname;
}
// // 假设图表的XML内容是作为一个JavaScript变量定义的
// var svgContent = '<svg width="400" height="400"><rect id="exampleID" x="10" y="10" width="100" height="100" fill="white" stroke="black"/></svg>'; // 替换为你的SVG内容
// setTimeout(()=>{
// // document.getElementById('svg-container').innerHTML = svgContent;
// // 查找并修改元素背景色的函数
// function changeElementColor(elementId, newColor) {
// var element = document.getElementById(elementId);
// if (element) {
// element.style.fill = newColor;
// } else {
// console.log('Element not found:', elementId);
// }
// }
// document.getElementById('change-color').addEventListener('click', function() {
// var elementId = document.getElementById('element-id').value;
// if (elementId) {
// changeElementColor(elementId, 'red'); // 这里设置为红色,可以根据需求更改
// } else {
// alert('Please enter an element ID.');
// }
// });
// },1000);
function ReturnParentNode(){
var parentId = currID.slice(0, -2);
try {
//menudata = JSON.parse(xhr.responseText);
var svgnamenew = findTitleById(menujson, parentId);
var groupnew = findGroupById(menujson, parentId);
currID = parentId;
drawsvg(svgnamenew,groupnew);
} catch (e) {
console.error('Failed to parse JSON:', e);
}
};
// 获取按钮元素
const button = document.getElementById('returnButton');
// 添加点击事件监听器
button.addEventListener('click', function() {
// 这里定义点击事件的处理逻辑
ReturnParentNode();
});
function AddListenDblclick (){
mermaid.init(undefined, document.querySelectorAll('.mermaid'));
var nodes = element.querySelectorAll('.node');
for(var i = 0;i<nodes.length;i++){
var nodeid = nodes[i].id;
var doid = nodeid.split('-')[1];
var rect = nodes[i].querySelector('rect')
if(doid == 'step2'){
rect.ondblclick= function(){
console.log('节点2被双击了');
}
}
}
};
// var element = document.getElementById("mermaidDiagram");
var t = null;
function time() {
clearTimeout(t); //清除定时器
UpdataChart()
t = setTimeout(time, 1 * 1000); //设定定时器,循环运行
}
async function UpdataChart() {
myajax = await $.ajax({
url: "/DevicesManage/DeviceMonitoring/GetRealDeviceTag",
type: "Get",
dataType: "json",
success: function (redata) {
}
});
$.when(myajax).done(function (redata) {
// debugger;
// 获取当前的SVG内容
var dataa = Object.entries(redata);
for(var j=0;j<dataa.length;j++){
var tagname = dataa[j][0];
var tagvalue = dataa[j][1];
var elements = document.querySelectorAll('[data-cell-id="'+tagname+'"]')//DEfbDvusWkKE94doMNAG-55"]');
if(tagvalue == 'True')
{
if (elements.length > 0) {
try
{
elements[0].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].style.background = '';
}catch{}
elements[0].childNodes[0].childNodes[0].style.fill = '#009900'; // 只修改第一个匹配的元素
// elements[0].childNodes[0].childNodes[0].style.stroke = '#009900';
} else {
// console.log('Element not found with data-cell-id:', tagname);
}
}
else if(tagvalue == '1')
{
if (elements.length > 0) {
try
{
elements[0].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].style.background = '';
}catch{}
elements[0].childNodes[0].childNodes[0].style.fill = '#009900'; // 只修改第一个匹配的元素
// elements[0].childNodes[0].childNodes[0].style.stroke = '#009900';
} else {
// console.log('Element not found with data-cell-id:', tagname);
}
}
else if(tagvalue == 'False')
{
if (elements.length > 0) {
try
{
elements[0].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].style.background = '';
}catch{}
elements[0].childNodes[0].childNodes[0].style.fill = '#ECECFF'; // 只修改第一个匹配的元素
// elements[0].childNodes[0].childNodes[0].style.stroke = '#000000';
} else {
// console.log('Element not found with data-cell-id:', tagname);
}
}
else if(tagvalue == '0')
{
if (elements.length > 0) {
try
{
elements[0].childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0].style.background = '';
}catch{}
elements[0].childNodes[0].childNodes[0].style.fill = '#ECECFF'; // 只修改第一个匹配的元素
// elements[0].childNodes[0].childNodes[0].style.stroke = '#000000';
} else {
// console.log('Element not found with data-cell-id:', tagname);
}
}
}
});
}
t = setTimeout(time, 1 * 1000); //开始运行
})
</script>
<script type="text/javascript" src="~/lib//drawio-embed/drawio-embed.min.js"></script>
<script type="text/javascript" src="~/lib//drawio/embed.dev.js"></script>
<script type="text/javascript" src="~/lib//mermaid/mermaid.js"></script>
<script type="text/javascript" src="~/lib//drawio/viewer-static.min.js"></script>
<script type="text/javascript" src="~/lib//leafer-ui@1.2.1/web.js"></script>
<script src="~/sfc//sfcmenu.json"></script>
<div style ="width:100%;height:100%;">
<div class="layuimini-container" style="width:100%;max-height:100%; ">
<div class="text-and-button">
<span id="mySpan" class="text-content">当前位置:主流程--启动流程--启动设备1</span>
<button id="returnButton">返回上级流程</button>
</div>
<div class="layui-row" style="overflow:hidden;max-height:100%">
<div class="layui-col-xs2" style="overflow-y: auto;height:800px">
<div id="ID-tree-demo-onlyIconControl"></div>
</div>
<div class="layui-col-xs7" style="overflow-y: auto;height:800px">
<div id="svg-container"></div>
@* <div id="mermaidDiagram" class="mermaid" style="width:10000px;height:10000px; "> *@
@* graph TD
step0[S0_初始步]-->con0{ 执行该流程请求 }
con0-->step1["S1_执行动作1"]
step1-->con11{S2转换条件}
con11-->step2["S2_执行子流程"]
step2-->con2{S3转换条件}
con2-->step3["S3_
设备输出1
设备输出2"]
step3-->con3{S6转换条件}
con3-->step6[S6_Set 执行该流程完成]
step1-->con12{S4转换条件}
con12-->step4["S4_执行子流程"]
step4-->con4{S5转换条件}
con4-->step5[S5_执行子流程]
step5-->con5{S6转换条件}
con5-->step6
step6-->con6{执行该流程完成}
con6-->step0 *@
</div>
<div class="layui-col-xs3" style="overflow-y: auto;height:800px">
<p style="font-weight: bold;font-size:16px">烟气系统启动条件:</p>
<table class="layui-table" lay-even id="dynamicTable">
@* <colgroup>
<col width="60">
<col>
<col width="90">
</colgroup>
<thead>
<tr>
<th>序号</th>
<th>条件</th>
<th>是否满足</th>
</tr>
</thead>
<tbody>
<tr style="background:#67E667;color:black">
<td>1</td>
<td>焦炉煤气压力>=2KPA</td>
<td>满足</td>
</tr>
<tr style="background:#67E667;color:black">
<td>2</td>
<td>助燃风机运行</td>
<td>满足</td>
</tr>
<tr style="background:#FF7373;color:black">
<td>3</td>
<td>助燃空气压力>3KPA</td>
<td>未满足</td>
</tr>
<tr style="background:#67E667;color:black">
<td>4</td>
<td>助燃空气流量>500m³/H</td>
<td>满足</td>
</tr>
<tr style="background:#FF7373;color:black">
<td>5</td>
<td>空气调节阀开度反馈>5%</td>
<td>未满足</td>
</tr>
<tr style="background:#67E667;color:black">
<td>6</td>
<td>高炉煤气压力>3KPA</td>
<td>满足</td>
</tr>
<tr style="background:#FF7373;color:black">
<td>7</td>
<td>高炉煤气流量>500m³/H</td>
<td>未满足</td>
</tr>
<tr style="color:black">
<td>8</td>
<td>煤气调节阀开度反馈>5%</td>
<td style="color:green">满足</td>
</tr>
<tr style="color:black">
<td>9</td>
<td>高炉煤气快切阀开到位</td>
<td style="color:red">未满足</td>
</tr>
<tr style="color:green">
<td>10</td>
<td>烟气炉炉膛温度>750℃</td>
<td>满足</td>
</tr>
<tr style="color:red">
<td>11</td>
<td>放散调节阀开度反馈>50%</td>
<td>未满足</td>
</tr>
</tbody> *@
</table>
</div>
</div>
@* <div id="mermaidDiagram" class="mermaid">
graph TD
step0[S0_初始步]-->con0{ 执行该流程请求 }
con0-->step1["S1_执行动作1"]
step1-->con11{S2转换条件}
con11-->step2["S2_执行子流程"]
step2-->con2{S3转换条件}
con2-->step3["S3_
设备输出1
设备输出2"]
step3-->con3{S6转换条件}
con3-->step6[S6_Set 执行该流程完成]
step1-->con12{S4转换条件}
con12-->step4["S4_执行子流程"]
step4-->con4{S5转换条件}
con4-->step5[S5_执行子流程]
step5-->con5{S6转换条件}
con5-->step6
step6-->con6{执行该流程完成}
con6-->step0
</div> *@
</div>
</div>