lb #19
@ -31,7 +31,6 @@ export default {
|
|||||||
// dialogFormConfig: [], // 占位
|
// dialogFormConfig: [], // 占位
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {},
|
|
||||||
methods: {
|
methods: {
|
||||||
// 过滤后端传回的详情数据
|
// 过滤后端传回的详情数据
|
||||||
filterData(data, keys) {
|
filterData(data, keys) {
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
<!--
|
||||||
|
filename: pieChart.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-06 15:02:49
|
||||||
|
description: 饼图
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="pie-chart" :data-eqname="value.equipmentName || 'Default'"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'pieChart',
|
||||||
|
components: {},
|
||||||
|
props: ['value'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chart: null,
|
||||||
|
config: {
|
||||||
|
grid: {
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: '0%',
|
||||||
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 10,
|
||||||
|
},
|
||||||
|
itemWidth: 10,
|
||||||
|
itemHeight: 10,
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: this.value.equipmentName || 'Default',
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['40%', '75%'],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
position: 'center',
|
||||||
|
},
|
||||||
|
data: ['workTime', 'stopTime', 'downTime'].map((v, index) => ({
|
||||||
|
name: ['工作时长', '停机时长', '故障时长'][index],
|
||||||
|
value: this.value[v],
|
||||||
|
})),
|
||||||
|
// data: [
|
||||||
|
// { value: 1048, name: 'Search Engine' },
|
||||||
|
// { value: 735, name: 'Direct' },
|
||||||
|
// { value: 580, name: 'Email' },
|
||||||
|
// { value: 484, name: 'Union Ads' },
|
||||||
|
// { value: 300, name: 'Video Ads' },
|
||||||
|
// ],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (!this.chart) {
|
||||||
|
this.chart = echarts.init(this.$el);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.chart.setOption(this.config);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.chart) this.chart.dispose();
|
||||||
|
},
|
||||||
|
methods: {},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.pie-chart {
|
||||||
|
padding: 12px;
|
||||||
|
min-height: 320px;
|
||||||
|
background: #f1f1f1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pie-chart::before {
|
||||||
|
content: attr(data-eqname);
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1;
|
||||||
|
position: absolute;
|
||||||
|
top: -16px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
</style>
|
419
src/views/equipment/analysis/efficiency/index.vue
Normal file
419
src/views/equipment/analysis/efficiency/index.vue
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
<!--
|
||||||
|
filename: index.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-04 09:34:52
|
||||||
|
description: 设备效率分析
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<SearchBar
|
||||||
|
:formConfigs="searchBarFormConfig"
|
||||||
|
ref="search-bar"
|
||||||
|
@headBtnClick="handleSearchBarBtnClick" />
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<base-table
|
||||||
|
class="base-table__margin"
|
||||||
|
:table-props="tableProps"
|
||||||
|
:table-data="list"
|
||||||
|
@emitFun="handleEmitFun">
|
||||||
|
<!-- :page="queryParams.pageNo"
|
||||||
|
:limit="queryParams.pageSize" -->
|
||||||
|
<!-- <method-btn
|
||||||
|
v-if="tableBtn.length"
|
||||||
|
slot="handleBtn"
|
||||||
|
label="操作"
|
||||||
|
:method-list="tableBtn"
|
||||||
|
@clickBtn="handleTableBtnClick" /> -->
|
||||||
|
</base-table>
|
||||||
|
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<!-- <pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNo"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList" /> -->
|
||||||
|
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<base-dialog
|
||||||
|
:dialogTitle="visualizationOpen ? '设备可视化' : '查看趋势'"
|
||||||
|
:dialogVisible="open"
|
||||||
|
:width="visualizationOpen ? '80%' : '700px'"
|
||||||
|
@closed="closed"
|
||||||
|
@close="cancel"
|
||||||
|
@cancel="cancel"
|
||||||
|
@confirm="submitForm">
|
||||||
|
<div class="visualization" v-if="visualizationOpen">
|
||||||
|
<pie-chart v-for="item in list" :key="item.id" :value="item" />
|
||||||
|
</div>
|
||||||
|
<div v-if="trendOpen">
|
||||||
|
<h1>查看趋势</h1>
|
||||||
|
</div>
|
||||||
|
</base-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// import moment from 'moment';
|
||||||
|
import basicPageMixin from '@/mixins/lb/basicPageMixin';
|
||||||
|
import PieChart from './components/pieChart.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EfficiencyAnalysis',
|
||||||
|
mixins: [basicPageMixin],
|
||||||
|
components: { PieChart },
|
||||||
|
props: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
open: false,
|
||||||
|
visualizationOpen: false,
|
||||||
|
trendOpen: false,
|
||||||
|
// tableBtn: [
|
||||||
|
// this.$auth.hasPermi('base:equipment-group:update')
|
||||||
|
// ? {
|
||||||
|
// type: 'edit',
|
||||||
|
// btnName: '修改',
|
||||||
|
// }
|
||||||
|
// : undefined,
|
||||||
|
// this.$auth.hasPermi('base:equipment-group:delete')
|
||||||
|
// ? {
|
||||||
|
// type: 'delete',
|
||||||
|
// btnName: '删除',
|
||||||
|
// }
|
||||||
|
// : undefined,
|
||||||
|
// ].filter((v) => v),
|
||||||
|
tableProps: [
|
||||||
|
{ prop: 'factoryName', label: '工厂', align: 'center' },
|
||||||
|
{ prop: 'lineName', label: '产线', align: 'center' },
|
||||||
|
{ prop: 'sectionName', label: '工段', align: 'center' },
|
||||||
|
{ prop: 'equipmentName', label: '设备', align: 'center' },
|
||||||
|
{
|
||||||
|
label: '有效时间',
|
||||||
|
align: 'center',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
width: 128,
|
||||||
|
prop: 'workTime',
|
||||||
|
label: '工作时长',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 128,
|
||||||
|
prop: 'workRate',
|
||||||
|
label: '百分比',
|
||||||
|
align: 'center',
|
||||||
|
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '关机时间',
|
||||||
|
align: 'center',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
width: 128,
|
||||||
|
prop: 'stopTime',
|
||||||
|
label: '停机时长',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{ width: 128, prop: 'stopRate', label: '百分比', align: 'center' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '中断损失',
|
||||||
|
align: 'center',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
width: 128,
|
||||||
|
prop: 'downTime',
|
||||||
|
label: '故障时长',
|
||||||
|
align: 'center',
|
||||||
|
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
|
||||||
|
},
|
||||||
|
{ width: 128, prop: 'downRate', label: '百分比', align: 'center' },
|
||||||
|
{
|
||||||
|
width: 128,
|
||||||
|
prop: 'timeEfficiency',
|
||||||
|
label: '时间开动率',
|
||||||
|
align: 'center',
|
||||||
|
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '速度损失',
|
||||||
|
align: 'center',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
width: 128,
|
||||||
|
prop: 'realProcSpeed',
|
||||||
|
label: '实际加工速度',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 128,
|
||||||
|
prop: 'designProcSpeed',
|
||||||
|
label: '理论加工速度',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 128,
|
||||||
|
prop: 'peEfficiency',
|
||||||
|
label: '速度开动率',
|
||||||
|
align: 'center',
|
||||||
|
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'oee',
|
||||||
|
label: 'OEE',
|
||||||
|
align: 'center',
|
||||||
|
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'teep',
|
||||||
|
label: 'TEEP',
|
||||||
|
align: 'center',
|
||||||
|
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// _action: 'view-trend',
|
||||||
|
// label: '趋势',
|
||||||
|
// align: 'center',
|
||||||
|
// subcomponent: {
|
||||||
|
// props: ['injectData'],
|
||||||
|
// render: function (h) {
|
||||||
|
// const _this = this;
|
||||||
|
// return h(
|
||||||
|
// 'el-button',
|
||||||
|
// {
|
||||||
|
// props: { type: 'text' },
|
||||||
|
// on: {
|
||||||
|
// click: function () {
|
||||||
|
// console.log('inejctdata', _this.injectData);
|
||||||
|
// _this.$emit('emitData', {
|
||||||
|
// action: _this.injectData._action,
|
||||||
|
// // value: _this.injectData.id,
|
||||||
|
// value: _this.injectData,
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// '查看趋势'
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
searchBarFormConfig: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '工厂',
|
||||||
|
placeholder: '请选择工厂',
|
||||||
|
param: 'factoryId',
|
||||||
|
selectOptions: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '产线',
|
||||||
|
placeholder: '请选择产线',
|
||||||
|
param: 'lineId',
|
||||||
|
selectOptions: [],
|
||||||
|
},
|
||||||
|
// 选项切换
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '时间类型',
|
||||||
|
param: 'dateFilterType',
|
||||||
|
defaultSelect: 0,
|
||||||
|
selectOptions: [
|
||||||
|
{ id: 0, name: '按时间段' },
|
||||||
|
{ id: 1, name: '按日期' },
|
||||||
|
],
|
||||||
|
index: 2,
|
||||||
|
extraOptions: [
|
||||||
|
{
|
||||||
|
parent: 'dateFilterType',
|
||||||
|
// 时间段选择
|
||||||
|
type: 'datePicker',
|
||||||
|
label: '时间段',
|
||||||
|
dateType: 'daterange',
|
||||||
|
format: 'yyyy-MM-dd',
|
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
defaultTime: ['00:00:00', '00:00:00'],
|
||||||
|
rangeSeparator: '-',
|
||||||
|
startPlaceholder: '开始时间',
|
||||||
|
endPlaceholder: '结束时间',
|
||||||
|
param: 'recordTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parent: 'dateFilterType',
|
||||||
|
// 日期选择
|
||||||
|
type: 'datePicker',
|
||||||
|
label: '日期',
|
||||||
|
dateType: 'date',
|
||||||
|
placeholder: '选择日期',
|
||||||
|
format: 'yyyy-MM-dd',
|
||||||
|
valueFormat: 'yyyy-MM-dd',
|
||||||
|
param: 'recordTime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '查询',
|
||||||
|
name: 'search',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'separate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '设备可视化',
|
||||||
|
name: 'visualization',
|
||||||
|
plain: true,
|
||||||
|
color: 'success',
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// type: 'button',
|
||||||
|
// btnName: 'OEE',
|
||||||
|
// name: 'add',
|
||||||
|
// plain: true,
|
||||||
|
// color: 'success',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'button',
|
||||||
|
// btnName: 'TEEP',
|
||||||
|
// name: 'add',
|
||||||
|
// plain: true,
|
||||||
|
// color: 'warning',
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
lineId: null,
|
||||||
|
factoryId: null,
|
||||||
|
recordTime: [],
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {},
|
||||||
|
list: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getFactory();
|
||||||
|
this.getLine();
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 准备工厂数据 */
|
||||||
|
async getFactory() {
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/base/factory/listAll',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
this.searchBarFormConfig[0].selectOptions = data.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
id: item.id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 准备产线数据 */
|
||||||
|
async getLine() {
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/base/production-line/listAll',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
this.searchBarFormConfig[1].selectOptions = data.map((item) => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
id: item.id,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 覆盖 handleEmitFun 的默认实现 */
|
||||||
|
handleEmitFun({ action, value }) {
|
||||||
|
switch (action) {
|
||||||
|
case 'view-trend':
|
||||||
|
const { id } = value;
|
||||||
|
this.open = true;
|
||||||
|
this.trendOpen = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/** 查询列表 */
|
||||||
|
async getList() {
|
||||||
|
this.loading = true;
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/analysis/equipment-analysis/efficiency',
|
||||||
|
method: 'get',
|
||||||
|
params: this.queryParams,
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
console.log('data', data);
|
||||||
|
this.list = data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearchBarBtnClick({ btnName, ...payload }) {
|
||||||
|
console.log('handleSearchBarBtnClick', btnName, payload);
|
||||||
|
if (btnName == 'visualization') {
|
||||||
|
// 可视化
|
||||||
|
this.visualizationOpen = true;
|
||||||
|
this.open = true;
|
||||||
|
}
|
||||||
|
if (btnName == 'search') {
|
||||||
|
this.queryParams.factoryId = payload.factoryId || null;
|
||||||
|
this.queryParams.lineId = payload.lineId || null;
|
||||||
|
if (payload.recordTime != null) {
|
||||||
|
if (typeof payload.recordTime == 'string') {
|
||||||
|
if (payload.recordTime.trim() !== '') {
|
||||||
|
this.queryParams.recordTime = [
|
||||||
|
`${payload.recordTime} 00:00:00`,
|
||||||
|
`${payload.recordTime} 23:59:59`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.queryParams.recordTime = payload.recordTime;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.queryParams.recordTime = null;
|
||||||
|
}
|
||||||
|
this.getList();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.open = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
closed() {
|
||||||
|
this.visualizationOpen = false;
|
||||||
|
this.trendOpen = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
submitForm() {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.visualization {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(240px, 1fr));
|
||||||
|
}
|
||||||
|
</style>
|
194
src/views/equipment/analysis/exception/index.vue
Normal file
194
src/views/equipment/analysis/exception/index.vue
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
<!--
|
||||||
|
filename: index.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-04 09:34:52
|
||||||
|
description: 设备异常分析
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<SearchBar
|
||||||
|
:formConfigs="searchBarFormConfig"
|
||||||
|
ref="search-bar"
|
||||||
|
@headBtnClick="handleSearchBarBtnClick" />
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<base-table
|
||||||
|
:table-props="tableProps"
|
||||||
|
:page="queryParams.pageNo"
|
||||||
|
:limit="queryParams.pageSize"
|
||||||
|
:table-data="list"
|
||||||
|
@emitFun="handleEmitFun">
|
||||||
|
<!-- <method-btn
|
||||||
|
v-if="tableBtn.length"
|
||||||
|
slot="handleBtn"
|
||||||
|
label="操作"
|
||||||
|
:method-list="tableBtn"
|
||||||
|
@clickBtn="handleTableBtnClick" /> -->
|
||||||
|
</base-table>
|
||||||
|
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
:total="total"
|
||||||
|
:page.sync="queryParams.pageNo"
|
||||||
|
:limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import moment from 'moment';
|
||||||
|
import basicPageMixin from '@/mixins/lb/basicPageMixin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ExceptionAnalysis',
|
||||||
|
mixins: [basicPageMixin],
|
||||||
|
components: {},
|
||||||
|
props: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
searchBarKeys: ['name', 'code'],
|
||||||
|
tableBtn: [
|
||||||
|
this.$auth.hasPermi('base:equipment-group:update')
|
||||||
|
? {
|
||||||
|
type: 'edit',
|
||||||
|
btnName: '修改',
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
this.$auth.hasPermi('base:equipment-group:delete')
|
||||||
|
? {
|
||||||
|
type: 'delete',
|
||||||
|
btnName: '删除',
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
].filter((v) => v),
|
||||||
|
tableProps: [
|
||||||
|
{ prop: 'lineName', label: '产线', align: 'center' },
|
||||||
|
{ prop: 'sectionName', label: '工段', align: 'center' },
|
||||||
|
{ prop: 'equipmentName', label: '设备', align: 'center' },
|
||||||
|
{
|
||||||
|
width: 188,
|
||||||
|
prop: 'mtbf',
|
||||||
|
label: '平均故障间隔时间[MTBF](h)',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 180,
|
||||||
|
prop: 'mttr',
|
||||||
|
label: '平均维修时间[MTTR](h)',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{ prop: 'workTime', label: '工作时长(h)', align: 'center' },
|
||||||
|
{ prop: 'downTime', label: '故障时长(h)', align: 'center' },
|
||||||
|
{ prop: 'downCount', label: '故障次数', align: 'center' },
|
||||||
|
],
|
||||||
|
searchBarFormConfig: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '请选择月份',
|
||||||
|
placeholder: '请选择月份',
|
||||||
|
param: 'month',
|
||||||
|
selectOptions: Array(12)
|
||||||
|
.fill(0)
|
||||||
|
.map((v, i) => ({
|
||||||
|
id: i + 1,
|
||||||
|
name: `${i + 1}月`,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__index: 'line',
|
||||||
|
type: 'select',
|
||||||
|
label: '产线',
|
||||||
|
placeholder: '请选择产线',
|
||||||
|
param: 'lineId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '查询',
|
||||||
|
name: 'search',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
lineId: null,
|
||||||
|
factoryId: null,
|
||||||
|
recordTime: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
created() {
|
||||||
|
this.fillLineOptions();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async fillLineOptions() {
|
||||||
|
const { data } = await this.$axios({
|
||||||
|
url: '/base/production-line/listAll',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
const cfg = this.searchBarFormConfig.find(
|
||||||
|
(item) => item.__index == 'line'
|
||||||
|
);
|
||||||
|
this.$set(
|
||||||
|
cfg,
|
||||||
|
'selectOptions',
|
||||||
|
data.map((item) => ({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async getList() {
|
||||||
|
this.loading = true;
|
||||||
|
// 执行查询
|
||||||
|
const { data } = await this.$axios({
|
||||||
|
url: '/analysis/equipment-analysis/efficiency',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
lineId: this.queryParams.lineId || null,
|
||||||
|
recordTime: this.queryParams.recordTime || null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearchBarBtnClick(btn) {
|
||||||
|
switch (btn.btnName) {
|
||||||
|
case 'search':
|
||||||
|
if (btn.month) {
|
||||||
|
this.queryParams.recordTime = [
|
||||||
|
moment()
|
||||||
|
.month(btn.month - 1)
|
||||||
|
.format('YYYY-MM')+'-01 00:00:00',
|
||||||
|
moment()
|
||||||
|
.month(btn.month)
|
||||||
|
.format('YYYY-MM')+'-01 00:00:00',
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
this.queryParams.recordTime = null;
|
||||||
|
}
|
||||||
|
this.queryParams.lineId = btn.lineId || null;
|
||||||
|
this.handleQuery();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
// this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm('queryForm');
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
@ -0,0 +1,49 @@
|
|||||||
|
<!--
|
||||||
|
filename: lineChart.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-04 13:45:00
|
||||||
|
description:
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="line-chart"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LineChart',
|
||||||
|
components: {},
|
||||||
|
props: ['config'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chart: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
mounted() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.chart) {
|
||||||
|
this.chart.dispose();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
console.log('thsi el', this.$el);
|
||||||
|
if (!this.chart) this.chart = echarts.init(this.$el);
|
||||||
|
this.chart.setOption(this.config);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.line-chart {
|
||||||
|
padding: 0 12px;
|
||||||
|
background: #e1e1e1;
|
||||||
|
min-height: 320px;
|
||||||
|
}
|
||||||
|
</style>
|
343
src/views/equipment/analysis/quality/index.vue
Normal file
343
src/views/equipment/analysis/quality/index.vue
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
<!--
|
||||||
|
filename: index.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-04 09:34:52
|
||||||
|
description: 设备质量分析
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<SearchBar
|
||||||
|
:formConfigs="searchBarFormConfig"
|
||||||
|
ref="search-bar"
|
||||||
|
@headBtnClick="handleSearchBarBtnClick" />
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<base-table
|
||||||
|
:table-props="tableProps"
|
||||||
|
:page="queryParams.pageNo"
|
||||||
|
:limit="queryParams.pageSize"
|
||||||
|
:table-data="list"
|
||||||
|
@emitFun="handleEmitFun"></base-table>
|
||||||
|
|
||||||
|
<!-- 图形分析 dialog -->
|
||||||
|
<!-- <base-dialog
|
||||||
|
dialogTitle="图形视角"
|
||||||
|
:dialogVisible="dialogVisible"
|
||||||
|
width="60%"
|
||||||
|
@close="dialogClose"
|
||||||
|
@cancel="dialogClose"
|
||||||
|
@confirm="dialogClose">
|
||||||
|
<LineChart v-if="dialogVisible" :config="lineChartConfig" />
|
||||||
|
</base-dialog> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import LineChart from './components/lineChart.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'QualityAnalysis',
|
||||||
|
components: { LineChart },
|
||||||
|
props: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
urls: {
|
||||||
|
page: '/analysis/equipment-analysis/quality',
|
||||||
|
},
|
||||||
|
mode: 'table', // defaults to 'table'
|
||||||
|
searchBarFormConfig: [
|
||||||
|
// 产品
|
||||||
|
{
|
||||||
|
__index: 'product',
|
||||||
|
type: 'select',
|
||||||
|
label: '产品',
|
||||||
|
placeholder: '请选择产品',
|
||||||
|
param: 'productId',
|
||||||
|
},
|
||||||
|
// 产线
|
||||||
|
{
|
||||||
|
__index: 'line',
|
||||||
|
type: 'select',
|
||||||
|
label: '产线',
|
||||||
|
placeholder: '请选择产线',
|
||||||
|
param: 'lineId',
|
||||||
|
},
|
||||||
|
// 时间段
|
||||||
|
{
|
||||||
|
type: 'datePicker',
|
||||||
|
label: '时间段',
|
||||||
|
dateType: 'daterange', // datetimerange
|
||||||
|
// format: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
format: 'yyyy-MM-dd',
|
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
// valueFormat: 'timestamp',
|
||||||
|
rangeSeparator: '-',
|
||||||
|
startPlaceholder: '开始日期',
|
||||||
|
endPlaceholder: '结束日期',
|
||||||
|
defaultTime: ['00:00:00', '23:59:59'],
|
||||||
|
param: 'recordTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '查询',
|
||||||
|
name: 'search',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'separate',
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// type: 'button',
|
||||||
|
// btnName: '列表数据',
|
||||||
|
// name: 'tableVersion',
|
||||||
|
// color: 'text btn-table',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'separate',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'button',
|
||||||
|
// btnName: '图形分析',
|
||||||
|
// name: 'graphVersion',
|
||||||
|
// color: 'text btn-graph',
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
// 动态的 props
|
||||||
|
tableProps: [
|
||||||
|
{
|
||||||
|
// width: 160,
|
||||||
|
prop: 'sectionName',
|
||||||
|
label: '工段',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// width: 160,
|
||||||
|
prop: 'equipmentName',
|
||||||
|
label: '设备名称',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// width: 160,
|
||||||
|
prop: 'products',
|
||||||
|
label: '产品名称',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// width: 160,
|
||||||
|
prop: 'inQuantity',
|
||||||
|
label: '进片数量',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// width: 160,
|
||||||
|
prop: 'outQuantity',
|
||||||
|
label: '出片数量',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// width: 160,
|
||||||
|
prop: 'nokQuantity',
|
||||||
|
label: '破损/不合格数',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// width: 160,
|
||||||
|
prop: 'passRate',
|
||||||
|
label: '合格率',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
lineChartConfig: {
|
||||||
|
grid: {
|
||||||
|
top: 88,
|
||||||
|
left: 56,
|
||||||
|
right: 56,
|
||||||
|
bottom: 56,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
padding: 5,
|
||||||
|
icon: 'roundRect',
|
||||||
|
itemWidth: 12,
|
||||||
|
itemHeight: 12,
|
||||||
|
itemGap: 20,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
lineHeight: 14
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: ['设备1', '设备2', '设备3', '设备4', '设备5'],
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '合格率',
|
||||||
|
nameLocation: 'end',
|
||||||
|
nameTextStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
align: 'right'
|
||||||
|
},
|
||||||
|
nameGap: 26
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '产线1',
|
||||||
|
data: [150, 230, 224, 218, 135],
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '产线2',
|
||||||
|
data: [111, 224, 42, 11, 24],
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '产线3',
|
||||||
|
data: [218, 112, 331, 44, 99],
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '产线4',
|
||||||
|
data: [3, 221, 42, 553, 311],
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
lineId: null,
|
||||||
|
productId: null,
|
||||||
|
recordTime: [],
|
||||||
|
},
|
||||||
|
list: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
created() {
|
||||||
|
this.fillLineOptions();
|
||||||
|
this.fillProductOptions();
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async fillLineOptions() {
|
||||||
|
const { data } = await this.$axios({
|
||||||
|
url: '/base/production-line/listAll',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
const cfg = this.searchBarFormConfig.find(
|
||||||
|
(item) => item.__index == 'line'
|
||||||
|
);
|
||||||
|
this.$set(
|
||||||
|
cfg,
|
||||||
|
'selectOptions',
|
||||||
|
data.map((item) => ({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async fillProductOptions() {
|
||||||
|
const { data } = await this.$axios({
|
||||||
|
url: '/base/product/listAll',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
const cfg = this.searchBarFormConfig.find(
|
||||||
|
(item) => item.__index == 'product'
|
||||||
|
);
|
||||||
|
this.$set(
|
||||||
|
cfg,
|
||||||
|
'selectOptions',
|
||||||
|
data.map((item) => ({
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async getList() {
|
||||||
|
const { data } = await this.$axios({
|
||||||
|
url: '/analysis/equipment-analysis/quality',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
lineId: this.queryParams.lineId || null,
|
||||||
|
productId: this.queryParams.productId || null,
|
||||||
|
recordTime: this.queryParams.recordTime || null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.list = data.map((item) => ({
|
||||||
|
...item,
|
||||||
|
products: item.products.join(','),
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearchBarBtnClick(btn) {
|
||||||
|
console.log('handleSearchBarBtnClick', btn);
|
||||||
|
switch (btn.btnName) {
|
||||||
|
case 'search':
|
||||||
|
this.queryParams.lineId = btn.lineId;
|
||||||
|
this.queryParams.productId = btn.productId;
|
||||||
|
this.queryParams.recordTime = btn.recordTime;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getList();
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'tableVersion':
|
||||||
|
this.dialogClose();
|
||||||
|
break;
|
||||||
|
case 'graphVersion':
|
||||||
|
this.dialogShow();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEmitFun({ action, payload }) {},
|
||||||
|
|
||||||
|
dialogShow() {
|
||||||
|
this.dialogVisible = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
dialogClose() {
|
||||||
|
this.dialogVisible = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
:deep(.searchBar) {
|
||||||
|
.el-button.btn-table {
|
||||||
|
color: rgb(0, 130, 130);
|
||||||
|
border: 1px solid rgb(0, 130, 130);
|
||||||
|
padding: 8px 10px;
|
||||||
|
border: 1px solid rgb(0, 130, 130);
|
||||||
|
padding: 8px 10px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #fff;
|
||||||
|
color: #fff;
|
||||||
|
background: rgb(0, 130, 130);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-button.btn-graph {
|
||||||
|
color: rgb(130, 0, 130);
|
||||||
|
border: 1px solid rgb(130, 0, 130);
|
||||||
|
padding: 8px 10px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #fff;
|
||||||
|
color: #fff;
|
||||||
|
background: rgb(130, 0, 130);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,49 @@
|
|||||||
|
<!--
|
||||||
|
filename: lineChart.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-04 13:45:00
|
||||||
|
description:
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="line-chart"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LineChart',
|
||||||
|
components: {},
|
||||||
|
props: ['config'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chart: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
mounted() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.chart) {
|
||||||
|
this.chart.dispose();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
console.log('thsi el', this.$el);
|
||||||
|
if (!this.chart) this.chart = echarts.init(this.$el);
|
||||||
|
this.chart.setOption(this.config);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.line-chart {
|
||||||
|
padding: 0 12px;
|
||||||
|
// background: #e1e1e1;
|
||||||
|
min-height: 320px;
|
||||||
|
}
|
||||||
|
</style>
|
330
src/views/equipment/timing-diagram/output/index.vue
Normal file
330
src/views/equipment/timing-diagram/output/index.vue
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
<!--
|
||||||
|
filename: index.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-04 09:34:52
|
||||||
|
description: 设备产量时序图
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<h1>设备产量时序图</h1>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<SearchBar
|
||||||
|
:formConfigs="searchBarFormConfig"
|
||||||
|
ref="search-bar"
|
||||||
|
@headBtnClick="handleSearchBarBtnClick" />
|
||||||
|
|
||||||
|
<div class="main-area">
|
||||||
|
<div class="graphs" v-if="graphList.length">
|
||||||
|
<div class="graph" v-for="(eq, index) in graphList" :key="eq.key">
|
||||||
|
<h2 class="graph-title">{{ eq.key }}</h2>
|
||||||
|
<LineChart
|
||||||
|
:key="eq.key + '__linechart'"
|
||||||
|
:config="getRealConfig(index)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2 v-else>请添加设备</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<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 LineChart from './components/lineChart.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SGProduction',
|
||||||
|
components: { LineChart },
|
||||||
|
props: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
searchBarFormConfig: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '产线',
|
||||||
|
placeholder: '请选择产线',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'lineId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '工段',
|
||||||
|
placeholder: '请选择工段',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'sectionId',
|
||||||
|
},
|
||||||
|
// 时间段
|
||||||
|
{
|
||||||
|
type: 'datePicker',
|
||||||
|
label: '时间段',
|
||||||
|
dateType: 'daterange', // datetimerange
|
||||||
|
// format: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
format: 'yyyy-MM-dd',
|
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
// valueFormat: 'timestamp',
|
||||||
|
rangeSeparator: '-',
|
||||||
|
startPlaceholder: '开始日期',
|
||||||
|
endPlaceholder: '结束日期',
|
||||||
|
defaultTime: ['00:00:00', '23:59:59'],
|
||||||
|
param: 'recordTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '查询',
|
||||||
|
name: 'search',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'separate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '设备对比',
|
||||||
|
name: 'compare',
|
||||||
|
color: 'warning',
|
||||||
|
plain: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
queryParams: {
|
||||||
|
lineId: null,
|
||||||
|
sectionId: null,
|
||||||
|
equipmentId: null,
|
||||||
|
recordTime: [],
|
||||||
|
},
|
||||||
|
open: false,
|
||||||
|
eqList: [],
|
||||||
|
graphList: [],
|
||||||
|
templateConfig: {
|
||||||
|
grid: {
|
||||||
|
top: 88,
|
||||||
|
left: 56,
|
||||||
|
right: 56,
|
||||||
|
bottom: 56,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
padding: 5,
|
||||||
|
icon: 'roundRect',
|
||||||
|
itemWidth: 12,
|
||||||
|
itemHeight: 12,
|
||||||
|
itemGap: 20,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
lineHeight: 14,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: Array(24)
|
||||||
|
.fill(1)
|
||||||
|
.map((item, index) => `${index}:00`),
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '产量',
|
||||||
|
nameLocation: 'end',
|
||||||
|
nameTextStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
align: 'right',
|
||||||
|
},
|
||||||
|
nameGap: 26,
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '产线1',
|
||||||
|
data: Array(24)
|
||||||
|
.fill(1)
|
||||||
|
.map(() => Math.random() * 100),
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initProductline();
|
||||||
|
this.initWorksection();
|
||||||
|
this.initEquipment();
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSearchBarBtnClick({ btnName, ...payload }) {
|
||||||
|
switch (btnName) {
|
||||||
|
case 'search':
|
||||||
|
this.queryParams.lineId = payload.lineId || null;
|
||||||
|
this.queryParams.sectionId = payload.sectionId || null;
|
||||||
|
this.queryParams.equipmentId = payload.equipmentId || null;
|
||||||
|
this.queryParams.recordTime = payload.recordTime || null;
|
||||||
|
this.getList();
|
||||||
|
break;
|
||||||
|
case 'compare':
|
||||||
|
this.open = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 重置查询条件 */
|
||||||
|
initQuery() {
|
||||||
|
this.queryParams.lineId = null;
|
||||||
|
this.queryParams.sectionId = null;
|
||||||
|
this.queryParams.equipmentId = null;
|
||||||
|
this.queryParams.recordTime = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 对象到数组的转换 */
|
||||||
|
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/quantity',
|
||||||
|
method: 'get',
|
||||||
|
params: this.queryParams,
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
this.graphList = this.objectToArray(data);
|
||||||
|
// const eq1 = [
|
||||||
|
// { totalQuantity: 20, startTime: 1693964578000 },
|
||||||
|
// { totalQuantity: 43, startTime: 1693964678000 },
|
||||||
|
// { totalQuantity: 12, startTime: 1693964778000 },
|
||||||
|
// { totalQuantity: 11, startTime: 1693964878000 },
|
||||||
|
// { totalQuantity: 98, startTime: 1693965478000 },
|
||||||
|
// { totalQuantity: 87, startTime: 1693965578000 },
|
||||||
|
// ];
|
||||||
|
// eq1.key = 'SS1';
|
||||||
|
// const eq2 = [
|
||||||
|
// { totalQuantity: 23, startTime: 1693961578000 },
|
||||||
|
// { totalQuantity: 42, startTime: 1693964578000 },
|
||||||
|
// { totalQuantity: 51, startTime: 1693965578000 },
|
||||||
|
// { totalQuantity: 18, startTime: 1693966578000 },
|
||||||
|
// { totalQuantity: 77, startTime: 1693966778000 },
|
||||||
|
// { totalQuantity: 38, startTime: 1693967578000 },
|
||||||
|
// { totalQuantity: 57, startTime: 1693969578000 },
|
||||||
|
// ];
|
||||||
|
// eq2.key = 'SS2';
|
||||||
|
// this.graphList = [eq1, eq2];
|
||||||
|
console.log('graph list', this.graphList);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 获得设备产量 */
|
||||||
|
getEquipmentQuantity(equipmentArr) {
|
||||||
|
return equipmentArr.map((item) => item.totalQuantity);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 获得设备产量的时间 */
|
||||||
|
getTimeinfo(equipmentArr) {
|
||||||
|
return equipmentArr.map((item) =>
|
||||||
|
new Date(item.startTime).toLocaleTimeString()
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
getRealConfig(index) {
|
||||||
|
// if (!this.graphList || this.graphList.length == 0) return;
|
||||||
|
const config = JSON.parse(JSON.stringify(this.templateConfig));
|
||||||
|
// config.legend.data = this.graphList[index].key;
|
||||||
|
config.series[0].name = this.graphList[index]?.key;
|
||||||
|
// console.log("this.graphList?.[index]", this.graphList?.[index]);
|
||||||
|
config.series[0].data = this.getEquipmentQuantity(
|
||||||
|
this.graphList?.[index] || []
|
||||||
|
);
|
||||||
|
config.xAxis.data = this.getTimeinfo(this.graphList?.[index] || []);
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 准备设备数据 */
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async submitForm() {
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/analysis/equipment-analysis/quantity',
|
||||||
|
method: 'get',
|
||||||
|
params: this.queryParams,
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
const newEqlist = this.objectToArray(data);
|
||||||
|
if (!newEqlist || newEqlist.length == 0) {
|
||||||
|
this.$message.error('该设备没有产量数据');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.graphList.push(newEqlist[0]);
|
||||||
|
}
|
||||||
|
this.open = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
449
src/views/equipment/timing-diagram/status/index.vue
Normal file
449
src/views/equipment/timing-diagram/status/index.vue
Normal file
@ -0,0 +1,449 @@
|
|||||||
|
<!--
|
||||||
|
filename: index.vue
|
||||||
|
author: liubin
|
||||||
|
date: 2023-09-04 09:34:52
|
||||||
|
description: 设备状态时序图
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<h1>设备状态时序图</h1>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<SearchBar
|
||||||
|
:formConfigs="searchBarFormConfig"
|
||||||
|
ref="search-bar"
|
||||||
|
@headBtnClick="handleSearchBarBtnClick" />
|
||||||
|
|
||||||
|
<div class="main-area">
|
||||||
|
<div class="legend-row">
|
||||||
|
<div class="legend">
|
||||||
|
<div class="icon running"></div>
|
||||||
|
<div>运行中</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="legend">
|
||||||
|
<div class="icon waiting"></div>
|
||||||
|
<div>待机</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="legend">
|
||||||
|
<div class="icon fault"></div>
|
||||||
|
<div>故障</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="legend">
|
||||||
|
<div class="icon lack"></div>
|
||||||
|
<div>缺料</div>
|
||||||
|
</div>
|
||||||
|
<div class="legend">
|
||||||
|
<div class="icon full"></div>
|
||||||
|
<div>满料</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="legend">
|
||||||
|
<div class="icon stop"></div>
|
||||||
|
<div>计划停机</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="graphs" v-if="graphList.length">
|
||||||
|
<!-- <div class="graph">
|
||||||
|
<h2 class="graph-title">设备1</h2>
|
||||||
|
<div class="graph-item running tick" data-time="00:00"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item lack tick" data-time="03:00"></div>
|
||||||
|
<div class="graph-item full tick" data-time="04:00"></div>
|
||||||
|
<div class="graph-item waiting tick" data-time="05:00"></div>
|
||||||
|
<div class="graph-item running tick" data-time="06:00"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item fault tick" data-time="08:00"></div>
|
||||||
|
<div class="graph-item waiting tick" data-time="09:00"></div>
|
||||||
|
<div class="graph-item running tick" data-time="10:00"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item lack tick" data-time="13:00"></div>
|
||||||
|
<div class="graph-item full tick" data-time="14:00"></div>
|
||||||
|
<div class="graph-item running tick" data-time="15:00"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item fault tick" data-time="18:00"></div>
|
||||||
|
<div class="graph-item running tick" data-time="19:00"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item running"></div>
|
||||||
|
<div class="graph-item stop tick" data-time="23:00"></div>
|
||||||
|
</div> -->
|
||||||
|
<div class="graph" v-for="eq in graphList" :key="eq.key">
|
||||||
|
<h2 class="graph-title">{{ eq.key }}</h2>
|
||||||
|
<div
|
||||||
|
v-for="blc in eq"
|
||||||
|
:key="blc.startTime"
|
||||||
|
class="graph-item-fixed tick"
|
||||||
|
:class="{
|
||||||
|
running: blc.status == 0,
|
||||||
|
fault: blc.status == 2,
|
||||||
|
stop: blc.status == 1,
|
||||||
|
}"
|
||||||
|
:style="{ width: blc.duration * 2 + 'px' }"
|
||||||
|
:data-time="new Date(blc.startTime).toLocaleTimeString()"></div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="graph">
|
||||||
|
<h2 class="graph-title">设备3</h2>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
<div class="graph-item"></div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<h2 v-else>请添加设备</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 对话框(添加 / 修改) -->
|
||||||
|
<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>
|
||||||
|
export default {
|
||||||
|
name: 'SGStatus',
|
||||||
|
components: {},
|
||||||
|
props: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
searchBarFormConfig: [
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '产线',
|
||||||
|
placeholder: '请选择产线',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'lineId',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
label: '工段',
|
||||||
|
placeholder: '请选择工段',
|
||||||
|
selectOptions: [],
|
||||||
|
param: 'sectionId',
|
||||||
|
},
|
||||||
|
// 时间段
|
||||||
|
{
|
||||||
|
type: 'datePicker',
|
||||||
|
label: '时间段',
|
||||||
|
dateType: 'daterange', // datetimerange
|
||||||
|
// format: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
format: 'yyyy-MM-dd',
|
||||||
|
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||||
|
// valueFormat: 'timestamp',
|
||||||
|
rangeSeparator: '-',
|
||||||
|
startPlaceholder: '开始日期',
|
||||||
|
endPlaceholder: '结束日期',
|
||||||
|
defaultTime: ['00:00:00', '23:59:59'],
|
||||||
|
param: 'recordTime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '查询',
|
||||||
|
name: 'search',
|
||||||
|
color: 'primary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'separate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
btnName: '设备对比',
|
||||||
|
name: 'compare',
|
||||||
|
color: 'warning',
|
||||||
|
plain: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
queryParams: {
|
||||||
|
lineId: null,
|
||||||
|
sectionId: null,
|
||||||
|
equipmentId: null,
|
||||||
|
recordTime: [],
|
||||||
|
},
|
||||||
|
graphList: [],
|
||||||
|
open: false,
|
||||||
|
eqList: [],
|
||||||
|
// 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();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 重置查询条件 */
|
||||||
|
initQuery() {
|
||||||
|
this.queryParams.lineId = null;
|
||||||
|
this.queryParams.equipmentId = null;
|
||||||
|
this.queryParams.sectionId = null;
|
||||||
|
this.queryParams.recordTime = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 对象到数组的转换 */
|
||||||
|
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.graphList = this.objectToArray(data);
|
||||||
|
console.log('graph list', this.graphList);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 准备设备数据 */
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSearchBarBtnClick({ btnName, ...payload }) {
|
||||||
|
switch (btnName) {
|
||||||
|
case 'search':
|
||||||
|
this.queryParams.lineId = payload.lineId || null;
|
||||||
|
this.queryParams.sectionId = payload.sectionId || null;
|
||||||
|
this.queryParams.equipmentId = payload.equipmentId || null;
|
||||||
|
this.queryParams.recordTime = payload.recordTime || null;
|
||||||
|
this.getList();
|
||||||
|
break;
|
||||||
|
case 'compare':
|
||||||
|
this.open = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async submitForm() {
|
||||||
|
const { code, data } = await this.$axios({
|
||||||
|
url: '/analysis/equipment-analysis/status',
|
||||||
|
method: 'get',
|
||||||
|
params: this.queryParams,
|
||||||
|
});
|
||||||
|
if (code == 0) {
|
||||||
|
const newEqlist = this.objectToArray(data);
|
||||||
|
if (!newEqlist || newEqlist.length == 0) {
|
||||||
|
this.$message.error('该设备没有状态数据');
|
||||||
|
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;
|
||||||
|
background: #ccc;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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: #84f04e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.waiting {
|
||||||
|
background-color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fault {
|
||||||
|
background-color: #ea5b5b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full {
|
||||||
|
background-color: #e6a23c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lack {
|
||||||
|
background-color: #a69c8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stop {
|
||||||
|
background-color: #000c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-row {
|
||||||
|
margin: 12px 0;
|
||||||
|
display: flex;
|
||||||
|
> .legend:not(:last-child) {
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -12,80 +12,64 @@
|
|||||||
ref="search-bar"
|
ref="search-bar"
|
||||||
@headBtnClick="handleSearchBarBtnClick" />
|
@headBtnClick="handleSearchBarBtnClick" />
|
||||||
|
|
||||||
|
<!-- <base-table
|
||||||
|
:table-props="[
|
||||||
|
{ type: 'index', label: '序号' },
|
||||||
|
{ prop: 'name', label: '设备名称', align: 'center' },
|
||||||
|
{ prop: 'code', label: '设备代码', align: 'center' },
|
||||||
|
{ prop: 'time', label: '时间', align: 'center' },
|
||||||
|
]"
|
||||||
|
:table-data="[
|
||||||
|
{ index: 1, name: '1', code: 'c1', time: '2021-08-31 09:14:19' },
|
||||||
|
{ index: 2, name: '2', code: 'c2', time: '2021-08-31 09:14:19' },
|
||||||
|
{ index: 3, name: '3', code: 'c3', time: '2021-08-31 09:14:19' },
|
||||||
|
{ index: 4, name: '4', code: 'c4', time: '2021-08-31 09:14:19' },
|
||||||
|
{ index: 5, name: '5', code: 'c5', time: '2021-08-31 09:14:19' },
|
||||||
|
]"
|
||||||
|
:span-method="
|
||||||
|
({ rowIndex, columnIndex }) => {
|
||||||
|
if (rowIndex == 1 && columnIndex == 0) {
|
||||||
|
return [1, 3];
|
||||||
|
}
|
||||||
|
return [1, 1];
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@emitFun="(val) => handleEmitFun(table, val)"></base-table> -->
|
||||||
|
|
||||||
<div class="tables">
|
<div class="tables">
|
||||||
<base-table
|
<div class="custom-table" v-for="table in tableList" :key="table.key">
|
||||||
:key="1 + '__basetable'"
|
<!-- {{ JSON.stringify(spanMethod) }} -->
|
||||||
:table-props="table1.tableProps"
|
|
||||||
:page="1"
|
|
||||||
:limit="999"
|
|
||||||
:table-data="table1.data"
|
|
||||||
@emitFun="(val) => handleEmitFun(table1, val)"></base-table>
|
|
||||||
<base-table
|
|
||||||
:key="2 + '__basetable'"
|
|
||||||
:table-props="table2.tableProps"
|
|
||||||
:page="1"
|
|
||||||
:limit="999"
|
|
||||||
:table-data="table2.data"
|
|
||||||
@emitFun="(val) => handleEmitFun(table2, val)"></base-table>
|
|
||||||
<base-table
|
|
||||||
:key="3 + '__basetable'"
|
|
||||||
:table-props="table3.tableProps"
|
|
||||||
:page="1"
|
|
||||||
:limit="999"
|
|
||||||
:table-data="table3.data"
|
|
||||||
@emitFun="(val) => handleEmitFun(table3, val)"></base-table>
|
|
||||||
<base-table
|
|
||||||
:key="4 + '__basetable'"
|
|
||||||
:table-props="table4.tableProps"
|
|
||||||
:page="1"
|
|
||||||
:limit="999"
|
|
||||||
:table-data="table4.data"
|
|
||||||
@emitFun="(val) => handleEmitFun(table4, val)"></base-table>
|
|
||||||
<base-table
|
|
||||||
:key="5 + '__basetable'"
|
|
||||||
:table-props="table5.tableProps"
|
|
||||||
:page="1"
|
|
||||||
:limit="999"
|
|
||||||
:table-data="table5.data"
|
|
||||||
@emitFun="(val) => handleEmitFun(table5, val)"></base-table>
|
|
||||||
<base-table
|
|
||||||
:key="6 + '__basetable'"
|
|
||||||
:table-props="table6.tableProps"
|
|
||||||
:page="1"
|
|
||||||
:limit="999"
|
|
||||||
:table-data="table6.data"
|
|
||||||
@emitFun="(val) => handleEmitFun(table6, val)"></base-table>
|
|
||||||
<base-table
|
|
||||||
:key="7 + '__basetable'"
|
|
||||||
:table-props="table7.tableProps"
|
|
||||||
:page="1"
|
|
||||||
:limit="999"
|
|
||||||
:table-data="table7.data"
|
|
||||||
@emitFun="(val) => handleEmitFun(table7, val)"></base-table>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="tables">
|
|
||||||
<div class="table-wrapper" v-for="table in tableList" :key="table.key">
|
|
||||||
<div class="table-title">PLC 1</div>
|
|
||||||
<base-table
|
<base-table
|
||||||
:key="table.key + '__basetable'"
|
:key="table.key + '__basetable'"
|
||||||
:table-props="table.tableProps"
|
:table-props="table.tableProps"
|
||||||
:page="1"
|
:table-data="table.dataManager?.dataList ?? []"
|
||||||
:limit="999"
|
:span-method="spanMethod"
|
||||||
:table-data="table.data"
|
@emitFun="(val) => handleEmitFun(table, val)"></base-table>
|
||||||
@emitFun="(val) => handleEmitFun(table, val)">
|
|
||||||
</base-table>
|
|
||||||
<pagination
|
<pagination
|
||||||
|
:key="table.key + '__pagination'"
|
||||||
v-show="table.total > 0"
|
v-show="table.total > 0"
|
||||||
:total="table.total"
|
:total="table.total"
|
||||||
:page.sync="table.queryParams.pageNo"
|
:page.sync="table.pageNo"
|
||||||
:limit.sync="table.queryParams.pageSize"
|
:limit.sync="table.pageSize"
|
||||||
@pagination="(val) => getListFor(table, val)" />
|
:page-size="table.pageSize"
|
||||||
|
:page-sizes="[1, 3, 5, 10, 20]"
|
||||||
|
@pagination="
|
||||||
|
({ page, limit, current }) =>
|
||||||
|
getListFor(table, { page, limit, current })
|
||||||
|
" />
|
||||||
|
</div>
|
||||||
|
<!-- v-show="table.dataManager?.total > 0"
|
||||||
|
:total="table.dataManager?.total || 0" -->
|
||||||
|
<!-- @size-change="($event) => handleSizeChange(table, $event)" -->
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import LocalDataManager from './utils/local-data-manager';
|
||||||
|
import response from './response';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EquipmentFullParams',
|
name: 'EquipmentFullParams',
|
||||||
components: {},
|
components: {},
|
||||||
@ -138,286 +122,16 @@ export default {
|
|||||||
id: null,
|
id: null,
|
||||||
time: [new Date(aWeekAgo), new Date(today)],
|
time: [new Date(aWeekAgo), new Date(today)],
|
||||||
},
|
},
|
||||||
|
tableList: [
|
||||||
table1: {
|
|
||||||
tableProps: [
|
|
||||||
{
|
{
|
||||||
prop: 'time',
|
key: 'base-table__key__1',
|
||||||
label: '时间',
|
tableProps: [],
|
||||||
},
|
list: [],
|
||||||
{
|
pageNo: 1,
|
||||||
prop: 'plcCode',
|
pageSize: 3,
|
||||||
label: 'PLC编码',
|
total: 0,
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val1',
|
|
||||||
label: '数值1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol1',
|
|
||||||
label: '布尔1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val2',
|
|
||||||
label: '数值2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol2',
|
|
||||||
label: '布尔2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val3',
|
|
||||||
label: '数值3',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol3',
|
|
||||||
label: '布尔3',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val4',
|
|
||||||
label: '数值4',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol4',
|
|
||||||
label: '布尔4',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
data: [
|
|
||||||
{
|
|
||||||
time: 1111111111111111,
|
|
||||||
plcCode: 2,
|
|
||||||
val1: 3,
|
|
||||||
bol1: 4,
|
|
||||||
val2: 5,
|
|
||||||
bol2: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: 1,
|
|
||||||
plcCode: 22222222222222,
|
|
||||||
val1: 3,
|
|
||||||
bol1: 4,
|
|
||||||
val2: 5,
|
|
||||||
bol2: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: 1,
|
|
||||||
plcCode: 2,
|
|
||||||
val1: 33333333333333,
|
|
||||||
bol1: 4,
|
|
||||||
val2: 5,
|
|
||||||
bol2: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: 1,
|
|
||||||
plcCode: 2,
|
|
||||||
val1: 3,
|
|
||||||
bol1: 44444444444444,
|
|
||||||
val2: 5,
|
|
||||||
bol2: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: 1,
|
|
||||||
plcCode: 2,
|
|
||||||
val1: 3,
|
|
||||||
bol1: 4,
|
|
||||||
val2: 5555555555555,
|
|
||||||
bol2: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
time: 1,
|
|
||||||
plcCode: 2,
|
|
||||||
val1: 3,
|
|
||||||
bol1: 4,
|
|
||||||
val2: 5,
|
|
||||||
bol2: 6666666666666666666,
|
|
||||||
},
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
{ time: 1, plcCode: 2, val1: 3, bol1: 4, val2: 5, bol2: 6 },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
table2: {
|
|
||||||
tableProps: [
|
|
||||||
{
|
|
||||||
prop: 'time',
|
|
||||||
label: '时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'plcCode',
|
|
||||||
label: 'PLC编码',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val1',
|
|
||||||
label: '数值1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol1',
|
|
||||||
label: '布尔1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val2',
|
|
||||||
label: '数值2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol2',
|
|
||||||
label: '布尔2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: [],
|
|
||||||
},
|
|
||||||
table3: {
|
|
||||||
tableProps: [
|
|
||||||
{
|
|
||||||
prop: 'time',
|
|
||||||
label: '时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'plcCode',
|
|
||||||
label: 'PLC编码',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val1',
|
|
||||||
label: '数值1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol1',
|
|
||||||
label: '布尔1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val2',
|
|
||||||
label: '数值2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol2',
|
|
||||||
label: '布尔2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: [],
|
|
||||||
},
|
|
||||||
table4: {
|
|
||||||
tableProps: [
|
|
||||||
{
|
|
||||||
prop: 'time',
|
|
||||||
label: '时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'plcCode',
|
|
||||||
label: 'PLC编码',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val1',
|
|
||||||
label: '数值1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol1',
|
|
||||||
label: '布尔1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val2',
|
|
||||||
label: '数值2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol2',
|
|
||||||
label: '布尔2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: [],
|
|
||||||
},
|
|
||||||
table5: {
|
|
||||||
tableProps: [
|
|
||||||
{
|
|
||||||
prop: 'time',
|
|
||||||
label: '时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'plcCode',
|
|
||||||
label: 'PLC编码',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val1',
|
|
||||||
label: '数值1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol1',
|
|
||||||
label: '布尔1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val2',
|
|
||||||
label: '数值2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol2',
|
|
||||||
label: '布尔2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: [],
|
|
||||||
},
|
|
||||||
table6: {
|
|
||||||
tableProps: [
|
|
||||||
{
|
|
||||||
prop: 'time',
|
|
||||||
label: '时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'plcCode',
|
|
||||||
label: 'PLC编码',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val1',
|
|
||||||
label: '数值1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol1',
|
|
||||||
label: '布尔1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val2',
|
|
||||||
label: '数值2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol2',
|
|
||||||
label: '布尔2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: [],
|
|
||||||
},
|
|
||||||
table7: {
|
|
||||||
tableProps: [
|
|
||||||
{
|
|
||||||
prop: 'time',
|
|
||||||
label: '时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'plcCode',
|
|
||||||
label: 'PLC编码',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val1',
|
|
||||||
label: '数值1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol1',
|
|
||||||
label: '布尔1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'val2',
|
|
||||||
label: '数值2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bol2',
|
|
||||||
label: '布尔2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: [],
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -437,8 +151,108 @@ export default {
|
|||||||
this.$set(this.searchBarFormConfig[0], 'defaultSelect', this.code);
|
this.$set(this.searchBarFormConfig[0], 'defaultSelect', this.code);
|
||||||
if (this.name)
|
if (this.name)
|
||||||
this.$set(this.searchBarFormConfig[1], 'defaultSelect', this.name);
|
this.$set(this.searchBarFormConfig[1], 'defaultSelect', this.name);
|
||||||
|
|
||||||
|
this.handleResponse();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
buildProps(table) {
|
||||||
|
console.log('building props', table);
|
||||||
|
// 通过 otherList 来构建 props
|
||||||
|
const { otherList } = table;
|
||||||
|
const props = [
|
||||||
|
{
|
||||||
|
// type: 'index',
|
||||||
|
width: 48,
|
||||||
|
prop: 'index',
|
||||||
|
label: '序号',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 160,
|
||||||
|
prop: 'time',
|
||||||
|
label: '时间',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
width: 200,
|
||||||
|
prop: 'plcCode',
|
||||||
|
label: 'PLC编码',
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const firstLineData = {
|
||||||
|
index: '参考值: [最小]-[最大][/标准]',
|
||||||
|
time: null, // 此处必须是空白
|
||||||
|
plcCode: null, // 此处必须是空白
|
||||||
|
};
|
||||||
|
otherList.forEach((item) => {
|
||||||
|
props.push({
|
||||||
|
label: item.name,
|
||||||
|
align: 'center',
|
||||||
|
prop: item.name,
|
||||||
|
width: 128,
|
||||||
|
});
|
||||||
|
firstLineData[item.name] = `${item.minValue ?? ''}-${
|
||||||
|
item.maxValue ?? ''
|
||||||
|
}${item.defaultValue != null ? '/' + item.defaultValue : ''}`;
|
||||||
|
});
|
||||||
|
return { props, firstLineData };
|
||||||
|
},
|
||||||
|
|
||||||
|
handleResponse() {
|
||||||
|
const { code, data } = response;
|
||||||
|
if (code == 0) {
|
||||||
|
console.log('response', code, data);
|
||||||
|
|
||||||
|
// 处理一个表格
|
||||||
|
data.forEach((table, index) => {
|
||||||
|
console.log('handle index:', index, table);
|
||||||
|
const { props: tableProps, firstLineData } = this.buildProps(table);
|
||||||
|
this.$set(this.tableList, index, {
|
||||||
|
key: 'base-table__key__' + index,
|
||||||
|
tableProps,
|
||||||
|
list: [firstLineData],
|
||||||
|
dataManager: null,
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 5,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理某一表格的各个行
|
||||||
|
const { data } = table;
|
||||||
|
data.forEach((row, idx) => {
|
||||||
|
const listItem = {
|
||||||
|
index: idx + 1,
|
||||||
|
time: moment(+row.time).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
plcCode: row.plcCode,
|
||||||
|
};
|
||||||
|
row.data.forEach((column) => {
|
||||||
|
listItem[column.dynamicName] = column.dynamicValue;
|
||||||
|
});
|
||||||
|
this.tableList[index].list.push(listItem);
|
||||||
|
this.tableList[index].total++;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理分页
|
||||||
|
const { pageNo, pageSize, list } = this.tableList[index];
|
||||||
|
this.tableList[index].dataManager = new LocalDataManager(
|
||||||
|
list,
|
||||||
|
pageNo,
|
||||||
|
pageSize
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
spanMethod({ row, column, rowIndex, columnIndex }) {
|
||||||
|
if (rowIndex == 0 && columnIndex == 0) {
|
||||||
|
return [1, 3];
|
||||||
|
} else if (rowIndex == 0 && (columnIndex == 1 || columnIndex == 2)) {
|
||||||
|
return [0, 0];
|
||||||
|
}
|
||||||
|
return [1, 1];
|
||||||
|
},
|
||||||
|
|
||||||
/** 查询 */
|
/** 查询 */
|
||||||
async handleQuery() {
|
async handleQuery() {
|
||||||
const { data } = this.$axios({
|
const { data } = this.$axios({
|
||||||
@ -462,19 +276,11 @@ export default {
|
|||||||
console.log('table val', table, val);
|
console.log('table val', table, val);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 构造 props */
|
|
||||||
buildProps() {
|
|
||||||
this.tableList.forEach((table) => {
|
|
||||||
this.buildTableProp(table);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** 构造一个 tableProps - 根据动态结构 */
|
|
||||||
buildTableProp(table) {},
|
|
||||||
|
|
||||||
/** 为某个 table 获取 list 数据 */
|
/** 为某个 table 获取 list 数据 */
|
||||||
getListFor(table, val) {
|
getListFor(table, { page, limit, current }) {
|
||||||
console.log('get list for', table, val);
|
console.log('get list for', table, { page, limit, current });
|
||||||
|
table.dataManager.pageNo = page ?? current;
|
||||||
|
table.dataManager.pageSize = limit;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -494,4 +300,8 @@ export default {
|
|||||||
.tables >>> .baseTable {
|
.tables >>> .baseTable {
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-table {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
247
src/views/monitoring/equipmentFullParams/response.js
Normal file
247
src/views/monitoring/equipmentFullParams/response.js
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
export default {
|
||||||
|
"code": 0,
|
||||||
|
"data": [
|
||||||
|
// 一个表格
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
// 一行参数
|
||||||
|
{
|
||||||
|
"time": "1694056192800",
|
||||||
|
"plcCode": "PLC_CODE_1",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-4', "parentId": 0, "dynamicName": "P1V4", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-5', "parentId": 0, "dynamicName": "P1V5", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-6', "parentId": 0, "dynamicName": "P1V6", "dynamicValue": 15 },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"otherList": [
|
||||||
|
// 一个参数的属性
|
||||||
|
{
|
||||||
|
"id": "attr-1",
|
||||||
|
"plcParamName": "P1V1",
|
||||||
|
"name": "P1V1", // 和 dynamicName 对应
|
||||||
|
"minValue": 1,
|
||||||
|
"maxValue": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-2",
|
||||||
|
"plcParamName": "P1V2",
|
||||||
|
"name": "P1V2",
|
||||||
|
"minValue": 10,
|
||||||
|
"maxValue": 90,
|
||||||
|
"defaultValue": 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-3",
|
||||||
|
"plcParamName": "P1V3",
|
||||||
|
"name": "P1V3",
|
||||||
|
"minValue": 10,
|
||||||
|
"maxValue": 98
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-4",
|
||||||
|
"plcParamName": "P1V4",
|
||||||
|
"name": "P1V4",
|
||||||
|
"minValue": 10,
|
||||||
|
"maxValue": 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-5",
|
||||||
|
"plcParamName": "P1V5",
|
||||||
|
"name": "P1V5",
|
||||||
|
"minValue": null,
|
||||||
|
"maxValue": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-6",
|
||||||
|
"plcParamName": "P1V6",
|
||||||
|
"name": "P1V6",
|
||||||
|
"minValue": null,
|
||||||
|
"maxValue": null,
|
||||||
|
"defaultValue": false
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"nameData": [],
|
||||||
|
"otherMap": []
|
||||||
|
},
|
||||||
|
// 一个表格
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
// 一行参数
|
||||||
|
{
|
||||||
|
"time": "1694056100800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694056102800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"otherList": [
|
||||||
|
// 一个参数的属性
|
||||||
|
{
|
||||||
|
"id": "attr-1",
|
||||||
|
"plcParamName": "P1V1",
|
||||||
|
"name": "P1V1", // 和 dynamicName 对应
|
||||||
|
"minValue": 1,
|
||||||
|
"maxValue": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-2",
|
||||||
|
"plcParamName": "P1V2",
|
||||||
|
"name": "P1V2",
|
||||||
|
"minValue": 10,
|
||||||
|
"maxValue": 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-3",
|
||||||
|
"plcParamName": "P1V3",
|
||||||
|
"name": "P1V3",
|
||||||
|
"minValue": 10,
|
||||||
|
"maxValue": 98
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"nameData": [],
|
||||||
|
"otherMap": []
|
||||||
|
},
|
||||||
|
// 一个表格
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
// 一行参数
|
||||||
|
{
|
||||||
|
"time": "1694056100800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694056102800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694056109800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694066109800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694067109800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694068109800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694069109800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"time": "1694071109800",
|
||||||
|
"plcCode": "PLC_CODE_2",
|
||||||
|
"data": [
|
||||||
|
// 一个参数值
|
||||||
|
{ "id": 'param-1', "parentId": 0, "dynamicName": "P1V1", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-2', "parentId": 0, "dynamicName": "P1V2", "dynamicValue": 15 },
|
||||||
|
{ "id": 'param-3', "parentId": 0, "dynamicName": "P1V3", "dynamicValue": 15 },
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"otherList": [
|
||||||
|
// 一个参数的属性
|
||||||
|
{
|
||||||
|
"id": "attr-1",
|
||||||
|
"plcParamName": "P1V1",
|
||||||
|
"name": "P1V1", // 和 dynamicName 对应
|
||||||
|
"minValue": 1,
|
||||||
|
"maxValue": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-2",
|
||||||
|
"plcParamName": "P1V2",
|
||||||
|
"name": "P1V2",
|
||||||
|
"minValue": 10,
|
||||||
|
"maxValue": 90
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "attr-3",
|
||||||
|
"plcParamName": "P1V3",
|
||||||
|
"name": "P1V3",
|
||||||
|
"minValue": 10,
|
||||||
|
"maxValue": 98
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nameData": [],
|
||||||
|
"otherMap": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
export default class LocalDataManager {
|
||||||
|
constructor(dataList, pageNo, pageSize) {
|
||||||
|
this._dataListStore = dataList;
|
||||||
|
this._pageNo = pageNo;
|
||||||
|
this._pageSize = pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
set pageNo(pageNo) {
|
||||||
|
console.log('set pageNo', pageNo);
|
||||||
|
this._pageNo = pageNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
set pageSize(pageSize) {
|
||||||
|
console.log('set pageSize', pageSize);
|
||||||
|
this._pageSize = pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
get dataList() {
|
||||||
|
const firstLine = this._dataListStore[0];
|
||||||
|
const realDataList = this._dataListStore.slice(1);
|
||||||
|
return [
|
||||||
|
firstLine,
|
||||||
|
...realDataList.slice((this._pageNo - 1) * this._pageSize, this._pageNo * this._pageSize)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
get total() {
|
||||||
|
return this._dataListStore.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteData(id) {
|
||||||
|
const idx = this._dataListStore.findIndex(item => item.id == id);
|
||||||
|
this._dataListStore.splice(idx, 1);
|
||||||
|
// send http request
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="chart-wrapper">
|
<div class="chart-wrapper">
|
||||||
<h4>line graph</h4>
|
|
||||||
<div class="chart" ref="chart"></div>
|
<div class="chart" ref="chart"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -18,22 +17,65 @@ import * as echarts from 'echarts';
|
|||||||
export default {
|
export default {
|
||||||
name: 'LineChartInEquipmentProcessAmount',
|
name: 'LineChartInEquipmentProcessAmount',
|
||||||
components: {},
|
components: {},
|
||||||
props: {},
|
props: ['equipmentList'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chart: null,
|
chart: null,
|
||||||
option: {
|
option: {
|
||||||
xAxis: {
|
grid: {
|
||||||
type: 'category',
|
top: 64,
|
||||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
left: 56,
|
||||||
|
right: 24,
|
||||||
|
bottom: 56,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
show: true,
|
||||||
|
text: '各设备加工数量',
|
||||||
|
textStyle: {
|
||||||
|
color: '#232323',
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
left: 'center',
|
||||||
|
top: 24,
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
|
type: 'category',
|
||||||
|
axisLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#ccc',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||||
|
data: [],
|
||||||
|
name: '设备名',
|
||||||
|
nameTextStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
type: 'value',
|
type: 'value',
|
||||||
|
axisLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#ccc',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
data: [120, 200, 150, 80, 70, 110, 130],
|
// data: [120, 200, 150, 80, 70, 110, 130],
|
||||||
|
data: [],
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
|
barWidth: 20,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
distance: 50,
|
||||||
|
formatter: '{c}',
|
||||||
|
},
|
||||||
showBackground: true,
|
showBackground: true,
|
||||||
backgroundStyle: {
|
backgroundStyle: {
|
||||||
color: 'rgba(180, 180, 180, 0.2)',
|
color: 'rgba(180, 180, 180, 0.2)',
|
||||||
@ -44,13 +86,29 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
// console.log('this.eq list', this.equipmentList);
|
||||||
if (!this.chart) this.chart = echarts.init(this.$refs.chart);
|
if (!this.chart) this.chart = echarts.init(this.$refs.chart);
|
||||||
this.chart.setOption(this.option);
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.chart.setOption(this.updateConfig(this.option));
|
||||||
|
});
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.chart.dispose();
|
this.chart.dispose();
|
||||||
},
|
},
|
||||||
methods: {},
|
methods: {
|
||||||
|
updateConfig(config) {
|
||||||
|
let nameData = [];
|
||||||
|
let valueData = [];
|
||||||
|
this.equipmentList.map((eq) => {
|
||||||
|
nameData.push(eq.equipmentName);
|
||||||
|
valueData.push(eq.totalQuantity);
|
||||||
|
});
|
||||||
|
config.yAxis.data = nameData;
|
||||||
|
config.series[0].data = valueData;
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -58,8 +116,7 @@ export default {
|
|||||||
.chart-wrapper {
|
.chart-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: #f1f1f1;
|
// background: #f9f9f9;
|
||||||
padding: 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart {
|
.chart {
|
||||||
|
@ -48,7 +48,8 @@
|
|||||||
|
|
||||||
<div class="graph" style="height: 56vh;" v-else>
|
<div class="graph" style="height: 56vh;" v-else>
|
||||||
<!-- graph -->
|
<!-- graph -->
|
||||||
<Graph />
|
<Graph v-if="list.length" :equipment-list="list" />
|
||||||
|
<div v-else style="color: #c7c7c7; text-align: center; margin-top: 20px;">没有设备</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user