图形化-设备监控
This commit is contained in:
223
nladmin-ui/src/views/system/monitor/device/XJDeviceMonitor.vue
Normal file
223
nladmin-ui/src/views/system/monitor/device/XJDeviceMonitor.vue
Normal file
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="监控详情"
|
||||
append-to-body
|
||||
:visible.sync="dialogVisible"
|
||||
fullscreen
|
||||
@open="open"
|
||||
@close="close"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="18" style="border: 1px solid white">
|
||||
<span />
|
||||
</el-col>
|
||||
<el-col :span="6" style="margin-bottom: 20px">
|
||||
<!-- <span style="float: right">
|
||||
<el-button icon="el-icon-close" size="mini" type="info" @click="dialogVisible = false">返 回</el-button>
|
||||
</span>-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-card class="box-card" shadow="never">
|
||||
<el-form ref="form" disabled :inline="true" :model="form" :rules="rules" size="mini" label-width="80px">
|
||||
<el-form-item label="设备编码">
|
||||
<el-input v-model="device_code" placeholder="自动生产" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备名称" prop="dtl_count">
|
||||
<el-input v-model="device_name" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="crud-opts2" style="margin-top: 30px;margin-bottom: 15px">
|
||||
<el-form ref="form" disabled :inline="true" :model="form" :rules="rules" size="mini" label-width="200px">
|
||||
<el-form-item label="心跳">
|
||||
<el-input v-model="form.heartbeat" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="工作模式">
|
||||
<el-input v-model="form.mode" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="故障">
|
||||
<el-input v-model="form.error" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="故障次数">
|
||||
<el-input v-model="form.error_num" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="待机时间(调试)">
|
||||
<el-input v-model="form.ready_time" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="生产时间">
|
||||
<el-input v-model="form.running_time" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="故障时间">
|
||||
<el-input v-model="form.error_time" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="温度">
|
||||
<el-input v-model="form.temperature" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="当前生产产品编号">
|
||||
<el-input v-model="form.material" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="缺料信号">
|
||||
<el-input v-model="form.lack_material" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="上料数量">
|
||||
<el-input v-model="form.feeding_qty" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="下料数量">
|
||||
<el-input v-model="form.blanking_qty" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="当前生产合格品数量">
|
||||
<el-input v-model="form.qualified_qty" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="当前生产不合格品数量">
|
||||
<el-input v-model="form.unqualified_qty" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="生产完成">
|
||||
<el-input v-model="form.finish" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="任务号">
|
||||
<el-input v-model="form.task" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备暂停">
|
||||
<el-input v-model="form.pause" style="width: 200px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { crud } from '@crud/crud'
|
||||
|
||||
export default {
|
||||
name: 'XJDeviceMonitor',
|
||||
components: {},
|
||||
mixins: [crud()],
|
||||
props: {
|
||||
dialogShow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
openParam: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
dicts: [],
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
form: {
|
||||
heartbeat: '',
|
||||
mode: '',
|
||||
error: '',
|
||||
error_num: '',
|
||||
ready_time: '',
|
||||
running_time: '',
|
||||
error_time: '',
|
||||
temperature: '',
|
||||
material: '',
|
||||
lack_material: '',
|
||||
feeding_qty: '',
|
||||
blanking_qty: '',
|
||||
qualified_qty: '',
|
||||
unqualified_qty: '',
|
||||
finish: '',
|
||||
task: '',
|
||||
pause: ''
|
||||
},
|
||||
device_code: '',
|
||||
device_name: '',
|
||||
rules: {
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
dialogShow: {
|
||||
handler(newValue) {
|
||||
this.dialogVisible = newValue
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.webSocket()
|
||||
},
|
||||
close() {
|
||||
this.$emit('AddChanged')
|
||||
},
|
||||
setForm(data) {
|
||||
this.dialogVisible = true
|
||||
this.form = data.data
|
||||
this.device_code = data.device_code
|
||||
this.device_name = data.device_name
|
||||
// this.form = row
|
||||
},
|
||||
webSocket() {
|
||||
const that = this
|
||||
if (typeof (WebSocket) === 'undefined') {
|
||||
this.$notify({
|
||||
title: '提示',
|
||||
message: '当前浏览器无法接收实时报警信息,请使用谷歌浏览器!',
|
||||
type: 'warning',
|
||||
duration: 0
|
||||
})
|
||||
} else {
|
||||
const id = 'xj_device_monitor'
|
||||
// 获取token保存到vuex中的用户信息,此处仅适用于本项目,注意删除或修改
|
||||
// 实例化socket,这里我把用户名传给了后台,使后台能判断要把消息发给哪个用户,其实也可以后台直接获取用户IP来判断并推送
|
||||
|
||||
// const wsUri = process.env.VUE_APP_WS_API + '/webSocket/' + id
|
||||
const wsUri = window.g.prod.VUE_APP_BASE_API.replace('http', 'ws') + '/webSocket/' + id
|
||||
this.socket = new WebSocket(wsUri)
|
||||
// 监听socket打开
|
||||
this.socket.onopen = function() {
|
||||
console.log('浏览器WebSocket已打开')
|
||||
// that.socket.send('测试客户端发送消息')
|
||||
}
|
||||
|
||||
// 监听socket消息接收
|
||||
this.socket.onmessage = function(msg) {
|
||||
const list = JSON.parse(msg.data).msg.detail
|
||||
// console.log(list)
|
||||
|
||||
for (const item of list) {
|
||||
const obj = JSON.parse(JSON.stringify(item))
|
||||
if (obj.device_code === that.device_code) {
|
||||
that.form = obj.data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监听socket错误
|
||||
this.socket.onerror = function() {
|
||||
that.$notify({
|
||||
title: '错误',
|
||||
message: '服务器错误,无法接收实时报警信息',
|
||||
type: 'error',
|
||||
duration: 0
|
||||
})
|
||||
}
|
||||
// 监听socket关闭
|
||||
this.socket.onclose = function() {
|
||||
console.log('WebSocket已关闭')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.crud-opts2 {
|
||||
padding: 0 0;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.crud-opts2 .crud-opts-right2 {
|
||||
margin-left: auto;
|
||||
padding: 4px 4px;
|
||||
}
|
||||
.input-with-select {
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
154
nladmin-ui/src/views/system/monitor/device/index.vue
Normal file
154
nladmin-ui/src/views/system/monitor/device/index.vue
Normal file
@@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row>
|
||||
<div id="container" className="container" />
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudStage from '@/api/logicflow/stage'
|
||||
import paramCrud from '@/api/system/param'
|
||||
import '@logicflow/core/dist/style/index.css'
|
||||
import '@logicflow/extension/lib/style/index.css'
|
||||
|
||||
import { LogicFlow } from '@logicflow/core'
|
||||
import { registerCustomElement } from '@/views/system/logicflow/editor/components/node'
|
||||
let data = {}
|
||||
let lf = ''
|
||||
export default {
|
||||
name: 'MonitorDevice',
|
||||
data() {
|
||||
return {
|
||||
stageParam: 'test', // 舞台参数
|
||||
dialogDeviceMsgVisible: false,
|
||||
device_code: null,
|
||||
tops: '20vh',
|
||||
stage_code: '',
|
||||
stageSelectList: [],
|
||||
arr: [], // 显示数组
|
||||
dialogFormVisible: false,
|
||||
dialogFormVisible1: false,
|
||||
dialogFormVisible2: false,
|
||||
dialogFormVisible3: false,
|
||||
dialogFormVisible4: false,
|
||||
form: {
|
||||
device_code: '',
|
||||
hasGoodStatus: null,
|
||||
barcode: '',
|
||||
suspended: null,
|
||||
material_type: '',
|
||||
requireSucess: '',
|
||||
fullrequireSucess: ''
|
||||
},
|
||||
allDeviceMsg: [],
|
||||
msgTop: '200px',
|
||||
msgLeft: '200px'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
// 流程图初始化
|
||||
init() {
|
||||
// 初始化配置
|
||||
lf = new LogicFlow({
|
||||
overlapMode: 1,
|
||||
container: document.querySelector('#container'), // 容器
|
||||
// 画布配置
|
||||
// width: window.innerWidth, // 宽度
|
||||
height: window.innerHeight, // 高度
|
||||
grid: { // 不用格子直接显示,使用背景
|
||||
visible: false,
|
||||
type: 'mesh',
|
||||
size: 5
|
||||
},
|
||||
background: {
|
||||
backgroundImage: 'url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImdyaWQiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZD0iTSAwIDEwIEwgNDAgMTAgTSAxMCAwIEwgMTAgNDAgTSAwIDIwIEwgNDAgMjAgTSAyMCAwIEwgMjAgNDAgTSAwIDMwIEwgNDAgMzAgTSAzMCAwIEwgMzAgNDAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2QwZDBkMCIgb3BhY2l0eT0iMC4yIiBzdHJva2Utd2lkdGg9IjEiLz48cGF0aCBkPSJNIDQwIDAgTCAwIDAgMCA0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZDBkMGQwIiBzdHJva2Utd2lkdGg9IjEiLz48L3BhdHRlcm4+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JpZCkiLz48L3N2Zz4=")',
|
||||
backgroundRepeat: 'repeat'
|
||||
},
|
||||
adjustEdge: false,
|
||||
adjustEdgeMiddle: false,
|
||||
adjustEdgeStartAndEnd: false,
|
||||
adjustNodePosition: false,
|
||||
hideAnchors: true,
|
||||
nodeTextEdit: false,
|
||||
edgeTextEdit: false
|
||||
})
|
||||
lf.setTheme(
|
||||
{
|
||||
baseEdge: { strokeWidth: 1 },
|
||||
baseNode: { strokeWidth: 1 },
|
||||
nodeText: { overflowMode: 'autoWrap', lineHeight: 1.5 },
|
||||
edgeText: { overflowMode: 'autoWrap', lineHeight: 1.5 }
|
||||
}
|
||||
)
|
||||
// 注册自定义元素
|
||||
registerCustomElement(lf)
|
||||
// 删除默认的右键菜单
|
||||
lf.extension.menu.setMenuConfig({
|
||||
nodeMenu: false
|
||||
})
|
||||
lf.on('node:click', (data, e) => { // 鼠标点击节点
|
||||
// 展开显示设备信息
|
||||
console.log('1')
|
||||
})
|
||||
lf.on('node:contextmenu', (data, e, position) => { // 右键
|
||||
console.log('2')
|
||||
})
|
||||
// 开始渲染
|
||||
lf.render(data)
|
||||
this.initStageData()
|
||||
},
|
||||
initStageData() {
|
||||
// 获取舞台编码
|
||||
paramCrud.getStageCodeByCode(this.stageParam).then(res => {
|
||||
if (res.value !== undefined) {
|
||||
crudStage.getNewStageDataByCode(res.value).then(res => {
|
||||
data = JSON.parse(res.stage_data)
|
||||
lf.render(data)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
.container {
|
||||
background-color: #f8f9fa;
|
||||
height: 100%;
|
||||
}
|
||||
.newDialog /deep/ .el-dialog__header {
|
||||
padding: 1vh 1vw 0 1vw;
|
||||
}
|
||||
.newDialog /deep/ .el-dialog__body {
|
||||
padding: 1vh 1vw;
|
||||
}
|
||||
.toolbar-sty {
|
||||
position: absolute;
|
||||
margin-top: 5px;
|
||||
top: 0;
|
||||
padding: 5px;
|
||||
left: 30px;
|
||||
height: 45px;
|
||||
/*width: 310px;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
z-index: 10;
|
||||
background: #e5e5e5;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user