yudao-dev/src/views/monitoring/equipmentProcessAmount/index.vue

560 lines
12 KiB
Vue
Raw Normal View History

2023-08-30 14:11:24 +08:00
<!--
filename: index.vue
author: liubin
date: 2023-08-30 14:02:49
description: 设备加工数量
-->
<template>
2023-08-30 15:36:16 +08:00
<div style="flex: 1; display: flex; background: #f2f4f9">
<div
class="app-container"
2023-09-21 17:03:07 +08:00
style="
margin-right: 12px;
border-radius: 8px;
background: #fff;
padding: 0;
">
2023-09-21 15:35:16 +08:00
<div
class="factory-list__selector"
2023-09-21 17:03:07 +08:00
style="margin: 12px"
2023-09-21 15:35:16 +08:00
title="点击切换工厂"
@mouseenter="factoryListOpen = true"
@mouseleave="factoryListOpen = false">
2023-09-21 15:54:11 +08:00
{{ currentFactory?.label || '工厂名称' }}
2023-09-21 15:35:16 +08:00
<div class="factory-list__wrapper" :class="{ open: factoryListOpen }">
2023-09-21 15:54:11 +08:00
<ul
class="factory-list"
v-if="sidebarContent.length"
@click.prevent="factoryChangeHandler">
2023-09-21 15:14:38 +08:00
<li
2023-09-21 15:54:11 +08:00
v-for="fc in sidebarContent"
2023-09-21 15:14:38 +08:00
:key="fc.id"
2023-09-21 15:54:11 +08:00
:data-value="fc.id"
2023-09-21 16:00:46 +08:00
class="factory-list__item"
:class="{ 'is-current': fc.id == currentFactory?.id }">
2023-09-21 15:54:11 +08:00
{{ fc.label }}
2023-09-21 15:35:16 +08:00
</li>
2023-09-21 15:14:38 +08:00
</ul>
2023-09-21 15:54:11 +08:00
<div v-else style="color: #0008; width: 128px; text-align: center">
- -
</div>
2023-09-21 15:14:38 +08:00
</div>
</div>
2023-08-30 15:36:16 +08:00
<!-- side bar -->
2023-09-21 17:03:07 +08:00
<div class="side-bar__left" style="width: 240px; height: 100%">
2023-08-30 15:36:16 +08:00
<el-tree
2023-09-21 17:03:07 +08:00
class="custom-tree-class"
2023-09-21 15:54:11 +08:00
:data="currentFactory?.children"
2023-08-30 15:36:16 +08:00
:props="treeProps"
2023-09-21 17:03:07 +08:00
:empty-text="' - 暂无数据 - '"
icon-class="custom-icon-class"
@node-click="handleSidebarItemClick">
<!-- <div class="custom-tree-node" slot-scope="{ node, data }">
<span class="icon"></span>
<span>{{ node.label }}</span>
</div> -->
</el-tree>
2023-08-30 15:36:16 +08:00
</div>
</div>
<div
class="app-container equipment-process-amount"
style="flex: 1; border-radius: 8px; background: #fff">
<!-- main area -->
<div class="main-content" style="display: flex; flex-direction: column">
2023-08-30 15:36:16 +08:00
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
2023-08-30 14:11:24 +08:00
2023-09-19 17:06:19 +08:00
<el-row>
<el-col class="custom-tabs">
<el-tabs v-model="activeName" @tab-click="handleTabClick">
2023-09-21 15:14:38 +08:00
<el-tab-pane :label="'\u2002数据列表\u2002'" name="table">
2023-09-19 17:06:19 +08:00
<base-table
v-if="mode == 'table'"
:table-props="tableProps"
:page="1"
:limit="999"
:table-data="list"
@emitFun="handleEmitFun">
<!-- <method-btn
v-if="tableBtn.length"
2023-08-30 14:11:24 +08:00
slot="handleBtn"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" /> -->
2023-09-19 17:06:19 +08:00
</base-table>
</el-tab-pane>
2023-09-21 15:14:38 +08:00
<el-tab-pane :label="'\u3000柱状图\u3000'" name="graph">
2023-09-19 17:06:19 +08:00
<div class="graph" style="height: 56vh">
<!-- graph -->
<Graph v-if="list.length" :equipment-list="list" />
<div
v-else
style="
color: #c7c7c7;
text-align: center;
margin-top: 20px;
">
没有设备
</div>
</div>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
2023-08-30 14:11:24 +08:00
2023-09-19 17:06:19 +08:00
<!-- <transition appear name="vvv" mode="out-in"></transition> -->
2023-08-30 14:11:24 +08:00
</div>
</div>
</div>
</template>
<script>
import Graph from './graph.vue';
2023-08-30 14:11:24 +08:00
export default {
name: 'EquipmentProcessAmount',
components: { Graph },
2023-08-30 14:11:24 +08:00
props: {},
data() {
return {
2023-09-21 15:35:16 +08:00
factoryListOpen: false,
currentFactory: null,
factoryList: [
{ name: '1', value: 1 },
{ name: '2', value: 2 },
{ name: '3', value: 3 },
{ name: '4', value: 4 },
{ name: '5', value: 5 },
{ name: '6', value: 6 },
],
2023-08-30 14:11:24 +08:00
sidebarContent: [
2023-08-30 16:24:44 +08:00
// {
// id: 'fc1',
// name: '工厂',
// lines: [
// {
// name: '产线1',
// id: 'pl1',
// sections: [
// {
// name: '工段1',
// id: 'pl1ws1',
// equipments: [
// {
// name: '设备1',
// id: 'pl1ws1--eq1',
// },
// {
// name: '设备2',
// id: 'pl1ws1--eq2',
// },
// {
// name: '设备3',
// id: 'pl1ws1--eq3',
// },
// ],
// },
// {
// name: '工段2',
// id: 'pl1ws2',
// equipments: [
// {
// name: '设备1',
// id: 'pl2ws1--eq1',
// },
// {
// name: '设备2',
// id: 'pl2ws1--eq2',
// },
// {
// name: '设备3',
// id: 'pl2ws1--eq3',
// },
// ],
// },
// {
// name: '工段3',
// id: 'pl1ws3',
// equipments: [
// {
// name: '设备1',
// id: 'pl3ws1--eq1',
// },
// {
// name: '设备2',
// id: 'pl3ws1--eq2',
// },
// {
// name: '设备3',
// id: 'pl3ws1--eq3',
// },
// ],
// },
// ],
// },
// {
// name: '产线2',
// id: 'pl2',
// sections: [
// {
// name: '工段1',
// id: 'pl2ws1',
// },
// {
// name: '工段2',
// id: 'pl2ws2',
// },
// {
// name: '工段3',
// id: 'pl2ws3',
// },
// ],
// },
// ],
// },
2023-08-30 14:11:24 +08:00
],
2023-09-19 17:06:19 +08:00
activeName: 'table',
2023-08-30 14:11:24 +08:00
searchBarFormConfig: [
{
2023-08-30 15:36:16 +08:00
type: 'datePicker',
label: '时间段',
dateType: 'daterange', // datetimerange
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
rangeSeparator: '-',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
defaultTime: ['00:00:00', '23:59:59'],
param: 'timeVal',
width: 350,
2023-08-30 14:11:24 +08:00
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
2023-09-19 17:06:19 +08:00
// {
// type: 'separate',
// },
// {
// type: 'button',
// btnName: '表格',
// name: 'table',
// plain: true,
// color: 'success',
// },
// {
// type: 'button',
// btnName: '图表',
// name: 'graph',
// plain: true,
// color: 'warning',
// },
2023-08-30 16:24:44 +08:00
// {
// type: this.$auth.hasPermi('base:equipment-group:export') ? 'button' : '',
// btnName: '导出',
// name: 'export',
// color: 'warning',
// },
2023-08-30 14:11:24 +08:00
],
tableProps: [
2023-09-19 17:06:19 +08:00
{ prop: 'lineName', label: '产线' },
{ prop: 'sectionName', label: '工段' },
{ prop: 'externalCode', label: '设备编码' },
{ prop: 'equipmentName', label: '设备名称' },
{ prop: 'totalQuantity', label: '加工数量' },
2023-08-30 14:11:24 +08:00
],
mode: 'table', // table | graph
queryParams: {
2023-08-30 16:24:44 +08:00
// pageNo: 1,
// pageSize: 999,
2023-08-30 15:36:16 +08:00
recordTime: [],
equipmentId: null,
lineId: null,
sectionId: null,
productId: null,
2023-08-30 14:11:24 +08:00
},
list: [],
2023-08-30 15:36:16 +08:00
treeProps: {
children: 'children',
label: 'label',
},
2023-08-30 14:11:24 +08:00
};
},
2023-08-30 15:36:16 +08:00
mounted() {
2023-08-30 16:24:44 +08:00
this.getTree();
2023-08-30 15:36:16 +08:00
},
2023-08-30 14:11:24 +08:00
methods: {
2023-08-30 15:36:16 +08:00
/** build side bar tree */
buildTree(data) {
data.forEach((factory) => {
this.$set(factory, 'label', factory.name);
2023-08-30 16:24:44 +08:00
this.$set(factory, 'type', '工厂');
2023-08-30 15:36:16 +08:00
delete factory.name;
2023-09-15 15:45:37 +08:00
// factory.children = factory.lines;
// delete factory.lines;
2023-08-30 16:24:44 +08:00
factory.children?.forEach((line) => {
2023-08-30 15:36:16 +08:00
this.$set(line, 'label', line.name);
2023-08-30 16:24:44 +08:00
this.$set(line, 'type', '产线');
2023-08-30 15:36:16 +08:00
delete line.name;
2023-09-15 15:45:37 +08:00
// line.children = line.sections;
// delete line.sections;
2023-08-30 16:24:44 +08:00
line.children?.forEach((ws) => {
2023-08-30 15:36:16 +08:00
this.$set(ws, 'label', ws.name);
2023-08-30 16:24:44 +08:00
this.$set(ws, 'type', '工段');
2023-08-30 15:36:16 +08:00
delete ws.name;
2023-09-15 15:45:37 +08:00
// ws.children = ws.equipments;
// delete ws.equipments;
2023-08-30 16:24:44 +08:00
ws.children?.forEach((eq) => {
this.$set(eq, 'label', eq.name);
this.$set(eq, 'type', '设备');
delete eq.name;
});
2023-08-30 15:36:16 +08:00
});
});
});
},
2023-08-30 16:24:44 +08:00
async getTree() {
const { data } = await this.$axios('/base/factory/getTree');
this.sidebarContent = data;
this.buildTree(data);
2023-09-19 17:06:19 +08:00
console.log('tree', this.sidebarContent);
},
handleTabClick(tab, event) {
console.log('handle tab click: ', tab, event);
2023-08-30 15:36:16 +08:00
},
2023-09-21 15:35:16 +08:00
factoryChangeHandler(event) {
this.factoryListOpen = false;
2023-09-21 15:54:11 +08:00
const fcId = event.target.dataset.value;
console.log('fc id', fcId);
this.handleSidebarItemClick({ id: fcId, type: '工厂' });
this.currentFactory = this.sidebarContent.find((item) => item.id == fcId);
2023-09-21 15:35:16 +08:00
},
2023-08-30 16:24:44 +08:00
handleSidebarItemClick({ label, id, type }) {
2023-09-21 15:54:11 +08:00
console.log('label clicked!', label, id, type);
2023-08-30 16:24:44 +08:00
switch (type) {
case '设备':
this.queryParams.equipmentId = id;
break;
case '工段':
this.queryParams.equipmentId = null;
this.queryParams.sectionId = id;
break;
case '产线':
this.queryParams.equipmentId = null;
this.queryParams.sectionId = null;
this.queryParams.lineId = id;
break;
case '工厂':
this.queryParams.equipmentId = null;
this.queryParams.sectionId = null;
this.queryParams.lineId = null;
break;
}
2023-08-30 15:36:16 +08:00
},
2023-08-30 14:11:24 +08:00
handleEmitFun() {},
2023-08-30 15:36:16 +08:00
handleSearchBarBtnClick(btn) {
2023-08-30 16:24:44 +08:00
switch (btn.btnName) {
case 'table':
this.mode = 'table';
break;
case 'graph':
this.mode = 'graph';
break;
case 'search':
if (btn.timeVal != null && btn.timeVal.length > 0)
this.queryParams.recordTime = btn.timeVal;
else this.queryParams.recordTime = null;
this.handleQuery();
break;
}
2023-08-30 15:36:16 +08:00
},
2023-08-30 16:24:44 +08:00
async handleQuery() {
console.log('queryParams', this.queryParams);
const { data } = await this.$axios({
url: '/monitoring/equipment-monitor/quantity-det-list',
method: 'get',
params: this.queryParams,
});
this.list = data;
},
2023-08-30 14:11:24 +08:00
},
};
</script>
2023-08-30 16:24:44 +08:00
<style scoped>
.side-bar__left >>> .is-current {
2023-09-21 17:03:07 +08:00
padding: 0;
2023-08-30 16:24:44 +08:00
color: #111;
background: #f2f4f7;
}
.vvv-enter,
.vvv-leave-to {
/* transform: translateY(24px) scaleY(0); */
transform: translateY(24px);
opacity: 0;
}
.vvv-enter-active,
.vvv-leave-active {
transition: all 0.3s ease-out;
}
.vvv-enter-to,
.vvv-leave {
/* transform: translateY(0) scaleY(1); */
transform: translateY(0);
}
2023-09-19 17:06:19 +08:00
.custom-tabs >>> .el-tabs__header {
margin-bottom: 8px;
display: inline-block;
transform: translateY(-12px);
}
.custom-tabs >>> .el-tabs__item {
2023-09-21 15:14:38 +08:00
padding-left: 0px !important;
padding-right: 0px !important;
2023-09-19 17:06:19 +08:00
line-height: 36px !important;
height: 36px;
}
2023-09-21 15:14:38 +08:00
.factory-list__selector {
position: relative;
height: 36px;
font-size: 16px;
line-height: 36px;
padding-left: 28px;
background: url(../../../assets/images/factory-icon.png) 0 / 10% no-repeat;
}
.factory-list__selector:hover {
cursor: pointer;
color: #0008;
}
.factory-list__selector::after {
2023-09-21 15:54:11 +08:00
/* content: ''; */
2023-09-21 15:14:38 +08:00
position: absolute;
top: 16px;
2023-09-21 15:54:11 +08:00
right: 12px;
2023-09-21 15:14:38 +08:00
display: inline-block;
width: 8px;
height: 8px;
/* background: #5c5c5c; */
border-color: #000;
border-width: 4px;
border-style: solid;
border-top-color: transparent;
border-right-color: transparent;
border-bottom-color: transparent;
}
.factory-list__selector:hover::after {
/* cursor: pointer; */
border-left-color: #0008;
}
2023-09-21 15:35:16 +08:00
.factory-list__wrapper {
visibility: hidden;
position: absolute;
background: #fff;
box-shadow: 0 0 32px 10px #0002;
border-radius: 8px;
top: 36px;
left: 90px;
/* max-width: 128px; */
height: auto;
2023-09-21 17:03:07 +08:00
width: auto;
white-space: nowrap;
2023-09-21 15:35:16 +08:00
overflow: hidden;
/* transition: all 0.3s ease-out; */
z-index: 1000;
}
.factory-list__wrapper.open {
visibility: visible;
}
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
.factory-list {
color: #0008;
max-height: 240px;
overflow-y: auto;
}
.factory-list__item {
font-size: 16px;
line-height: 1;
2023-09-21 16:00:46 +08:00
padding: 8px 64px 8px 16px;
/* min-width: 64px; */
position: relative;
}
.factory-list__item:hover,
.factory-list__item.is-current {
background: #e3efff;
color: #0b58ff;
2023-09-21 15:35:16 +08:00
}
2023-09-21 16:00:46 +08:00
.factory-list__item.is-current::after {
2023-09-21 17:03:07 +08:00
content: '√';
2023-09-21 16:00:46 +08:00
position: absolute;
top: 8px;
right: 16px;
font-weight: bold;
2023-09-21 17:03:07 +08:00
}
.custom-tree-class >>> .el-tree-node__content {
height: auto !important;
padding: 8px 12px !important;
}
.custom-tree-class >>> .el-tree-node__children .el-tree-node__content {
padding: 8px 18px !important;
}
.custom-tree-class >>> .el-tree-node__children .el-tree-node__children .el-tree-node__content {
padding: 8px 24px !important;
}
</style>
<style>
.custom-icon-class {
margin-right: 8px;
width: 20px;
height: 24px;
background: url('../../../assets/images/tree-icon-1.png') 100% / contain
no-repeat;
}
.custom-icon-class.el-tree-node__expand-icon.expanded {
transform: unset;
}
.el-tree-node__children .custom-icon-class {
background: url('../../../assets/images/tree-icon-2.png') 100% / contain
no-repeat;
}
2023-09-21 16:00:46 +08:00
2023-09-21 17:03:07 +08:00
.el-tree-node__children .el-tree-node__children .custom-icon-class {
background: unset;
2023-09-21 15:35:16 +08:00
}
2023-08-30 16:24:44 +08:00
</style>