更新
This commit is contained in:
parent
f143c5e2d9
commit
b43876fe67
@ -1,3 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* @Author: zwq
|
||||||
|
* @Date: 2024-10-29 09:47:40
|
||||||
|
* @LastEditors: zwq
|
||||||
|
* @LastEditTime: 2025-02-12 09:25:11
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
// 获得工厂产线工段设备树形结构
|
// 获得工厂产线工段设备树形结构
|
||||||
export function getTree() {
|
export function getTree() {
|
||||||
|
@ -58,3 +58,12 @@ export function exportFactoryExcel(query) {
|
|||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 获取产线设备状态
|
||||||
|
export function getLineEqStatus(data) {
|
||||||
|
return request({
|
||||||
|
url: '/base/production-line/getLineEqStatus',
|
||||||
|
method: 'post',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,7 @@
|
|||||||
{ label: '无类型', value: 0 },
|
{ label: '无类型', value: 0 },
|
||||||
{ label: '进口统计', value: 1 },
|
{ label: '进口统计', value: 1 },
|
||||||
{ label: '出口统计', value: 2 },
|
{ label: '出口统计', value: 2 },
|
||||||
|
{ label: '进出口计数', value: 3 },
|
||||||
]"
|
]"
|
||||||
:key="opt.value"
|
:key="opt.value"
|
||||||
:label="opt.label"
|
:label="opt.label"
|
||||||
|
529
src/views/equipment/timing-diagram/status/index-old.vue
Normal file
529
src/views/equipment/timing-diagram/status/index-old.vue
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
<!--
|
||||||
|
filename: index.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-04 09:34:52
|
||||||
|
description: 设备状态时序图
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="status-timegraph-container" style="background: #f2f4f9; flex: 1; display: flex; flex-direction: column">
|
||||||
|
<el-row class="" style="
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background: #fff;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
">
|
||||||
|
<div class="blue-title">生产节拍时序图</div>
|
||||||
|
<SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" :remove-blue="true"
|
||||||
|
@select-changed="handleSearchBarSelectChange" @headBtnClick="handleSearchBarBtnClick" />
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row class="" style="
|
||||||
|
height: 1px;
|
||||||
|
flex: 1;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background: #fff;
|
||||||
|
padding: 16px 16px 32px;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="blue-title">设备状态时序图</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="18" class="legend-row">
|
||||||
|
<div class="legend">
|
||||||
|
<div class="icon running"></div>
|
||||||
|
<div>运行中</div>
|
||||||
|
</div>
|
||||||
|
<div class="legend">
|
||||||
|
<div class="icon fault"></div>
|
||||||
|
<div>故障</div>
|
||||||
|
</div>
|
||||||
|
<div class="legend">
|
||||||
|
<div class="icon stop"></div>
|
||||||
|
<div>计划停机</div>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<div class="main-area" style="flex: 1; display: flex; flex-direction: column;">
|
||||||
|
<div class="graphs" v-show="graphList.length" id="status-chart" style="height: 1px; flex: 1;"></div>
|
||||||
|
<h2 v-if="!graphList || graphList.length == 0" class="no-data-bg"></h2>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<base-dialog dialogTitle="添加设备" :dialogVisible="open" width="500px" @close="open = false" @cancel="open = false"
|
||||||
|
@confirm="submitForm">
|
||||||
|
<el-select v-if="open" style="width: 100%" v-model="queryParams.equipmentId" placeholder="请选择一个设备">
|
||||||
|
<el-option v-for="eq in eqList" :key="eq.id" :value="eq.id" :label="eq.name"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</base-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Gantt from './gantt';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SGStatus',
|
||||||
|
components: {},
|
||||||
|
props: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chart: null,
|
||||||
|
searchBarFormConfig: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '产线',
|
||||||
|
placeholder: '请选择产线',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'lineId',
|
||||||
|
onchange: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '工段',
|
||||||
|
placeholder: '请选择工段',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'sectionId',
|
||||||
|
},
|
||||||
|
// 时间段
|
||||||
|
{
|
||||||
|
type: 'datePicker',
|
||||||
|
label: '时间段',
|
||||||
|
dateType: 'date',
|
||||||
|
format: 'yyyy-MM-dd',
|
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
rangeSeparator: '-',
|
||||||
|
placeholder: '选择日期',
|
||||||
|
param: 'recordTime',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '查询',
|
||||||
|
name: 'search',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'separate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '添加对比',
|
||||||
|
name: 'compare',
|
||||||
|
color: 'primary',
|
||||||
|
plain: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
queryParams: {
|
||||||
|
lineId: null,
|
||||||
|
sectionId: null,
|
||||||
|
equipmentId: null,
|
||||||
|
recordTime: null,
|
||||||
|
},
|
||||||
|
graphList: [],
|
||||||
|
existingEquipments: [],
|
||||||
|
open: false,
|
||||||
|
eqList: [],
|
||||||
|
startTime: null,
|
||||||
|
gantt: null
|
||||||
|
// demo: [
|
||||||
|
// [
|
||||||
|
// {
|
||||||
|
// equipmentName: '下片机',
|
||||||
|
// duration: 30,
|
||||||
|
// relativeDuration: 0.6,
|
||||||
|
// status: 0,
|
||||||
|
// startPos: 0,
|
||||||
|
// startTime: 1691568181000,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// equipmentName: '下片机',
|
||||||
|
// duration: 20,
|
||||||
|
// relativeDuration: 0.4,
|
||||||
|
// status: 2,
|
||||||
|
// startPos: 30,
|
||||||
|
// startTime: 1691569981000
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// ],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
created() {
|
||||||
|
this.initProductline();
|
||||||
|
this.initWorksection();
|
||||||
|
this.initEquipment();
|
||||||
|
// this.getList();
|
||||||
|
},
|
||||||
|
mounted() { },
|
||||||
|
watch: {
|
||||||
|
graphList: {
|
||||||
|
handler(val) {
|
||||||
|
if (val && val.length) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (!this.gantt) {
|
||||||
|
this.gantt = new Gantt('#status-chart', this.startTime);
|
||||||
|
this.gantt.init(val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.gantt.update(val);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
findMin() {
|
||||||
|
let min = 0;
|
||||||
|
this.graphList.forEach((arr) => {
|
||||||
|
arr.forEach((item) => {
|
||||||
|
if (min < item.startTime) min = item.startTime;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return min;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 重置查询条件 */
|
||||||
|
initQuery() {
|
||||||
|
this.queryParams.lineId = null;
|
||||||
|
this.queryParams.equipmentId = null;
|
||||||
|
this.queryParams.sectionId = null;
|
||||||
|
this.queryParams.recordTime = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 对象到数组的转换 */
|
||||||
|
objectToArray(obj) {
|
||||||
|
return Object.keys(obj).map((key) => {
|
||||||
|
obj[key].sort((a, b) => a.startTime - b.startTime);
|
||||||
|
obj[key].key = key;
|
||||||
|
return obj[key];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async getList() {
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/analysis/equipment-analysis/status',
|
||||||
|
method: 'get',
|
||||||
|
params: this.queryParams,
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
this.existingEquipments = Object.values(data).map((eq) => eq[0].equipmentId);
|
||||||
|
this.graphList = this.objectToArray(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 准备设备数据 */
|
||||||
|
async initEquipment() {
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/base/equipment/listAll',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
this.eqList = data.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
id: item.id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 准备产线数据 */
|
||||||
|
async initProductline() {
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/base/production-line/listAll',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
this.searchBarFormConfig[0].selectOptions = data.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
id: item.id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 准备工段数据 */
|
||||||
|
async initWorksection() {
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/base/workshop-section/listAll',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
this.searchBarFormConfig[1].selectOptions = data.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
id: item.id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearchBarSelectChange({ param, value }) {
|
||||||
|
if (!value) {
|
||||||
|
this.searchBarFormConfig[1].selectOptions = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (param) {
|
||||||
|
case 'lineId':
|
||||||
|
this.$axios({
|
||||||
|
url: '/base/workshop-section/listByParentId',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
id: value,
|
||||||
|
},
|
||||||
|
}).then(({ code, data }) => {
|
||||||
|
if (code == 0) {
|
||||||
|
this.searchBarFormConfig[1].selectOptions = data.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
id: item.id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearchBarBtnClick({ btnName, ...payload }) {
|
||||||
|
switch (btnName) {
|
||||||
|
case 'search':
|
||||||
|
if (!payload.recordTime || payload.recordTime.length <= 0) {
|
||||||
|
this.$message.warning('请选择时间段');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.startTime = new Date(payload.recordTime)
|
||||||
|
this.queryParams.lineId = payload.lineId || null;
|
||||||
|
this.queryParams.sectionId = payload.sectionId || null;
|
||||||
|
this.queryParams.equipmentId = payload.equipmentId || null;
|
||||||
|
this.queryParams.recordTime = payload.recordTime
|
||||||
|
? [
|
||||||
|
payload.recordTime,
|
||||||
|
new Date(
|
||||||
|
new Date(payload.recordTime).getTime() + 24 * 3600 * 1000
|
||||||
|
)
|
||||||
|
.toLocaleDateString()
|
||||||
|
.split('/')
|
||||||
|
.map((value, index) => {
|
||||||
|
if (index == 1 || index == 2) {
|
||||||
|
return value.padStart(2, '0');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
.join('-') + ' 00:00:00',
|
||||||
|
]
|
||||||
|
: null;
|
||||||
|
this.getList();
|
||||||
|
break;
|
||||||
|
case 'compare':
|
||||||
|
this.open = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async submitForm() {
|
||||||
|
if (this.existingEquipments.indexOf(this.queryParams.equipmentId) >= 0) {
|
||||||
|
this.$message.warning('该设备已存在');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const {sectionId,...params} = this.queryParams
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/analysis/equipment-analysis/status',
|
||||||
|
method: 'get',
|
||||||
|
params: params,
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
const newEqlist = this.objectToArray(data);
|
||||||
|
if (!newEqlist || newEqlist.length == 0) {
|
||||||
|
this.$message.warning('该设备没有状态数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.graphList.push(newEqlist[0]);
|
||||||
|
}
|
||||||
|
this.open = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.graph {
|
||||||
|
// border: 1px solid #ccc;
|
||||||
|
// padding: 12px 12px 28px 12px;
|
||||||
|
// margin: 64px 0;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-title {
|
||||||
|
// position: absolute;
|
||||||
|
// top: -64px;
|
||||||
|
// left: -1px;
|
||||||
|
// padding: 8px 18px;
|
||||||
|
padding: 0 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-content {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
padding: 22px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
border-top: none;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-content::after,
|
||||||
|
.graph-content::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 80%;
|
||||||
|
background: #fff;
|
||||||
|
right: -1px;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-content::before {
|
||||||
|
right: unset;
|
||||||
|
left: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-item,
|
||||||
|
.graph-item-fixed {
|
||||||
|
// height: 88px;
|
||||||
|
// width: 24px;
|
||||||
|
flex: 1;
|
||||||
|
// border: 1px solid #ccc;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-item-fixed {
|
||||||
|
flex: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-item::before,
|
||||||
|
.graph-item-fixed::before {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -16px;
|
||||||
|
left: 0;
|
||||||
|
content: attr(data-time);
|
||||||
|
// font-size - js
|
||||||
|
// rotate - js
|
||||||
|
// color - js, default:
|
||||||
|
color: #777;
|
||||||
|
transform-origin: left top;
|
||||||
|
transform: rotate(12deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-item-fixed::after,
|
||||||
|
.graph-item::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: -3px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-item.tick::after,
|
||||||
|
.graph-item-fixed.tick::after {
|
||||||
|
width: 1px;
|
||||||
|
height: 6px;
|
||||||
|
border-left: 1px solid #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.running {
|
||||||
|
background-color: #288AFF;
|
||||||
|
// background-color: #84f04e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.waiting {
|
||||||
|
background-color: #5ad8a6;
|
||||||
|
// background-color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fault {
|
||||||
|
// background-color: #ea5b5b;
|
||||||
|
background-color: #FC9C91;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full {
|
||||||
|
// background-color: #e6a23c;
|
||||||
|
background-color: #598fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lack {
|
||||||
|
// background-color: #a69c8d;
|
||||||
|
background-color: #7585a2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stop {
|
||||||
|
background-color: #FFDC94;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-row {
|
||||||
|
margin: 6px 0;
|
||||||
|
padding-right: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
>.legend:not(:last-child) {
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 2px;
|
||||||
|
margin-right: 4px;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue-title {
|
||||||
|
position: relative;
|
||||||
|
padding: 4px 0;
|
||||||
|
padding-left: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 6px;
|
||||||
|
height: 16px;
|
||||||
|
width: 4px;
|
||||||
|
border-radius: 1px;
|
||||||
|
background: #0b58ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.echarts__status-chart {
|
||||||
|
background: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.echarts__status-chart>div {
|
||||||
|
height: 100% !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -6,19 +6,28 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="status-timegraph-container" style="background: #f2f4f9; flex: 1; display: flex; flex-direction: column">
|
<div
|
||||||
<el-row class="" style="
|
class="status-timegraph-container"
|
||||||
|
style="background: #f2f4f9; flex: 1; display: flex; flex-direction: column">
|
||||||
|
<el-row
|
||||||
|
class=""
|
||||||
|
style="
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 16px 16px 0;
|
padding: 16px 16px 0;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
">
|
">
|
||||||
<div class="blue-title">生产节拍时序图</div>
|
<div class="blue-title">生产节拍时序图</div>
|
||||||
<SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" :remove-blue="true"
|
<SearchBar
|
||||||
@select-changed="handleSearchBarSelectChange" @headBtnClick="handleSearchBarBtnClick" />
|
:formConfigs="searchBarFormConfig"
|
||||||
|
ref="search-bar"
|
||||||
|
:remove-blue="true"
|
||||||
|
@headBtnClick="handleSearchBarBtnClick" />
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row class="" style="
|
<el-row
|
||||||
|
class=""
|
||||||
|
style="
|
||||||
height: 1px;
|
height: 1px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
@ -47,17 +56,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="main-area" style="flex: 1; display: flex; flex-direction: column;">
|
<div
|
||||||
<div class="graphs" v-show="graphList.length" id="status-chart" style="height: 1px; flex: 1;"></div>
|
class="main-area"
|
||||||
|
style="flex: 1; display: flex; flex-direction: column">
|
||||||
|
<div
|
||||||
|
class="graphs"
|
||||||
|
v-show="graphList.length"
|
||||||
|
id="status-chart"
|
||||||
|
style="height: 1px; flex: 1"></div>
|
||||||
<h2 v-if="!graphList || graphList.length == 0" class="no-data-bg"></h2>
|
<h2 v-if="!graphList || graphList.length == 0" class="no-data-bg"></h2>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 对话框(添加 / 修改) -->
|
<!-- 对话框(添加 / 修改) -->
|
||||||
<base-dialog dialogTitle="添加设备" :dialogVisible="open" width="500px" @close="open = false" @cancel="open = false"
|
<base-dialog
|
||||||
|
dialogTitle="添加设备"
|
||||||
|
:dialogVisible="open"
|
||||||
|
width="500px"
|
||||||
|
@close="open = false"
|
||||||
|
@cancel="open = false"
|
||||||
@confirm="submitForm">
|
@confirm="submitForm">
|
||||||
<el-select v-if="open" style="width: 100%" v-model="queryParams.equipmentId" placeholder="请选择一个设备">
|
<el-select
|
||||||
<el-option v-for="eq in eqList" :key="eq.id" :value="eq.id" :label="eq.name"></el-option>
|
v-if="open"
|
||||||
|
style="width: 100%"
|
||||||
|
v-model="queryParams.equipmentId"
|
||||||
|
placeholder="请选择一个设备">
|
||||||
|
<el-option
|
||||||
|
v-for="eq in eqList"
|
||||||
|
:key="eq.id"
|
||||||
|
:value="eq.id"
|
||||||
|
:label="eq.name"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</base-dialog>
|
</base-dialog>
|
||||||
</div>
|
</div>
|
||||||
@ -74,21 +102,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
chart: null,
|
chart: null,
|
||||||
searchBarFormConfig: [
|
searchBarFormConfig: [
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
label: '产线',
|
|
||||||
placeholder: '请选择产线',
|
|
||||||
selectOptions: [],
|
|
||||||
param: 'lineId',
|
|
||||||
onchange: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
label: '工段',
|
|
||||||
placeholder: '请选择工段',
|
|
||||||
selectOptions: [],
|
|
||||||
param: 'sectionId',
|
|
||||||
},
|
|
||||||
// 时间段
|
// 时间段
|
||||||
{
|
{
|
||||||
type: 'datePicker',
|
type: 'datePicker',
|
||||||
@ -119,8 +132,6 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
queryParams: {
|
queryParams: {
|
||||||
lineId: null,
|
|
||||||
sectionId: null,
|
|
||||||
equipmentId: null,
|
equipmentId: null,
|
||||||
recordTime: null,
|
recordTime: null,
|
||||||
},
|
},
|
||||||
@ -129,37 +140,41 @@ export default {
|
|||||||
open: false,
|
open: false,
|
||||||
eqList: [],
|
eqList: [],
|
||||||
startTime: null,
|
startTime: null,
|
||||||
gantt: null
|
gantt: null,
|
||||||
// demo: [
|
|
||||||
// [
|
|
||||||
// {
|
|
||||||
// equipmentName: '下片机',
|
|
||||||
// duration: 30,
|
|
||||||
// relativeDuration: 0.6,
|
|
||||||
// status: 0,
|
|
||||||
// startPos: 0,
|
|
||||||
// startTime: 1691568181000,
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// equipmentName: '下片机',
|
|
||||||
// duration: 20,
|
|
||||||
// relativeDuration: 0.4,
|
|
||||||
// status: 2,
|
|
||||||
// startPos: 30,
|
|
||||||
// startTime: 1691569981000
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// ],
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
created() {
|
created() {
|
||||||
this.initProductline();
|
const now = new Date();
|
||||||
this.initWorksection();
|
const year = now.getFullYear();
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(now.getDate()).padStart(2, '0');
|
||||||
|
const formattedDate = `${year}-${month}-${day} 00:00:00`;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs['search-bar'].formInline.recordTime = formattedDate;
|
||||||
|
});
|
||||||
|
this.queryParams.equipmentId = Number(this.$route.query.eqid);
|
||||||
|
this.startTime = new Date(formattedDate);
|
||||||
|
this.queryParams.recordTime = formattedDate
|
||||||
|
? [
|
||||||
|
formattedDate,
|
||||||
|
new Date(new Date(formattedDate).getTime() + 24 * 3600 * 1000)
|
||||||
|
.toLocaleDateString()
|
||||||
|
.split('/')
|
||||||
|
.map((value, index) => {
|
||||||
|
if (index == 1 || index == 2) {
|
||||||
|
return value.padStart(2, '0');
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
.join('-') + ' 00:00:00',
|
||||||
|
]
|
||||||
|
: null;
|
||||||
|
this.getList();
|
||||||
this.initEquipment();
|
this.initEquipment();
|
||||||
// this.getList();
|
|
||||||
},
|
},
|
||||||
mounted() { },
|
mounted() {
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
graphList: {
|
graphList: {
|
||||||
handler(val) {
|
handler(val) {
|
||||||
@ -171,7 +186,6 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.gantt.update(val);
|
this.gantt.update(val);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -193,9 +207,7 @@ export default {
|
|||||||
|
|
||||||
/** 重置查询条件 */
|
/** 重置查询条件 */
|
||||||
initQuery() {
|
initQuery() {
|
||||||
this.queryParams.lineId = null;
|
|
||||||
this.queryParams.equipmentId = null;
|
this.queryParams.equipmentId = null;
|
||||||
this.queryParams.sectionId = null;
|
|
||||||
this.queryParams.recordTime = null;
|
this.queryParams.recordTime = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -215,7 +227,9 @@ export default {
|
|||||||
params: this.queryParams,
|
params: this.queryParams,
|
||||||
});
|
});
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
this.existingEquipments = Object.values(data).map((eq) => eq[0].equipmentId);
|
this.existingEquipments = Object.values(data).map(
|
||||||
|
(eq) => eq[0].equipmentId
|
||||||
|
);
|
||||||
this.graphList = this.objectToArray(data);
|
this.graphList = this.objectToArray(data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -236,65 +250,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 准备产线数据 */
|
|
||||||
async initProductline() {
|
|
||||||
const { code, data } = await this.$axios({
|
|
||||||
url: '/base/production-line/listAll',
|
|
||||||
method: 'get',
|
|
||||||
});
|
|
||||||
if (code == 0) {
|
|
||||||
this.searchBarFormConfig[0].selectOptions = data.map((item) => {
|
|
||||||
return {
|
|
||||||
name: item.name,
|
|
||||||
id: item.id,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 准备工段数据 */
|
|
||||||
async initWorksection() {
|
|
||||||
const { code, data } = await this.$axios({
|
|
||||||
url: '/base/workshop-section/listAll',
|
|
||||||
method: 'get',
|
|
||||||
});
|
|
||||||
if (code == 0) {
|
|
||||||
this.searchBarFormConfig[1].selectOptions = data.map((item) => {
|
|
||||||
return {
|
|
||||||
name: item.name,
|
|
||||||
id: item.id,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleSearchBarSelectChange({ param, value }) {
|
|
||||||
if (!value) {
|
|
||||||
this.searchBarFormConfig[1].selectOptions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (param) {
|
|
||||||
case 'lineId':
|
|
||||||
this.$axios({
|
|
||||||
url: '/base/workshop-section/listByParentId',
|
|
||||||
method: 'get',
|
|
||||||
params: {
|
|
||||||
id: value,
|
|
||||||
},
|
|
||||||
}).then(({ code, data }) => {
|
|
||||||
if (code == 0) {
|
|
||||||
this.searchBarFormConfig[1].selectOptions = data.map((item) => {
|
|
||||||
return {
|
|
||||||
name: item.name,
|
|
||||||
id: item.id,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleSearchBarBtnClick({ btnName, ...payload }) {
|
handleSearchBarBtnClick({ btnName, ...payload }) {
|
||||||
|
this.queryParams.equipmentId = Number(this.$route.query.eqid);
|
||||||
switch (btnName) {
|
switch (btnName) {
|
||||||
case 'search':
|
case 'search':
|
||||||
if (!payload.recordTime || payload.recordTime.length <= 0) {
|
if (!payload.recordTime || payload.recordTime.length <= 0) {
|
||||||
@ -302,26 +259,23 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.startTime = new Date(payload.recordTime)
|
this.startTime = new Date(payload.recordTime);
|
||||||
this.queryParams.lineId = payload.lineId || null;
|
|
||||||
this.queryParams.sectionId = payload.sectionId || null;
|
|
||||||
this.queryParams.equipmentId = payload.equipmentId || null;
|
|
||||||
this.queryParams.recordTime = payload.recordTime
|
this.queryParams.recordTime = payload.recordTime
|
||||||
? [
|
? [
|
||||||
payload.recordTime,
|
payload.recordTime,
|
||||||
new Date(
|
new Date(
|
||||||
new Date(payload.recordTime).getTime() + 24 * 3600 * 1000
|
new Date(payload.recordTime).getTime() + 24 * 3600 * 1000
|
||||||
)
|
)
|
||||||
.toLocaleDateString()
|
.toLocaleDateString()
|
||||||
.split('/')
|
.split('/')
|
||||||
.map((value, index) => {
|
.map((value, index) => {
|
||||||
if (index == 1 || index == 2) {
|
if (index == 1 || index == 2) {
|
||||||
return value.padStart(2, '0');
|
return value.padStart(2, '0');
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
})
|
})
|
||||||
.join('-') + ' 00:00:00',
|
.join('-') + ' 00:00:00',
|
||||||
]
|
]
|
||||||
: null;
|
: null;
|
||||||
this.getList();
|
this.getList();
|
||||||
break;
|
break;
|
||||||
@ -336,10 +290,11 @@ export default {
|
|||||||
this.$message.warning('该设备已存在');
|
this.$message.warning('该设备已存在');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const { ...params } = this.queryParams;
|
||||||
const { code, data } = await this.$axios({
|
const { code, data } = await this.$axios({
|
||||||
url: '/analysis/equipment-analysis/status',
|
url: '/analysis/equipment-analysis/status',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: this.queryParams,
|
params: params,
|
||||||
});
|
});
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
const newEqlist = this.objectToArray(data);
|
const newEqlist = this.objectToArray(data);
|
||||||
@ -444,7 +399,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.running {
|
.running {
|
||||||
background-color: #288AFF;
|
background-color: #288aff;
|
||||||
// background-color: #84f04e;
|
// background-color: #84f04e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,7 +410,7 @@ export default {
|
|||||||
|
|
||||||
.fault {
|
.fault {
|
||||||
// background-color: #ea5b5b;
|
// background-color: #ea5b5b;
|
||||||
background-color: #FC9C91;
|
background-color: #fc9c91;
|
||||||
}
|
}
|
||||||
|
|
||||||
.full {
|
.full {
|
||||||
@ -469,7 +424,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.stop {
|
.stop {
|
||||||
background-color: #FFDC94;
|
background-color: #ffdc94;
|
||||||
}
|
}
|
||||||
|
|
||||||
.legend-row {
|
.legend-row {
|
||||||
@ -478,7 +433,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|
||||||
>.legend:not(:last-child) {
|
> .legend:not(:last-child) {
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,7 +476,7 @@ export default {
|
|||||||
background: #ccc;
|
background: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.echarts__status-chart>div {
|
.echarts__status-chart > div {
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ import Editor from '@/components/Editor';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import basicPageMixin from '@/mixins/lb/basicPageMixin';
|
import basicPageMixin from '@/mixins/lb/basicPageMixin';
|
||||||
import { getAccessToken } from '@/utils/auth';
|
import { getAccessToken } from '@/utils/auth';
|
||||||
|
import { getFactoryPage } from '@/api/core/base/factory';
|
||||||
import { publicFormatter } from '@/utils/dict';
|
import { publicFormatter } from '@/utils/dict';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -67,6 +68,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchBarKeys: ['checkTime'],
|
searchBarKeys: ['checkTime'],
|
||||||
|
optionArrUrl: [getFactoryPage],
|
||||||
tableBtn: [
|
tableBtn: [
|
||||||
this.$auth.hasPermi('base:equipment-alarm-log:update')
|
this.$auth.hasPermi('base:equipment-alarm-log:update')
|
||||||
? {
|
? {
|
||||||
@ -82,6 +84,10 @@ export default {
|
|||||||
: undefined,
|
: undefined,
|
||||||
].filter((v) => v),
|
].filter((v) => v),
|
||||||
tableProps: [
|
tableProps: [
|
||||||
|
{
|
||||||
|
prop: 'factoryName',
|
||||||
|
label: '工厂',
|
||||||
|
},
|
||||||
{ prop: 'productionLine', label: '产线' },
|
{ prop: 'productionLine', label: '产线' },
|
||||||
{ prop: 'workshopSection', label: '工段' },
|
{ prop: 'workshopSection', label: '工段' },
|
||||||
{ prop: 'equipment', label: '设备名称' },
|
{ prop: 'equipment', label: '设备名称' },
|
||||||
@ -128,6 +134,13 @@ export default {
|
|||||||
// },
|
// },
|
||||||
],
|
],
|
||||||
searchBarFormConfig: [
|
searchBarFormConfig: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '工厂',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'factoryId',
|
||||||
|
onchange: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'datePicker',
|
type: 'datePicker',
|
||||||
label: '时间段',
|
label: '时间段',
|
||||||
@ -155,6 +168,7 @@ export default {
|
|||||||
queryParams: {
|
queryParams: {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
|
factoryId: undefined,
|
||||||
createTime: [],
|
createTime: [],
|
||||||
},
|
},
|
||||||
// 表单参数
|
// 表单参数
|
||||||
@ -164,12 +178,25 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
this.getArr();
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getArr() {
|
||||||
|
const params = {
|
||||||
|
page: 1,
|
||||||
|
limit: 500,
|
||||||
|
};
|
||||||
|
this.optionArrUrl.forEach((item, index) => {
|
||||||
|
item(params).then((response) => {
|
||||||
|
this.searchBarFormConfig[index].selectOptions = response.data.list;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
/** 重写 basicPageMixin 里的 handleSearchBarBtnClick */
|
/** 重写 basicPageMixin 里的 handleSearchBarBtnClick */
|
||||||
handleSearchBarBtnClick(btn) {
|
handleSearchBarBtnClick(btn) {
|
||||||
// 仅查询一种情况
|
// 仅查询一种情况
|
||||||
|
this.queryParams.factoryId = btn.factoryId;
|
||||||
this.queryParams.createTime = btn.createTime;
|
this.queryParams.createTime = btn.createTime;
|
||||||
this.handleQuery();
|
this.handleQuery();
|
||||||
},
|
},
|
||||||
|
@ -48,6 +48,9 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import basicPageMixin from '@/mixins/lb/basicPageMixin';
|
import basicPageMixin from '@/mixins/lb/basicPageMixin';
|
||||||
import { publicFormatter } from '@/utils/dict';
|
import { publicFormatter } from '@/utils/dict';
|
||||||
|
import { getPdList } from '@/api/core/monitoring/auto';
|
||||||
|
import { getProductionLinePage } from '@/api/core/base/productionLine';
|
||||||
|
import { getFactoryPage } from '@/api/core/base/factory';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EquipmentStatusAndParams',
|
name: 'EquipmentStatusAndParams',
|
||||||
@ -56,6 +59,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchBarKeys: ['equipmentId', 'productionLineId'],
|
searchBarKeys: ['equipmentId', 'productionLineId'],
|
||||||
|
optionArrUrl: [getFactoryPage, getProductionLinePage],
|
||||||
tableBtn: [
|
tableBtn: [
|
||||||
this.$auth.hasPermi('base:equipment-alarm-log:update')
|
this.$auth.hasPermi('base:equipment-alarm-log:update')
|
||||||
? {
|
? {
|
||||||
@ -71,6 +75,10 @@ export default {
|
|||||||
: undefined,
|
: undefined,
|
||||||
].filter((v) => v),
|
].filter((v) => v),
|
||||||
tableProps: [
|
tableProps: [
|
||||||
|
{
|
||||||
|
prop: 'factoryName',
|
||||||
|
label: '工厂',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
prop: 'lineName',
|
prop: 'lineName',
|
||||||
label: '产线名',
|
label: '产线名',
|
||||||
@ -78,7 +86,7 @@ export default {
|
|||||||
{
|
{
|
||||||
prop: 'workshopName',
|
prop: 'workshopName',
|
||||||
label: '工段名',
|
label: '工段名',
|
||||||
showOverflowtooltip :true,
|
showOverflowtooltip: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: 200,
|
width: 200,
|
||||||
@ -87,7 +95,7 @@ export default {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: 150,
|
width: 150,
|
||||||
showOverflowtooltip :true,
|
showOverflowtooltip: true,
|
||||||
prop: 'equipmentCode',
|
prop: 'equipmentCode',
|
||||||
label: '设备编码',
|
label: '设备编码',
|
||||||
},
|
},
|
||||||
@ -106,24 +114,24 @@ export default {
|
|||||||
filter: (val) =>
|
filter: (val) =>
|
||||||
val != null ? ['正常', '计划停机', '故障'][val] : '-',
|
val != null ? ['正常', '计划停机', '故障'][val] : '-',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
width: 128,
|
// width: 128,
|
||||||
prop: 'error',
|
// prop: 'error',
|
||||||
label: '是否故障',
|
// label: '是否故障',
|
||||||
filter: (val) => (val != null ? (val ? '是' : '否') : '-'),
|
// filter: (val) => (val != null ? (val ? '是' : '否') : '-'),
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
prop: 'quantityRecordTime',
|
// prop: 'quantityRecordTime',
|
||||||
label: '生产量记录时间',
|
// label: '生产量记录时间',
|
||||||
width: 180,
|
// width: 180,
|
||||||
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
|
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
prop: 'statusRecordTime',
|
// prop: 'statusRecordTime',
|
||||||
label: '状态记录时间',
|
// label: '状态记录时间',
|
||||||
width: 180,
|
// width: 180,
|
||||||
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
|
// filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
_action: 'params-monitor',
|
_action: 'params-monitor',
|
||||||
label: '操作',
|
label: '操作',
|
||||||
@ -154,20 +162,13 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
searchBarFormConfig: [
|
searchBarFormConfig: [
|
||||||
// {
|
{
|
||||||
// type: 'datePicker',
|
type: 'select',
|
||||||
// label: '时间段',
|
label: '工厂',
|
||||||
// dateType: 'daterange', // datetimerange
|
selectOptions: [],
|
||||||
// // format: 'yyyy-MM-dd HH:mm:ss',
|
param: 'factoryId',
|
||||||
// format: 'yyyy-MM-dd',
|
onchange: true,
|
||||||
// valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
},
|
||||||
// rangeSeparator: '-',
|
|
||||||
// startPlaceholder: '开始日期',
|
|
||||||
// endPlaceholder: '结束日期',
|
|
||||||
// defaultTime: ['00:00:00', '23:59:59'],
|
|
||||||
// param: 'createTime',
|
|
||||||
// // width: 350,
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
type: 'select',
|
type: 'select',
|
||||||
label: '产线',
|
label: '产线',
|
||||||
@ -196,6 +197,7 @@ export default {
|
|||||||
queryParams: {
|
queryParams: {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
|
factoryId: null,
|
||||||
productionLineId: null,
|
productionLineId: null,
|
||||||
equipmentId: null,
|
equipmentId: null,
|
||||||
},
|
},
|
||||||
@ -207,22 +209,21 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getLineList();
|
this.getArr();
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/** 获取产线 */
|
getArr() {
|
||||||
async getLineList() {
|
const params = {
|
||||||
const { data } = await this.$axios({
|
page: 1,
|
||||||
url: '/base/production-line/listAll',
|
limit: 500,
|
||||||
method: 'get',
|
};
|
||||||
|
this.optionArrUrl.forEach((item, index) => {
|
||||||
|
item(params).then((response) => {
|
||||||
|
this.searchBarFormConfig[index].selectOptions = response.data.list;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
this.searchBarFormConfig[0].selectOptions = data.map((line) => ({
|
|
||||||
name: line.name,
|
|
||||||
id: line.id,
|
|
||||||
}));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 根据产线获取设备 */
|
/** 根据产线获取设备 */
|
||||||
async getEquipmentList(id) {
|
async getEquipmentList(id) {
|
||||||
const { data } = await this.$axios({
|
const { data } = await this.$axios({
|
||||||
@ -238,14 +239,24 @@ export default {
|
|||||||
if (param == 'productionLineId') {
|
if (param == 'productionLineId') {
|
||||||
if (id == '') {
|
if (id == '') {
|
||||||
// 清除设备选框里的选项
|
// 清除设备选框里的选项
|
||||||
this.searchBarFormConfig[1].selectOptions = [];
|
this.searchBarFormConfig[2].selectOptions = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const list = await this.getEquipmentList(id);
|
const list = await this.getEquipmentList(id);
|
||||||
this.searchBarFormConfig[1].selectOptions = list.map((eq) => ({
|
this.searchBarFormConfig[2].selectOptions = list.map((eq) => ({
|
||||||
name: eq.name,
|
name: eq.name,
|
||||||
id: eq.id,
|
id: eq.id,
|
||||||
}));
|
}));
|
||||||
|
} else if (param == 'factoryId') {
|
||||||
|
// 清除设备选框里的选项
|
||||||
|
this.searchBarFormConfig[2].selectOptions = [];
|
||||||
|
this.queryParams.equipmentId = undefined;
|
||||||
|
this.queryParams.productionLineId = undefined;
|
||||||
|
this.$refs['search-bar'].formInline.equipmentId = undefined;
|
||||||
|
this.$refs['search-bar'].formInline.productionLineId = undefined;
|
||||||
|
getPdList(id).then((res) => {
|
||||||
|
this.searchBarFormConfig[1].selectOptions = res.data || [];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -256,6 +267,7 @@ export default {
|
|||||||
if (productionLineId)
|
if (productionLineId)
|
||||||
this.queryParams.productionLineId = productionLineId;
|
this.queryParams.productionLineId = productionLineId;
|
||||||
else this.queryParams.productionLineId = null;
|
else this.queryParams.productionLineId = null;
|
||||||
|
this.queryParams.factoryId = btn.factoryId || null;
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
299
src/views/monitoring/equipmentVisualize/index.vue
Normal file
299
src/views/monitoring/equipmentVisualize/index.vue
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: zwq
|
||||||
|
* @Date: 2025-02-10 09:15:55
|
||||||
|
* @LastEditors: zwq
|
||||||
|
* @LastEditTime: 2025-02-19 09:41:10
|
||||||
|
* @Description:
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<div class="app-container" style="overflow: auto">
|
||||||
|
<search-bar
|
||||||
|
:formConfigs="formConfig"
|
||||||
|
ref="searchBarForm"
|
||||||
|
@select-changed="handleSearchBarChanged"
|
||||||
|
@headBtnClick="buttonClick" />
|
||||||
|
<div class="top-tip">
|
||||||
|
<div class="block" style="background: #5b8ff9" />
|
||||||
|
运行
|
||||||
|
<div class="block" style="background: #f4b183" />
|
||||||
|
停机
|
||||||
|
<div class="block" style="background: #ff4f3e" />
|
||||||
|
故障
|
||||||
|
</div>
|
||||||
|
<div class="canvas-line" v-for="(item, index) in lineArr" :key="index">
|
||||||
|
<div class="title">{{ item.name }}</div>
|
||||||
|
<canvas
|
||||||
|
style="
|
||||||
|
box-shadow: 1px 1px 2px 2px #909399;
|
||||||
|
padding: 0;
|
||||||
|
height: 210px;
|
||||||
|
width: 100%;
|
||||||
|
"
|
||||||
|
@click="getclient($event, index + 1, item.num)"
|
||||||
|
:id="'mycanvas' + (index + 1)"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getPdList } from '@/api/core/monitoring/auto';
|
||||||
|
import { getFactoryPage, getLineEqStatus } from '@/api/core/base/factory';
|
||||||
|
import linePot from './line-pot';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
listQuery: {
|
||||||
|
factoryId: null,
|
||||||
|
lineId: null,
|
||||||
|
},
|
||||||
|
ctx: '', //canvas
|
||||||
|
lineArr: [],
|
||||||
|
formConfig: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '工厂',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'factoryId',
|
||||||
|
onchange: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '产线',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'lineId',
|
||||||
|
multiple: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '搜索',
|
||||||
|
name: 'search',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
linePot,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
components: {},
|
||||||
|
created() {
|
||||||
|
this.getPdLineList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initCanvas(name) {
|
||||||
|
let canvas = document.getElementById(name);
|
||||||
|
canvas.width = canvas.clientWidth;
|
||||||
|
canvas.width = canvas.clientWidth;
|
||||||
|
canvas.height = 210;
|
||||||
|
this.ctx = canvas.getContext('2d');
|
||||||
|
this.ctx.lineWidth = 1;
|
||||||
|
this.ctx.strokeStyle = '#909399';
|
||||||
|
this.ctx.fillStyle = '#5b8ff9';
|
||||||
|
this.ctx.font = '12px 宋体'; //文字大小 字体样式
|
||||||
|
this.ctx.clearRect(0, 0, canvas.clientWidth, 210); //清空画布
|
||||||
|
},
|
||||||
|
//画长方形
|
||||||
|
fillRect(x, y, width, height, name, color) {
|
||||||
|
this.ctx.beginPath(); //开始
|
||||||
|
this.ctx.fillStyle = color ? color : '#5b8ff9'; //填充颜色
|
||||||
|
this.ctx.fillRect(x, y, width, height); //左上角点的坐标(x,y) 宽 高
|
||||||
|
this.ctx.strokeRect(x, y, width, height);
|
||||||
|
this.ctx.fillStyle = '#fff'; //填充颜色
|
||||||
|
if (height === 50) {
|
||||||
|
//判断是否特殊机器 机器文字y轴定位加10
|
||||||
|
this.ctx.fillText(name, x + 5, y + 30);
|
||||||
|
} else {
|
||||||
|
this.ctx.fillText(name, x + 5, y + 20);
|
||||||
|
}
|
||||||
|
this.ctx.closePath(); //结束
|
||||||
|
},
|
||||||
|
//画特殊形
|
||||||
|
fillLRect(LArr, name, color) {
|
||||||
|
this.ctx.beginPath(); //开始
|
||||||
|
LArr.forEach((item, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
this.ctx.moveTo(item[0], item[1]);
|
||||||
|
} else {
|
||||||
|
this.ctx.lineTo(item[0], item[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.ctx.closePath(); //结束 // 闭合路径
|
||||||
|
this.ctx.fillStyle = color ? color : '#5b8ff9'; //填充颜色
|
||||||
|
this.ctx.fill();
|
||||||
|
this.ctx.stroke();
|
||||||
|
this.ctx.fillStyle = '#fff'; //填充颜色
|
||||||
|
if (LArr[0][0] === LArr[1][0]) {
|
||||||
|
//判断L形第一截是竖着还是横着
|
||||||
|
this.ctx.fillText(name, LArr[1][0] + 5, LArr[1][1] + 20); //竖着
|
||||||
|
} else {
|
||||||
|
this.ctx.fillText(name, LArr[0][0] + 5, LArr[0][1] + 20);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setRect(item, index) {
|
||||||
|
const identifier = 'line' + item.num + 'canvas';
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initCanvas('mycanvas' + (index + 1));
|
||||||
|
});
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.linePot[identifier].forEach((idItem) => {
|
||||||
|
item.children.forEach((eqItem) => {
|
||||||
|
if (eqItem.id === idItem.id) {
|
||||||
|
idItem.color = ['#5b8ff9', '#f4b183', '#ff4f3e'][
|
||||||
|
eqItem.equipmentStatus
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (idItem.isL) {
|
||||||
|
this.fillLRect(idItem.line, idItem.name, idItem.color);
|
||||||
|
} else {
|
||||||
|
this.fillRect(
|
||||||
|
idItem.x,
|
||||||
|
idItem.y,
|
||||||
|
idItem.width,
|
||||||
|
idItem.height,
|
||||||
|
idItem.name,
|
||||||
|
idItem.color
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getclient(e, index, num) {
|
||||||
|
let canvas = document.getElementById('mycanvas' + index);
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
const identifier = 'line' + num + 'canvas';
|
||||||
|
this.isEQ(e.clientX - rect.left, e.clientY - rect.top, identifier);
|
||||||
|
},
|
||||||
|
// 检查点击位置是否在设备内
|
||||||
|
isEQ(x, y, identifier) {
|
||||||
|
this.linePot[identifier].forEach((idItem) => {
|
||||||
|
if (idItem.isEQ) {
|
||||||
|
// 检查点击位置是否在矩形内
|
||||||
|
if (
|
||||||
|
x >= idItem.x &&
|
||||||
|
x <= idItem.x + idItem.width &&
|
||||||
|
y >= idItem.y &&
|
||||||
|
y <= idItem.y + idItem.height
|
||||||
|
) {
|
||||||
|
console.log(idItem.name, idItem.id);
|
||||||
|
this.$router.push({
|
||||||
|
path: '/equipment/analysis/timing-diagram/equipment-status',
|
||||||
|
query: { eqid: idItem.id },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getPdLineList() {
|
||||||
|
const params = {
|
||||||
|
pageSize: 100,
|
||||||
|
pageNo: 1,
|
||||||
|
};
|
||||||
|
getFactoryPage(params).then((res) => {
|
||||||
|
this.formConfig[0].selectOptions = res.data.list || [];
|
||||||
|
});
|
||||||
|
getPdList().then((res) => {
|
||||||
|
this.formConfig[1].selectOptions = res.data || [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
buttonClick(val) {
|
||||||
|
switch (val.btnName) {
|
||||||
|
case 'search':
|
||||||
|
this.listQuery.pageNo = 1;
|
||||||
|
this.listQuery.pageSize = 100;
|
||||||
|
this.listQuery.factoryId = val.factoryId || undefined;
|
||||||
|
this.listQuery.lineId = val.lineId ? val.lineId : [];
|
||||||
|
this.getDataList();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log(val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSearchBarChanged({ param, value }) {
|
||||||
|
this.listQuery.lineId = [];
|
||||||
|
this.$refs.searchBarForm.formInline.lineId = undefined;
|
||||||
|
getPdList(value).then((res) => {
|
||||||
|
this.formConfig[1].selectOptions = res.data || [];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getDataList() {
|
||||||
|
// this.lineArr = [
|
||||||
|
// {
|
||||||
|
// num: 1,
|
||||||
|
// name: 'A1',
|
||||||
|
// children: [],
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// num: 2,
|
||||||
|
// name: 'A2',
|
||||||
|
// children: [],
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// num: 3,
|
||||||
|
// name: 'A3',
|
||||||
|
// children: [],
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// num: 4,
|
||||||
|
// name: 'A4',
|
||||||
|
// children: [],
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// num: 5,
|
||||||
|
// name: 'A5',
|
||||||
|
// children: [],
|
||||||
|
// },
|
||||||
|
// ];
|
||||||
|
getLineEqStatus(this.listQuery).then((response) => {
|
||||||
|
this.lineArr = response.data;
|
||||||
|
this.lineArr.forEach((item, index) => {
|
||||||
|
const num = [
|
||||||
|
'',
|
||||||
|
'1672847052717821953',
|
||||||
|
'1672847052717821954',
|
||||||
|
'1686260211054157825',
|
||||||
|
'1701892552632770122',
|
||||||
|
'1714562503683465331',
|
||||||
|
].indexOf(item.id);
|
||||||
|
if (num > 0) {
|
||||||
|
item.num = num;
|
||||||
|
item.name = item.lineName;
|
||||||
|
this.setRect(item, index);
|
||||||
|
} else {
|
||||||
|
this.$message.warning('没有对应的产线!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.top-tip {
|
||||||
|
.block {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20px;
|
||||||
|
height: 10px;
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.canvas-line {
|
||||||
|
margin-top: 20px;
|
||||||
|
min-width: 1600px;
|
||||||
|
.title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bolder;
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
background: rgb(39, 240, 17);
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 3px;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
1810
src/views/monitoring/equipmentVisualize/line-pot.js
Normal file
1810
src/views/monitoring/equipmentVisualize/line-pot.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,13 +2,13 @@
|
|||||||
setlocal enabledelayedexpansion
|
setlocal enabledelayedexpansion
|
||||||
set cmdstr=rsync
|
set cmdstr=rsync
|
||||||
set zipfile=cwrsync.zip
|
set zipfile=cwrsync.zip
|
||||||
set downurl=https://itefix.net/dl/free-software/cwrsync_6.3.0_x64_free.zip
|
set downurl=https://itefix.net/download/free/cwrsync_6.3.0_x64_free.zip
|
||||||
set currpath=%~dp0
|
set currpath=%~dp0
|
||||||
set "rsynchome=%ProgramFiles%\%zipfile:~0,-4%"
|
set "rsynchome=%ProgramFiles%\%zipfile:~0,-4%"
|
||||||
set passfile=%temp%\.password
|
set passfile=%temp%\.password
|
||||||
set syncdir=dist/
|
set syncdir=dist/
|
||||||
:: 以下需要配置同步服务器
|
:: 以下需要配置同步服务器
|
||||||
set accountwithost=kszny@47.96.93.140::line
|
set accountwithost=kszny@192.168.8.22::line
|
||||||
set "password=kszny@123"
|
set "password=kszny@123"
|
||||||
set "runcommand=%cmdstr% --port=873 -rlptvz --progress --password-file=%passfile% --exclude=google.exe --exclude=Lodap.zip %syncdir% %accountwithost%"
|
set "runcommand=%cmdstr% --port=873 -rlptvz --progress --password-file=%passfile% --exclude=google.exe --exclude=Lodap.zip %syncdir% %accountwithost%"
|
||||||
|
|
68
sync_line_yy_prod.bat
Normal file
68
sync_line_yy_prod.bat
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
set cmdstr=rsync
|
||||||
|
set zipfile=cwrsync.zip
|
||||||
|
set downurl=https://itefix.net/download/free/cwrsync_6.3.0_x64_free.zip
|
||||||
|
set currpath=%~dp0
|
||||||
|
set "rsynchome=%ProgramFiles%\%zipfile:~0,-4%"
|
||||||
|
set passfile=%temp%\.password
|
||||||
|
set syncdir=dist/
|
||||||
|
:: 以下需要配置同步服务器
|
||||||
|
set accountwithost=kszny@192.168.4.142::line
|
||||||
|
set "password=kszny@123"
|
||||||
|
set "runcommand=%cmdstr% --port=873 -rlptvz --progress --password-file=%passfile% --exclude=google.exe --exclude=Lodap.zip %syncdir% %accountwithost%"
|
||||||
|
|
||||||
|
where %cmdstr% >nul 2>nul
|
||||||
|
::有错误输出,说明不存在该命令
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
::还未下载安装包或未正常解压到安装目录
|
||||||
|
if not exist "%rsynchome%" (
|
||||||
|
:: 请求提升管理员权限
|
||||||
|
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\runAsAdmin.vbs"
|
||||||
|
echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\runAsAdmin.vbs"
|
||||||
|
"%temp%\runAsAdmin.vbs"
|
||||||
|
:: 需要提升管理员权限才能创建此目录
|
||||||
|
mkdir "%rsynchome%"
|
||||||
|
del "%temp%\runAsAdmin.vbs"
|
||||||
|
exit /B
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 使用powershell的curl下载软件包
|
||||||
|
powershell curl -o %temp%\%zipfile% %downurl%
|
||||||
|
:: 解压
|
||||||
|
tar -xf "%temp%\%zipfile%" -C "%rsynchome%"
|
||||||
|
echo "%cmdstr%已经安装到了%rsynchome%目录下"
|
||||||
|
|
||||||
|
:: 检查路径是否存在于 PATH 中
|
||||||
|
set "found=false"
|
||||||
|
for %%I in ("%PATH:;=";"%") do (
|
||||||
|
if /I "%%~I"=="%rsynchome%\bin" (
|
||||||
|
set "found=true"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
:: 未设置到path变量中,添加到path变量
|
||||||
|
if "!found!"=="false" (
|
||||||
|
:: 更新注册表中的 PATH 变量,通过setx方式,变量值长度超过1024个字符就会被截断
|
||||||
|
reg add "HKCU\Environment" /v PATH /t REG_EXPAND_SZ /d "%PATH%;%rsynchome%\bin" /f
|
||||||
|
)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
::当前目录下没有dist目录
|
||||||
|
if not exist "%currpath%%syncdir%" (
|
||||||
|
echo 当前目录下没有需要同步的%syncdir%目录,请把需要同步的%syncdir%目录拷贝到当前目录下!
|
||||||
|
) else (
|
||||||
|
echo !password!>%passfile%
|
||||||
|
echo 数据同步开始,请稍后...
|
||||||
|
!runcommand! && (
|
||||||
|
echo 数据同步完成!
|
||||||
|
) || (
|
||||||
|
echo !runcommand!
|
||||||
|
echo 数据同步失败,请确认是否开启了VPN!
|
||||||
|
)
|
||||||
|
del %passfile%
|
||||||
|
)
|
||||||
|
|
||||||
|
endlocal
|
||||||
|
pause
|
Loading…
Reference in New Issue
Block a user