11-mes-new/src/views/DataAnalysis/equipmentProduction.vue

368 lines
11 KiB
Vue
Raw Normal View History

2022-11-07 08:45:49 +08:00
<!--
/*
* @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,
// 比例数据: 工作时长比率停机时长比率故障时长比率速度开动率OEETEEP
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>