Merge pull request ''数据分析-产量分析,产品质量分析,设备产量时序图'' (#24) from fzq into develop
Tüm denetlemeler başarılı oldu
continuous-integration/drone/push Build is passing
Tüm denetlemeler başarılı oldu
continuous-integration/drone/push Build is passing
Reviewed-on: #24
Bu işleme şunda yer alıyor:
işleme
092d7da353
@ -51,7 +51,11 @@ t.routes['登录日志'] = 'Login Records'
|
||||
t.routes['操作日志'] = 'Operations Records'
|
||||
t.routes['设备效率分析'] = 'EQU Efficiency Analysis'
|
||||
t.routes['设备异常分析'] = 'EQU Exceptions Analysis'
|
||||
t.routes['设备状态时序图'] = 'EQU Status Timesequence'
|
||||
t.routes['设备状态时序图'] = 'EQU Status Timeseq'
|
||||
t.routes['产品质量分析'] = 'Product Quality Analysis'
|
||||
t.routes['产量分析'] = 'Product Analysis'
|
||||
t.routes['生产节拍时序图'] = 'Product Beat Timeseq'
|
||||
t.routes['设备产量时序图'] = 'EQU Product Timeseq'
|
||||
|
||||
// 三级
|
||||
t.routes['工厂'] = 'Factory'
|
||||
@ -143,6 +147,7 @@ t.normal = 'Normal'
|
||||
t.shutdown = 'Shut Down'
|
||||
t.malfunction = 'Malfunction' // ?
|
||||
t.diagram = 'Device Status Sequence Diagram'
|
||||
t.diagram2 = 'Device Product Sequence Diagram'
|
||||
t.addr = 'Address'
|
||||
t.planStop = 'Plan to stop'
|
||||
t.startTime = 'Start Time'
|
||||
@ -384,8 +389,20 @@ t.eq.month = 'month'
|
||||
t.eq.realyield = 'Actual processing speed'
|
||||
t.eq.designyield = 'Theoretical processing speed'
|
||||
t.eq.viewtrend = 'View Trends'
|
||||
t.eq.productQuality = 'Product Quality Analysis'
|
||||
t.eq.productionAnalysis = 'Production Analysis'
|
||||
t.eq.productQuantity = 'Product Quantity'
|
||||
t.eq.line1= 'Line 1'
|
||||
t.eq.line2= 'Line 2'
|
||||
t.eq.line3= 'Line 3'
|
||||
t.eq.line4= 'Line 4'
|
||||
|
||||
|
||||
t.eq.sectionName = 'Section Name'
|
||||
t.eq.equipmentName = 'Equipment Name'
|
||||
t.eq.okNum = 'Qualified Quantity'
|
||||
t.eq.nokNum = 'Unqualified Quantity'
|
||||
t.eq.passRate = 'Qualified Rate'
|
||||
t.eq.passRatePercent = 'Qualified Rate(%)'
|
||||
|
||||
t.pl = {}
|
||||
t.pl.title = 'Product Line'
|
||||
|
@ -51,6 +51,11 @@ t.routes['操作日志'] = '操作日志'
|
||||
t.routes['设备效率分析'] = '设备效率分析'
|
||||
t.routes['设备异常分析'] = '设备异常分析'
|
||||
t.routes['设备状态时序图'] = '设备状态时序图'
|
||||
t.routes['产品质量分析'] = '产品质量分析'
|
||||
t.routes['产量分析'] = '产量分析'
|
||||
t.routes['生产节拍时序图'] = '生产节拍时序图'
|
||||
t.routes['设备产量时序图'] = '设备产量时序图'
|
||||
|
||||
|
||||
// 三级
|
||||
t.routes['工厂'] = '工厂'
|
||||
@ -141,6 +146,7 @@ t.normal = '正常' // ?
|
||||
t.shutdown = '停机' // ?
|
||||
t.malfunction = '故障' // ?
|
||||
t.diagram = '设备状态时序图'
|
||||
t.diagram2 = '设备产量时序图'
|
||||
t.addr = '地址' // 1
|
||||
t.planStop = '计划停机' // ?
|
||||
t.startTime = '开始时间' // 1
|
||||
@ -383,6 +389,20 @@ t.eq.month='月'
|
||||
t.eq.realyield = '实际加工速度'
|
||||
t.eq.designyield = '理论加工速度'
|
||||
t.eq.viewtrend = '查看趋势'
|
||||
t.eq.productQuality = '产品质量分析'
|
||||
t.eq.productionAnalysis = '产量分析'
|
||||
t.eq.productQuantity = '产品数量'
|
||||
t.eq.line1= '产线1'
|
||||
t.eq.line2= '产线2'
|
||||
t.eq.line3= '产线3'
|
||||
t.eq.line4= '产线4'
|
||||
|
||||
t.eq.sectionName = '工序'
|
||||
t.eq.equipmentName = '设备名称'
|
||||
t.eq.okNum = '合格数量'
|
||||
t.eq.nokNum = '不合格数量'
|
||||
t.eq.passRate = '合格率'
|
||||
t.eq.passRatePercent = '合格率(%)'
|
||||
|
||||
|
||||
t.pl = {}
|
||||
|
781
src/views/modules/monitoring/equProductTimesequence.vue
Normal dosya
781
src/views/modules/monitoring/equProductTimesequence.vue
Normal dosya
@ -0,0 +1,781 @@
|
||||
<template>
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" @keyup.enter.native="getDataList()" class="blueTip" size="small">
|
||||
<el-form-item>
|
||||
{{ $t('pl.name') }}
|
||||
</el-form-item>
|
||||
<!-- 产线 -->
|
||||
<el-form-item>
|
||||
<el-select v-model="lineIds" :placeholder="$t('pl.name')" @change="handleProductLineChange" clearable filterable multiple>
|
||||
<el-option v-for="line in lineList" :key="line.code" :value="line.id" :label="line.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 工序 -->
|
||||
<el-form-item>
|
||||
{{ $t('pl.process') }}
|
||||
</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="sectionIds" :placeholder="$t('pl.process')" clearable filterable multiple>
|
||||
<el-option v-for="ws in wsList" :key="ws.id" :value="ws.id" :label="ws.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 时间 -->
|
||||
<el-form-item>
|
||||
{{ $t('time') }}
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- type="datetimerange" -->
|
||||
<!-- <el-date-picker
|
||||
type="daterange"
|
||||
v-model="datetime"
|
||||
value-format="yyyy-MM-ddTHH:mm:ss"
|
||||
:start-placeholder="$t('startTime')"
|
||||
:end-placeholder="$t('endTime')"
|
||||
:range-separator="$t('to')"
|
||||
:default-time="['00:00:00', '23:59:59']"
|
||||
:picker-options="quickOptions"
|
||||
clearable /> -->
|
||||
<el-date-picker v-model="datetime" type="date" :placeholder="$t('hints.date')" format="yyyy-MM-dd" value-format="yyyy-MM-dd" />
|
||||
</el-form-item>
|
||||
<!-- 查询 -->
|
||||
<el-form-item>
|
||||
<el-button class="buttonColor" @click="getDataList()">{{ $t('query') }}</el-button>
|
||||
<!-- <el-button v-if="$hasPermission('monitoring:qualityinspectionrecord:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> -->
|
||||
</el-form-item>
|
||||
<!-- 添加对比 -->
|
||||
<el-form-item>
|
||||
<el-button type="success" @click="addEq()">{{ $t('pl.add2') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog :visible.sync="dialogVisible" :title="$t('pl.add')" width="30%">
|
||||
<el-select v-model="eqId" style="width: 100%" :placeholder="$t('pl.choose')" clearable filterable>
|
||||
<el-option v-for="eq in dialogEqList" :key="eq.id" :label="eq.name" :value="eq.id" />
|
||||
</el-select>
|
||||
<div slot="footer">
|
||||
<el-button @click="dialogVisible = false">{{ $t('pl.cancel') }}</el-button>
|
||||
<!-- @click="dialogConfirm" -->
|
||||
<el-button type="primary" @click="dialogConfirm">{{ $t('pl.confirm') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<div class="quality-inspection-current base-container">
|
||||
<!-- <el-row>
|
||||
<el-col>
|
||||
<small-title :size="'md'">{{ $t('inspect.ioTotal') }}</small-title>
|
||||
<el-row style="margin-top: 12px;">
|
||||
<base-table :data="dataListStatic" :table-head-configs="tableConfigStatic" :max-height="500" @operate-event="handleOperations" @refreshDataList="getDataList" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row> -->
|
||||
|
||||
<!-- style="margin-top: 28px;" -->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-row>
|
||||
<small-title :size="'md'">{{ $t('diagram2'), }}</small-title>
|
||||
</el-row>
|
||||
<!-- <el-row style="margin-top: 8px">
|
||||
<el-radio-group v-model="dataType" size="medium" @change="handleDataTypeChange">
|
||||
<el-radio-button :label="$t('table2')"></el-radio-button>
|
||||
<el-radio-button :label="$t('graph')"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-row> -->
|
||||
<!-- style="margin-top: 12px" -->
|
||||
<!-- <el-row>
|
||||
<base-table
|
||||
:data="dataList"
|
||||
:table-head-configs="tableConfigDynamic"
|
||||
:max-height="500"
|
||||
@operate-event="handleOperations"
|
||||
@refreshDataList="getDataList" />
|
||||
</el-row> -->
|
||||
<!-- :series-data="echartsData" -->
|
||||
<!-- v-else -->
|
||||
<el-row>
|
||||
<fake-chart :categories="echartCategories" :type-list="echartCheckTypes" :series="series" :keys="keys" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
import { timeFilter } from '@/utils/filters'
|
||||
import moment from 'moment'
|
||||
import i18n from '@/i18n'
|
||||
import BaseTable from '@/components/base-table'
|
||||
import SmallTitle from '@/components/small-title'
|
||||
import * as echarts from 'echarts'
|
||||
import { keys } from 'lodash'
|
||||
|
||||
// const tableConfigStatic = [
|
||||
// { type: 'index', width: 100, name: i18n.t('index') },
|
||||
// { name: i18n.t('pl.title'), prop: 'lineName' },
|
||||
// { name: i18n.t('inspect.inTotal'), prop: 'sumUp' },
|
||||
// { name: i18n.t('inspect.outTotal'), prop: 'sumDown' },
|
||||
// { name: i18n.t('inspect.checkTotal'), prop: 'sumCheck' },
|
||||
// { name: i18n.t('inspect.rate'), prop: 'scrapRatio', filter: (val) => (val || val === 0 ? `${val}%` : '-') }
|
||||
// ]
|
||||
const tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ name: i18n.t('pl.name'), prop: '0' }
|
||||
]
|
||||
|
||||
const FakeChart = {
|
||||
name: 'FakeChart',
|
||||
props: {
|
||||
categories: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
typeList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
keys: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
series: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
calcMaxHeight,
|
||||
chart: null,
|
||||
lineIds: [],
|
||||
// 新加
|
||||
// keys: [],
|
||||
values: [],
|
||||
// finalVal: [],
|
||||
defaultOpts: {
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '12%',
|
||||
top: '20%',
|
||||
bottom: '10%'
|
||||
},
|
||||
title: {
|
||||
text: i18n.t('eq.productQuantity')
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis', //坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用
|
||||
axisPointer: {
|
||||
// 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
type: 'scroll',
|
||||
top: 10,
|
||||
right: 0,
|
||||
width: '12%',
|
||||
/** 修复文本太长时显示问题 */
|
||||
// formatter: function (name) {
|
||||
// return echarts.format.truncateText(name, 120, '14px Microsoft Yahei', '...')
|
||||
// },
|
||||
tooltip: {
|
||||
show: true
|
||||
},
|
||||
/** end */
|
||||
data: []
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [
|
||||
'1:00',
|
||||
'2:00',
|
||||
'3:00',
|
||||
'4:00',
|
||||
'5:00',
|
||||
'6:00',
|
||||
'7:00',
|
||||
'8:00',
|
||||
'9:00',
|
||||
'10:00',
|
||||
'11:00',
|
||||
'12:00',
|
||||
'13:00',
|
||||
'14:00',
|
||||
'15:00',
|
||||
'16:00',
|
||||
'17:00',
|
||||
'18:00',
|
||||
'19:00',
|
||||
'20:00',
|
||||
'21:00',
|
||||
'22:00',
|
||||
'23:00',
|
||||
'24:00'
|
||||
],
|
||||
// axisLine: {
|
||||
// show: true,
|
||||
// lineStyle: {
|
||||
// color: 'rgba(219,225,255,1)',
|
||||
// width: 1,
|
||||
// type: 'solid'
|
||||
// }
|
||||
// },
|
||||
axisLabel: {
|
||||
//设置x轴的字
|
||||
show: true,
|
||||
rotate: 0,
|
||||
interval: 0 //使x轴横坐标全部显示
|
||||
// textStyle: {
|
||||
// //x轴字体样式
|
||||
// color: 'rgba(219,225,255,1)',
|
||||
// margin: 15
|
||||
// }
|
||||
}
|
||||
|
||||
// data: ['下片1', '上片1', '磨边机1', '设备13', '钢化炉2', '磨边机2', '设备15', '清洗机1', '钢化炉3']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
// dynamic
|
||||
// {
|
||||
// name: '',
|
||||
// type: 'line',
|
||||
// data: [],
|
||||
// label: {
|
||||
// normal: {
|
||||
// show: true,
|
||||
// position: 'top'
|
||||
// },
|
||||
// formatter: '{@value}'
|
||||
// }
|
||||
// }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
categories: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
// this.defaultOpts.xAxis.data.push(...val)
|
||||
this.defaultOpts.xAxis.data = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
keys: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
// this.defaultOpts.legend.data.push(...val)
|
||||
this.defaultOpts.legend.data = val
|
||||
// this.defaultOpts.series.name = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
series: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
// this.defaultOpts.legend.data.push(...val)
|
||||
this.defaultOpts.series = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
defaultOpts: {
|
||||
handler: function (val) {
|
||||
// console.log('defaullt options change: ', val)
|
||||
this.setOptions()
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
// console.log('this.defaultOpts.xAxis.data', this.defaultOpts.xAxis.data)
|
||||
// console.log('this.keys渲染', this.keys)
|
||||
// console.log('this.series渲染', this.series)
|
||||
this.setOptions()
|
||||
window.addEventListener('resize', () => {
|
||||
//监听浏览器窗口大小
|
||||
this.chart.resize()
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
if (!this.chart) {
|
||||
this.chart = echarts.init(document.getElementById('bar-chart'))
|
||||
this.chart.resize()
|
||||
}
|
||||
},
|
||||
setOptions(opts) {
|
||||
/** prop options */
|
||||
if (opts) {
|
||||
// console.log('this.keys渲染', this.keys)
|
||||
// console.log('this.finalVal渲染', this.finalVal)
|
||||
// // 动态添加series
|
||||
// for (let l = 0; l < this.finalVal.length; l++) {
|
||||
// this.defaultOpts.series.push({
|
||||
// name: this.keys[l],
|
||||
// type: 'line',
|
||||
// // stack: '总量',
|
||||
// data: this.finalVal[l]
|
||||
// })
|
||||
// }
|
||||
// console.log('之后的defaultOpts',this.defaultOpts);
|
||||
}
|
||||
if (this.chart) this.chart.setOption(this.defaultOpts, true)
|
||||
}
|
||||
},
|
||||
render: function (h) {
|
||||
return h('div', { attrs: { id: 'bar-chart' }, style: { background: '#eee', width: '100%', height: '300px', padding: '8px' } }, '')
|
||||
}
|
||||
}
|
||||
|
||||
const dict = [i18n.t('table2'), i18n.t('graph')]
|
||||
export default {
|
||||
name: 'QualityInspectionCurrent',
|
||||
components: { BaseTable, SmallTitle, FakeChart },
|
||||
data() {
|
||||
return {
|
||||
// 新加
|
||||
values: [],
|
||||
values2: [],
|
||||
keys: [], // 设备名动态series
|
||||
finalVal: [],
|
||||
series: [],
|
||||
equipments: {},
|
||||
wsList: [],
|
||||
dialogVisible: false,
|
||||
eqId: null,
|
||||
dialogEqList: [],
|
||||
count: 0,
|
||||
// 产线默认产线1
|
||||
lineIds: ['1'],
|
||||
sectionIds: [],
|
||||
lineList: [],
|
||||
// tableConfigStatic,
|
||||
tableConfigDynamic,
|
||||
datetime: new Date(),
|
||||
dataListStatic: [],
|
||||
dataListDynamic: [],
|
||||
dataList: [],
|
||||
dict,
|
||||
dataType: dict[0], // 表格 | 图形
|
||||
showGraph: false,
|
||||
// quickOptions: {
|
||||
// shortcuts: [
|
||||
// {
|
||||
// text: i18n.t('today'),
|
||||
// onClick(picker) {
|
||||
// const baseTime = moment().set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
|
||||
// const startTime = baseTime.format('yyyy-MM-DDTHH:mm:ss')
|
||||
// const endTime = baseTime.set({ hour: 23, minute: 59, second: 59, millisecond: 999 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// picker.$emit('pick', [startTime, endTime])
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
echartCategories: null,
|
||||
echartCheckTypes: [],
|
||||
interval: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
equipmentCount: function () {
|
||||
return Object.keys(this.equipments).length
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getEqList()
|
||||
this.getLineList()
|
||||
this.getWorksetionList()
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
this.$message.info(i18n.t('refresh'))
|
||||
// this.dataListStatic.splice(0)
|
||||
this.series.splice(0)
|
||||
this.getDataList()
|
||||
}, 1000 * 5 * 60)
|
||||
},
|
||||
// activated() {
|
||||
// this.getLineList()
|
||||
// // this.handleProductLineChange(this.lineIds)
|
||||
// // .then(() => {
|
||||
// this.getWorksetionList()
|
||||
// // })
|
||||
// },
|
||||
deactivated() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval)
|
||||
this.interval = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 产线
|
||||
getLineList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/productionLine/list'),
|
||||
method: 'get'
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.lineList = data.data
|
||||
// console.log('产线数组', this.lineList)
|
||||
/** set default */
|
||||
if (this.lineList.length) {
|
||||
this.lineIds = [this.lineList[this.lineList.length - 1].id]
|
||||
}
|
||||
} else {
|
||||
this.lineList = []
|
||||
}
|
||||
// 这样可以出数据
|
||||
this.getDataList()
|
||||
})
|
||||
},
|
||||
handleOperations() {},
|
||||
handleDataTypeChange(value) {
|
||||
this.showGraph = value === dict[0] ? false : true
|
||||
},
|
||||
// 获取工序列表
|
||||
getWorksetionList() {
|
||||
// 分页列表才有根据产线过滤功能
|
||||
for (let i = 0; i < this.lineIds.length; i++) {
|
||||
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.lineIds[i]
|
||||
})
|
||||
}).then(({ data: res }) => {
|
||||
if (res && res.code === 0) {
|
||||
// this.wsList = res.data.list
|
||||
// ES6 解构 数组合并
|
||||
this.wsList = this.unique([...this.wsList, ...res.data.list])
|
||||
// console.log('this.wsList',this.wsList);
|
||||
/** select 默认选项set default */
|
||||
// if (this.wsList.length) {
|
||||
// this.sectionIds = this.wsList.map((item) => item.id)
|
||||
// // console.log('this.wsList',this.wsList)
|
||||
// } else {
|
||||
// this.sectionIds = null
|
||||
// }
|
||||
} else {
|
||||
this.wsList.splice(0)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
handleProductLineChange(val) {
|
||||
this.wsList = []
|
||||
this.getWorksetionList()
|
||||
},
|
||||
|
||||
getDataList() {
|
||||
// for (var z = 0; z < this.defaultOpts.series.length; z++) {
|
||||
// this.defaultOpts.series[z].data = []
|
||||
// }
|
||||
// this.echartCategories = []
|
||||
// 下面全部要初始化,清空数据
|
||||
// this.series = []
|
||||
this.dataList = []
|
||||
this.finalVal = []
|
||||
this.keys = []
|
||||
this.values = []
|
||||
this.count = 0
|
||||
this.showGraph = false
|
||||
this.dataType = i18n.t('table2')
|
||||
this.echartCategories = null
|
||||
this.echartCheckTypes.splice(0)
|
||||
/** 设置默认日期 */
|
||||
// const startTime = this.datetime[0] || moment().set({ hour: 0, minute: 0, second: 0 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// const endTime = this.datetime[1] || moment().set({ hour: 23, minute: 59, second: 59 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// console.log('this.datatime',this.datatime)
|
||||
// const startTime = this.datetime ? this.datetime + '-01T00:00:00' : null
|
||||
const startTime = this.datetime ? moment(this.datetime).format('YYYY-MM-DD') + 'T00:00:00' : null
|
||||
const endTime = this.datetime ? moment(this.datetime).format('YYYY-MM-DD') + 'T23:59:59' : null
|
||||
// const endTime = this.datetime ? this.getMonthSE(moment(this.datetime).format('YYYY-MM')) + 'T23:59:59' : null
|
||||
const condition = {
|
||||
startTime,
|
||||
endTime,
|
||||
// 加个判断防止为空时传参[]报错
|
||||
lineIds: this.lineIds.length == 0 ? null : this.lineIds,
|
||||
sectionIds: this.sectionIds.length == 0 ? null : this.sectionIds
|
||||
}
|
||||
/** 获取设备产量时序图数据 */
|
||||
// this.fetchList(startTime, endTime, lineIds).then(({ data: res }) => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/equProductAnalysis'),
|
||||
method: 'POST',
|
||||
data: condition
|
||||
}).then((res) => {
|
||||
if (res.code === 500) {
|
||||
this.dataList.splice(0)
|
||||
this.equipments = {} // 关闭 echarts 的显示
|
||||
this.$message.error(res.msg)
|
||||
} else {
|
||||
/** handle actual data */
|
||||
this.dataList = res.data.data
|
||||
// console.log('this.dataList', this.dataList)
|
||||
//遍历属性
|
||||
this.keys = Object.keys(this.dataList)
|
||||
// console.log('keys', this.keys)
|
||||
this.values = Object.values(this.dataList)
|
||||
for (let c = 0; c < this.values.length; c++) {
|
||||
this.finalVal.push(
|
||||
this.values[c].map((item) => {
|
||||
return item.outputNum
|
||||
})
|
||||
)
|
||||
}
|
||||
// console.log('values', this.values)
|
||||
// console.log('this.finalVal', this.finalVal)
|
||||
this.buildGraphData()
|
||||
/** test 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
|
||||
// }
|
||||
// ]
|
||||
|
||||
// this.equipments = this.transformDataToEquipments(this.dataList)
|
||||
// this.chartOption.setYAxis(Object.keys(this.equipments).map((eId) => this.equipments[eId].name))
|
||||
// console.log('(((set x axis))): ', this.dataList[0].startTime)
|
||||
// this.chartOption.setXAxis(this.dataList[0].startTime)
|
||||
// this.chartOption.setData(this.transformEquipmentsToSeries(this.equipments))
|
||||
|
||||
// this.$nextTick(() => {
|
||||
// this.renderChart()
|
||||
// })
|
||||
}
|
||||
})
|
||||
},
|
||||
setOptions(opts) {
|
||||
/** prop options */
|
||||
if (opts) {
|
||||
}
|
||||
|
||||
if (this.chart) this.chart.setOption(this.defaultOpts, true)
|
||||
},
|
||||
// 失效函数
|
||||
parseTableProps(nameData) {
|
||||
const subProps = []
|
||||
const labelNameMap = new Map()
|
||||
|
||||
// if (nameData.length) {
|
||||
// /** 处理 nameData */
|
||||
// nameData.forEach((item) => {
|
||||
// if (!labelNameMap.get(item.name)) {
|
||||
// labelNameMap.set(item.name, 1)
|
||||
// subProps.push({ name: item.name, prop: item.name })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
this.tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ name: i18n.t('pl.name'), prop: '0' },
|
||||
...Array.from(new Set(res.data.data[0].records.map((item) => moment(item.recordTime).format('MM-DD')))).map((name) => ({ prop: String(++this.count), name }))
|
||||
]
|
||||
/** echarts related */
|
||||
// this.echartCategories = subProps.map((item) => item.name)
|
||||
this.echartCategories = this.dataListDynamic.map((item) => item.name)
|
||||
},
|
||||
|
||||
// parseDynamicData(data) {
|
||||
// this.echartCheckTypes.splice(0)
|
||||
// return data.map((item) => {
|
||||
// /** echarts related */
|
||||
// this.echartCheckTypes.push(item.inspectionContent)
|
||||
// if (item.data.length) {
|
||||
// /** 解析子数组 */
|
||||
// item.data.forEach((subitem) => {
|
||||
// item[subitem.dynamicName] = subitem.dynamicValue
|
||||
// })
|
||||
// }
|
||||
// return item
|
||||
// })
|
||||
// },
|
||||
|
||||
buildGraphData() {
|
||||
/** 构造 echart 需要的数据 */
|
||||
// 动态添加series
|
||||
this.series = []
|
||||
// console.log('this.finalVal', this.finalVal)
|
||||
// console.log('this.keys', this.keys)
|
||||
for (let l = 0; l < this.finalVal.length; l++) {
|
||||
this.series.push({
|
||||
name: this.keys[l],
|
||||
type: 'line',
|
||||
// stack: '总量',
|
||||
data: this.finalVal[l]
|
||||
})
|
||||
}
|
||||
// console.log('第二部分的series', this.series)
|
||||
},
|
||||
|
||||
fetchList(startTime, endTime, lineIds) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/equProductAnalysis'),
|
||||
method: 'POST',
|
||||
data: {
|
||||
startTime,
|
||||
endTime,
|
||||
lineIds: this.lineIds
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 默认当前月
|
||||
* date 带月份的日期,例:2021-8
|
||||
* 返回月初至月末数组,例:[2021-8-1, 2021-8-31]
|
||||
*/
|
||||
getMonthSE(date) {
|
||||
let nowdays = date ? new Date(date) : new Date()
|
||||
let year = nowdays.getFullYear()
|
||||
let month = nowdays.getMonth() + 1
|
||||
|
||||
if (month < 10) {
|
||||
month = '0' + month
|
||||
}
|
||||
|
||||
let myDate = new Date(year, month, 0)
|
||||
|
||||
let startDate = year + '-' + month + '-01'
|
||||
let endDate = year + '-' + month + '-' + myDate.getDate()
|
||||
|
||||
// return [startDate, endDate]
|
||||
return endDate
|
||||
},
|
||||
// 数组转对象
|
||||
// toObject(pairs) {
|
||||
// return Array.from(pairs).reduce((acc, [key, value]) => Object.assign(acc, { [key]: value }), {})
|
||||
// },
|
||||
// 获取对话框里的设备列表
|
||||
getEqList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/equipment/page'),
|
||||
method: 'get',
|
||||
params: this.$http.adornParams({
|
||||
page: 1,
|
||||
limit: 99999
|
||||
})
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.dialogEqList = data.data.list
|
||||
} else {
|
||||
this.dialogEqList.splice(0)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 添加设备
|
||||
addEq() {
|
||||
// console.log('this.equipments',this.equipments);
|
||||
if (this.series) {
|
||||
this.dialogVisible = true
|
||||
} else {
|
||||
this.$message.warning(this.$t('pl.queryFirst'))
|
||||
}
|
||||
},
|
||||
|
||||
// 确认添加设备
|
||||
dialogConfirm() {
|
||||
let startTime = this.datetime ? moment(this.datetime).format('YYYY-MM-DD') + 'T00:00:00' : null
|
||||
let endTime = this.datetime ? moment(this.datetime).format('YYYY-MM-DD') + 'T23:59:59' : null
|
||||
const condition = {
|
||||
startTime,
|
||||
endTime,
|
||||
// productlines: [this.dataForm.productlines],
|
||||
// wsId: this.dataForm.wsId,
|
||||
equId: this.eqId
|
||||
}
|
||||
|
||||
/** fetch data */
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/equProductAnalysis'),
|
||||
method: 'post',
|
||||
data: condition
|
||||
}).then(({ data: res }) => {
|
||||
if (res.code === 500) {
|
||||
this.$message.error(res.msg)
|
||||
} else {
|
||||
// console.log('res',res)
|
||||
//遍历属性
|
||||
this.keys = [...Object.keys(res.data),...this.keys]
|
||||
// console.log('this.finalVal', this.finalVal)
|
||||
// console.log('keys', this.keys)
|
||||
this.values = Object.values(res.data)
|
||||
// console.log('values', this.values)
|
||||
for (let c = 0; c < this.values.length; c++) {
|
||||
this.values2.push(
|
||||
this.values[c].map((item) => {
|
||||
return item.outputNum
|
||||
})
|
||||
)
|
||||
}
|
||||
this.finalVal = [...this.values2,...this.finalVal]
|
||||
// console.log('this.finalVal', this.finalVal)
|
||||
this.$message.success(this.$t('pl.success'))
|
||||
this.$nextTick(() => {
|
||||
this.dialogVisible = false
|
||||
this.buildGraphData()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// 数组去重
|
||||
unique(arr) {
|
||||
return Array.from(new Set(arr))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.base-container {
|
||||
min-height: 60vh;
|
||||
background: #fff;
|
||||
padding: 12px;
|
||||
}
|
||||
.buttonColor {
|
||||
color: #fff;
|
||||
background: #0b58ff;
|
||||
}
|
||||
</style>
|
@ -130,7 +130,7 @@ export default {
|
||||
res.data[1].data &&
|
||||
res.data[1].data.length > 0
|
||||
) {
|
||||
// console.log(this.equipmentName)
|
||||
console.log('res.data[1]',res.data[1])
|
||||
this.setTableProps2(res.data[1].nameData)
|
||||
this.setTableData2(res.data[1].data)
|
||||
}
|
||||
|
695
src/views/modules/monitoring/productAnalysis.vue
Normal dosya
695
src/views/modules/monitoring/productAnalysis.vue
Normal dosya
@ -0,0 +1,695 @@
|
||||
<template>
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" @keyup.enter.native="getDataList()" class="blueTip" size="small">
|
||||
<el-form-item>
|
||||
{{ $t('pl.name') }}
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="lineIds" :placeholder="$t('pl.name')" clearable filterable multiple>
|
||||
<el-option v-for="line in lineList" :key="line.code" :value="line.id" :label="line.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
{{ $t('time') }}
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- type="datetimerange" -->
|
||||
<!-- <el-date-picker
|
||||
type="daterange"
|
||||
v-model="datetime"
|
||||
value-format="yyyy-MM-ddTHH:mm:ss"
|
||||
:start-placeholder="$t('startTime')"
|
||||
:end-placeholder="$t('endTime')"
|
||||
:range-separator="$t('to')"
|
||||
:default-time="['00:00:00', '23:59:59']"
|
||||
:picker-options="quickOptions"
|
||||
clearable /> -->
|
||||
<el-date-picker v-model="datetime" type="month" :placeholder="$t('hints.date')" format="yyyy-MM" value-format="yyyy-MM" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="buttonColor" @click="getDataList()">{{ $t('query') }}</el-button>
|
||||
<!-- <el-button v-if="$hasPermission('monitoring:qualityinspectionrecord:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="quality-inspection-current base-container">
|
||||
<!-- <el-row>
|
||||
<el-col>
|
||||
<small-title :size="'md'">{{ $t('inspect.ioTotal') }}</small-title>
|
||||
<el-row style="margin-top: 12px;">
|
||||
<base-table :data="dataListStatic" :table-head-configs="tableConfigStatic" :max-height="500" @operate-event="handleOperations" @refreshDataList="getDataList" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row> -->
|
||||
|
||||
<!-- style="margin-top: 28px;" -->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-row>
|
||||
<small-title :size="'md'">{{ $t('eq.productionAnalysis') }}</small-title>
|
||||
</el-row>
|
||||
<!-- <el-row style="margin-top: 8px">
|
||||
<el-radio-group v-model="dataType" size="medium" @change="handleDataTypeChange">
|
||||
<el-radio-button :label="$t('table2')"></el-radio-button>
|
||||
<el-radio-button :label="$t('graph')"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-row> -->
|
||||
<!-- style="margin-top: 12px" -->
|
||||
<el-row>
|
||||
<!-- v-if="!showGraph" -->
|
||||
<base-table
|
||||
:data="dataList"
|
||||
:table-head-configs="tableConfigDynamic"
|
||||
:max-height="500"
|
||||
@operate-event="handleOperations"
|
||||
@refreshDataList="getDataList" />
|
||||
</el-row>
|
||||
<!-- :series-data="echartsData" -->
|
||||
<!-- v-else -->
|
||||
<el-row style="margin-top: 8px">
|
||||
<fake-chart
|
||||
:categories="echartCategories"
|
||||
:type-list="echartCheckTypes"
|
||||
:series-data1="echartsData1"
|
||||
:series-data2="echartsData2"
|
||||
:series-data3="echartsData3"
|
||||
:series-data4="echartsData4" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
import { timeFilter } from '@/utils/filters'
|
||||
import moment from 'moment'
|
||||
import i18n from '@/i18n'
|
||||
import BaseTable from '@/components/base-table'
|
||||
import SmallTitle from '@/components/small-title'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
// const tableConfigStatic = [
|
||||
// { type: 'index', width: 100, name: i18n.t('index') },
|
||||
// { name: i18n.t('pl.title'), prop: 'lineName' },
|
||||
// { name: i18n.t('inspect.inTotal'), prop: 'sumUp' },
|
||||
// { name: i18n.t('inspect.outTotal'), prop: 'sumDown' },
|
||||
// { name: i18n.t('inspect.checkTotal'), prop: 'sumCheck' },
|
||||
// { name: i18n.t('inspect.rate'), prop: 'scrapRatio', filter: (val) => (val || val === 0 ? `${val}%` : '-') }
|
||||
// ]
|
||||
const tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ name: i18n.t('pl.name'), prop: '0' }
|
||||
]
|
||||
|
||||
const FakeChart = {
|
||||
name: 'FakeChart',
|
||||
props: {
|
||||
categories: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
typeList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
seriesData1: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
seriesData2: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
seriesData3: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
seriesData4: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
calcMaxHeight,
|
||||
chart: null,
|
||||
// 新加
|
||||
echartsData1: [],
|
||||
echartsData2: [],
|
||||
echartsData3: [],
|
||||
echartsData4: [],
|
||||
pass: [],
|
||||
defaultOpts: {
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '12%',
|
||||
top: '20%',
|
||||
bottom: '10%'
|
||||
},
|
||||
title: {
|
||||
text: i18n.t('eq.productQuantity')
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis', //坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用
|
||||
axisPointer: {
|
||||
// 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
type: 'scroll',
|
||||
top: 10,
|
||||
right: 0,
|
||||
width: '12%',
|
||||
/** 修复文本太长时显示问题 */
|
||||
// formatter: function (name) {
|
||||
// return echarts.format.truncateText(name, 120, '14px Microsoft Yahei', '...')
|
||||
// },
|
||||
tooltip: {
|
||||
show: true
|
||||
},
|
||||
/** end */
|
||||
data: [this.$t('eq.line1'), this.$t('eq.line2'), this.$t('eq.line3'), this.$t('eq.line4')]
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
// axisLine: {
|
||||
// show: true,
|
||||
// lineStyle: {
|
||||
// color: 'rgba(219,225,255,1)',
|
||||
// width: 1,
|
||||
// type: 'solid'
|
||||
// }
|
||||
// },
|
||||
axisLabel: {
|
||||
//设置x轴的字
|
||||
show: true,
|
||||
rotate: 0,
|
||||
interval: 0 //使x轴横坐标全部显示
|
||||
// textStyle: {
|
||||
// //x轴字体样式
|
||||
// color: 'rgba(219,225,255,1)',
|
||||
// margin: 15
|
||||
// }
|
||||
}
|
||||
|
||||
// data: ['下片1', '上片1', '磨边机1', '设备13', '钢化炉2', '磨边机2', '设备15', '清洗机1', '钢化炉3']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
// dynamic
|
||||
{
|
||||
name: this.$t('eq.line1'),
|
||||
type: 'line',
|
||||
data: [],
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'top'
|
||||
},
|
||||
formatter: '{@value}'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.$t('eq.line2'),
|
||||
type: 'line',
|
||||
data: [],
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'top'
|
||||
},
|
||||
formatter: '{@value}'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.$t('eq.line3'),
|
||||
type: 'line',
|
||||
data: [],
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'top'
|
||||
},
|
||||
formatter: '{@value}'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.$t('eq.line4'),
|
||||
type: 'line',
|
||||
data: [],
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'top'
|
||||
},
|
||||
formatter: '{@value}'
|
||||
}
|
||||
}
|
||||
// {
|
||||
// data: [120, 200, 150, 80, 70, 110, 130],
|
||||
// type: 'bar'
|
||||
// }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
categories: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
// this.defaultOpts.xAxis.data.push(...val)
|
||||
this.defaultOpts.xAxis.data = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
typeList: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.legend.data.push(...val)
|
||||
// this.defaultOpts.legend.data = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
seriesData1: {
|
||||
// this.defaultOpts.series[0].data.push 会循环增加横坐标和数据,改成 =
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
// this.defaultOpts.series[0].data.push(...val)
|
||||
this.defaultOpts.series[0].data = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
seriesData2: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
// this.defaultOpts.series[1].data.push(...val)
|
||||
this.defaultOpts.series[1].data = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
seriesData3: {
|
||||
// this.defaultOpts.series[0].data.push 注意
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
// this.defaultOpts.series[2].data.push(...val)
|
||||
this.defaultOpts.series[2].data = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
seriesData4: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
// this.defaultOpts.series[3].data.push(...val)
|
||||
this.defaultOpts.series[3].data = val
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
defaultOpts: {
|
||||
handler: function (val) {
|
||||
// console.log('defaullt opts change: ', val)
|
||||
this.setOptions()
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
// console.log('echarts data1: ', this.echartsData1)
|
||||
// console.log('echarts data2: ', this.echartsData2)
|
||||
// console.log('echarts data3: ', this.echartsData3)
|
||||
// console.log('echarts data4: ', this.echartsData4)
|
||||
this.initChart()
|
||||
// console.log('this.defaultOpts.xAxis.data', this.defaultOpts.xAxis.data)
|
||||
this.setOptions()
|
||||
window.addEventListener('resize', () => {
|
||||
//监听浏览器窗口大小
|
||||
this.chart.resize()
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
if (!this.chart) {
|
||||
this.chart = echarts.init(document.getElementById('bar-chart'))
|
||||
this.chart.resize()
|
||||
}
|
||||
},
|
||||
setOptions(opts) {
|
||||
/** prop options */
|
||||
if (opts) {
|
||||
}
|
||||
|
||||
if (this.chart) this.chart.setOption(this.defaultOpts, true)
|
||||
}
|
||||
},
|
||||
render: function (h) {
|
||||
return h('div', { attrs: { id: 'bar-chart' }, style: { background: '#eee', width: '100%', height: '300px', padding: '8px' } }, '')
|
||||
}
|
||||
}
|
||||
|
||||
const dict = [i18n.t('table2'), i18n.t('graph')]
|
||||
export default {
|
||||
name: 'QualityInspectionCurrent',
|
||||
components: { BaseTable, SmallTitle, FakeChart },
|
||||
data() {
|
||||
return {
|
||||
echartsData1: [],
|
||||
echartsData2: [],
|
||||
echartsData3: [],
|
||||
echartsData4: [],
|
||||
count: 0,
|
||||
lineIds: [],
|
||||
lineList: [],
|
||||
// tableConfigStatic,
|
||||
tableConfigDynamic,
|
||||
datetime: new Date(),
|
||||
dataListStatic: [],
|
||||
dataListDynamic: [],
|
||||
dataList: [],
|
||||
dict,
|
||||
dataType: dict[0], // 表格 | 图形
|
||||
showGraph: false,
|
||||
// quickOptions: {
|
||||
// shortcuts: [
|
||||
// {
|
||||
// text: i18n.t('today'),
|
||||
// onClick(picker) {
|
||||
// const baseTime = moment().set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
|
||||
// const startTime = baseTime.format('yyyy-MM-DDTHH:mm:ss')
|
||||
// const endTime = baseTime.set({ hour: 23, minute: 59, second: 59, millisecond: 999 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// picker.$emit('pick', [startTime, endTime])
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
echartCategories: null,
|
||||
echartCheckTypes: [],
|
||||
interval: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getLineList()
|
||||
// this.getDataList()
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
this.$message.info(i18n.t('refresh'))
|
||||
// this.dataListStatic.splice(0)
|
||||
this.dataListDynamic.splice(0)
|
||||
this.getDataList()
|
||||
}, 1000 * 5 * 60)
|
||||
},
|
||||
deactivated() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval)
|
||||
this.interval = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 产线
|
||||
getLineList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/productionLine/list'),
|
||||
method: 'get'
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.lineList = data.data
|
||||
// console.log('产线数组', this.lineList)
|
||||
/** set default */
|
||||
if (this.lineList.length) {
|
||||
this.lineIds = [this.lineList[this.lineList.length - 1].id]
|
||||
}
|
||||
} else {
|
||||
this.lineList = []
|
||||
}
|
||||
// 这样可以出数据
|
||||
this.getDataList()
|
||||
})
|
||||
},
|
||||
handleOperations() {},
|
||||
handleDataTypeChange(value) {
|
||||
this.showGraph = value === dict[0] ? false : true
|
||||
},
|
||||
getDataList() {
|
||||
// for (var z = 0; z < this.defaultOpts.series.length; z++) {
|
||||
// this.defaultOpts.series[z].data = []
|
||||
// }
|
||||
// this.echartCategories = []
|
||||
// 下面全部要初始化,清空数据
|
||||
this.echartsData1 = []
|
||||
this.echartsData2 = []
|
||||
this.echartsData3 = []
|
||||
this.echartsData4 = []
|
||||
this.dataListDynamic = []
|
||||
this.dataList = []
|
||||
this.count = 0
|
||||
this.showGraph = false
|
||||
this.dataType = i18n.t('table2')
|
||||
this.echartCategories = null
|
||||
this.echartCheckTypes.splice(0)
|
||||
/** 设置默认日期 */
|
||||
// const startTime = this.datetime[0] || moment().set({ hour: 0, minute: 0, second: 0 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// const endTime = this.datetime[1] || moment().set({ hour: 23, minute: 59, second: 59 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// console.log('this.datatime',this.datatime)
|
||||
// const startTime = this.datetime ? this.datetime + '-01T00:00:00' : null
|
||||
const startTime = this.datetime ? moment(this.datetime).format('YYYY-MM') + '-01T00:00:00' : null
|
||||
// const endTime = this.datetime ? moment(this.datetime).format('YYYY-MM-DD') + 'T23:59:59' : null
|
||||
const endTime = this.datetime ? this.getMonthSE(moment(this.datetime).format('YYYY-MM')) + 'T23:59:59' : null
|
||||
|
||||
/** 获取产品质量分析数据 */
|
||||
// this.fetchList(startTime, endTime, lineIds).then(({ data: res }) => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/productAnalysis'),
|
||||
method: 'POST',
|
||||
data: {
|
||||
startTime,
|
||||
endTime,
|
||||
// 加个判断防止为空时传参[]报错
|
||||
lineIds: this.lineIds.length == 0 ? null : this.lineIds
|
||||
// lineIds: this.lineIds.length == 0 ? ["1"] : this.lineIds
|
||||
}
|
||||
})
|
||||
.then((res) => {
|
||||
// console.log('res: ', res)
|
||||
/** TODO: 解析 nameData */
|
||||
// 新加
|
||||
this.tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ name: i18n.t('pl.name'), prop: '0' },
|
||||
...Array.from(new Set(res.data.data[0].records.map((item) => moment(item.recordTime).format('MM-DD')))).map((name) => ({ prop: String(++this.count), name }))
|
||||
/**
|
||||
这一行无敌的,记一下:
|
||||
1. '...'是扩展运算符,是ES6的语法,用于取出参数对象的所有可遍历属性,然后拷贝到当前对象之中。例如
|
||||
let foo = { ...['a', 'b', 'c'] };
|
||||
foo
|
||||
// {0: "a", 1: "b", 2: "c"}
|
||||
2.Array.from(new Set())是JS的数组去重
|
||||
3.map() 方法定义在JavaScript的Array中,它返回一个新的数组,数组中的元素为原始数组调用函数处理后的值。
|
||||
4.moment(time).format()时间格式化
|
||||
5.String(),因为prop只能接收String,需要把数字转化
|
||||
6.++this.count是定义了个从0开始自增的常量count,用来标注一个月每天的下标,this.count++会从每个月2号开始,因此是 ++this.count
|
||||
7.要在getDataList() 中
|
||||
this.dataList = []
|
||||
this.count = 0
|
||||
初始化一下,否则连续按按钮会空
|
||||
*/
|
||||
]
|
||||
// console.log('this.tableConfigDynamic', this.tableConfigDynamic)
|
||||
|
||||
// this.dataListDynamic = this.parseDynamicData(res.data.data) || []
|
||||
for (let i = 0; i < res.data.data.length; i++) {
|
||||
this.dataListDynamic[i] = res.data.data[i].records.map((item) => item.outputNum) || []
|
||||
this.dataListDynamic[i].unshift(res.data.data[i].records[i].lineName)
|
||||
var json = {}
|
||||
for (var j = 0; j < this.dataListDynamic[i].length; j++) {
|
||||
json[j] = this.dataListDynamic[i][j]
|
||||
}
|
||||
this.dataList.push(json)
|
||||
// this.dataListDynamic[i] =JSON.stringify(this.dataListDynamic[i])
|
||||
}
|
||||
/** echarts related */
|
||||
// this.echartCategories = subProps.map((item) => item.name)
|
||||
// console.log('res.data.data[0].records.map((item) => moment(item.recordTime)',res.data.data[0].records.map((item) => moment(item.recordTime).format('MM-DD')));
|
||||
// 创建横坐标
|
||||
this.echartCategories = res.data.data[0].records.map((item) => moment(item.recordTime).format('MM-DD'))
|
||||
// this.parseTableProps(res.data.nameData)
|
||||
|
||||
// console.log('this.echartCategories', this.echartCategories)
|
||||
// console.log('this.dataListDynamic', this.dataListDynamic)
|
||||
// console.log('this.dataList', this.dataList)
|
||||
|
||||
this.buildGraphData()
|
||||
})
|
||||
.catch((err) => {
|
||||
// 忽略掉0报错
|
||||
// console.error(err)
|
||||
})
|
||||
},
|
||||
setOptions(opts) {
|
||||
/** prop options */
|
||||
if (opts) {
|
||||
}
|
||||
|
||||
if (this.chart) this.chart.setOption(this.defaultOpts, true)
|
||||
},
|
||||
// 失效函数
|
||||
parseTableProps(nameData) {
|
||||
const subProps = []
|
||||
const labelNameMap = new Map()
|
||||
|
||||
// if (nameData.length) {
|
||||
// /** 处理 nameData */
|
||||
// nameData.forEach((item) => {
|
||||
// if (!labelNameMap.get(item.name)) {
|
||||
// labelNameMap.set(item.name, 1)
|
||||
// subProps.push({ name: item.name, prop: item.name })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
this.tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ name: i18n.t('pl.name'), prop: '0' },
|
||||
...Array.from(new Set(res.data.data[0].records.map((item) => moment(item.recordTime).format('MM-DD')))).map((name) => ({ prop: String(++this.count), name }))
|
||||
]
|
||||
/** echarts related */
|
||||
// this.echartCategories = subProps.map((item) => item.name)
|
||||
this.echartCategories = this.dataListDynamic.map((item) => item.name)
|
||||
},
|
||||
|
||||
// parseDynamicData(data) {
|
||||
// this.echartCheckTypes.splice(0)
|
||||
// return data.map((item) => {
|
||||
// /** echarts related */
|
||||
// this.echartCheckTypes.push(item.inspectionContent)
|
||||
// if (item.data.length) {
|
||||
// /** 解析子数组 */
|
||||
// item.data.forEach((subitem) => {
|
||||
// item[subitem.dynamicName] = subitem.dynamicValue
|
||||
// })
|
||||
// }
|
||||
// return item
|
||||
// })
|
||||
// },
|
||||
|
||||
buildGraphData() {
|
||||
/** 构造 echart 需要的数据 */
|
||||
const result = []
|
||||
|
||||
// this.echartCheckTypes.forEach((ect) => {
|
||||
// result.push({ name: ect, type: 'bar', data: [] })
|
||||
// })
|
||||
// console.log('echartCheckTypes', this.echartCheckTypes)
|
||||
// console.log('this.echartCategories', this.echartCategories)
|
||||
// console.log('this.dataListDynamic', this.dataListDynamic)
|
||||
// this.dataListDynamic.forEach((inspection, index) => {
|
||||
// // console.log('inspection: ', inspection)
|
||||
// this.echartCategories.forEach((cate) => {
|
||||
// if (cate in inspection) {
|
||||
// result[index].data.push(inspection[cate])
|
||||
// } else {
|
||||
// result[index].data.push('0')
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
// this.dataListDynamic[0].shift()
|
||||
// this.dataListDynamic[1].shift()
|
||||
// this.dataListDynamic[2].shift()
|
||||
// this.dataListDynamic[3].shift()
|
||||
for (var key = 0; key < this.dataListDynamic.length; key++) {
|
||||
if (this.dataListDynamic[key][0].indexOf('1') != -1) {
|
||||
this.echartsData1 = this.dataListDynamic[key]
|
||||
} else if (this.dataListDynamic[key][0].indexOf('2') != -1) {
|
||||
this.echartsData2 = this.dataListDynamic[key]
|
||||
} else if (this.dataListDynamic[key][0].indexOf('3') != -1) {
|
||||
this.echartsData3 = this.dataListDynamic[key]
|
||||
} else if (this.dataListDynamic[key][0].indexOf('4') != -1) {
|
||||
this.echartsData4 = this.dataListDynamic[key]
|
||||
}
|
||||
}
|
||||
// this.echartsData1 = this.dataListDynamic[0]
|
||||
// this.echartsData2 = this.dataListDynamic[1]
|
||||
// this.echartsData3 = this.dataListDynamic[2]
|
||||
// this.echartsData4 = this.dataListDynamic[3]
|
||||
// 不抛出老是报shift错误
|
||||
try {
|
||||
this.echartsData1.shift()
|
||||
this.echartsData2.shift()
|
||||
this.echartsData3.shift()
|
||||
this.echartsData4.shift()
|
||||
} catch (error) {}
|
||||
// this.echartsData = result
|
||||
// console.log('this.echartsData1', this.echartsData1)
|
||||
// [
|
||||
// { name: '11', type: 'bar', data: [/**产线1*/ 2, /**产线2*/ 3] },
|
||||
// { name: '222', type: 'bar', data: [1, 2, 3] }
|
||||
// ]
|
||||
},
|
||||
|
||||
fetchList(startTime, endTime, lineIds) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/productQualityAnalysis'),
|
||||
method: 'POST',
|
||||
data: {
|
||||
startTime,
|
||||
endTime,
|
||||
lineIds: this.lineIds
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 默认当前月
|
||||
* date 带月份的日期,例:2021-8
|
||||
* 返回月初至月末数组,例:[2021-8-1, 2021-8-31]
|
||||
*/
|
||||
getMonthSE(date) {
|
||||
let nowdays = date ? new Date(date) : new Date()
|
||||
let year = nowdays.getFullYear()
|
||||
let month = nowdays.getMonth() + 1
|
||||
|
||||
if (month < 10) {
|
||||
month = '0' + month
|
||||
}
|
||||
|
||||
let myDate = new Date(year, month, 0)
|
||||
|
||||
let startDate = year + '-' + month + '-01'
|
||||
let endDate = year + '-' + month + '-' + myDate.getDate()
|
||||
|
||||
// return [startDate, endDate]
|
||||
return endDate
|
||||
}
|
||||
// 数组转对象
|
||||
// toObject(pairs) {
|
||||
// return Array.from(pairs).reduce((acc, [key, value]) => Object.assign(acc, { [key]: value }), {})
|
||||
// }
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.base-container {
|
||||
min-height: 60vh;
|
||||
background: #fff;
|
||||
padding: 12px;
|
||||
}
|
||||
.buttonColor {
|
||||
color: #fff;
|
||||
background: #0b58ff;
|
||||
}
|
||||
</style>
|
557
src/views/modules/monitoring/productQuality.vue
Normal dosya
557
src/views/modules/monitoring/productQuality.vue
Normal dosya
@ -0,0 +1,557 @@
|
||||
<template>
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" @keyup.enter.native="getDataList()" class="blueTip" size="small">
|
||||
<el-form-item>
|
||||
{{ $t('pl.name') }}
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="lineIds" :placeholder="$t('pl.name')" clearable filterable multiple>
|
||||
<el-option v-for="line in lineList" :key="line.code" :value="line.id" :label="line.name" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
{{ $t('time') }}
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- type="datetimerange" -->
|
||||
<!-- <el-date-picker
|
||||
type="daterange"
|
||||
v-model="datetime"
|
||||
value-format="yyyy-MM-ddTHH:mm:ss"
|
||||
:start-placeholder="$t('startTime')"
|
||||
:end-placeholder="$t('endTime')"
|
||||
:range-separator="$t('to')"
|
||||
:default-time="['00:00:00', '23:59:59']"
|
||||
:picker-options="quickOptions"
|
||||
clearable /> -->
|
||||
<el-date-picker v-model="datetime" type="date" :placeholder="$t('hints.date')" format="yyyy-MM-dd" value-format="yyyy-MM-dd" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="buttonColor" @click="getDataList()">{{ $t('query') }}</el-button>
|
||||
<!-- <el-button v-if="$hasPermission('monitoring:qualityinspectionrecord:save')" type="primary" @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> -->
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="quality-inspection-current base-container">
|
||||
<!-- <el-row>
|
||||
<el-col>
|
||||
<small-title :size="'md'">{{ $t('inspect.ioTotal') }}</small-title>
|
||||
<el-row style="margin-top: 12px;">
|
||||
<base-table :data="dataListStatic" :table-head-configs="tableConfigStatic" :max-height="500" @operate-event="handleOperations" @refreshDataList="getDataList" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row> -->
|
||||
|
||||
<!-- style="margin-top: 28px;" -->
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-row>
|
||||
<small-title :size="'md'">{{ $t('eq.productQuality') }}</small-title>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 8px">
|
||||
<el-radio-group v-model="dataType" size="medium" @change="handleDataTypeChange">
|
||||
<el-radio-button :label="$t('table2')"></el-radio-button>
|
||||
<el-radio-button :label="$t('graph')"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 12px">
|
||||
<base-table
|
||||
v-if="!showGraph"
|
||||
:data="dataListDynamic"
|
||||
:table-head-configs="tableConfigDynamic"
|
||||
:max-height="500"
|
||||
@operate-event="handleOperations"
|
||||
@refreshDataList="getDataList" />
|
||||
<!-- :series-data="echartsData" -->
|
||||
<fake-chart v-else :categories="echartCategories" :type-list="echartCheckTypes" :series-data1="echartsData1" :series-data2="echartsData2" :pass-rate="pass" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { calcMaxHeight } from '@/utils'
|
||||
import { timeFilter } from '@/utils/filters'
|
||||
import moment from 'moment'
|
||||
import i18n from '@/i18n'
|
||||
import BaseTable from '@/components/base-table'
|
||||
import SmallTitle from '@/components/small-title'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
// const tableConfigStatic = [
|
||||
// { type: 'index', width: 100, name: i18n.t('index') },
|
||||
// { name: i18n.t('pl.title'), prop: 'lineName' },
|
||||
// { name: i18n.t('inspect.inTotal'), prop: 'sumUp' },
|
||||
// { name: i18n.t('inspect.outTotal'), prop: 'sumDown' },
|
||||
// { name: i18n.t('inspect.checkTotal'), prop: 'sumCheck' },
|
||||
// { name: i18n.t('inspect.rate'), prop: 'scrapRatio', filter: (val) => (val || val === 0 ? `${val}%` : '-') }
|
||||
// ]
|
||||
const tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ name: i18n.t('eq.sectionName'), prop: 'sectionName' },
|
||||
// ...subProps,
|
||||
{ name: i18n.t('eq.equipmentName'), prop: 'equipmentName' },
|
||||
{ name: i18n.t('eq.okNum'), prop: 'okNum' },
|
||||
{ name: i18n.t('eq.nokNum'), prop: 'nokNum' },
|
||||
{ name: i18n.t('eq.passRate'), prop: 'passRate', filter: (val) => (val || val === 0 ? `${val}%` : '-') }
|
||||
]
|
||||
|
||||
const FakeChart = {
|
||||
name: 'FakeChart',
|
||||
props: {
|
||||
categories: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
typeList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
seriesData1: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
seriesData2: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
passRate: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
calcMaxHeight,
|
||||
chart: null,
|
||||
// 新加
|
||||
echartsData1: [],
|
||||
echartsData2: [],
|
||||
pass: [],
|
||||
defaultOpts: {
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '12%',
|
||||
top: '20%',
|
||||
bottom: '10%'
|
||||
},
|
||||
title: {
|
||||
text: i18n.t('eq.productQuality')
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis', //坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用
|
||||
axisPointer: {
|
||||
// 坐标轴指示器,坐标轴触发有效
|
||||
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
type: 'scroll',
|
||||
top: 10,
|
||||
right: 0,
|
||||
width: '12%',
|
||||
/** 修复文本太长时显示问题 */
|
||||
// formatter: function (name) {
|
||||
// return echarts.format.truncateText(name, 120, '14px Microsoft Yahei', '...')
|
||||
// },
|
||||
tooltip: {
|
||||
show: true
|
||||
},
|
||||
/** end */
|
||||
data: [i18n.t('eq.okNum'), i18n.t('eq.nokNum'), i18n.t('eq.passRatePercent')]
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
// axisLine: {
|
||||
// show: true,
|
||||
// lineStyle: {
|
||||
// color: 'rgba(219,225,255,1)',
|
||||
// width: 1,
|
||||
// type: 'solid'
|
||||
// }
|
||||
// },
|
||||
axisLabel: {
|
||||
//设置x轴的字
|
||||
show: true,
|
||||
interval: 0 //使x轴横坐标全部显示
|
||||
// textStyle: {
|
||||
// //x轴字体样式
|
||||
// color: 'rgba(219,225,255,1)',
|
||||
// margin: 15
|
||||
// }
|
||||
}
|
||||
|
||||
// data: ['下片1', '上片1', '磨边机1', '设备13', '钢化炉2', '磨边机2', '设备15', '清洗机1', '钢化炉3']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
// dynamic
|
||||
{
|
||||
name: i18n.t('eq.okNum'),
|
||||
type: 'line',
|
||||
data: [],
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'top'
|
||||
},
|
||||
formatter: '{@value}'
|
||||
}
|
||||
// data: ['314', '1813', '136', '2202', '9895', '0', '411', '0', '2050']
|
||||
},
|
||||
{
|
||||
name: i18n.t('eq.nokNum'),
|
||||
type: 'line',
|
||||
data: [],
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'top'
|
||||
},
|
||||
formatter: '{@value}'
|
||||
}
|
||||
// data: ['62', '39', '21', '23', '40', '0', '3', '0', '4']
|
||||
},
|
||||
{
|
||||
name: i18n.t('eq.passRatePercent'),
|
||||
type: 'line',
|
||||
data: [],
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'top'
|
||||
},
|
||||
formatter: '{@value}'
|
||||
}
|
||||
// data: ['62', '39', '21', '23', '40', '0', '3', '0', '4']
|
||||
}
|
||||
// {
|
||||
// data: [120, 200, 150, 80, 70, 110, 130],
|
||||
// type: 'bar'
|
||||
// }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
categories: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.xAxis.data.push(...val)
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
typeList: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.legend.data.push(...val)
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
seriesData1: {
|
||||
// this.defaultOpts.series[0].data.push 注意
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.series[0].data.push(...val)
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
seriesData2: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.series[1].data.push(...val)
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
passRate: {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.series[2].data.push(...val)
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
defaultOpts: {
|
||||
handler: function (val) {
|
||||
// console.log('defaullt opts change: ', val)
|
||||
this.setOptions()
|
||||
},
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
// console.log('echarts data1: ', this.echartsData1)
|
||||
// console.log('echarts data2: ', this.echartsData2)
|
||||
// console.log('passRate', this.pass)
|
||||
this.initChart()
|
||||
// console.log('this.defaultOpts.xAxis.data', this.defaultOpts.xAxis.data)
|
||||
this.setOptions()
|
||||
window.addEventListener('resize', () => {
|
||||
//监听浏览器窗口大小
|
||||
this.chart.resize()
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
if (!this.chart) {
|
||||
this.chart = echarts.init(document.getElementById('bar-chart'))
|
||||
}
|
||||
},
|
||||
setOptions(opts) {
|
||||
/** prop options */
|
||||
if (opts) {
|
||||
}
|
||||
|
||||
if (this.chart) this.chart.setOption(this.defaultOpts)
|
||||
}
|
||||
},
|
||||
render: function (h) {
|
||||
return h('div', { attrs: { id: 'bar-chart' }, style: { background: '#eee', width: '100%', height: '300px', padding: '8px' } }, '')
|
||||
}
|
||||
}
|
||||
|
||||
const dict = [i18n.t('table2'), i18n.t('graph')]
|
||||
export default {
|
||||
name: 'QualityInspectionCurrent',
|
||||
components: { BaseTable, SmallTitle, FakeChart },
|
||||
data() {
|
||||
return {
|
||||
lineIds: [],
|
||||
lineList: [],
|
||||
// tableConfigStatic,
|
||||
tableConfigDynamic,
|
||||
dataListStatic: [],
|
||||
dataListDynamic: [],
|
||||
dict,
|
||||
dataType: dict[0], // 表格 | 图形
|
||||
showGraph: false,
|
||||
// datetime: [],
|
||||
datetime: new Date(),
|
||||
// quickOptions: {
|
||||
// shortcuts: [
|
||||
// {
|
||||
// text: i18n.t('today'),
|
||||
// onClick(picker) {
|
||||
// const baseTime = moment().set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
|
||||
// const startTime = baseTime.format('yyyy-MM-DDTHH:mm:ss')
|
||||
// const endTime = baseTime.set({ hour: 23, minute: 59, second: 59, millisecond: 999 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// picker.$emit('pick', [startTime, endTime])
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
echartCategories: null,
|
||||
echartCheckTypes: [],
|
||||
interval: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getLineList()
|
||||
this.getDataList()
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
this.$message.info(i18n.t('refresh'))
|
||||
// this.dataListStatic.splice(0)
|
||||
this.dataListDynamic.splice(0)
|
||||
this.getDataList()
|
||||
}, 1000 * 5 * 60)
|
||||
},
|
||||
deactivated() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval)
|
||||
this.interval = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 产线
|
||||
getLineList() {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/productionLine/list'),
|
||||
method: 'get'
|
||||
}).then(({ data }) => {
|
||||
if (data && data.code === 0) {
|
||||
this.lineList = data.data
|
||||
// console.log('产线数组',this.lineList);
|
||||
} else {
|
||||
this.lineList = []
|
||||
}
|
||||
})
|
||||
},
|
||||
handleOperations() {},
|
||||
handleDataTypeChange(value) {
|
||||
this.showGraph = value === dict[0] ? false : true
|
||||
},
|
||||
getDataList() {
|
||||
this.showGraph = false
|
||||
this.dataType = i18n.t('table2')
|
||||
this.echartCategories = null
|
||||
this.echartCheckTypes.splice(0)
|
||||
/** 设置默认日期 */
|
||||
// const startTime = this.datetime[0] || moment().set({ hour: 0, minute: 0, second: 0 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// const endTime = this.datetime[1] || moment().set({ hour: 23, minute: 59, second: 59 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
// console.log('this.datatime',this.datatime)
|
||||
// const startTime = this.datetime ? this.datetime + 'T00:00:00' : null
|
||||
const startTime = this.datetime ? moment(this.datetime).format('YYYY-MM-DD') + 'T00:00:00' : null
|
||||
// const endTime = this.datetime ? this.datetime + 'T23:59:59' : null
|
||||
const endTime = this.datetime ? moment(this.datetime).format('YYYY-MM-DD') + 'T23:59:59' : null
|
||||
const lineIds = this.lineIds
|
||||
|
||||
/** 获取产品质量分析数据 */
|
||||
// this.fetchList(startTime, endTime, lineIds).then(({ data: res }) => {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/productQualityAnalysis'),
|
||||
method: 'POST',
|
||||
data: {
|
||||
startTime,
|
||||
endTime,
|
||||
lineIds: this.lineIds.length == 0 ? null : this.lineIds
|
||||
}
|
||||
})
|
||||
.then((res) => {
|
||||
// console.log('res: ', res)
|
||||
/** TODO: 解析 nameData */
|
||||
// 新加
|
||||
this.tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ name: i18n.t('eq.sectionName'), prop: 'sectionName' },
|
||||
// ...subProps,
|
||||
{ name: i18n.t('eq.equipmentName'), prop: 'equipmentName' },
|
||||
{ name: i18n.t('eq.okNum'), prop: 'okNum' },
|
||||
{ name: i18n.t('eq.nokNum'), prop: 'nokNum' },
|
||||
{ name: i18n.t('eq.passRate'), prop: 'passRate', filter: (val) => (val || val === 0 ? `${val}%` : '-') }
|
||||
]
|
||||
|
||||
// this.dataListDynamic = this.parseDynamicData(res.data.data) || []
|
||||
this.dataListDynamic = res.data.data || []
|
||||
|
||||
/** echarts related */
|
||||
// this.echartCategories = subProps.map((item) => item.name)
|
||||
this.echartCategories = this.dataListDynamic.map((item) => {
|
||||
return item.equipmentName
|
||||
})
|
||||
// this.parseTableProps(res.data.nameData)
|
||||
|
||||
// console.log('this.dataListDynamic', this.dataListDynamic)
|
||||
|
||||
this.buildGraphData()
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
},
|
||||
|
||||
parseTableProps(nameData) {
|
||||
const subProps = []
|
||||
const labelNameMap = new Map()
|
||||
|
||||
// if (nameData.length) {
|
||||
// /** 处理 nameData */
|
||||
// nameData.forEach((item) => {
|
||||
// if (!labelNameMap.get(item.name)) {
|
||||
// labelNameMap.set(item.name, 1)
|
||||
// subProps.push({ name: item.name, prop: item.name })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
this.tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
{ name: i18n.t('eq.sectionName'), prop: 'sectionName' },
|
||||
// ...subProps,
|
||||
{ name: i18n.t('eq.equipmentName'), prop: 'equipmentName' },
|
||||
{ name: i18n.t('eq.okNum'), prop: 'okNum' },
|
||||
{ name: i18n.t('eq.nokNum'), prop: 'nokNum' },
|
||||
{ name: i18n.t('eq.passRate'), prop: 'passRate', filter: (val) => (val || val === 0 ? `${val}%` : '-') }
|
||||
]
|
||||
|
||||
/** echarts related */
|
||||
// this.echartCategories = subProps.map((item) => item.name)
|
||||
this.echartCategories = this.dataListDynamic.map((item) => item.name)
|
||||
},
|
||||
|
||||
// parseDynamicData(data) {
|
||||
// this.echartCheckTypes.splice(0)
|
||||
// return data.map((item) => {
|
||||
// /** echarts related */
|
||||
// this.echartCheckTypes.push(item.inspectionContent)
|
||||
// if (item.data.length) {
|
||||
// /** 解析子数组 */
|
||||
// item.data.forEach((subitem) => {
|
||||
// item[subitem.dynamicName] = subitem.dynamicValue
|
||||
// })
|
||||
// }
|
||||
// return item
|
||||
// })
|
||||
// },
|
||||
|
||||
buildGraphData() {
|
||||
/** 构造 echart 需要的数据 */
|
||||
const result = []
|
||||
|
||||
// this.echartCheckTypes.forEach((ect) => {
|
||||
// result.push({ name: ect, type: 'bar', data: [] })
|
||||
// })
|
||||
// console.log('echartCheckTypes', this.echartCheckTypes)
|
||||
// console.log('this.echartCategories', this.echartCategories)
|
||||
// this.dataListDynamic.forEach((inspection, index) => {
|
||||
// // console.log('inspection: ', inspection)
|
||||
// this.echartCategories.forEach((cate) => {
|
||||
// if (cate in inspection) {
|
||||
// result[index].data.push(inspection[cate])
|
||||
// } else {
|
||||
// result[index].data.push('0')
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
this.echartsData1 = this.dataListDynamic.map((item) => item.okNum)
|
||||
this.echartsData2 = this.dataListDynamic.map((item) => item.nokNum)
|
||||
this.pass = this.dataListDynamic.map((item) => item.passRate)
|
||||
// this.echartsData = result
|
||||
// console.log('result', result)
|
||||
// [
|
||||
// { name: '11', type: 'bar', data: [/**产线1*/ 2, /**产线2*/ 3] },
|
||||
// { name: '222', type: 'bar', data: [1, 2, 3] }
|
||||
// ]
|
||||
},
|
||||
|
||||
fetchList(startTime, endTime, lineIds) {
|
||||
this.$http({
|
||||
url: this.$http.adornUrl('/monitoring/eqAnalysis/productQualityAnalysis'),
|
||||
method: 'POST',
|
||||
data: {
|
||||
startTime,
|
||||
endTime,
|
||||
lineIds: this.lineIds
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.base-container {
|
||||
min-height: 60vh;
|
||||
background: #fff;
|
||||
padding: 12px;
|
||||
}
|
||||
.buttonColor {
|
||||
color: #fff;
|
||||
background: #0b58ff;
|
||||
}
|
||||
</style>
|
@ -2,7 +2,7 @@
|
||||
<div class="mod-config">
|
||||
<el-form :inline="true" @keyup.enter.native="getDataList()" class="blueTip" size="small">
|
||||
<el-form-item>
|
||||
{{ $t('time')}}
|
||||
{{ $t('time') }}
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- type="datetimerange" -->
|
||||
@ -15,8 +15,7 @@
|
||||
:range-separator="$t('to')"
|
||||
:default-time="['00:00:00', '23:59:59']"
|
||||
:picker-options="quickOptions"
|
||||
clearable
|
||||
/>
|
||||
clearable />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="buttonColor" @click="getDataList()">{{ $t('query') }}</el-button>
|
||||
@ -28,32 +27,31 @@
|
||||
<el-row>
|
||||
<el-col>
|
||||
<small-title :size="'md'">{{ $t('inspect.ioTotal') }}</small-title>
|
||||
<el-row style="margin-top: 12px;">
|
||||
<el-row style="margin-top: 12px">
|
||||
<base-table :data="dataListStatic" :table-head-configs="tableConfigStatic" :max-height="500" @operate-event="handleOperations" @refreshDataList="getDataList" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row style="margin-top: 28px;">
|
||||
<el-row style="margin-top: 28px">
|
||||
<el-col>
|
||||
<el-row>
|
||||
<small-title :size="'md'">{{ $t('inspect.plTotal') }}</small-title>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 8px;">
|
||||
<el-row style="margin-top: 8px">
|
||||
<el-radio-group v-model="dataType" size="medium" @change="handleDataTypeChange">
|
||||
<el-radio-button :label="$t('table2')"></el-radio-button>
|
||||
<el-radio-button :label="$t('graph')"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 12px;">
|
||||
<el-row style="margin-top: 12px">
|
||||
<base-table
|
||||
v-if="!showGraph"
|
||||
:data="dataListDynamic"
|
||||
:table-head-configs="tableConfigDynamic"
|
||||
:max-height="500"
|
||||
@operate-event="handleOperations"
|
||||
@refreshDataList="getDataList"
|
||||
/>
|
||||
@refreshDataList="getDataList" />
|
||||
<fake-chart v-else :categories="echartCategories" :type-list="echartCheckTypes" :series-data="echartsData" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
@ -77,7 +75,7 @@ const tableConfigStatic = [
|
||||
{ name: i18n.t('inspect.inTotal'), prop: 'sumUp' },
|
||||
{ name: i18n.t('inspect.outTotal'), prop: 'sumDown' },
|
||||
{ name: i18n.t('inspect.checkTotal'), prop: 'sumCheck' },
|
||||
{ name: i18n.t('inspect.rate'), prop: 'scrapRatio', filter: val => (val || val === 0 ? `${val}%` : '-') }
|
||||
{ name: i18n.t('inspect.rate'), prop: 'scrapRatio', filter: (val) => (val || val === 0 ? `${val}%` : '-') }
|
||||
]
|
||||
const tableConfigDynamic = [
|
||||
{ type: 'index', width: 100, name: i18n.t('index') },
|
||||
@ -125,7 +123,7 @@ const FakeChart = {
|
||||
right: 0,
|
||||
width: '12%',
|
||||
/** 修复文本太长时显示问题 */
|
||||
formatter: function(name) {
|
||||
formatter: function (name) {
|
||||
return echarts.format.truncateText(name, 120, '14px Microsoft Yahei', '...')
|
||||
},
|
||||
tooltip: {
|
||||
@ -153,7 +151,7 @@ const FakeChart = {
|
||||
},
|
||||
watch: {
|
||||
categories: {
|
||||
handler: function(val, oldVal) {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.xAxis.data.push(...val)
|
||||
}
|
||||
@ -161,7 +159,7 @@ const FakeChart = {
|
||||
immediate: true
|
||||
},
|
||||
typeList: {
|
||||
handler: function(val, oldVal) {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.legend.data.push(...val)
|
||||
}
|
||||
@ -169,7 +167,7 @@ const FakeChart = {
|
||||
immediate: true
|
||||
},
|
||||
seriesData: {
|
||||
handler: function(val, oldVal) {
|
||||
handler: function (val, oldVal) {
|
||||
if (val && val !== oldVal) {
|
||||
this.defaultOpts.series.push(...val)
|
||||
}
|
||||
@ -177,7 +175,7 @@ const FakeChart = {
|
||||
immediate: true
|
||||
},
|
||||
defaultOpts: {
|
||||
handler: function(val) {
|
||||
handler: function (val) {
|
||||
console.log('defaullt opts change: ', val)
|
||||
this.setOptions()
|
||||
},
|
||||
@ -205,7 +203,7 @@ const FakeChart = {
|
||||
if (this.chart) this.chart.setOption(this.defaultOpts)
|
||||
}
|
||||
},
|
||||
render: function(h) {
|
||||
render: function (h) {
|
||||
return h('div', { attrs: { id: 'bar-chart' }, style: { background: '#eee', width: '100%', height: '300px', padding: '8px' } }, '')
|
||||
}
|
||||
}
|
||||
@ -269,16 +267,8 @@ export default {
|
||||
this.echartCategories = null
|
||||
this.echartCheckTypes.splice(0)
|
||||
/** 设置默认日期 */
|
||||
const startTime =
|
||||
this.datetime[0] ||
|
||||
moment()
|
||||
.set({ hour: 0, minute: 0, second: 0 })
|
||||
.format('yyyy-MM-DDTHH:mm:ss')
|
||||
const endTime =
|
||||
this.datetime[1] ||
|
||||
moment()
|
||||
.set({ hour: 23, minute: 59, second: 59 })
|
||||
.format('yyyy-MM-DDTHH:mm:ss')
|
||||
const startTime = this.datetime[0] || moment().set({ hour: 0, minute: 0, second: 0 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
const endTime = this.datetime[1] || moment().set({ hour: 23, minute: 59, second: 59 }).format('yyyy-MM-DDTHH:mm:ss')
|
||||
|
||||
/** [1] 获取上下片数据 */
|
||||
this.fetchList('sx', startTime, endTime).then(({ data: res }) => {
|
||||
@ -287,11 +277,12 @@ export default {
|
||||
})
|
||||
/** [2] 获取产线检测类型 */
|
||||
this.fetchList('pl', startTime, endTime).then(({ data: res }) => {
|
||||
// console.log('pl: ', res)
|
||||
console.log('res: ', res)
|
||||
/** TODO: 解析 nameData */
|
||||
this.parseTableProps(res.data.nameData)
|
||||
|
||||
this.dataListDynamic = this.parseDynamicData(res.data.data) || []
|
||||
console.log('this.dataListDynamic', this.dataListDynamic)
|
||||
|
||||
this.buildGraphData()
|
||||
})
|
||||
@ -303,7 +294,7 @@ export default {
|
||||
|
||||
if (nameData.length) {
|
||||
/** 处理 nameData */
|
||||
nameData.forEach(item => {
|
||||
nameData.forEach((item) => {
|
||||
if (!labelNameMap.get(item.name)) {
|
||||
labelNameMap.set(item.name, 1)
|
||||
subProps.push({ name: item.name, prop: item.name })
|
||||
@ -316,21 +307,22 @@ export default {
|
||||
{ name: i18n.t('inspect.det'), prop: 'inspectionContent' },
|
||||
...subProps,
|
||||
{ name: i18n.t('inspect.typetotal'), prop: 'sumInput' },
|
||||
{ name: i18n.t('inspect.rate'), prop: 'scrapRatio', filter: val => (val || val === 0 ? `${val}%` : '-') }
|
||||
{ name: i18n.t('inspect.rate'), prop: 'scrapRatio', filter: (val) => (val || val === 0 ? `${val}%` : '-') }
|
||||
]
|
||||
|
||||
/** echarts related */
|
||||
this.echartCategories = subProps.map(item => item.name)
|
||||
this.echartCategories = subProps.map((item) => item.name)
|
||||
// console.log('this.echartCategories',this.echartCategories)
|
||||
},
|
||||
|
||||
parseDynamicData(data) {
|
||||
this.echartCheckTypes.splice(0)
|
||||
return data.map(item => {
|
||||
return data.map((item) => {
|
||||
/** echarts related */
|
||||
this.echartCheckTypes.push(item.inspectionContent)
|
||||
if (item.data.length) {
|
||||
/** 解析子数组 */
|
||||
item.data.forEach(subitem => {
|
||||
item.data.forEach((subitem) => {
|
||||
item[subitem.dynamicName] = subitem.dynamicValue
|
||||
})
|
||||
}
|
||||
@ -342,13 +334,15 @@ export default {
|
||||
/** 构造 echart 需要的数据 */
|
||||
const result = []
|
||||
|
||||
this.echartCheckTypes.forEach(ect => {
|
||||
this.echartCheckTypes.forEach((ect) => {
|
||||
result.push({ name: ect, type: 'bar', data: [] })
|
||||
})
|
||||
|
||||
console.log('result', result)
|
||||
console.log('echartCheckTypes',this.echartCheckTypes);
|
||||
console.log('this.echartCategories',this.echartCategories);
|
||||
this.dataListDynamic.forEach((inspection, index) => {
|
||||
console.log('inspection: ', inspection)
|
||||
this.echartCategories.forEach(cate => {
|
||||
// console.log('inspection: ', inspection)
|
||||
this.echartCategories.forEach((cate) => {
|
||||
if (cate in inspection) {
|
||||
result[index].data.push(inspection[cate])
|
||||
} else {
|
||||
@ -376,7 +370,7 @@ export default {
|
||||
startTime,
|
||||
endTime
|
||||
}
|
||||
}).catch(err => {
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
case 'pl':
|
||||
@ -387,7 +381,7 @@ export default {
|
||||
startTime,
|
||||
endTime
|
||||
}
|
||||
}).catch(err => {
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
}
|
||||
|
Yükleniyor…
Yeni konuda referans
Bir kullanıcı engelle