更新
This commit is contained in:
198
src/views/core/analysis/balanceAnalysis/BarChart.vue
Normal file
198
src/views/core/analysis/balanceAnalysis/BarChart.vue
Normal file
@@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<div
|
||||
ref="lineChart"
|
||||
:id="id"
|
||||
:class="className"
|
||||
:style="{ height: height, width: width, marginLeft: '10px' }" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
require('echarts/theme/macarons'); // echarts theme
|
||||
import resize from '@/utils/chartMixins/resize';
|
||||
import { parseTime } from '../../mixins/code-filter';
|
||||
|
||||
const animationDuration = 1000;
|
||||
export default {
|
||||
name: 'lineChart',
|
||||
mixins: [resize],
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: 'chart',
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: 'chart',
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '300px',
|
||||
},
|
||||
barData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (!this.chart) {
|
||||
this.chart = echarts.init(this.$refs.lineChart);
|
||||
this.$nextTick(() => {
|
||||
this.initChart();
|
||||
});
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return;
|
||||
}
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
watch: {
|
||||
barData: {
|
||||
handler() {
|
||||
if (this.chart) {
|
||||
this.$nextTick(() => {
|
||||
this.initChart();
|
||||
});
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.chart = echarts.init(this.$refs.lineChart);
|
||||
this.initChart();
|
||||
});
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
const _this = this;
|
||||
this.chart.setOption({
|
||||
title: {
|
||||
text: this.title
|
||||
? '{space|}{tip|}{space|}{value|' + this.title + '}'
|
||||
: '',
|
||||
textStyle: {
|
||||
rich: {
|
||||
tip: {
|
||||
width: 6,
|
||||
height: 6,
|
||||
borderRadius: 50,
|
||||
backgroundColor: '#288AFF',
|
||||
},
|
||||
space: {
|
||||
width: 8,
|
||||
},
|
||||
value: {
|
||||
fontSize: 14,
|
||||
color: 'black',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
color: ['#288AFF', '#8EF0AB', '#FFDC94'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
crossStyle: {
|
||||
color: '#999',
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ['磨边节拍', '钢化节拍', '下片节拍'],
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: this.barData.edgeCt.map((item) => {
|
||||
return parseTime(item.recordTime, '{m}-{d} {h}:{i}');
|
||||
}),
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '节拍',
|
||||
min: 0,
|
||||
interval: 20,
|
||||
axisLabel: {
|
||||
formatter: '{value} pcs/min',
|
||||
},
|
||||
},
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '磨边节拍',
|
||||
type: 'line',
|
||||
tooltip: {
|
||||
valueFormatter: function (value) {
|
||||
return value + 'pcs/min';
|
||||
},
|
||||
},
|
||||
data: this.barData.edgeCt.map((item) => {
|
||||
return item.ct;
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: '钢化节拍',
|
||||
type: 'line',
|
||||
tooltip: {
|
||||
valueFormatter: function (value) {
|
||||
return value + 'pcs/min';
|
||||
},
|
||||
},
|
||||
data: this.barData.temperCt.map((item) => {
|
||||
return item.ct;
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: '下片节拍',
|
||||
type: 'line',
|
||||
tooltip: {
|
||||
valueFormatter: function (value) {
|
||||
return value + 'pcs/min';
|
||||
},
|
||||
},
|
||||
data: this.barData.downCt.map((item) => {
|
||||
return item.ct;
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
273
src/views/core/analysis/balanceAnalysis/eq-detail.vue
Normal file
273
src/views/core/analysis/balanceAnalysis/eq-detail.vue
Normal file
@@ -0,0 +1,273 @@
|
||||
<!--
|
||||
* @Author: zwq
|
||||
* @Date: 2023-08-24 14:47:58
|
||||
* @LastEditors: zwq
|
||||
* @LastEditTime: 2025-01-09 10:04:17
|
||||
* @Description:
|
||||
-->
|
||||
<template>
|
||||
<div>
|
||||
<base-table
|
||||
:page="1"
|
||||
:limit="999"
|
||||
v-loading="dataListLoading"
|
||||
:table-props="tableProps"
|
||||
max-height="400"
|
||||
:table-data="tableData">
|
||||
<method-btn
|
||||
v-if="tableData.length"
|
||||
slot="handleBtn"
|
||||
:width="80"
|
||||
label="操作"
|
||||
:method-list="tableBtn"
|
||||
@clickBtn="handleClick" />
|
||||
</base-table>
|
||||
<div v-if="eqChartData.length > 0" style="margin-top: 10px">
|
||||
<search-bar
|
||||
:formConfigs="formConfig"
|
||||
ref="searchBarForm1"
|
||||
@headBtnClick="buttonClick" />
|
||||
<div
|
||||
ref="lineChart"
|
||||
id="chart"
|
||||
:style="{ height: '400px', width: '100%', marginLeft: '10px' }" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getNewCTDet, getNewCTCharts } from '@/api/core/analysis/index';
|
||||
import * as echarts from 'echarts';
|
||||
require('echarts/theme/macarons'); // echarts theme
|
||||
import resize from '@/utils/chartMixins/resize';
|
||||
import { parseTime } from '../../mixins/code-filter';
|
||||
|
||||
const tableProps = [
|
||||
{
|
||||
prop: 'equipmentName',
|
||||
label: '设备',
|
||||
},
|
||||
{
|
||||
prop: 'size',
|
||||
label: '规格',
|
||||
showOverflowtooltip: true,
|
||||
},
|
||||
{
|
||||
prop: 'process',
|
||||
label: '产品工艺',
|
||||
},
|
||||
{
|
||||
prop: 'standardCt',
|
||||
label: '标准节拍pcs/min',
|
||||
},
|
||||
{
|
||||
prop: 'ct',
|
||||
label: '当前节拍pcs/min',
|
||||
},
|
||||
];
|
||||
export default {
|
||||
mixins: [resize],
|
||||
data() {
|
||||
return {
|
||||
tableProps,
|
||||
tableData: [],
|
||||
tableBtn: [
|
||||
{
|
||||
type: 'eqChart',
|
||||
btnName: '趋势图',
|
||||
},
|
||||
].filter((v) => v),
|
||||
dataListLoading: false,
|
||||
time: {},
|
||||
eqChartData: [],
|
||||
eqName: null,
|
||||
equipmentId: null,
|
||||
chart: null,
|
||||
formConfig: [
|
||||
{
|
||||
type: 'datePicker',
|
||||
label: '时间范围',
|
||||
dateType: 'datetimerange',
|
||||
format: 'yyyy-MM-dd HH:mm:ss',
|
||||
valueFormat: 'timestamp',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
defaultTime: ['00:00:00', '23:59:59'],
|
||||
param: 'timeVal',
|
||||
width: 350,
|
||||
clearable: false,
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
btnName: '查询',
|
||||
name: 'search',
|
||||
color: 'primary',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
components: {},
|
||||
created() {},
|
||||
mounted() {},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return;
|
||||
}
|
||||
this.chart.dispose();
|
||||
this.chart = null;
|
||||
},
|
||||
methods: {
|
||||
// 获取数据列表
|
||||
init(lineId, startTime, endTime) {
|
||||
this.eqChartData = [];
|
||||
this.time.startTime = startTime;
|
||||
this.time.endTime = endTime;
|
||||
this.dataListLoading = true;
|
||||
getNewCTDet(lineId).then((response) => {
|
||||
this.tableData = response.data;
|
||||
this.dataListLoading = false;
|
||||
});
|
||||
},
|
||||
handleClick(val) {
|
||||
const data = {
|
||||
...this.time,
|
||||
equipmentId: val.data.equipmentId,
|
||||
};
|
||||
this.eqName = val.data.equipmentName;
|
||||
this.equipmentId = val.data.equipmentId;
|
||||
getNewCTCharts(data).then((response) => {
|
||||
this.eqChartData = response.data;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.searchBarForm1.formInline.timeVal = [
|
||||
this.time.startTime,
|
||||
this.time.endTime,
|
||||
];
|
||||
this.initChart();
|
||||
});
|
||||
});
|
||||
},
|
||||
buttonClick(val) {
|
||||
switch (val.btnName) {
|
||||
case 'search':
|
||||
this.time.startTime = val.timeVal ? val.timeVal[0] : undefined;
|
||||
this.time.endTime = val.timeVal ? val.timeVal[1] : undefined;
|
||||
const data = {
|
||||
...this.time,
|
||||
equipmentId: this.equipmentId,
|
||||
};
|
||||
getNewCTCharts(data).then((response) => {
|
||||
this.eqChartData = response.data;
|
||||
this.$nextTick(() => {
|
||||
this.initChart();
|
||||
});
|
||||
});
|
||||
break;
|
||||
default:
|
||||
console.log(val);
|
||||
}
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(this.$refs.lineChart);
|
||||
const _this = this;
|
||||
this.chart.setOption({
|
||||
title: {
|
||||
text: this.eqName
|
||||
? '{space|}{tip|}{space|}{value|' + this.eqName + ' 节拍趋势图' + '}'
|
||||
: '',
|
||||
textStyle: {
|
||||
rich: {
|
||||
tip: {
|
||||
width: 6,
|
||||
height: 6,
|
||||
borderRadius: 50,
|
||||
backgroundColor: '#288AFF',
|
||||
},
|
||||
space: {
|
||||
width: 8,
|
||||
},
|
||||
value: {
|
||||
fontSize: 14,
|
||||
color: 'black',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
color: ['#288AFF', '#8EF0AB', '#FFDC94'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
crossStyle: {
|
||||
color: '#999',
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ['当前节拍', '标准节拍'],
|
||||
},
|
||||
grid: {
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: this.eqChartData[0].ct.map((item) => {
|
||||
return parseTime(item.recordTime, '{m}-{d} {h}:{i}');
|
||||
}),
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '节拍',
|
||||
min: 0,
|
||||
interval: 20,
|
||||
axisLabel: {
|
||||
formatter: '{value} pcs/min',
|
||||
},
|
||||
},
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '标准节拍',
|
||||
type: 'line',
|
||||
tooltip: {
|
||||
valueFormatter: function (value) {
|
||||
return value + 'pcs/min';
|
||||
},
|
||||
},
|
||||
data: this.eqChartData[0].ct.map((item) => {
|
||||
return item.standardCt;
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: '当前节拍',
|
||||
type: 'line',
|
||||
tooltip: {
|
||||
valueFormatter: function (value) {
|
||||
return value + 'pcs/min';
|
||||
},
|
||||
},
|
||||
data: this.eqChartData[0].ct.map((item) => {
|
||||
return item.ct;
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
296
src/views/core/analysis/balanceAnalysis/index-old.vue
Normal file
296
src/views/core/analysis/balanceAnalysis/index-old.vue
Normal file
@@ -0,0 +1,296 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<search-bar
|
||||
:formConfigs="formConfig"
|
||||
ref="searchBarForm"
|
||||
@headBtnClick="buttonClick" />
|
||||
<div v-if="tableData.length">
|
||||
<base-table
|
||||
v-loading="dataListLoading"
|
||||
:span-method="mergeColumnHandler"
|
||||
:max-height="tableH"
|
||||
:table-props="tableProps"
|
||||
:table-data="tableData" />
|
||||
<SearchBar :formConfigs="[{ label: '产线平衡分析图', type: 'title' }]" />
|
||||
<balance-chart ref="lineChart" />
|
||||
</div>
|
||||
<div v-else class="no-data-bg"></div>
|
||||
<!-- <pagination
|
||||
:limit.sync="listQuery.pageSize"
|
||||
:page.sync="listQuery.pageNo"
|
||||
:total="listQuery.total"
|
||||
@pagination="getDataList" /> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import basicPage from '../../mixins/basic-page';
|
||||
import { parseTime } from '../../mixins/code-filter';
|
||||
import { getCT } from '@/api/core/analysis/index';
|
||||
import { getProductionLinePage } from '@/api/core/base/productionLine';
|
||||
import BalanceChart from '../balanceChart';
|
||||
import { time } from 'echarts';
|
||||
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
|
||||
// import { getWorkshopSectionPage } from '@/api/core/base/workshopSection';
|
||||
|
||||
// const tableProps = [
|
||||
// // {
|
||||
// // prop: 'lineName',
|
||||
// // label: '产线',
|
||||
// // align: 'center',
|
||||
// // },
|
||||
// // {
|
||||
// // prop: 'sum',
|
||||
// // label: '合计',
|
||||
// // align: 'center',
|
||||
// // },
|
||||
// // {
|
||||
// // prop: 'dynamicValue',
|
||||
// // label: 'dynamicName',
|
||||
// // align: 'center',
|
||||
// // children:[
|
||||
|
||||
// // ]
|
||||
// // }
|
||||
// ];
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BalanceChart,
|
||||
},
|
||||
mixins: [tableHeightMixin],
|
||||
data() {
|
||||
return {
|
||||
urlOptions: {
|
||||
getDataListURL: getCT,
|
||||
},
|
||||
tableProps: [],
|
||||
dataListLoading: false,
|
||||
tableData: [],
|
||||
listQuery: {
|
||||
// time: ''
|
||||
endTime: undefined,
|
||||
lineId: undefined,
|
||||
startTime: undefined,
|
||||
},
|
||||
timeList: [],
|
||||
spanArr: [],
|
||||
xData: [],
|
||||
yData: [],
|
||||
optionArrUrl: [getProductionLinePage],
|
||||
formConfig: [
|
||||
{
|
||||
type: 'select',
|
||||
label: '产线',
|
||||
selectOptions: [],
|
||||
param: 'lineIds',
|
||||
defaultSelect: '',
|
||||
multiple: false,
|
||||
filterable: true,
|
||||
},
|
||||
{
|
||||
type: 'datePicker',
|
||||
label: '时间',
|
||||
dateType: 'datetimerange',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
width: 350,
|
||||
param: 'time',
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
btnName: '查询',
|
||||
name: 'search',
|
||||
color: 'primary',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getArr();
|
||||
},
|
||||
methods: {
|
||||
getArr() {
|
||||
const params = {
|
||||
page: 1,
|
||||
limit: 500,
|
||||
};
|
||||
this.optionArrUrl.forEach((item, index) => {
|
||||
item(params).then((response) => {
|
||||
this.formConfig[index].selectOptions = response.data.list;
|
||||
});
|
||||
});
|
||||
},
|
||||
setRowSpan(arr) {
|
||||
let count = 0;
|
||||
arr.forEach((item, index) => {
|
||||
if (index === 0) {
|
||||
this.spanArr.push(1);
|
||||
} else {
|
||||
if (item === arr[index - 1]) {
|
||||
this.spanArr[count] += 1;
|
||||
this.spanArr.push(0);
|
||||
} else {
|
||||
count = index;
|
||||
this.spanArr.push(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 合并table列的规则 */
|
||||
mergeColumnHandler({ row, column, rowIndex, columnIndex }) {
|
||||
if (columnIndex == 0) {
|
||||
if (this.spanArr[rowIndex]) {
|
||||
return [
|
||||
this.spanArr[rowIndex], // row span
|
||||
1, // col span
|
||||
];
|
||||
} else {
|
||||
return [0, 0];
|
||||
}
|
||||
}
|
||||
},
|
||||
getData() {
|
||||
// this.listQuery.lineId = '1672847052717821953'
|
||||
// this.listQuery.startTime = '1693497600000';
|
||||
// this.listQuery.endTime = '1693843200000';
|
||||
this.urlOptions.getDataListURL(this.listQuery).then((res) => {
|
||||
console.log(res);
|
||||
let arr = [
|
||||
{
|
||||
prop: 'sectionName',
|
||||
label: '工段',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
prop: 'equName',
|
||||
label: '设备',
|
||||
align: 'center',
|
||||
width: 150
|
||||
},
|
||||
];
|
||||
let sectionArr = [];
|
||||
res.data.data.forEach((ele, index) => {
|
||||
let tempData = [];
|
||||
let ggData = [];
|
||||
let sbluData = [];
|
||||
let sbsjData = [];
|
||||
let cxluData = [];
|
||||
let cxsjData = [];
|
||||
ele.data.forEach((item, index) => {
|
||||
item.children.forEach((params) => {
|
||||
if (params.dynamicName === '生产规格') {
|
||||
tempData[item.dynamicName + '_gg'] = params.dynamicValue;
|
||||
ggData[index] = params.dynamicValue;
|
||||
} else if (params.dynamicName === '设备理论速度') {
|
||||
tempData[item.dynamicName + '_sblu'] = params.dynamicValue;
|
||||
sbluData[index] = params.dynamicValue;
|
||||
} else if (params.dynamicName === '设备实际速度') {
|
||||
tempData[item.dynamicName + '_sbsj'] = params.dynamicValue;
|
||||
sbsjData[index] = params.dynamicValue;
|
||||
} else if (params.dynamicName === '产线理论速度') {
|
||||
tempData[item.dynamicName + '_cxlu'] = params.dynamicValue;
|
||||
cxluData[index] = params.dynamicValue;
|
||||
} else if(params.dynamicName === '产线实际速度') {
|
||||
tempData[item.dynamicName + '_cxsj'] = params.dynamicValue;
|
||||
cxsjData[index] = params.dynamicValue;
|
||||
}
|
||||
});
|
||||
});
|
||||
const equipment = {
|
||||
name: ele.equName,
|
||||
ggData: ggData,
|
||||
sbluData: sbluData,
|
||||
sbsjData: sbsjData,
|
||||
cxluData: cxluData,
|
||||
cxsjData: cxsjData,
|
||||
};
|
||||
tempData['equName'] = ele.equName;
|
||||
tempData['sectionName'] = ele.sectionName;
|
||||
this.tableData.push(tempData);
|
||||
const { sectionName } = tempData;
|
||||
sectionArr.push(sectionName);
|
||||
this.yData.push(equipment);
|
||||
});
|
||||
this.setRowSpan(sectionArr);
|
||||
res.data.nameData.forEach((item) => {
|
||||
this.timeList.push(item.name);
|
||||
});
|
||||
const timeArray = Array.from(new Set(this.timeList));
|
||||
console.log(timeArray)
|
||||
for (const times of timeArray) {
|
||||
if (times !== '生产规格' && times !== '设备理论速度' && times !== '设备实际速度'
|
||||
&& times !== '产线理论速度' && times !== '产线实际速度'
|
||||
) {
|
||||
const subprop = {
|
||||
label: times,
|
||||
align: 'center',
|
||||
children: [
|
||||
{ prop: times + '_gg', label: '生产规格', align: 'center' },
|
||||
{ prop: times + '_sblu', label: '设备理论速度[片/min]', align: 'center' },
|
||||
{ prop: times + '_sbsj', label: '设备实际速度[片/min]', align: 'center' },
|
||||
{ prop: times + '_cxlu', label: '产线理论速度[片/min]', align: 'center' },
|
||||
{ prop: times + '_cxsj', label: '产线实际速度[片/min]', align: 'center' },
|
||||
],
|
||||
};
|
||||
arr.push(subprop);
|
||||
this.xData.push(times);
|
||||
}
|
||||
}
|
||||
this.tableProps = arr;
|
||||
|
||||
console.log(this.$refs)
|
||||
this.$nextTick(()=>{
|
||||
this.$refs.lineChart.initChart(this.xData, this.yData);
|
||||
})
|
||||
// this.total = response.data.total;
|
||||
// this.dataListLoading = false;
|
||||
});
|
||||
},
|
||||
buttonClick(val) {
|
||||
// console.log(val)
|
||||
switch (val.btnName) {
|
||||
case 'search':
|
||||
// this.listQuery.pageNo = 1;
|
||||
// this.listQuery.pageSize = 10;
|
||||
this.listQuery.lineId = val.lineIds;
|
||||
this.listQuery.startTime = val.time
|
||||
? String(new Date(val.time[0]).getTime())
|
||||
: undefined;
|
||||
this.listQuery.endTime = val.time
|
||||
? String(new Date(val.time[1]).getTime())
|
||||
: undefined;
|
||||
if (val.time && val.lineIds) {
|
||||
this.tableData = [];
|
||||
this.xData = [];
|
||||
this.yData = [];
|
||||
this.tableProps = [];
|
||||
this.spanArr = [];
|
||||
this.timeList = [];
|
||||
this.getData();
|
||||
} else {
|
||||
this.$message({
|
||||
message: '请选择产线和时间',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'reset':
|
||||
this.$refs.searchBarForm.resetForm();
|
||||
this.listQuery = {
|
||||
pageSize: 10,
|
||||
pageNo: 1,
|
||||
total: 1,
|
||||
};
|
||||
this.getDataList();
|
||||
break;
|
||||
default:
|
||||
console.log(val);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,104 +1,162 @@
|
||||
<!--
|
||||
* @Author: Do not edit
|
||||
* @Date: 2023-08-29 14:59:29
|
||||
* @LastEditTime: 2025-01-09 10:27:53
|
||||
* @LastEditors: zwq
|
||||
* @Description:
|
||||
-->
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<search-bar
|
||||
:formConfigs="formConfig"
|
||||
ref="searchBarForm"
|
||||
@select-changed="handleSearchBarChanged"
|
||||
@headBtnClick="buttonClick" />
|
||||
<div v-if="tableData.length">
|
||||
<div v-if="showData.length">
|
||||
<base-table
|
||||
class="right-aside"
|
||||
v-loading="dataListLoading"
|
||||
:span-method="mergeColumnHandler"
|
||||
:max-height="tableH"
|
||||
:table-props="tableProps"
|
||||
:table-data="tableData" />
|
||||
<SearchBar :formConfigs="[{ label: '产线平衡分析图', type: 'title' }]" />
|
||||
<balance-chart ref="lineChart" />
|
||||
:page="1"
|
||||
:limit="999"
|
||||
:table-data="showData">
|
||||
<method-btn
|
||||
v-if="showData.length"
|
||||
slot="handleBtn"
|
||||
:width="80"
|
||||
label="操作"
|
||||
:method-list="tableBtn"
|
||||
@clickBtn="handleClick" />
|
||||
</base-table>
|
||||
<barChart
|
||||
v-for="item in chartData"
|
||||
:key="item.name + 'echart'"
|
||||
style="margin-top: 50px"
|
||||
height="600px"
|
||||
:id="item.name + 'echart'"
|
||||
:title="item.name + ' 节拍趋势图'"
|
||||
:bar-data="item" />
|
||||
</div>
|
||||
<div v-else class="no-data-bg"></div>
|
||||
<!-- <pagination
|
||||
:limit.sync="listQuery.pageSize"
|
||||
:page.sync="listQuery.pageNo"
|
||||
:total="listQuery.total"
|
||||
@pagination="getDataList" /> -->
|
||||
<base-dialog
|
||||
:dialogTitle="addOrEditTitle"
|
||||
:dialogVisible="addOrUpdateVisible"
|
||||
@cancel="handleCancel"
|
||||
@confirm="handleConfirm"
|
||||
:before-close="handleCancel"
|
||||
close-on-click-modal
|
||||
top="0"
|
||||
width="50%">
|
||||
<eq-detail ref="eqDetail" />
|
||||
<slot name="footer">
|
||||
<el-row slot="footer" type="flex" justify="end">
|
||||
<el-col :span="24">
|
||||
<el-button size="small" class="btnTextStyle" @click="handleCancel">
|
||||
取消
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</slot>
|
||||
</base-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import basicPage from '../../mixins/basic-page';
|
||||
import eqDetail from './eq-detail';
|
||||
import { parseTime } from '../../mixins/code-filter';
|
||||
import { getCT } from '@/api/core/analysis/index';
|
||||
import { getProductionLinePage } from '@/api/core/base/productionLine';
|
||||
import BalanceChart from '../balanceChart';
|
||||
import { time } from 'echarts';
|
||||
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
|
||||
// import { getWorkshopSectionPage } from '@/api/core/base/workshopSection';
|
||||
import { getPdList } from '@/api/core/monitoring/auto';
|
||||
import { getNewCTNow, getNewCTCharts } from '@/api/core/analysis/index';
|
||||
import { getFactoryPage } from '@/api/core/base/factory';
|
||||
// import codeFilter from '../../mixins/code-filter'
|
||||
import * as XLSX from 'xlsx';
|
||||
import FileSaver from 'file-saver';
|
||||
import barChart from './BarChart.vue';
|
||||
|
||||
// const tableProps = [
|
||||
// // {
|
||||
// // prop: 'lineName',
|
||||
// // label: '产线',
|
||||
// // align: 'center',
|
||||
// // },
|
||||
// // {
|
||||
// // prop: 'sum',
|
||||
// // label: '合计',
|
||||
// // align: 'center',
|
||||
// // },
|
||||
// // {
|
||||
// // prop: 'dynamicValue',
|
||||
// // label: 'dynamicName',
|
||||
// // align: 'center',
|
||||
// // children:[
|
||||
|
||||
// // ]
|
||||
// // }
|
||||
// ];
|
||||
const tableProps = [
|
||||
{
|
||||
prop: 'factoryName',
|
||||
label: '工厂',
|
||||
},
|
||||
{
|
||||
prop: 'lineName',
|
||||
label: '产线',
|
||||
},
|
||||
{
|
||||
prop: 'size',
|
||||
label: '规格',
|
||||
showOverflowtooltip: true,
|
||||
},
|
||||
{
|
||||
prop: 'process',
|
||||
label: '产品工艺',
|
||||
},
|
||||
{
|
||||
prop: 'edgeCt',
|
||||
label: '磨边当前节拍pcs/min',
|
||||
},
|
||||
{
|
||||
prop: 'temperCt',
|
||||
label: '钢化当前节拍pcs/min',
|
||||
},
|
||||
{
|
||||
prop: 'downCt',
|
||||
label: '下片当前节拍pcs/min',
|
||||
},
|
||||
];
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BalanceChart,
|
||||
barChart,
|
||||
eqDetail,
|
||||
},
|
||||
mixins: [tableHeightMixin],
|
||||
data() {
|
||||
return {
|
||||
urlOptions: {
|
||||
getDataListURL: getCT,
|
||||
getDataListURL: getNewCTNow,
|
||||
},
|
||||
tableProps: [],
|
||||
dataListLoading: false,
|
||||
tableData: [],
|
||||
listQuery: {
|
||||
// time: ''
|
||||
endTime: undefined,
|
||||
lineId: undefined,
|
||||
startTime: undefined,
|
||||
lineId: [],
|
||||
},
|
||||
timeList: [],
|
||||
spanArr: [],
|
||||
xData: [],
|
||||
yData: [],
|
||||
optionArrUrl: [getProductionLinePage],
|
||||
fileName: '',
|
||||
dataListLoading: false,
|
||||
tableProps,
|
||||
tableBtn: [
|
||||
{
|
||||
type: 'eq',
|
||||
btnName: '详情',
|
||||
},
|
||||
].filter((v) => v),
|
||||
showData: [],
|
||||
tableData: [],
|
||||
chartData: [],
|
||||
formConfig: [
|
||||
{
|
||||
type: 'select',
|
||||
label: '工厂',
|
||||
selectOptions: [],
|
||||
param: 'factoryId',
|
||||
onchange: true,
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '产线',
|
||||
selectOptions: [],
|
||||
param: 'lineIds',
|
||||
defaultSelect: '',
|
||||
multiple: false,
|
||||
filterable: true,
|
||||
param: 'lineId',
|
||||
multiple: true,
|
||||
},
|
||||
{
|
||||
type: 'datePicker',
|
||||
label: '时间',
|
||||
label: '时间范围',
|
||||
dateType: 'datetimerange',
|
||||
format: 'yyyy-MM-dd',
|
||||
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||
format: 'yyyy-MM-dd HH:mm:ss',
|
||||
valueFormat: 'timestamp',
|
||||
rangeSeparator: '-',
|
||||
startPlaceholder: '开始时间',
|
||||
endPlaceholder: '结束时间',
|
||||
defaultTime: ['00:00:00', '23:59:59'],
|
||||
param: 'timeVal',
|
||||
width: 350,
|
||||
param: 'time',
|
||||
clearable: false,
|
||||
},
|
||||
{
|
||||
type: 'button',
|
||||
@@ -106,191 +164,139 @@ export default {
|
||||
name: 'search',
|
||||
color: 'primary',
|
||||
},
|
||||
// {
|
||||
// type: 'separate',
|
||||
// },
|
||||
// {
|
||||
// // type: this.$auth.hasPermi('base:factory:export') ? 'button' : '',
|
||||
// type: 'button',
|
||||
// btnName: '导出',
|
||||
// name: 'export',
|
||||
// color: 'warning',
|
||||
// },
|
||||
],
|
||||
addOrEditTitle: '',
|
||||
addOrUpdateVisible: false,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getArr();
|
||||
// 获取当前时间
|
||||
const now = new Date();
|
||||
// 获取前一天的同一时间
|
||||
const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
||||
// 设置为00:00:00
|
||||
yesterday.setHours(0, 0, 0, 0);
|
||||
// 设置为23:59:59
|
||||
const end = new Date(yesterday.getTime());
|
||||
end.setHours(23, 59, 59, 59);
|
||||
this.listQuery.startTime = yesterday.getTime();
|
||||
this.listQuery.endTime = end.getTime();
|
||||
this.$nextTick(() => {
|
||||
this.$refs.searchBarForm.formInline.timeVal = [
|
||||
yesterday.getTime(),
|
||||
end.getTime(),
|
||||
];
|
||||
});
|
||||
this.getDataList();
|
||||
this.getPdLineList();
|
||||
},
|
||||
methods: {
|
||||
getArr() {
|
||||
const params = {
|
||||
page: 1,
|
||||
limit: 500,
|
||||
};
|
||||
this.optionArrUrl.forEach((item, index) => {
|
||||
item(params).then((response) => {
|
||||
this.formConfig[index].selectOptions = response.data.list;
|
||||
});
|
||||
});
|
||||
},
|
||||
setRowSpan(arr) {
|
||||
let count = 0;
|
||||
arr.forEach((item, index) => {
|
||||
if (index === 0) {
|
||||
this.spanArr.push(1);
|
||||
} else {
|
||||
if (item === arr[index - 1]) {
|
||||
this.spanArr[count] += 1;
|
||||
this.spanArr.push(0);
|
||||
} else {
|
||||
count = index;
|
||||
this.spanArr.push(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 合并table列的规则 */
|
||||
mergeColumnHandler({ row, column, rowIndex, columnIndex }) {
|
||||
if (columnIndex == 0) {
|
||||
if (this.spanArr[rowIndex]) {
|
||||
return [
|
||||
this.spanArr[rowIndex], // row span
|
||||
1, // col span
|
||||
];
|
||||
} else {
|
||||
return [0, 0];
|
||||
}
|
||||
handleExport() {
|
||||
let tables = document.querySelector('.el-table').cloneNode(true);
|
||||
const fix = tables.querySelector('.el-table__fixed');
|
||||
const fixRight = tables.querySelector('.el-table__fixed-right');
|
||||
if (fix) {
|
||||
tables.removeChild(tables.querySelector('.el-table__fixed'));
|
||||
}
|
||||
},
|
||||
getData() {
|
||||
// this.listQuery.lineId = '1672847052717821953'
|
||||
// this.listQuery.startTime = '1693497600000';
|
||||
// this.listQuery.endTime = '1693843200000';
|
||||
this.urlOptions.getDataListURL(this.listQuery).then((res) => {
|
||||
console.log(res);
|
||||
let arr = [
|
||||
{
|
||||
prop: 'sectionName',
|
||||
label: '工段',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
prop: 'equName',
|
||||
label: '设备',
|
||||
align: 'center',
|
||||
width: 150
|
||||
},
|
||||
];
|
||||
let sectionArr = [];
|
||||
res.data.data.forEach((ele, index) => {
|
||||
let tempData = [];
|
||||
let ggData = [];
|
||||
let sbluData = [];
|
||||
let sbsjData = [];
|
||||
let cxluData = [];
|
||||
let cxsjData = [];
|
||||
ele.data.forEach((item, index) => {
|
||||
item.children.forEach((params) => {
|
||||
if (params.dynamicName === '生产规格') {
|
||||
tempData[item.dynamicName + '_gg'] = params.dynamicValue;
|
||||
ggData[index] = params.dynamicValue;
|
||||
} else if (params.dynamicName === '设备理论速度') {
|
||||
tempData[item.dynamicName + '_sblu'] = params.dynamicValue;
|
||||
sbluData[index] = params.dynamicValue;
|
||||
} else if (params.dynamicName === '设备实际速度') {
|
||||
tempData[item.dynamicName + '_sbsj'] = params.dynamicValue;
|
||||
sbsjData[index] = params.dynamicValue;
|
||||
} else if (params.dynamicName === '产线理论速度') {
|
||||
tempData[item.dynamicName + '_cxlu'] = params.dynamicValue;
|
||||
cxluData[index] = params.dynamicValue;
|
||||
} else if(params.dynamicName === '产线实际速度') {
|
||||
tempData[item.dynamicName + '_cxsj'] = params.dynamicValue;
|
||||
cxsjData[index] = params.dynamicValue;
|
||||
}
|
||||
});
|
||||
});
|
||||
const equipment = {
|
||||
name: ele.equName,
|
||||
ggData: ggData,
|
||||
sbluData: sbluData,
|
||||
sbsjData: sbsjData,
|
||||
cxluData: cxluData,
|
||||
cxsjData: cxsjData,
|
||||
};
|
||||
tempData['equName'] = ele.equName;
|
||||
tempData['sectionName'] = ele.sectionName;
|
||||
this.tableData.push(tempData);
|
||||
const { sectionName } = tempData;
|
||||
sectionArr.push(sectionName);
|
||||
this.yData.push(equipment);
|
||||
});
|
||||
this.setRowSpan(sectionArr);
|
||||
res.data.nameData.forEach((item) => {
|
||||
this.timeList.push(item.name);
|
||||
});
|
||||
const timeArray = Array.from(new Set(this.timeList));
|
||||
console.log(timeArray)
|
||||
for (const times of timeArray) {
|
||||
if (times !== '生产规格' && times !== '设备理论速度' && times !== '设备实际速度'
|
||||
&& times !== '产线理论速度' && times !== '产线实际速度'
|
||||
) {
|
||||
const subprop = {
|
||||
label: times,
|
||||
align: 'center',
|
||||
children: [
|
||||
{ prop: times + '_gg', label: '生产规格', align: 'center' },
|
||||
{ prop: times + '_sblu', label: '设备理论速度', align: 'center' },
|
||||
{ prop: times + '_sbsj', label: '设备实际速度', align: 'center' },
|
||||
{ prop: times + '_cxlu', label: '产线理论速度', align: 'center' },
|
||||
{ prop: times + '_cxsj', label: '产线实际速度', align: 'center' },
|
||||
],
|
||||
};
|
||||
arr.push(subprop);
|
||||
this.xData.push(times);
|
||||
}
|
||||
}
|
||||
this.tableProps = arr;
|
||||
if (fixRight) {
|
||||
tables.removeChild(tables.querySelector('.el-table__fixed-right'));
|
||||
}
|
||||
let exportTable = XLSX.utils.table_to_book(tables);
|
||||
|
||||
console.log(this.$refs)
|
||||
this.$nextTick(()=>{
|
||||
this.$refs.lineChart.initChart(this.xData, this.yData);
|
||||
})
|
||||
// this.total = response.data.total;
|
||||
// this.dataListLoading = false;
|
||||
var exportTableOut = XLSX.write(exportTable, {
|
||||
bookType: 'xlsx',
|
||||
bookSST: true,
|
||||
type: 'array',
|
||||
});
|
||||
// sheetjs.xlsx为导出表格的标题名称
|
||||
try {
|
||||
FileSaver.saveAs(
|
||||
new Blob([exportTableOut], {
|
||||
type: 'application/octet-stream',
|
||||
}),
|
||||
this.fileName + '产线自动报表.xlsx'
|
||||
);
|
||||
} catch (e) {
|
||||
if (typeof console !== 'undefined') console.log(e, exportTableOut);
|
||||
}
|
||||
return exportTableOut;
|
||||
},
|
||||
getPdLineList() {
|
||||
getPdList().then((res) => {
|
||||
this.formConfig[1].selectOptions = res.data || [];
|
||||
});
|
||||
const params = {
|
||||
pageSize: 100,
|
||||
pageNo: 1,
|
||||
};
|
||||
getFactoryPage(params).then((res) => {
|
||||
this.formConfig[0].selectOptions = res.data.list || [];
|
||||
});
|
||||
},
|
||||
buttonClick(val) {
|
||||
// console.log(val)
|
||||
switch (val.btnName) {
|
||||
case 'search':
|
||||
// this.listQuery.pageNo = 1;
|
||||
// this.listQuery.pageSize = 10;
|
||||
this.listQuery.lineId = val.lineIds;
|
||||
this.listQuery.startTime = val.time
|
||||
? String(new Date(val.time[0]).getTime())
|
||||
: undefined;
|
||||
this.listQuery.endTime = val.time
|
||||
? String(new Date(val.time[1]).getTime())
|
||||
: undefined;
|
||||
if (val.time && val.lineIds) {
|
||||
this.tableData = [];
|
||||
this.xData = [];
|
||||
this.yData = [];
|
||||
this.tableProps = [];
|
||||
this.spanArr = [];
|
||||
this.timeList = [];
|
||||
this.getData();
|
||||
} else {
|
||||
this.$message({
|
||||
message: '请选择产线和时间',
|
||||
type: 'warning',
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'reset':
|
||||
this.$refs.searchBarForm.resetForm();
|
||||
this.listQuery = {
|
||||
pageSize: 10,
|
||||
pageNo: 1,
|
||||
total: 1,
|
||||
};
|
||||
this.listQuery.factoryId = val.factoryId || undefined;
|
||||
this.listQuery.lineId = val.lineId ? val.lineId : [];
|
||||
this.listQuery.startTime = val.timeVal ? val.timeVal[0] : undefined;
|
||||
this.listQuery.endTime = val.timeVal ? val.timeVal[1] : undefined;
|
||||
this.getDataList();
|
||||
break;
|
||||
case 'export':
|
||||
this.handleExport();
|
||||
break;
|
||||
default:
|
||||
console.log(val);
|
||||
}
|
||||
},
|
||||
// 获取数据列表
|
||||
getDataList() {
|
||||
this.dataListLoading = true;
|
||||
this.urlOptions.getDataListURL(this.listQuery).then((response) => {
|
||||
this.tableData = response.data;
|
||||
this.dataListLoading = false;
|
||||
this.showData = this.tableData;
|
||||
});
|
||||
getNewCTCharts(this.listQuery).then((response) => {
|
||||
this.chartData = response.data;
|
||||
});
|
||||
},
|
||||
handleSearchBarChanged({ param, value }) {
|
||||
this.listQuery.lineId = [];
|
||||
this.$refs.searchBarForm.formInline.lineId = undefined;
|
||||
getPdList(value).then((res) => {
|
||||
this.formConfig[1].selectOptions = res.data || [];
|
||||
});
|
||||
},
|
||||
handleClick(val) {
|
||||
this.addOrUpdateVisible = true;
|
||||
this.addOrEditTitle =
|
||||
val.data?.factoryName + '-' + val.data?.lineName + ' 详情';
|
||||
this.$nextTick(() => {
|
||||
this.$refs.eqDetail.init(
|
||||
val.data.lineId,
|
||||
this.listQuery.startTime,
|
||||
this.listQuery.endTime
|
||||
);
|
||||
});
|
||||
},
|
||||
handleCancel() {
|
||||
this.addOrUpdateVisible = false;
|
||||
this.addOrEditTitle = '';
|
||||
},
|
||||
handleConfirm() {
|
||||
this.handleCancel();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user