yudao-dev/src/views/equipment/timing-diagram/output/index.vue

441 lines
9.7 KiB
Vue
Raw Normal View History

2023-09-04 09:41:31 +08:00
<!--
filename: index.vue
author: liubin
date: 2023-09-04 09:34:52
description: 设备产量时序图
-->
<template>
2023-09-20 14:44:39 +08:00
<div
class="production-timegraph-container"
style="background: #f2f4f9; flex: 1">
<el-row
class=""
style="
margin-bottom: 12px;
background: #fff;
padding: 16px 16px 0;
border-radius: 8px;
">
<div class="blue-title">生产节拍时序图</div>
<!-- <h1>设备状态时序图</h1> -->
<!-- 搜索工作栏 -->
<SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
:remove-blue="true"
@headBtnClick="handleSearchBarBtnClick" />
</el-row>
2023-09-05 16:30:24 +08:00
2023-09-20 14:44:39 +08:00
<el-row
class=""
style="
margin-bottom: 12px;
background: #fff;
2023-09-20 15:17:29 +08:00
padding: 16px 16px 24px;
2023-09-20 14:44:39 +08:00
border-radius: 8px;
">
<div class="blue-title">设备产量时序图</div>
<div class="main-area">
<div class="graphs" v-if="graphList.length">
2023-09-20 15:17:29 +08:00
<LineChart :config="templateConfig" />
2023-09-05 16:30:24 +08:00
</div>
2023-09-20 15:17:29 +08:00
<div class="no-data-bg" v-else></div>
2023-09-05 16:30:24 +08:00
</div>
2023-09-20 14:44:39 +08:00
</el-row>
2023-09-06 10:39:32 +08:00
<!-- 对话框(添加 / 修改) -->
<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>
2023-09-05 16:30:24 +08:00
</div>
2023-09-04 09:41:31 +08:00
</template>
<script>
2023-09-06 09:56:05 +08:00
import LineChart from './components/lineChart.vue';
2023-09-04 09:41:31 +08:00
export default {
2023-09-05 16:30:24 +08:00
name: 'SGProduction',
2023-09-06 09:56:05 +08:00
components: { LineChart },
2023-09-05 16:30:24 +08:00
props: {},
data() {
return {
2023-09-20 15:17:29 +08:00
accumulators: new Map(),
2023-09-05 16:30:24 +08:00
searchBarFormConfig: [
{
type: 'select',
label: '产线',
placeholder: '请选择产线',
selectOptions: [],
param: 'lineId',
},
{
type: 'select',
label: '工段',
placeholder: '请选择工段',
selectOptions: [],
param: 'sectionId',
},
// 时间段
{
type: 'datePicker',
label: '时间段',
2023-09-20 15:17:29 +08:00
dateType: 'date', // datetimerange
2023-09-05 16:30:24 +08:00
// format: 'yyyy-MM-dd HH:mm:ss',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
// valueFormat: 'timestamp',
2023-09-20 15:17:29 +08:00
// rangeSeparator: '-',
// startPlaceholder: '开始日期',
// endPlaceholder: '结束日期',
// defaultTime: ['00:00:00', '23:59:59'],
placeholder: '选择日期',
2023-09-05 16:30:24 +08:00
param: 'recordTime',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
},
{
type: 'separate',
},
{
type: 'button',
2023-09-20 14:44:39 +08:00
btnName: '添加对比',
2023-09-05 16:30:24 +08:00
name: 'compare',
2023-09-20 14:44:39 +08:00
color: 'primary',
2023-09-05 16:30:24 +08:00
plain: true,
},
],
queryParams: {
lineId: null,
sectionId: null,
2023-09-06 09:56:05 +08:00
equipmentId: null,
2023-09-05 16:30:24 +08:00
recordTime: [],
},
2023-09-06 10:39:32 +08:00
open: false,
eqList: [],
2023-09-05 16:30:24 +08:00
graphList: [],
2023-09-06 09:56:05 +08:00
templateConfig: {
2023-09-20 15:17:29 +08:00
color: ['#283D68', '#FFB61F', '#4481FF', '#5AD8A6', '#E97466'],
2023-09-06 09:56:05 +08:00
grid: {
2023-09-20 15:17:29 +08:00
top: 48,
left: 48,
right: 24,
2023-09-26 14:38:30 +08:00
bottom: 64,
2023-09-06 09:56:05 +08:00
},
legend: {
top: 0,
2023-09-20 15:17:29 +08:00
right: 12,
padding: 6,
itemWidth: 16,
itemHeight: 8,
2023-09-06 09:56:05 +08:00
itemGap: 20,
textStyle: {
2023-09-20 15:17:29 +08:00
fontSize: 12,
lineHeight: 12,
color: '#0007',
2023-09-06 09:56:05 +08:00
},
},
2023-09-20 15:17:29 +08:00
tooltip: {
show: true,
trigger: 'axis',
},
2023-09-06 09:56:05 +08:00
xAxis: {
type: 'category',
2023-09-20 15:17:29 +08:00
boundaryGap: true,
axisTick: {
// show: false,
alignWithLabel: true,
lineStyle: {
color: '#0003',
},
},
axisLabel: {
2023-09-26 14:38:30 +08:00
// show: true,
// textStyle: {
// color: '#0007',
// },
2023-09-20 15:17:29 +08:00
},
data: [],
// data: Array(24)
// .fill(1)
// .map((item, index) => `${index}:00`),
2023-09-06 09:56:05 +08:00
},
yAxis: {
type: 'value',
name: '产量',
nameLocation: 'end',
nameTextStyle: {
fontSize: 14,
2023-09-20 15:17:29 +08:00
align: 'center',
2023-09-06 09:56:05 +08:00
},
nameGap: 26,
2023-09-20 15:17:29 +08:00
max: function (value) {
return value.max + Math.floor(value.max / 5);
},
2023-09-06 09:56:05 +08:00
},
series: [
2023-09-20 15:17:29 +08:00
// {
// name: '产线1',
// data: Array(24)
// .fill(1)
// .map(() => Math.random() * 100),
// type: 'line',
// symbol: 'circle',
// // smooth: true,
// },
// {
// name: '产线2',
// data: Array(24)
// .fill(1)
// .map(() => Math.random() * 100),
// type: 'line',
// symbol: 'circle',
// // smooth: true,
// },
// {
// name: '产线3',
// data: Array(24)
// .fill(1)
// .map(() => Math.random() * 100),
// type: 'line',
// symbol: 'circle',
// // smooth: true,
// },
2023-09-06 09:56:05 +08:00
],
},
2023-09-05 16:30:24 +08:00
};
},
created() {
this.initProductline();
this.initWorksection();
2023-09-06 10:39:32 +08:00
this.initEquipment();
2023-09-05 16:30:24 +08:00
this.getList();
},
methods: {
2023-09-06 09:56:05 +08:00
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;
2023-09-20 15:17:29 +08:00
this.queryParams.recordTime = payload.recordTime
? [
payload.recordTime,
payload.recordTime.replace('00:00:00', '23:59:59'),
]
: null;
2023-09-06 09:56:05 +08:00
this.getList();
break;
case 'compare':
2023-09-06 10:39:32 +08:00
this.open = true;
2023-09-06 09:56:05 +08:00
break;
}
},
2023-09-05 16:30:24 +08:00
/** 重置查询条件 */
initQuery() {
this.queryParams.lineId = null;
this.queryParams.sectionId = null;
2023-09-06 09:56:05 +08:00
this.queryParams.equipmentId = null;
2023-09-05 16:30:24 +08:00
this.queryParams.recordTime = [];
},
2023-09-06 09:56:05 +08:00
/** 对象到数组的转换 */
objectToArray(obj) {
return Object.keys(obj).map((key) => {
obj[key].sort((a, b) => a.startTime - b.startTime);
obj[key].key = key;
return obj[key];
});
},
2023-09-05 16:30:24 +08:00
async getList() {
const { code, data } = await this.$axios({
2023-09-06 09:56:05 +08:00
url: '/analysis/equipment-analysis/quantity',
2023-09-05 16:30:24 +08:00
method: 'get',
params: this.queryParams,
});
if (code == 0) {
2023-09-06 09:56:05 +08:00
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];
2023-09-20 15:17:29 +08:00
this.graphList.forEach(this.setSeries);
} else {
this.graphList = [];
this.graphList.forEach(this.setSeries);
}
},
setSeries(eqArr) {
if (eqArr.length == 0) {
this.templateConfig.series = [];
return;
2023-09-05 16:30:24 +08:00
}
2023-09-20 15:17:29 +08:00
let isInit = false;
if (this.accumulators.has(eqArr.key) == false) {
this.accumulators.set(eqArr.key, 0);
isInit = true;
}
let accumulator = this.accumulators.get(eqArr.key);
if ((accumulator && !isInit) || (accumulator == 0 && isInit == false)) {
accumulator++;
this.accumulators.set(eqArr.key, accumulator);
}
this.templateConfig.series.push({
name: eqArr.key + (accumulator == 0 ? '' : '-' + accumulator),
// name: Math.random(),
type: 'line',
symbol: 'circle',
data: this.getEquipmentQuantity(eqArr),
});
2023-09-05 16:30:24 +08:00
},
2023-09-04 09:41:31 +08:00
2023-09-06 09:56:05 +08:00
/** 获得设备产量 */
getEquipmentQuantity(equipmentArr) {
return equipmentArr.map((item) => item.totalQuantity);
},
/** 获得设备产量的时间 */
getTimeinfo(equipmentArr) {
2023-09-06 10:39:32 +08:00
return equipmentArr.map((item) =>
new Date(item.startTime).toLocaleTimeString()
);
2023-09-06 09:56:05 +08:00
},
2023-09-06 10:39:32 +08:00
/** 准备设备数据 */
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,
};
});
}
},
2023-09-05 16:30:24 +08:00
/** 准备产线数据 */
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,
};
});
}
},
2023-09-06 10:39:32 +08:00
async submitForm() {
const { code, data } = await this.$axios({
url: '/analysis/equipment-analysis/quantity',
method: 'get',
params: this.queryParams,
});
2023-09-20 15:17:29 +08:00
this.queryParams.equipmentId = null; // 清空一下
2023-09-06 10:39:32 +08:00
if (code == 0) {
const newEqlist = this.objectToArray(data);
if (!newEqlist || newEqlist.length == 0) {
this.$message.error('该设备没有产量数据');
return;
}
2023-09-20 15:17:29 +08:00
this.graphList.push(...newEqlist);
newEqlist.forEach(this.setSeries);
2023-09-06 10:39:32 +08:00
}
this.open = false;
2023-09-20 14:44:39 +08:00
},
2023-09-05 16:30:24 +08:00
},
};
</script>
2023-09-04 09:41:31 +08:00
2023-09-20 14:44:39 +08:00
<style scoped lang="scss">
.blue-title {
position: relative;
padding: 4px 0;
padding-left: 12px;
font-size: 14px;
color: #606266;
font-weight: 700;
margin-bottom: 12px;
&::before {
content: '';
position: absolute;
left: 0;
top: 6px;
height: 16px;
width: 4px;
border-radius: 1px;
background: #0b58ff;
}
}
</style>