368 lines
11 KiB
Vue
368 lines
11 KiB
Vue
<!--
|
||
/*
|
||
* @Author: lb
|
||
* @Date: 2022-07-21 13:30:00
|
||
* @LastEditors: lb
|
||
* @LastEditTime: 2022-07-21 13:30:00
|
||
* @Description: 设备产量时序图
|
||
*/
|
||
-->
|
||
<template>
|
||
<div>
|
||
<div class="app-container">
|
||
<head-form :form-config="headFormConfig" @headBtnClick="btnClick" />
|
||
|
||
<transition mode="out-in" name="slide-to-left">
|
||
<equipment-efficiency-graph v-if="showGraph" key="graph" ref="eegraph" @close-graph="showGraph = false" />
|
||
<base-table
|
||
v-else
|
||
key="table"
|
||
:page="listQuery.current"
|
||
:limit="listQuery.size"
|
||
:table-config="tableProps"
|
||
:table-data="dataList"
|
||
:is-loading="listLoading"
|
||
:index-config="{ align: 'left', fixed: 'left' }"
|
||
@emitFun="handleTableEvents"
|
||
/>
|
||
</transition>
|
||
</div>
|
||
<!-- <div class="app-container">
|
||
<el-radio-group v-model="chartType" class="data-analysis-radio" size="mini" @change="changeChartType">
|
||
<el-radio-button v-for="(item, index) in chartDataArr" :key="index" :label="index">
|
||
{{ item.equipmentName }}
|
||
</el-radio-button>
|
||
</el-radio-group>
|
||
<Line-chart :chart-data="chartDataItem" width="100%" height="400px" />
|
||
</div> -->
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
// import i18n from '@/lang'
|
||
import HeadForm from '@/components/basicData/HeadForm'
|
||
import BaseTable from '@/components/BaseTable/index-compound'
|
||
// import LineChart from '@/components/Charts/LineChart'
|
||
import { getLineList, getFactoryList, getOEE } from '@/api/DataAnalysis/equipmentEfficiency'
|
||
import moment from 'moment'
|
||
import commonBtn from '@/components/BaseTable/subcomponents/CommonBtn.vue'
|
||
|
||
import EquipmentEfficiencyGraph from './components/equipmentEfficiencyGraph.vue'
|
||
// import { timeFormatter } from '@/filters'
|
||
/**
|
||
* 表格表头配置项 TypeScript接口注释
|
||
* tableConfig<ConfigItem> = []
|
||
*
|
||
* Interface ConfigItem = {
|
||
* prop: string,
|
||
* label: string,
|
||
* width: string,
|
||
* align: string,
|
||
* subcomponent: function,
|
||
* filter: function
|
||
* }
|
||
*
|
||
*
|
||
*/
|
||
|
||
const tableProps = [
|
||
{
|
||
label: '工厂',
|
||
prop: 'factoryName'
|
||
},
|
||
{
|
||
label: '产线',
|
||
prop: 'pdName'
|
||
},
|
||
{
|
||
label: '工序',
|
||
prop: 'wsName'
|
||
},
|
||
{
|
||
label: '设备',
|
||
prop: 'eqName'
|
||
},
|
||
{
|
||
label: '有效时间(h)',
|
||
children: [
|
||
{ prop: 'workTime', label: '工作时长(小时)', width: 120, filter: val => `${val} 小时` },
|
||
{ prop: 'workRate', label: '工作时长比率', width: 120, filter: val => (val * 100).toFixed(2) + '%' }
|
||
]
|
||
},
|
||
{
|
||
label: '关机时间(h)',
|
||
children: [
|
||
{ prop: 'stopTime', label: '停机时长(小时)', width: 120, filter: val => `${val} 小时` },
|
||
{ prop: 'stopRate', label: '停机比率', filter: val => (val * 100).toFixed(2) + '%' }
|
||
]
|
||
},
|
||
{
|
||
label: '中断损失',
|
||
children: [
|
||
{ prop: 'downTime', label: '故障时长(小时)', width: 120, filter: val => `${val} 小时` },
|
||
{ prop: 'downRate', label: '故障比率', filter: val => (val * 100).toFixed(2) + '%' }
|
||
]
|
||
},
|
||
{
|
||
label: '速度损失',
|
||
children: [
|
||
{ prop: 'realYield', label: '实际加工速度', width: 120, filter: val => `${val} 片/小时` }, // 片/小时
|
||
{ prop: 'designYield', label: '理论加工速度', width: 120, filter: val => `${val} 片/小时` },
|
||
{ prop: 'peEfficiency', label: '速度开动率', width: 120, filter: val => (val * 100).toFixed(2) + '%' }
|
||
]
|
||
},
|
||
// {
|
||
// prop: 'goodRate',
|
||
// label: '良品率' // 暂时先隐藏
|
||
// },
|
||
{
|
||
label: 'OEE',
|
||
prop: 'oee',
|
||
filter: val => (val * 100).toFixed(2) + '%'
|
||
},
|
||
{
|
||
label: 'TEEP',
|
||
prop: 'teep',
|
||
filter: val => (val * 100).toFixed(2) + '%'
|
||
},
|
||
{
|
||
label: '操作',
|
||
subcomponent: commonBtn,
|
||
emitFullData: true,
|
||
buttonContent: '查看趋势',
|
||
actionName: 'view-trend'
|
||
}
|
||
]
|
||
|
||
export default {
|
||
name: 'EquipmentEfficiency',
|
||
components: { BaseTable, HeadForm, EquipmentEfficiencyGraph /** LineChart */ },
|
||
data() {
|
||
return {
|
||
addOrUpdateVisible: false,
|
||
tableProps,
|
||
dataList: [],
|
||
total: 0,
|
||
listLoading: false,
|
||
listQuery: {
|
||
current: 1,
|
||
size: 20
|
||
},
|
||
lineList: [],
|
||
headFormConfig: [
|
||
// label: i18n.t('module.dataAnalysis.productionLineBalance.line'),
|
||
// placeholder: this.$t('module.dataAnalysis.productionLineBalance.line'),
|
||
// width: 300,
|
||
{
|
||
type: 'select',
|
||
label: '工厂',
|
||
param: 'factoryId',
|
||
selectOptions: []
|
||
},
|
||
{
|
||
type: 'select',
|
||
label: '产线',
|
||
param: 'productLineIds',
|
||
multiple: true,
|
||
selectOptions: []
|
||
},
|
||
{
|
||
// 对于日期:2022-7-1 ~ 2022-7-1 要转换为 2022/7/1T00:02:00 - 2022/7/2T00:02:00
|
||
type: 'select',
|
||
label: '时间类型',
|
||
param: 'dateFilterType',
|
||
defaultSelect: 0,
|
||
selectOptions: [{ id: 0, name: '按时间段' }, { id: 1, name: '按日期' }],
|
||
index: 2, // 记录下当前配置项的index,省的遍历的开销; index 和 extraOptions 要配合
|
||
extraOptions: [
|
||
{
|
||
elDatePickerKey: '8dkfl', // 防止el-date-picker飞到左上角
|
||
parent: 'dateFilterType',
|
||
// 时间段选择
|
||
type: 'datePicker',
|
||
label: '时间段',
|
||
dateType: 'daterange',
|
||
format: 'yyyy-MM-dd',
|
||
// valueFormat: 'yyyy-MM-dd',
|
||
defaultTime: ['00:00:00', '00:00:00'],
|
||
rangeSeparator: '-',
|
||
startPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.startTime'),
|
||
endPlaceholder: this.$t('module.dataAnalysis.productionLineBalance.endTime'),
|
||
param: 'timeValue'
|
||
},
|
||
{
|
||
elDatePickerKey: '0lkfl',
|
||
parent: 'dateFilterType',
|
||
// 日期选择
|
||
type: 'datePicker',
|
||
label: '日期',
|
||
dateType: 'date',
|
||
placeholder: '选择日期',
|
||
format: 'yyyy-MM-dd',
|
||
// valueFormat: 'yyyy-MM-dd', // 需要返回Date()
|
||
param: 'timeValue'
|
||
}
|
||
]
|
||
},
|
||
{
|
||
type: 'button',
|
||
btnName: 'btn.search',
|
||
name: 'search',
|
||
color: 'primary'
|
||
}
|
||
],
|
||
headFormValue: {},
|
||
showGraph: false
|
||
}
|
||
},
|
||
created() {
|
||
this.fetchList('factory')
|
||
this.fetchList('product-line')
|
||
// this.getList() // 时间间隔必填
|
||
},
|
||
methods: {
|
||
// 获取各种列表
|
||
fetchList(type) {
|
||
switch (type) {
|
||
case 'factory':
|
||
return getFactoryList().then(res => {
|
||
if (res.data) {
|
||
this.headFormConfig[0].selectOptions = res.data.map(factory => ({ id: factory.id, name: factory.name }))
|
||
// 设置defaultSelect
|
||
this.headFormConfig[0].defaultSelect = this.headFormConfig[0].selectOptions[0].id
|
||
}
|
||
})
|
||
case 'product-line':
|
||
return getLineList().then(res => {
|
||
if (res.data) {
|
||
this.headFormConfig[1].selectOptions = res.data.map(line => ({ id: line.id, name: line.name }))
|
||
// 设置defaultSelect
|
||
this.headFormConfig[1].defaultSelect = [this.headFormConfig[1].selectOptions[0].id]
|
||
}
|
||
})
|
||
}
|
||
},
|
||
|
||
// 获取首页列表
|
||
getList() {
|
||
// this.listLoading = true
|
||
|
||
const ftId = this.headFormValue.factoryId ? this.headFormValue.factoryId : ''
|
||
const productlines = this.headFormValue.productLineIds.length ? this.headFormValue.productLineIds : []
|
||
let startTime
|
||
let endTime
|
||
|
||
if (this.headFormValue.timeValue instanceof Array) {
|
||
startTime = this.headFormValue.timeValue[0]
|
||
? moment(this.headFormValue.timeValue[0]).format('YYYY-MM-DDTHH:mm:ss')
|
||
: '' // 强制axios使用北京时间
|
||
endTime = this.headFormValue.timeValue[1]
|
||
? moment(this.headFormValue.timeValue[1]).format('YYYY-MM-DDTHH:mm:ss')
|
||
: ''
|
||
} else {
|
||
if (this.headFormValue.timeValue) {
|
||
startTime = moment(this.headFormValue.timeValue)
|
||
.add(2, 'm')
|
||
.format('YYYY-MM-DDTHH:mm:ss')
|
||
endTime = moment(startTime)
|
||
.add(1, 'd')
|
||
.format('YYYY-MM-DDTHH:mm:ss')
|
||
} else {
|
||
startTime = ''
|
||
endTime = ''
|
||
}
|
||
}
|
||
|
||
getOEE({ ...this.listQuery, type: 1, ftId, productlines, startTime, endTime })
|
||
.then(res => {
|
||
this.dataList = res.data
|
||
// this.listLoading = false
|
||
})
|
||
.catch(err => {
|
||
if (err.message === '该时间段内设备未连接到数据库') {
|
||
this.dataList.splice(0)
|
||
}
|
||
})
|
||
},
|
||
|
||
// 顶部查询按钮
|
||
btnClick(val) {
|
||
this.headFormValue = val
|
||
if (this.headFormValue.btnName === 'search') {
|
||
this.getList()
|
||
}
|
||
this.showGraph = false
|
||
},
|
||
// handlers
|
||
handleTableEvents({ action, data }) {
|
||
// 有查看趋势,和保留待用的OEE对比图(此者暂时不做)
|
||
switch (action) {
|
||
case 'view-trend':
|
||
this.viewTrends(data)
|
||
break
|
||
case 'view-oee-compare':
|
||
break
|
||
}
|
||
},
|
||
|
||
viewTrends(data) {
|
||
const startTime = this.headFormValue.timeValue[0]
|
||
? moment(this.headFormValue.timeValue[0]).format('YYYY-MM-DDTHH:mm:ss')
|
||
: '' // 强制axios使用北京时间
|
||
const endTime = this.headFormValue.timeValue[1]
|
||
? moment(this.headFormValue.timeValue[1]).format('YYYY-MM-DDTHH:mm:ss')
|
||
: ''
|
||
const injectData = {
|
||
// 时间段
|
||
startTime,
|
||
endTime,
|
||
// 设备id
|
||
equipmentId: data.eqId,
|
||
equipmentName: data.eqName,
|
||
// 时间类型, type 按年,按月,按日等
|
||
type: 1, // 默认 type 1, 1无间隔;2按月分隔;3按周分隔;4按天分隔
|
||
// 时长数据: 工作时长, 停机时长,故障时长
|
||
workTime: data.workTime,
|
||
stopTime: data.stopTime,
|
||
downTime: data.downTime,
|
||
// 比例数据: 工作时长比率,停机时长比率,故障时长比率,速度开动率,OEE,TEEP
|
||
workRate: data.workRate,
|
||
stopRate: data.stopRate,
|
||
downRate: data.downRate,
|
||
peEfficiency: data.peEfficiency
|
||
}
|
||
console.log('trends data: ', data)
|
||
|
||
this.showGraph = true
|
||
|
||
setTimeout(() => {
|
||
console.log('befoer graph: ', this.$refs.eegraph)
|
||
this.$refs.eegraph.init(injectData) // 注入初始数据,这些数据在组件内部用作条件,有可能会被更改
|
||
}, 600) // 动画是500ms
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.slide-to-left-enter-active,
|
||
.slide-to-left-leave-active {
|
||
transition: all 0.5s;
|
||
}
|
||
|
||
.slide-to-left-enter {
|
||
transform: translateX(10px);
|
||
opacity: 0;
|
||
}
|
||
|
||
.slide-to-left-leave-to {
|
||
transform: translateX(-10px);
|
||
opacity: 0;
|
||
}
|
||
|
||
.slide-to-left-leave,
|
||
.slide-to-left-enter-to {
|
||
transform: translateX(0);
|
||
}
|
||
</style>
|