386 lines
9.8 KiB
Vue
386 lines
9.8 KiB
Vue
<template>
|
|
<!-- 设备效率分析 -->
|
|
<div class="mod-config">
|
|
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
|
|
<!-- 产线 -->
|
|
<el-form-item>
|
|
<el-select v-model="dataForm.productlines" :placeholder="'产线'" @change="handleProductLineChange" clearable>
|
|
<el-option v-for="productLine in productLineList" :key="productLine.id" :value="productLine.id" :label="productLine.name" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<!-- 工序 -->
|
|
<el-form-item>
|
|
<!-- <el-select v-model="dataForm.factoryId" :placeholder="$t('eq.name') + ' / ' + $t('eq.code')" clearable></el-select> -->
|
|
<el-select v-model="dataForm.wsId" :placeholder="'工序'" clearable>
|
|
<el-option v-for="ws in wsList" :key="ws.id" :value="ws.id" :label="ws.name" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<!-- 日期选择 -->
|
|
<el-form-item>
|
|
<el-date-picker key="date-picker" v-model="rawTime" type="date" :placeholder="'请选择日期'" format="yyyy-MM-dd" />
|
|
</el-form-item>
|
|
<!-- 按钮 -->
|
|
<el-form-item>
|
|
<el-button @click="getDataList()">{{ $t('search') }}</el-button>
|
|
<!-- <el-button v-if="$hasPermission('monitoring:equipmentEffiency:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> -->
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<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">请先查询数据</div>
|
|
<!-- <div v-show="equipmentCount === 0">{{ $t('module.basicData.visual.hints.searchFirst') }}</div> -->
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import * as echarts from 'echarts'
|
|
// import i18n from '@/i18n'
|
|
import BaseTable from '@/components/base-table'
|
|
import { calcMaxHeight } from '@/utils'
|
|
import moment from 'moment'
|
|
// import TableOperateComponent from '@/components/base-table/components/operationComponent'
|
|
// import TableTextComponent from '@/components/base-table/components/detailComponent'
|
|
// import { timeFilter } from '@/utils/filters'
|
|
|
|
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'),
|
|
'正常',
|
|
'停机',
|
|
'故障'
|
|
],
|
|
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'),
|
|
text: '设备状态时序图',
|
|
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: '停机', type: 'bar', data: [] },
|
|
{ name: '故障', 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 {
|
|
data() {
|
|
return {
|
|
/** hfxny part */
|
|
wsList: [],
|
|
productLineList: [],
|
|
chart: null,
|
|
chartOption: new ChartOption(),
|
|
equipments: {},
|
|
state: ['正常', '停机', '故障'],
|
|
colors: ['#4caf50', '#ffb300', '#e53935'],
|
|
queryBuffer: {},
|
|
// tableConfigs,
|
|
calcMaxHeight,
|
|
timeType: 'range',
|
|
currentLine: null,
|
|
rawTime: null,
|
|
dataForm: {
|
|
wsId: null,
|
|
productlines: [],
|
|
startTime: null,
|
|
entTime: null
|
|
},
|
|
dataList: [],
|
|
pageIndex: 1,
|
|
pageSize: 10,
|
|
totalPage: 0,
|
|
dataListLoading: false
|
|
}
|
|
},
|
|
components: {
|
|
BaseTable
|
|
},
|
|
computed: {
|
|
autoHeight: function() {
|
|
return Object.keys(this.equipments).length * 100 || 500
|
|
},
|
|
equipmentCount: function() {
|
|
return Object.keys(this.equipments).length
|
|
}
|
|
},
|
|
created() {
|
|
this.getProductLineList().then(() => {
|
|
this.getWorksetionList()
|
|
})
|
|
},
|
|
watch: {
|
|
timeType() {
|
|
// 防止切换日期类型时报错
|
|
this.rawTime = null
|
|
}
|
|
},
|
|
methods: {
|
|
initChart() {
|
|
if (!this.chart) {
|
|
this.chart = echarts.init(this.$refs['time-chart__inner'])
|
|
}
|
|
},
|
|
// 获取产线列表
|
|
getProductLineList() {
|
|
return this.$http({
|
|
url: this.$http.adornUrl('/monitoring/productionLine/page'),
|
|
method: 'get'
|
|
}).then(({ data }) => {
|
|
if (data && data.code === 0) {
|
|
this.productLineList = data.data.list
|
|
/** set default */
|
|
if (this.productLineList.length) {
|
|
this.dataForm.productlines = this.productLineList[0].id
|
|
}
|
|
} else {
|
|
this.productLineList = []
|
|
}
|
|
})
|
|
},
|
|
|
|
// 获取工序列表
|
|
getWorksetionList() {
|
|
// 分页列表才有根据产线过滤功能
|
|
this.$http({
|
|
// url: this.$http.adornUrl('/monitoring/workshopSection/list'),
|
|
url: this.$http.adornUrl('/monitoring/workshopSection/page'),
|
|
method: 'get',
|
|
params: this.$http.adornParams({
|
|
limit: 99999,
|
|
page: 1,
|
|
lineId: this.dataForm.productlines ?? ''
|
|
})
|
|
}).then(({ data: res }) => {
|
|
if (res && res.code === 0) {
|
|
this.wsList = res.data.list
|
|
/** set default */
|
|
if (this.wsList.length) {
|
|
this.dataForm.wsId = this.wsList[0].id
|
|
}
|
|
} else {
|
|
this.wsList.splice(0)
|
|
this.dataForm.wsId = '' // <== 不起作用...
|
|
}
|
|
})
|
|
},
|
|
|
|
// 把服务器数据按照设备分组
|
|
transformDataToEquipments(dataList) {
|
|
console.log('transformDataToEquipments() datalist: ', 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
|
|
},
|
|
|
|
// 获取数据列表
|
|
getDataList() {
|
|
let startTime = this.rawTime
|
|
? moment(this.rawTime)
|
|
.set({ date: 1, hour: 0, minute: 0, second: 0, millisecond: 0 })
|
|
.format('YYYY-MM-DDTHH:mm:ss')
|
|
: ''
|
|
let endTime = startTime
|
|
? moment(startTime)
|
|
.add(1, 'M')
|
|
.format('YYYY-MM-DDTHH:mm:ss')
|
|
: ''
|
|
|
|
this.dataListLoading = true
|
|
this.$http({
|
|
url: this.$http.adornUrl('/monitoring/eqAnalysis/timeAndStatus'),
|
|
method: 'post',
|
|
data: {
|
|
startTime,
|
|
endTime,
|
|
productlines: [this.dataForm.productlines],
|
|
wsId: this.dataForm.wsId
|
|
}
|
|
}).then(({ data: res }) => {
|
|
if (res.code === 500) {
|
|
this.dataList.splice(0)
|
|
this.$message.error(res.msg)
|
|
} else {
|
|
this.dataList = res.data
|
|
}
|
|
})
|
|
},
|
|
handleProductLineChange(val) {
|
|
console.log('handleProductLineChange', this.dataForm.productlines)
|
|
this.getWorksetionList()
|
|
},
|
|
// 每页数
|
|
sizeChangeHandle(val) {
|
|
this.pageSize = val
|
|
this.pageIndex = 1
|
|
this.getDataList()
|
|
},
|
|
// 当前页
|
|
currentChangeHandle(val) {
|
|
this.pageIndex = val
|
|
this.getDataList()
|
|
},
|
|
// 多选
|
|
selectionChangeHandle(val) {
|
|
this.dataListSelections = val
|
|
},
|
|
handleOperations({ type, data: id }) {
|
|
switch (type) {
|
|
case 'view-detail':
|
|
return this.addOrUpdateHandle(id, true)
|
|
case 'edit':
|
|
return this.addOrUpdateHandle(id)
|
|
case 'delete':
|
|
return this.deleteHandle(id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|