lb #19
@ -31,7 +31,6 @@ export default {
|
||||
// dialogFormConfig: [], // 占位
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
// 过滤后端传回的详情数据
|
||||
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"
|
||||
@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">
|
||||
<base-table
|
||||
:key="1 + '__basetable'"
|
||||
: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>
|
||||
<div class="custom-table" v-for="table in tableList" :key="table.key">
|
||||
<!-- {{ JSON.stringify(spanMethod) }} -->
|
||||
<base-table
|
||||
:key="table.key + '__basetable'"
|
||||
:table-props="table.tableProps"
|
||||
:page="1"
|
||||
:limit="999"
|
||||
:table-data="table.data"
|
||||
@emitFun="(val) => handleEmitFun(table, val)">
|
||||
</base-table>
|
||||
:table-data="table.dataManager?.dataList ?? []"
|
||||
:span-method="spanMethod"
|
||||
@emitFun="(val) => handleEmitFun(table, val)"></base-table>
|
||||
<pagination
|
||||
:key="table.key + '__pagination'"
|
||||
v-show="table.total > 0"
|
||||
:total="table.total"
|
||||
:page.sync="table.queryParams.pageNo"
|
||||
:limit.sync="table.queryParams.pageSize"
|
||||
@pagination="(val) => getListFor(table, val)" />
|
||||
:page.sync="table.pageNo"
|
||||
:limit.sync="table.pageSize"
|
||||
: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>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LocalDataManager from './utils/local-data-manager';
|
||||
import response from './response';
|
||||
import moment from 'moment';
|
||||
|
||||
export default {
|
||||
name: 'EquipmentFullParams',
|
||||
components: {},
|
||||
@ -138,286 +122,16 @@ export default {
|
||||
id: null,
|
||||
time: [new Date(aWeekAgo), new Date(today)],
|
||||
},
|
||||
|
||||
table1: {
|
||||
tableProps: [
|
||||
tableList: [
|
||||
{
|
||||
prop: 'time',
|
||||
label: '时间',
|
||||
},
|
||||
{
|
||||
prop: 'plcCode',
|
||||
label: 'PLC编码',
|
||||
},
|
||||
{
|
||||
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',
|
||||
key: 'base-table__key__1',
|
||||
tableProps: [],
|
||||
list: [],
|
||||
pageNo: 1,
|
||||
pageSize: 3,
|
||||
total: 0,
|
||||
},
|
||||
],
|
||||
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: {
|
||||
@ -437,8 +151,108 @@ export default {
|
||||
this.$set(this.searchBarFormConfig[0], 'defaultSelect', this.code);
|
||||
if (this.name)
|
||||
this.$set(this.searchBarFormConfig[1], 'defaultSelect', this.name);
|
||||
|
||||
this.handleResponse();
|
||||
},
|
||||
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() {
|
||||
const { data } = this.$axios({
|
||||
@ -462,19 +276,11 @@ export default {
|
||||
console.log('table val', table, val);
|
||||
},
|
||||
|
||||
/** 构造 props */
|
||||
buildProps() {
|
||||
this.tableList.forEach((table) => {
|
||||
this.buildTableProp(table);
|
||||
});
|
||||
},
|
||||
|
||||
/** 构造一个 tableProps - 根据动态结构 */
|
||||
buildTableProp(table) {},
|
||||
|
||||
/** 为某个 table 获取 list 数据 */
|
||||
getListFor(table, val) {
|
||||
console.log('get list for', table, val);
|
||||
getListFor(table, { page, limit, current }) {
|
||||
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 {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.custom-table {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</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>
|
||||
<div class="chart-wrapper">
|
||||
<h4>line graph</h4>
|
||||
<div class="chart" ref="chart"></div>
|
||||
</div>
|
||||
</template>
|
||||
@ -18,22 +17,65 @@ import * as echarts from 'echarts';
|
||||
export default {
|
||||
name: 'LineChartInEquipmentProcessAmount',
|
||||
components: {},
|
||||
props: {},
|
||||
props: ['equipmentList'],
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
option: {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||
grid: {
|
||||
top: 64,
|
||||
left: 56,
|
||||
right: 24,
|
||||
bottom: 56,
|
||||
},
|
||||
title: {
|
||||
show: true,
|
||||
text: '各设备加工数量',
|
||||
textStyle: {
|
||||
color: '#232323',
|
||||
fontSize: 16,
|
||||
},
|
||||
left: 'center',
|
||||
top: 24,
|
||||
},
|
||||
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',
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#ccc',
|
||||
},
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [120, 200, 150, 80, 70, 110, 130],
|
||||
// data: [120, 200, 150, 80, 70, 110, 130],
|
||||
data: [],
|
||||
type: 'bar',
|
||||
barWidth: 20,
|
||||
label: {
|
||||
show: true,
|
||||
distance: 50,
|
||||
formatter: '{c}',
|
||||
},
|
||||
showBackground: true,
|
||||
backgroundStyle: {
|
||||
color: 'rgba(180, 180, 180, 0.2)',
|
||||
@ -44,13 +86,29 @@ export default {
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
// console.log('this.eq list', this.equipmentList);
|
||||
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() {
|
||||
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>
|
||||
|
||||
@ -58,8 +116,7 @@ export default {
|
||||
.chart-wrapper {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
background: #f1f1f1;
|
||||
padding: 12px;
|
||||
// background: #f9f9f9;
|
||||
}
|
||||
|
||||
.chart {
|
||||
|
@ -48,7 +48,8 @@
|
||||
|
||||
<div class="graph" style="height: 56vh;" v-else>
|
||||
<!-- graph -->
|
||||
<Graph />
|
||||
<Graph v-if="list.length" :equipment-list="list" />
|
||||
<div v-else style="color: #c7c7c7; text-align: center; margin-top: 20px;">没有设备</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user