11-mes-new/src/views/DataAnalysis/equipmentStatus.vue
2022-11-07 08:45:49 +08:00

657 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
/*
* @Author: lb
* @Date: 2022-07-21 13:30:00
* @LastEditors: lb
* @LastEditTime: 2022-07-21 13:30:00
* @Description: 设备状态时序图
*/
-->
<template>
<div class="app-container">
<head-form
class="head-form"
style="padding-top: 8px;"
:form-config="headFormConfig"
@headBtnClick="btnClick"
@select-changed="handleHeadSelectChanged"
/>
<div class="time-chart" style="margin-top: 10px;">
<div
v-show="equipmentCount > 0"
id="time-chart__inner"
ref="time-chart__inner"
class="time-chart__inner"
style="width: 100%; min-height: 50vh;"
:style="{ height: autoHeight + 'px' }"
/>
<div v-show="equipmentCount === 0">{{ $t('module.basicData.visual.hints.searchFirst') }}</div>
</div>
<eq-dialog v-if="addOrUpdateVisible" ref="addOrUpdate" :ws-id="wsId" @add-equipment="addEquipmentToSeriesData" />
</div>
</template>
<script>
import i18n from '@/lang'
// import { timeFormatter } from '@/filters'
import HeadForm from '@/components/basicData/HeadForm'
import { getLineList, getWorkSequenceList, getStatus } from '@/api/DataAnalysis/equipmentStatus'
import moment from 'moment'
import echarts from 'echarts'
import EqDialog from './components/equipmentStatus--dialog.vue'
/**
* 表格表头配置项 TypeScript接口注释
* tableConfig<ConfigItem> = []
*
* Interface ConfigItem = {
* prop: string,
* label: string,
* width: string,
* align: string,
* subcomponent: function,
* filter: function
* }
*
*
*/
function renderItem(params, api) {
var categoryIndex = api.value(0)
var start = api.coord([api.value(1), categoryIndex])
var end = api.coord([api.value(2), categoryIndex])
var height = 32
return {
type: 'rect',
shape: echarts.graphic.clipRectByRect(
{
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height
},
{
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
),
style: api.style()
}
}
class ChartOption {
constructor() {
this.color = ['#4caf50', '#ffb300', '#e53935']
this.legend = {
data: [
i18n.t('module.basicData.visual.echartLegends.working'),
i18n.t('module.basicData.visual.echartLegends.stop'),
i18n.t('module.basicData.visual.echartLegends.breakdown')
],
bottom: '0%',
selectedMode: false,
textStyle: {
color: '#000'
}
}
this.tooltip = {
formatter: function(params) {
return (
moment(params.value[1]).format('YYYY-MM-DD HH:mm:ss') +
' - ' +
moment(params.value[2]).format('YYYY-MM-DD HH:mm:ss') +
' : ' +
params.name
)
}
}
this.title = {
text: i18n.t('module.basicData.visual.echartTitles.eqStatus'),
left: 'center'
}
this.xAxis = {
type: 'time',
// min: +new Date().setHours(0, 0, 0, 0),
splitNumber: 24,
interval: 3600 * 1000,
axisTick: {
show: true,
alignWithLabel: true
},
axisLine: {
show: true
},
axisLabel: {
formatter: function(val) {
const time = new Date(val)
const hour = time.getHours()
const minute = time.getMinutes()
const hours = hour >= 10 ? hour + '' : '0' + hour
const minutes = minute >= 10 ? minute + '' : '0' + minute
return hours + ':' + minutes
}
}
}
this.yAxis = {
// data: Object.keys(eqData).map(item => eqData[item].name)
data: []
}
this.series = [
{ name: i18n.t('module.basicData.visual.echartLegends.working'), type: 'bar', data: [] },
{ name: i18n.t('module.basicData.visual.echartLegends.stop'), type: 'bar', data: [] },
{ name: i18n.t('module.basicData.visual.echartLegends.breakdown'), type: 'bar', data: [] },
{
type: 'custom',
renderItem: renderItem,
itemStyle: {
opacity: 0.8
},
encode: {
x: [1, 2],
y: 0
},
data: []
}
]
}
setTitle(title) {
this.title.text = title
}
// date: 服务器返回来的日期时间数据
setXAxis(date) {
// this.xAxis.min = +new Date(date).setHours(0)
this.xAxis.min = +new Date(date).setHours(0, 0, 0, 0)
this.xAxis.max = this.xAxis.min + 3600 * 1000 * 24
}
setYAxis(data) {
this.yAxis.data = data
}
setData(data) {
this.series[3].data = data
}
}
export default {
name: 'SxtEquipmentStatus',
components: { HeadForm, EqDialog },
data() {
return {
addOrUpdateVisible: false,
dataList: [],
total: 0,
listLoading: false,
listQuery: {
current: 1,
size: 20
},
headFormConfig: [
{
type: 'select',
// label: '产线',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.line'),
param: 'productLineId',
// multiple: true,
selectOptions: [],
defaultSelect: '',
onchange: true
},
{
type: 'select',
// label: '工序',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.process'),
param: 'workSequenceId',
// multiple: true,
selectOptions: [],
defaultSelect: ''
},
{
// 对于日期2022-7-1 ~ 2022-7-1 要转换为 2022/7/1T00:02:00 - 2022/7/2T00:02:00
type: 'datePicker',
// label: '日期',
label: i18n.t('module.dataAnalysis.equipmentEfficiency.date'),
dateType: 'date',
placeholder: this.$t('module.basicData.visual.hints.selectDate'),
param: 'date',
defaultSelect: new Date()
},
{
type: 'button',
btnName: 'btn.search',
name: 'search',
color: 'primary'
},
{
type: 'button',
btnName: `+ ${i18n.t('module.dataAnalysis.equipmentEfficiency.addEq')}`,
name: 'add-eq',
color: 'success'
}
],
headFormValue: {},
chart: null,
chartOption: new ChartOption(),
equipments: {},
startTime: null,
state: ['正常', '停机', '故障'],
colors: ['#4caf50', '#ffb300', '#e53935'],
queryBuffer: {},
wsId: null
}
},
computed: {
autoHeight: function() {
return Object.keys(this.equipments).length * 100 || 500
},
equipmentCount: function() {
return Object.keys(this.equipments).length
}
},
updated() {
if (this.chart) this.chart.resize()
},
mounted() {
this.fetchList('product-line').then(() => {
this.fetchList('work-section')
})
this.$nextTick(() => {
this.initChart()
})
},
methods: {
initChart() {
if (!this.chart) {
this.chart = echarts.init(this.$refs['time-chart__inner'])
// 获取数据
// const today = new Date(new Date().setHours(0,0,0,0))
// getStatus({
// productlines: this.headFormConfig[0].defaultSelect,
// wsId: this.headFormConfig[1].defaultSelect,
// startTime: today,
// endTime: new Date(today.getTime() + 3600 * 1000 * 24)
// }).then(res => {})
}
},
// handlers
async handleHeadSelectChanged(data) {
if (data.param === 'productLineId') {
this.headFormConfig[0].defaultSelect = data.value
await this.fetchList('work-section')
}
},
// 获取各种列表
fetchList(type) {
switch (type) {
case 'work-section': {
return getWorkSequenceList({ productionLineId: this.headFormConfig[0].defaultSelect }).then(res => {
if (res.data && res.data.length) {
this.headFormConfig[1].selectOptions = res.data.map(ws => ({ id: ws.id, name: ws.name }))
// 设置defaultSelect
this.wsId = this.headFormConfig[1].selectOptions[0].id
this.headFormConfig[1].defaultSelect = this.headFormConfig[1].selectOptions[0].id
} else {
this.headFormConfig[1].selectOptions.splice(0)
this.headFormConfig[1].defaultSelect = null
}
})
}
case 'product-line':
return getLineList().then(res => {
if (res.data) {
this.headFormConfig[0].selectOptions = res.data.map(line => ({ id: line.id, name: line.name }))
// 设置defaultSelect
this.headFormConfig[0].defaultSelect = this.headFormConfig[0].selectOptions[0].id
}
})
}
},
// 把服务器数据按照设备分组
transformDataToEquipments(dataList) {
const equipments = {}
dataList.map(item => {
if (equipments[item.eqId]) {
// 如果设备已存在
equipments[item.eqId].name = item.eqName
equipments[item.eqId].status.push({
startTime: +new Date(item.startTime),
endTime: +new Date(item.endTime),
status: this.state[item.status] // 0 正常、1 停机、2 故障
})
} else {
equipments[item.eqId] = {
name: item.eqName,
status: [
{
startTime: +new Date(item.startTime),
endTime: +new Date(item.endTime),
status: this.state[item.status] // 0 正常、1 停机、2 故障
}
]
}
}
})
// console.log('items --- ', equipments)
return equipments
},
// 把分组好的设备数据转换为echarts需要的series数据
transformEquipmentsToSeries(equipments) {
const seriesData = []
Object.entries(equipments).map(([key, item], index) => {
item.status.forEach(status => {
seriesData.push({
name: status.status,
value: [index, status.startTime, status.endTime],
itemStyle: {
normal: {
color:
status.status === '正常'
? '#4caf50'
: status.status === '停机'
? '#ffb300'
: status.status === '故障'
? '#e53935'
: null
}
}
})
})
})
return seriesData
},
// 顶部查询按钮
btnClick(val) {
this.headFormValue = val
if (this.headFormValue.btnName === 'search') {
const productlines = this.headFormValue.productLineId ? [this.headFormValue.productLineId] : []
const wsId = this.headFormValue.workSequenceId || ''
const date = this.headFormValue.date || new Date()
const startTime = moment(new Date(date.setHours(0, 0, 0, 0))).format('YYYY-MM-DDTHH:mm:ss')
const endTime = moment(new Date(date.setHours(0, 0, 0, 0)))
.add(1, 'd')
.format('YYYY-MM-DDTHH:mm:ss')
this.$set(this.queryBuffer, 'productlines', productlines)
this.$set(this.queryBuffer, 'wsId', wsId)
this.$set(this.queryBuffer, 'startTime', startTime)
this.$set(this.queryBuffer, 'endTime', endTime)
getStatus({
productlines,
wsId,
startTime,
endTime
}).then(res => {
if (res.data && res.data.length > 0) {
this.dataList = res.data
// this.dataList = [
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T00:30:34',
// endTime: '2022-05-04T08:30:34',
// status: 0
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T09:30:34',
// status: 1
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T09:30:34',
// endTime: '2022-05-04T11:30:34',
// status: 2
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T11:30:34',
// endTime: '2022-05-04T13:30:34',
// status: 1
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T13:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 0
// },
// {
// eqId: 'eq-001',
// eqName: 'A1预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-05T00:00:00',
// status: 1
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T01:30:34',
// endTime: '2022-05-04T08:30:34',
// status: 2
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 2
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-04T22:30:34',
// status: 0
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T22:30:34',
// endTime: '2022-05-04T23:30:34',
// status: 1
// },
// {
// eqId: 'eq-002',
// eqName: 'A2预热机',
// startTime: '2022-05-04T23:30:34',
// endTime: '2022-05-05T00:00:00',
// status: 2
// },
// {
// eqId: 'eq-0003',
// eqName: 'A3预热机',
// startTime: '2022-05-04T00:00:00',
// endTime: '2022-05-04T08:30:34',
// status: 0
// },
// {
// eqId: 'eq-0003',
// eqName: 'A3预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 2
// },
// {
// eqId: 'eq-0003',
// eqName: 'A3预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-04T22:30:34',
// status: 1
// },
// {
// eqId: 'eq-0003',
// eqName: 'A3预热机',
// startTime: '2022-05-04T22:30:34',
// endTime: '2022-05-04T23:30:34',
// status: 1
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T01:30:34',
// endTime: '2022-05-04T04:30:34',
// status: 2
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T04:30:34',
// endTime: '2022-05-04T08:30:34',
// status: 0
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T11:30:34',
// status: 1
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T11:30:34',
// endTime: '2022-05-04T13:30:34',
// status: 2
// },
// {
// eqId: 'eq-004',
// eqName: 'A4预热机',
// startTime: '2022-05-04T13:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 1
// },
// {
// eqId: 'eq-005',
// eqName: 'A4预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-04T20:30:34',
// status: 1
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T08:30:34',
// endTime: '2022-05-04T18:30:34',
// status: 0
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T18:30:34',
// endTime: '2022-05-04T20:30:34',
// status: 2
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T20:30:34',
// endTime: '2022-05-04T22:30:34',
// status: 1
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T22:30:34',
// endTime: '2022-05-04T23:30:34',
// status: 0
// },
// {
// eqId: 'eq-005',
// eqName: 'A5预热机',
// startTime: '2022-05-04T23:30:34',
// endTime: '2022-05-05T00:30:34',
// status: 1
// }
// ]
this.equipments = this.transformDataToEquipments(this.dataList)
this.chartOption.setYAxis(Object.keys(this.equipments).map(item => this.equipments[item].name))
this.chartOption.setXAxis(this.dataList[0].startTime)
this.chartOption.setData(this.transformEquipmentsToSeries(this.equipments))
this.renderChart()
} else {
this.dataList.splice(0)
}
})
} else if (this.headFormValue.btnName === 'add-eq') {
if (this.equipmentCount === 0) {
this.$message({
message: this.$t('module.basicData.visual.hints.searchFirst'),
type: 'warning',
duration: 1500
})
} else {
// 添加设备
// console.log('添加设备')
this.addOrUpdateVisible = true
this.$nextTick(() => {
// console.log('ref', this.$refs.addOrUpdate)
this.$refs.addOrUpdate.init(this.queryBuffer)
})
}
// 1.get eq
// const testEq = {
// code: 0,
// data: [
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T00:00:00', endTime: '2022-05-04T01:30:34', status: 1 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T01:30:34', endTime: '2022-05-04T03:00:34', status: 0 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T03:00:34', endTime: '2022-05-04T06:30:00', status: 2 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T06:30:00', endTime: '2022-05-04T12:30:00', status: 0 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T12:30:00', endTime: '2022-05-04T13:30:00', status: 1 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T13:30:00', endTime: '2022-05-04T18:30:34', status: 0 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T18:30:34', endTime: '2022-05-04T19:30:34', status: 2 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T19:30:34', endTime: '2022-05-04T22:00:00', status: 0 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T22:00:00', endTime: '2022-05-04T23:00:00', status: 1 },
// { eqId: 'eq-006', eqName: 'A6预热机', startTime: '2022-05-04T23:00:00', endTime: '2022-05-05T00:00:00', status: 2 },
// ]
// }
// this.addEquipmentToSeriesData(testEq.data)
}
},
addEquipmentToSeriesData(dataList) {
const newEq = this.transformDataToEquipments(dataList)
this.$set(this.equipments, Object.keys(newEq)[0], newEq[Object.keys(newEq)[0]])
this.chartOption.setYAxis(Object.keys(this.equipments).map(item => this.equipments[item].name))
this.chartOption.setData(this.transformEquipmentsToSeries(this.equipments))
this.renderChart()
},
renderChart() {
// console.log('rendering chart: ', this.chartOption)
this.chart.setOption(this.chartOption)
}
}
}
</script>
<style scoped>
.head-form >>> .el-date-editor .el-input__prefix {
left: unset;
right: 5px;
color: #0b58ff;
}
.head-form >>> .el-date-editor .el-input__suffix {
left: 5px;
right: unset;
color: #0b58ff;
}
</style>