更新汝阳bug

This commit is contained in:
朱文强 2024-11-26 16:51:07 +08:00
parent 8ad8e3a5b4
commit ca390fd764
33 changed files with 5798 additions and 703 deletions

View File

@ -1,7 +1,7 @@
###
# @Author: Do not edit
# @Date: 2023-08-29 09:40:39
# @LastEditTime: 2024-09-10 14:43:39
# @LastEditTime: 2024-11-25 14:31:39
# @LastEditors: zwq
# @Description:
###
@ -9,13 +9,11 @@
ENV = 'development'
# 页面标题
VUE_APP_TITLE = 成本管理系统
VUE_APP_TITLE = 智能监控分析系统
# 芋道管理系统/开发环境
# VUE_APP_BASE_API = 'http://192.168.1.49:48080'
VUE_APP_BASE_API = 'http://line.kszny.picaiba.com'
# VUE_APP_BASE_API = 'http://192.168.1.40:48080'
# VUE_APP_BASE_API = 'http://192.168.1.188:48080'
# VUE_APP_BASE_API = 'http://192.168.8.22:48080'
VUE_APP_BASE_API = 'http://172.16.32.40:48080'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@ -2,14 +2,14 @@
# @Author: zwq
# @Date: 2024-03-27 15:49:55
# @LastEditors: zwq
# @LastEditTime: 2024-09-10 15:19:19
# @LastEditTime: 2024-10-30 11:08:47
# @Description:
###
# 生产环境配置
ENV = 'production'
# 页面标题
VUE_APP_TITLE = 成本管理系统
VUE_APP_TITLE = 智能监控分析系统
# 芋道管理系统/生产环境
# VUE_APP_BASE_API = '/prod-api'

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: dialogForm.vue
author: liubin
date: 2023-09-11 15:55:13
@ -71,14 +71,14 @@
</el-col>
<el-col :span="12">
<el-form-item label="工段排序" prop="sort">
<el-form-item label="工段设备排序" prop="sort">
<el-input-number
v-model="dataForm.sort"
filterable
min="0"
max="100"
@change="$emit('update', dataForm)"
placeholder="请输入工段排序" />
placeholder="请输入工段设备排序" />
</el-form-item>
</el-col>
</el-row>

View File

@ -1,18 +1,26 @@
<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" :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
<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>
</div>
</template>
<script>
@ -20,8 +28,9 @@
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 BalanceChart from '../balanceChart';
import { time } from 'echarts';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
// import { getWorkshopSectionPage } from '@/api/core/base/workshopSection';
// const tableProps = [
@ -46,92 +55,92 @@ import { time } from 'echarts';
// ];
export default {
components: {
BalanceChart
},
// mixins: [basicPage],
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列的规则 */
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]) {
@ -144,117 +153,144 @@ export default {
}
}
},
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',
}
]
let sectionArr= []
res.data.data.forEach((ele, index) => {
let tempData = []
let eqData = []
let plData = []
ele.data.forEach((item, index) => {
item.children.forEach(params => {
if (params.dynamicName === '设备CT') {
tempData[item.dynamicName + '_eq'] = params.dynamicValue
eqData[index] = params.dynamicValue
} else {
tempData[item.dynamicName + '_pl'] = params.dynamicValue
plData[index] = params.dynamicValue
}
})
})
const equipment = {
name: ele.equName,
eqData: eqData,
plData: plData
}
tempData['equName'] = ele.equName
tempData['sectionName'] = ele.sectionName
this.tableData.push(tempData)
const { sectionName } = tempData
sectionArr.push(sectionName)
this.yData.push(equipment)
console.log('看看equ', this.yData)
})
this.setRowSpan(sectionArr)
res.data.nameData.forEach(item => {
this.timeList.push(item.name)
})
const timeArray = Array.from(new Set(this.timeList))
for (const times of timeArray) {
if (times !== '设备CT' && times !== '产线CT') {
const subprop = {
label: times,
align: 'center',
children: [
{ prop: times + '_eq', label: '设备CT', align: 'center' },
{ prop: times + '_pl', label: '产线CT', align: 'center' }
]
}
arr.push(subprop)
this.xData.push(times)
}
}
this.tableProps = arr
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;
console.log('表格横坐标', this.xData)
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);
}
},
},
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>

View File

@ -1,8 +1,8 @@
<!--
* @Author: zhp
* @Date: 2023-09-13 09:02:25
* @LastEditTime: 2023-10-08 16:36:37
* @LastEditors: DY
* @LastEditTime: 2024-11-26 15:52:29
* @LastEditors: zwq
* @Description:
-->
<template>
@ -108,13 +108,28 @@ export default {
},
series: [
{
name: '设备CT',
data: dataList.eqData,
name: '生产规格',
data: dataList.ggData,
type: 'line',
},
{
name: '产线CT',
data: dataList.plData,
name: '设备理论速度',
data: dataList.sbluData,
type: 'line',
},
{
name: '设备实际速度',
data: dataList.sbsjData,
type: 'line',
},
{
name: '产线理论速度',
data: dataList.cxluData,
type: 'line',
},
{
name: '产线实际速度',
data: dataList.cxsjData,
type: 'line',
}
]

View File

@ -1,18 +1,25 @@
<template>
<div class="app-container">
<search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
<div v-if="tableData.length">
<base-table v-loading="dataListLoading" :table-props="tableProps" :table-data="tableData" />
<SearchBar :formConfigs="[{ label: '产品产量对比图', type: 'title' }]" />
<line-chart ref="lineChart" />
</div>
<div v-else class="no-data-bg"></div>
<!-- <pagination
<div class="app-container">
<search-bar
:formConfigs="formConfig"
ref="searchBarForm"
@headBtnClick="buttonClick" />
<div v-if="tableData.length">
<base-table
v-loading="dataListLoading"
:table-props="tableProps"
:max-height="tableH"
:table-data="tableData" />
<SearchBar :formConfigs="[{ label: '产品产量对比图', type: 'title' }]" />
<line-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>
</div>
</template>
<script>
@ -20,7 +27,8 @@
import { parseTime } from '../../mixins/code-filter';
import { getYieldAnalysisPageData } from '@/api/core/analysis/index';
import { getProductionLinePage } from '@/api/core/base/productionLine';
import lineChart from '../LineChart'
import lineChart from '../LineChart';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
// import { getWorkshopSectionPage } from '@/api/core/base/workshopSection';
// const tableProps = [
@ -45,51 +53,52 @@ import lineChart from '../LineChart'
// ];
export default {
components: {
lineChart,
},
// mixins: [basicPage],
components: {
lineChart,
},
mixins: [tableHeightMixin],
data() {
return {
urlOptions: {
getDataListURL: getYieldAnalysisPageData,
getDataListURL: getYieldAnalysisPageData,
},
tableProps:[],
dataListLoading:false,
tableData: [],
listQuery: {
lineIds: [],
time: ''
},
dateLabelList: [],
optionArrUrl: [getProductionLinePage ],
tableProps: [],
dataListLoading: false,
tableData: [],
listQuery: {
lineIds: [],
time: '',
},
dateLabelList: [],
optionArrUrl: [getProductionLinePage],
formConfig: [
{
type: 'select',
label: '产线',
selectOptions: [],
param: 'lineIds',
defaultSelect: '',
multiple:true,
param: 'lineIds',
defaultSelect: [],
multiple: true,
filterable: true,
width: 400,
},
{
type: 'datePicker',
label: '时间',
dateType: 'month',
format: 'yyyy-MM-dd',
format: 'yyyy-MM',
valueFormat: 'yyyy-MM-dd HH:mm:ss',
rangeSeparator: '-',
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
param: 'time',
param: 'time',
},
{
type: 'button',
btnName: '查询',
name: 'search',
color: 'primary',
}
},
],
};
},
@ -104,145 +113,147 @@ export default {
};
this.optionArrUrl.forEach((item, index) => {
item(params).then((response) => {
this.formConfig[index].selectOptions = response.data.list
// this.formConfig[0].defaultSelect = response.data.list[0].id
this.$set(this.formConfig[0], 'defaultSelect', response.data.list[0].id)
this.formConfig[index].selectOptions = response.data.list;
// this.formConfig[0].defaultSelect = response.data.list[0].id
// this.$set(this.formConfig[0], 'defaultSelect', response.data.list[0].id)
});
});
},
getData() {
// this.listQuery.lineIds = ['1672847052717821953']
// this.listQuery.productId = val.productId;
// this.listQuery.time = '1694486098000';
this.urlOptions.getDataListURL(this.listQuery).then(res => {
let arr = [
{
prop: 'lineName',
label: '产线',
fixed: 'left'
},
{
prop: 'sum',
label: '合计',
fixed: 'left'
},
{
prop: res.data ? res.data.nameData[0].name : undefined,
label: res.data ? res.data.nameData[0].name : undefined,
align: 'center',
children:[
},
getData() {
// this.listQuery.lineIds = ['1672847052717821953']
// this.listQuery.productId = val.productId;
// this.listQuery.time = '1694486098000';
this.urlOptions.getDataListURL(this.listQuery).then((res) => {
let arr = [
{
prop: 'lineName',
label: '产线',
fixed: 'left',
},
{
prop: 'sum',
label: '合计[片]',
fixed: 'left',
},
{
prop: res.data ? res.data.nameData[0].name : undefined,
label: res.data ? res.data.nameData[0].name : undefined,
align: 'center',
children: [],
},
];
// console.log(res.data.nameData.slice(1))
let xData = [];
let yAllData = [];
let lineName = [];
if (res.data) {
let tempDateList = [];
res.data.nameData.forEach((date) => {
tempDateList.push(date.name);
});
this.dateLabelList = Array.from(new Set(tempDateList));
]
}
]
// console.log(res.data.nameData.slice(1))
let xData = []
let yAllData = []
let lineName = []
if (res.data) {
let tempDateList = []
res.data.nameData.forEach(date => {
tempDateList.push(date.name)
})
this.dateLabelList = Array.from(new Set(tempDateList))
this.dateLabelList.forEach((item) => {
if (item.indexOf('年') === -1) {
//
const props = {
prop: item,
label: item,
};
arr[2].children.push(props);
this.dateLabelList.forEach(item => {
if (item.indexOf('年') === -1) {
//
const props = {
'prop': item,
'label': item
}
arr[2].children.push(props)
// echarts
xData.push(item);
}
});
// res.data.nameData.slice(1).forEach(item => {
// const props = {
// 'prop': item.name,
// 'label': item.name,
// 'align': 'center'
// }
// arr[2].children.push(props)
// })
let tableDataArr = [];
res.data.data.forEach((item) => {
let obj = {};
(obj.lineName = item.lineName),
(obj.sum = item.sum),
item.data.forEach((ele, index) => {
// console.log(ele)
ele.children.forEach((e) => {
console.log(e.dynamicName);
obj['' + e.dynamicName + ''] = e.dynamicValue;
console.log(obj['' + e.dynamicName + '']);
});
});
tableDataArr.push(obj);
});
this.tableData = tableDataArr;
this.tableProps = arr;
// echarts
xData.push(item)
}
})
// res.data.nameData.slice(1).forEach(item => {
// const props = {
// 'prop': item.name,
// 'label': item.name,
// 'align': 'center'
// }
// arr[2].children.push(props)
// })
let tableDataArr =[]
res.data.data.forEach(item => {
let obj = {}
obj.lineName= item.lineName,
obj.sum= item.sum,
item.data.forEach((ele, index) => {
// console.log(ele)
ele.children.forEach((e) => {
console.log(e.dynamicName)
obj['' + e.dynamicName + ''] = e.dynamicValue
console.log(obj['' + e.dynamicName + '']);
})
})
tableDataArr.push(obj)
});
this.tableData = tableDataArr
this.tableProps = arr
// let tempList = []
// res.data.nameData.slice(1).forEach(item => {
// tempList.push(item.name)
// // arr[2].children.push(props)
// })
// xData = Array.from(new Set(tempList))
res.data.data.forEach(item => {
let yData = []
lineName.push(item.lineName)
// let obj = {}
// obj.lineName = item.lineName,
// obj.sum = item.sum,
item.data.forEach((ele, index) => {
// console.log(ele)
ele.children.forEach((e) => {
// let yData = []
yData.push(e.dynamicValue)
})
})
yAllData.push(yData)
});
console.log(lineName)
} else {
this.tableProps = arr
this.tableData = []
xData = []
yAllData = []
lineName = []
}
// res.data.data[0].data[0].children.forEach((item, index) => {
// // console.log(item)
// yData.push(item.dynamicValue)
// // let data = 'data' + Number(index+1)
// // obj['' + item.dynamicName + ''] = item.dynamicValue
// })
// console.log(this.yData)
this.$refs.lineChart.initChart(xData, yAllData, lineName)
// this.total = response.data.total;
// this.dataListLoading = false;
});
},
buttonClick(val) {
// let tempList = []
// res.data.nameData.slice(1).forEach(item => {
// tempList.push(item.name)
// // arr[2].children.push(props)
// })
// xData = Array.from(new Set(tempList))
res.data.data.forEach((item) => {
let yData = [];
lineName.push(item.lineName);
// let obj = {}
// obj.lineName = item.lineName,
// obj.sum = item.sum,
item.data.forEach((ele, index) => {
// console.log(ele)
ele.children.forEach((e) => {
// let yData = []
yData.push(e.dynamicValue);
});
});
yAllData.push(yData);
});
console.log(lineName);
} else {
this.tableProps = arr;
this.tableData = [];
xData = [];
yAllData = [];
lineName = [];
}
// res.data.data[0].data[0].children.forEach((item, index) => {
// // console.log(item)
// yData.push(item.dynamicValue)
// // let data = 'data' + Number(index+1)
// // obj['' + item.dynamicName + ''] = item.dynamicValue
// })
// console.log(this.yData)
this.$nextTick(() => {
this.$refs.lineChart.initChart(xData, yAllData, lineName);
});
// this.total = response.data.total;
// this.dataListLoading = false;
});
},
buttonClick(val) {
switch (val.btnName) {
case 'search':
this.listQuery.lineIds = val.lineIds ? val.lineIds :undefined
// this.listQuery.productId = val.productId;
this.listQuery.time = val.time ? new Date(val.time).getTime() : undefined
case 'search':
this.listQuery.lineIds = val.lineIds ? val.lineIds : undefined;
// this.listQuery.productId = val.productId;
this.listQuery.time = val.time
? new Date(val.time).getTime()
: undefined;
// this.listQuery.pageNo = 1;
// this.listQuery.pageSize = 10;
if (val.time) {
this.getData()
} else {
this.$message({
message: '请选择时间',
type: 'warning'
});
}
// this.listQuery.pageSize = 10;
if (val.time) {
this.getData();
} else {
this.$message({
message: '请选择时间',
type: 'warning',
});
}
break;
case 'reset':
this.$refs.searchBarForm.resetForm();

View File

@ -308,6 +308,7 @@ export default {
});
if (code == 0) {
this.$modal.msgSuccess('更新成功');
this.$emit('refreshDataList');
}
this.btnLoading = false;

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: dialogForm.vue
author: liubin
date: 2023-08-15 10:32:36
@ -57,6 +57,7 @@
v-model="form.equipmentTypeId"
:disabled="disabled"
filterable
clearable
placeholder="请选择设备类型">
<el-option
v-for="eqType in eqTypeList"
@ -79,7 +80,7 @@
<el-col :span="8">
<el-form-item label="生产日期" prop="productionTime" :rules="[]">
<el-date-picker
v-model="form.enterTime"
v-model="form.productionTime"
:disabled="disabled"
type="datetime"
placeholder="请选择生产日期"

View File

@ -157,7 +157,7 @@ export default {
width: 180,
filter: (val) => moment(val).format('yyyy-MM-DD HH:mm:ss'),
},
{ prop: 'name', label: '设备名称' },
{ width: 200,showOverflowtooltip :true, prop: 'name', label: '设备名称' },
{ width: 256, prop: 'code', label: '设备编码' },
{ prop: 'equipmentType', label: '设备类型' },
{ prop: 'enName', label: '英文名称' },
@ -270,6 +270,7 @@ export default {
url: '/base/equipment-type/page?pageNo=1&pageSize=100',
bind: {
filterable: true,
clearable: true,
},
},
// {

View File

@ -153,6 +153,9 @@ export default {
label: '父类',
prop: 'parentId',
url: '/base/equipment-type/page?pageNo=1&pageSize=100',
bind: {
clearable: true, // some condition, like detail mode...
}
},
{},
],

View File

@ -28,11 +28,11 @@ import { getProductPage } from '@/api/core/base/product';
const tableProps = [
{
prop: 'productionLineName',
label: '产线'
label: '产线',
},
{
prop: 'productName',
label: '在制产品'
label: '在制产品',
},
{
prop: 'startTime',
@ -83,7 +83,7 @@ export default {
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
param: 'startTime',
valueFormat: 'timestamp'
valueFormat: 'timestamp',
},
{
type: 'button',
@ -99,8 +99,7 @@ export default {
],
};
},
components: {
},
components: {},
created() {
this.getArr();
},
@ -123,7 +122,7 @@ export default {
this.listQuery.pageSize = 10;
this.listQuery.productionLineId = val.productionLineId;
this.listQuery.productId = val.productId;
this.listQuery.startTime = val.startTime;
this.listQuery.startTime = val.startTime ? val.startTime : null;
this.getDataList();
break;
case 'reset':

View File

@ -154,7 +154,9 @@
<el-button v-if="isdetail" type="primary" @click="goEdit()">
编辑
</el-button>
<el-button v-else type="primary" @click="dataFormSubmit()">确定</el-button>
<el-button v-else type="primary" @click="dataFormSubmit()">
确定
</el-button>
</div>
<product-attr-add
@ -371,8 +373,19 @@ export default {
//
createProduct(this.dataForm).then((response) => {
this.$modal.msgSuccess('新增成功');
this.visible = false;
this.$emit('refreshDataList');
this.$confirm(`是否新增产品属性?`, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(() => {
this.dataForm.id = response.data
this.addNew();
})
.catch(() => {
this.visible = false;
this.$emit('refreshDataList');
});
});
}
});
@ -382,10 +395,14 @@ export default {
},
// /
addNew(id) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
if (this.dataForm.id) {
this.addOrUpdateVisible = true;
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id);
});
} else {
this.$message('请先创建产品!');
}
},
goback() {
this.$emit('refreshDataList');

View File

@ -2,7 +2,7 @@
* @Author: zwq
* @Date: 2023-08-01 13:52:10
* @LastEditors: zwq
* @LastEditTime: 2024-04-10 16:31:51
* @LastEditTime: 2024-11-22 14:02:59
* @Description:
-->
<template>
@ -139,11 +139,11 @@ export default {
},
pdTypeArr: [
{
id: 0,
id: '0',
name: '深加工'
},
{
id: 1,
id: '1',
name: '原片'
}
],

View File

@ -1,8 +1,8 @@
<!--
* @Author: Do not edit
* @Date: 2023-08-29 14:59:29
* @LastEditTime: 2023-10-16 15:10:42
* @LastEditors: DY
* @LastEditTime: 2024-11-20 15:17:53
* @LastEditors: zwq
* @Description:
-->
<template>
@ -312,8 +312,8 @@ export default {
this.listQuery.pageSize = 10;
this.listQuery.lineId = val.line ? val.line : undefined;
this.listQuery.reportType = val.reportType ? val.reportType : undefined;
this.listQuery.reportStartTime = val.timeVal ? [new Date(val.timeVal[0]).getTime()] : undefined;
this.listQuery.reportEndTime = val.timeVal ? [new Date(val.timeVal[1]).getTime()] : undefined;
this.listQuery.reportStartTime = val.timeVal ? [new Date(val.timeVal[0]).getTime(),new Date(val.timeVal[1]).getTime()] : undefined;
//this.listQuery.reportEndTime = val.timeVal ? [new Date(val.timeVal[1]).getTime()] : undefined;
if (val.timeVal && val.timeVal.length > 0) {
this.fileName = val.timeVal[0].slice(0, 10) + '-' + val.timeVal[1].slice(0, 10) + '_'
}

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: index.vue
author: liubin
date: 2023-08-04 14:44:58
@ -16,6 +16,7 @@
v-if="tableData && tableData.length > 0"
:table-props="tableProps"
:table-data="tableData"
:max-height="tableH"
@emitFun="handleEmitFun"
/>
</div>
@ -24,11 +25,13 @@
<script>
import { getPdlDataOneDay } from '@/api/core/monitoring/data24'
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
export default {
name: 'productionLineData24',
components: {},
props: {},
mixins: [tableHeightMixin],
data() {
return {
urlOptions: {
@ -41,7 +44,7 @@ export default {
},
list: [],
arr: [],
spanArr: [],
spanArr: [],
timeList: [],
tableData: [],
tableProps: [],
@ -168,7 +171,7 @@ export default {
// // console.log('recent-24', data);
// this.initing = true;
// this.queryParams.pageSize = this.list.length;
// setTimeout(() => {

View File

@ -1,8 +1,8 @@
<!--
* @Author: Do not edit
* @Date: 2023-08-29 14:59:29
* @LastEditTime: 2023-10-16 15:19:04
* @LastEditors: DY
* @LastEditTime: 2024-11-26 16:35:22
* @LastEditors: zwq
* @Description:
-->
<template>
@ -69,11 +69,13 @@ const tableProps = [
prop: 'reportStartTime',
label: '统计开始时间',
filter: parseTime,
width:160
},
{
prop: 'reportEndTime',
label: '统计结束时间',
filter: parseTime,
width:160
},
{
prop: 'lineName',
@ -309,8 +311,8 @@ export default {
this.listQuery.lineId = val.line ? val.line : undefined;
this.listQuery.sectionId = val.section ? val.section : undefined;
this.listQuery.reportType = val.reportType ? val.reportType : undefined;
this.listQuery.reportStartTime = val.timeVal ? [new Date(val.timeVal[0]).getTime()] : undefined;
this.listQuery.reportEndTime = val.timeVal ? [new Date(val.timeVal[1]).getTime()] : undefined;
this.listQuery.reportStartTime = val.timeVal ? [new Date(val.timeVal[0]).getTime(),new Date(val.timeVal[1]).getTime()] : undefined;
//this.listQuery.reportEndTime = val.timeVal ? [new Date(val.timeVal[1]).getTime()] : undefined;
if (val.timeVal && val.timeVal.length > 0) {
this.fileName = val.timeVal[0].slice(0, 10) + '-' + val.timeVal[1].slice(0, 10) + '_'
}

View File

@ -14,8 +14,7 @@
:limit="listQuery.pageSize"
:selectWidth="55"
:table-data="showData"
@selection-change="selectChange"
/>
@selection-change="selectChange" />
<div v-else class="no-data-bg"></div>
<pagination
:limit.sync="listQuery.pageSize"
@ -28,10 +27,12 @@
width="30%"
:before-close="handleClose">
<el-button type="primary" @click="exportXlsx">xlsx</el-button>
<el-button type="success" @click="exportPdf">pdf</el-button>
<el-button type="success" @click="exportPdf">pdf</el-button>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="dialogVisible = false">
</el-button>
</span>
</el-dialog>
</div>
@ -42,40 +43,41 @@
import { getSectionDataSearch } from '@/api/core/monitoring';
import { getProductionLinePage } from '@/api/core/base/productionLine';
import { getWorkshopSectionPage } from '@/api/core/base/workshopSection';
import * as XLSX from 'xlsx'
import FileSaver from 'file-saver'
import jsPDF from 'jspdf'
import html2canvas from 'html2canvas'
import { parseTime } from '@/filter/code-filter';
import * as XLSX from 'xlsx';
import FileSaver from 'file-saver';
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';
const tableProps = [
{
prop: 'proLineName',
label: '产线名称'
prop: 'proLineName',
label: '产线名称',
},
{
prop: 'sectionName',
label: '工段名称',
},
{
prop: 'inputNum',
label: '进片数量/片',
},
{
prop: 'outputNum',
label: '出片数量/片',
},
{
prop: 'lossNum',
label: '损耗数量/片',
},
{
prop: 'lossArea',
label: '损耗面积/m²',
},
{
prop: 'lossRate',
label: '损耗比例/%',
},
{
prop: 'sectionName',
label: '工段名称'
},
{
prop: 'inputNum',
label: '进片数量/片'
},
{
prop: 'outputNum',
label: '出片数量/片'
},
{
prop: 'lossNum',
label: '损耗数量/片'
},
{
prop: 'lossArea',
label: '损耗面积/m²'
},
{
prop: 'lossRate',
label: '损耗比例/%'
}
];
export default {
@ -83,29 +85,29 @@ export default {
data() {
return {
urlOptions: {
getDataListURL: getSectionDataSearch,
getDataListURL: getSectionDataSearch,
},
tableProps,
tableData: [],
tableData: [],
showData: [],
selectedList: [],
listQuery: {
proLineId:undefined,
sectionId: undefined,
startTime: undefined,
endTime: undefined,
total: 0
},
listQuery: {
proLineId: undefined,
sectionId: undefined,
startTime: undefined,
endTime: undefined,
total: 0,
},
dataListLoading: false,
dialogVisible: false,
fileName: [],
optionArrUrl: [getProductionLinePage, getWorkshopSectionPage],
optionArrUrl: [getProductionLinePage, getWorkshopSectionPage],
formConfig: [
{
type: 'select',
label: '产线',
selectOptions: [],
param: 'proLineId',
param: 'proLineId',
defaultSelect: '',
filterable: true,
onchange: true,
@ -114,7 +116,7 @@ export default {
type: 'select',
label: '工段',
selectOptions: [],
param: 'sectionId',
param: 'sectionId',
defaultSelect: '',
filterable: true,
},
@ -143,15 +145,21 @@ export default {
btnName: '导出',
name: 'export',
color: 'warning',
}
},
],
};
},
components: {
},
components: {},
created() {
this.getArr();
// this.getDataList()
this.getArr();
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 1);
this.listQuery.startTime = start.getTime();
this.listQuery.endTime = end.getTime();
this.formConfig[2].startPlaceholder = parseTime(start).substr(0, 10);
this.formConfig[2].endPlaceholder = parseTime(end).substr(0, 10);
this.getDataList();
},
methods: {
/** 根据产线获取工段 */
@ -184,92 +192,96 @@ export default {
}
},
test() {
var target = document.getElementsByClassName("right-aside")[0]
target.style.background = '#FFFFFF'
var that = this
var target = document.getElementsByClassName('right-aside')[0];
target.style.background = '#FFFFFF';
var that = this;
setTimeout(() => {
html2canvas(target).then(function(canvas) {
var contentWidth = canvas.width
var contentHeight = canvas.height
html2canvas(target).then(function (canvas) {
var contentWidth = canvas.width;
var contentHeight = canvas.height;
// pdfhtmlcanvas
var pageHeight = contentHeight / 592.28 * 841.89
// pdfhtml
var leftHeight = contentHeight
//
var position = 0
// a4[595.28,841.89]htmlcanvaspdf
var imgWidth = 595.28
var imgHeight = 592.28 / contentWidth * contentHeight
// pdfhtmlcanvas
var pageHeight = (contentHeight / 592.28) * 841.89;
// pdfhtml
var leftHeight = contentHeight;
//
var position = 0;
// a4[595.28,841.89]htmlcanvaspdf
var imgWidth = 595.28;
var imgHeight = (592.28 / contentWidth) * contentHeight;
var pageData = canvas.toDataURL('image/jpeg', 1.0)
var pageData = canvas.toDataURL('image/jpeg', 1.0);
console.log('nihc URL', leftHeight, pageHeight)
console.log('nihc URL', leftHeight, pageHeight);
var pdf = new jsPDF('', 'pt', 'a4')
var pdf = new jsPDF('', 'pt', 'a4');
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, 20, imgWidth, imgHeight)
} else {
while(leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
//
if (leftHeight > 0) {
pdf.addPage()
}
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, 20, imgWidth, imgHeight);
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= 841.89;
//
if (leftHeight > 0) {
pdf.addPage();
}
}
}
pdf.save(that.fileName[0] + '-' + that.fileName[1] + '_工段统计.pdf')
})
}, 300)
pdf.save(that.fileName[0] + '-' + that.fileName[1] + '_工段统计.pdf');
});
}, 300);
},
exportECL() {
let tables = document.querySelector('.el-table').cloneNode(true)
const fix = tables.querySelector('.el-table__fixed')
const fixRight = tables.querySelector('.el-table__fixed-right')
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'))
tables.removeChild(tables.querySelector('.el-table__fixed'));
}
if (fixRight) {
tables.removeChild(tables.querySelector('.el-table__fixed-right'))
tables.removeChild(tables.querySelector('.el-table__fixed-right'));
}
let exportTable = XLSX.utils.table_to_book(tables)
let exportTable = XLSX.utils.table_to_book(tables);
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[0] + '-' + this.fileName[1] + '_工段统计.xlsx')
} catch (e) {
if (typeof console !== 'undefined') console.log(e, exportTableOut)
}
return exportTableOut
},
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[0] + '-' + this.fileName[1] + '_工段统计.xlsx'
);
} catch (e) {
if (typeof console !== 'undefined') console.log(e, exportTableOut);
}
return exportTableOut;
},
exportPdf() {
this.test()
setTimeout(() =>{
this.dialogVisible = false
this.showData = this.tableData
}, 600)
this.test();
setTimeout(() => {
this.dialogVisible = false;
this.showData = this.tableData;
}, 600);
},
exportXlsx() {
this.exportECL()
this.dialogVisible = false
this.showData = this.tableData
this.exportECL();
this.dialogVisible = false;
this.showData = this.tableData;
},
handleClose(done) {
this.$confirm('确认关闭?')
.then(_ => {
.then((_) => {
done();
})
.catch(_ => {});
.catch((_) => {});
},
getArr() {
const params = {
@ -281,61 +293,62 @@ export default {
this.formConfig[index].selectOptions = response.data.list;
});
});
},
getDataList() {
// this.listQuery.proLineId = '1672847052717821953';
// this.listQuery.startTime = '1690626657000'
// this.listQuery.endTime = '1693564257000'
this.urlOptions.getDataListURL(this.listQuery).then(res => {
this.tableData = res.data
this.listQuery.total = this.tableData.length;
this.dataListLoading = false;
},
getDataList() {
this.urlOptions.getDataListURL(this.listQuery).then((res) => {
this.tableData = res.data;
this.listQuery.total = this.tableData.length;
this.dataListLoading = false;
this.showData = this.tableData;
});
},
});
},
//
sizeChangeHandle(val) {
this.listQuery.pageSize = val;
this.listQuery.pageNo = 1;
this.getDataList();
},
//
currentChangeHandle(val) {
this.listQuery.pageNo = val;
this.getDataList();
},
sizeChangeHandle(val) {
this.listQuery.pageSize = val;
this.listQuery.pageNo = 1;
this.getDataList();
},
//
currentChangeHandle(val) {
this.listQuery.pageNo = val;
this.getDataList();
},
handleExport() {
if (this.selectedList.length > 0) {
this.showData = this.selectedList
this.showData = this.selectedList;
}
this.dialogVisible = true
},
this.dialogVisible = true;
},
selectChange(val) {
console.log(val)
this.selectedList = val
},
buttonClick(val) {
console.log(val)
switch (val.btnName) {
case 'search':
console.log(val.timeSlot);
console.log(val);
this.selectedList = val;
},
buttonClick(val) {
console.log(val);
switch (val.btnName) {
case 'search':
console.log(val.timeSlot);
// this.listQuery.pageNo = 1;
// this.listQuery.pageSize = 10;
this.listQuery.proLineId = val.proLineId ? val.proLineId : undefined
this.listQuery.sectionId = val.sectionId ? val.sectionId : undefined
this.listQuery.startTime = val.timeSlot ? new Date(val.timeSlot[0]).getTime() : undefined
this.listQuery.endTime = val.timeSlot ? new Date(val.timeSlot[1]).getTime() : undefined
// this.listQuery.pageSize = 10;
this.listQuery.proLineId = val.proLineId ? val.proLineId : undefined;
this.listQuery.sectionId = val.sectionId ? val.sectionId : undefined;
this.listQuery.startTime = val.timeSlot
? new Date(val.timeSlot[0]).getTime()
: undefined;
this.listQuery.endTime = val.timeSlot
? new Date(val.timeSlot[1]).getTime()
: undefined;
if (val.timeSlot && val.timeSlot.length > 0) {
this.fileName[0] = val.timeSlot[0].slice(0, 10)
this.fileName[1] = val.timeSlot[1].slice(0, 10)
this.getDataList()
} else {
this.$message({
message: '请选择时间',
type: 'warning'
});
}
this.fileName[0] = val.timeSlot[0].slice(0, 10);
this.fileName[1] = val.timeSlot[1].slice(0, 10);
this.getDataList();
} else {
this.$message({
message: '请选择时间',
type: 'warning',
});
}
break;
case 'reset':
this.$refs.searchBarForm.resetForm();
@ -349,12 +362,12 @@ export default {
case 'export':
if (val.timeSlot && val.timeSlot.length > 0) {
this.handleExport();
} else {
this.$message({
message: '请选择时间',
type: 'warning'
});
}
} else {
this.$message({
message: '请选择时间',
type: 'warning',
});
}
break;
default:
console.log(val);

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: index.vue
author: liubin
date: 2023-09-04 09:34:52
@ -25,8 +25,9 @@
class="base-table__margin"
:table-props="tableProps"
:page="1"
:limit="10"
:limit="999"
:table-data="list"
:max-height="tableH"
@emitFun="handleEmitFun"></base-table>
</el-tab-pane>
<el-tab-pane
@ -88,11 +89,12 @@
<script>
// import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
import PieChart from './components/pieChart.vue';
export default {
name: 'EfficiencyAnalysis',
mixins: [basicPageMixin],
mixins: [basicPageMixin,tableHeightMixin],
components: { PieChart },
props: {},
data() {
@ -118,8 +120,8 @@ export default {
tableProps: [
{ prop: 'factoryName', label: '工厂' },
{ prop: 'lineName', label: '产线' },
{ prop: 'sectionName', label: '工段' },
{ prop: 'equipmentName', label: '设备' },
{ prop: 'sectionName', width:120,showOverflowtooltip :true,label: '工段' },
{ prop: 'equipmentName',width:150,showOverflowtooltip :true, label: '设备' },
{
label: '有效时间',
children: [
@ -127,12 +129,13 @@ export default {
width: 128,
prop: 'workTime',
label: '工作时长[h]',
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
{
width: 128,
prop: 'workRate',
label: '百分比[%]',
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
],
},
@ -143,8 +146,11 @@ export default {
width: 128,
prop: 'stopTime',
label: '停机时长[h]',
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
{ width: 128, prop: 'stopRate', label: '百分比[%]' },
{ width: 128, prop: 'stopRate', label: '百分比[%]',
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
],
},
{
@ -154,14 +160,16 @@ export default {
width: 128,
prop: 'downTime',
label: '故障时长[h]',
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
{ width: 128, prop: 'downRate', label: '百分比[%]' },
{ width: 128, prop: 'downRate', label: '百分比[%]' ,
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
{
width: 128,
prop: 'timeEfficiency',
label: '时间开动率',
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
],
},
@ -172,29 +180,31 @@ export default {
width: 128,
prop: 'realProcSpeed',
label: '实际加工速度',
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
{
width: 128,
prop: 'designProcSpeed',
label: '理论加工速度',
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
{
width: 128,
prop: 'peEfficiency',
label: '速度开动率',
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
],
},
{
prop: 'oee',
label: 'OEE',
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
{
prop: 'teep',
label: 'TEEP',
filter: (val) => (val != null ? +val.toFixed(3) : '-'),
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
// {
// _action: 'view-trend',

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: index.vue
author: liubin
date: 2023-09-04 09:34:52
@ -19,6 +19,7 @@
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
:max-height="tableH"
@emitFun="handleEmitFun">
<!-- <method-btn
v-if="tableBtn.length"
@ -41,10 +42,11 @@
<script>
import moment from 'moment';
import basicPageMixin from '@/mixins/lb/basicPageMixin';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
export default {
name: 'ExceptionAnalysis',
mixins: [basicPageMixin],
mixins: [basicPageMixin, tableHeightMixin],
components: {},
props: {},
data() {

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
<!--
<!--
filename: lineChart.vue
author: liubin
date: 2023-09-04 13:45:00
description:
description:
-->
<template>
@ -11,6 +11,7 @@
<script>
import * as echarts from 'echarts';
import edata from './data';
export default {
name: 'LineChart',
@ -43,7 +44,7 @@ export default {
eq.okQuantity,
eq.nokQuantity,
eq.totalQuantity,
eq.passRate?.toFixed(4),
typeof eq.passRate === "number" ? eq.passRate.toFixed(4) : "0.0000"
]);
});
return {

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: index.vue
author: liubin
date: 2023-09-04 09:34:52
@ -26,6 +26,7 @@
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
:max-height="tableH"
@emitFun="handleEmitFun"></base-table>
</el-tab-pane>
<el-tab-pane :label="'\u3000柱状图\u3000'" name="graph">
@ -47,10 +48,13 @@
<script>
import moment from 'moment';
import LineChart from './components/lineChart.vue';
import { parseTime } from '@/filter/code-filter';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
export default {
name: 'QualityAnalysis',
components: { LineChart },
mixins: [tableHeightMixin],
props: {},
data() {
const now = new Date();
@ -92,24 +96,6 @@ export default {
endPlaceholder: '结束日期',
defaultTime: ['00:00:00', '23:59:59'],
param: 'recordTime',
defaultSelect: [
new Date(y, m, d)
.toLocaleString()
.split('/')
.map((item, index) => {
if (index == 1 || index == 2) return item.padStart(2, '0');
return item;
})
.join('-'),
new Date(y, m, d, 23, 59, 59)
.toLocaleString()
.split('/')
.map((item, index) => {
if (index == 1 || index == 2) return item.padStart(2, '0');
return item;
})
.join('-'),
],
},
{
type: 'button',
@ -156,22 +142,23 @@ export default {
{
// width: 160,
prop: 'inQuantity',
label: '进片数量',
label: '进片数量[片]',
},
{
// width: 160,
prop: 'outQuantity',
label: '出片数量',
label: '出片数量[片]',
},
{
// width: 160,
prop: 'nokQuantity',
label: '破损/不合格数',
label: '破损/不合格数[片]',
},
{
// width: 160,
prop: 'passRate',
label: '合格率',
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
],
lineChartConfig: {
@ -248,11 +235,23 @@ export default {
},
computed: {},
created() {
const end = new Date();
const start = new Date();
this.queryParams.recordTime = [
parseTime(start).substr(0, 10) + ' 00:00:00',
parseTime(end).substr(0, 10) + ' 23:59:59',
];
this.searchBarFormConfig[2].startPlaceholder = parseTime(start).substr(
0,
10
);
this.searchBarFormConfig[2].endPlaceholder = parseTime(end).substr(0, 10);
this.fillLineOptions();
this.fillProductOptions();
this.getList();
},
mounted() {
this.$refs['search-bar'].headBtnClick('search');
//this.$refs['search-bar'].headBtnClick('search');
},
methods: {
handleTabClick(tab, event) {

View File

@ -1,8 +1,15 @@
<!--
<!--
* @Author: zwq
* @Date: 2024-10-29 09:47:40
* @LastEditors: zwq
* @LastEditTime: 2024-11-26 14:41:52
* @Description:
-->
<!--
filename: lineChart.vue
author: liubin
date: 2023-09-04 13:45:00
description:
description:
-->
<template>
@ -32,6 +39,12 @@ export default {
mounted() {
this.init();
},
activated() {
// echartresize, resize, bug
if (this.chart) {
this.echart.resize();
}
},
beforeDestroy() {
if (this.chart) {
this.chart.dispose();
@ -43,7 +56,10 @@ export default {
this.setOption(this.config);
},
setOption(option) {
if (this.chart) this.chart.setOption(option);
if (this.chart) this.chart.setOption(option,true);
window.addEventListener("resize", () => {
this.chart.resize();
});
},
},
};

View File

@ -144,28 +144,18 @@ export default {
eqList: [],
graphList: [],
templateConfig: {
color: [
'#283D68',
'#FFB61F',
'#4481FF',
'#5AD8A6',
'#E97466',
'#ccc', //<===
'#ccc',
'#ccc',
'#ccc',
'#ccc',
],
grid: {
top: 48,
left: 48,
right: 24,
right: 90,
bottom: 24,
},
legend: {
top: 0,
right: 12,
padding: 6,
type: 'scroll',
orient: 'vertical',
right: 10,
top: 20,
bottom: 20,
itemWidth: 16,
itemHeight: 8,
itemGap: 20,
@ -495,6 +485,7 @@ export default {
return;
}
this.graphList.push(...newEqlist);
this.templateConfig.series = [];
newEqlist.forEach(this.setSeries);
}
this.open = false;

View File

@ -86,7 +86,7 @@ export default class GanttGraph {
<span class="eq-name" style="margin-left: 4px;">${params.seriesName}</span>
</div>
<span class="run-status" style="margin-left: 8px; opacity: 0.6">${params.name}</span>
</div>
</div>
`
}
}
@ -112,7 +112,7 @@ export default class GanttGraph {
// top: 12 + 128 * this.gridIndex,
top: 12 + 104 * this.gridIndex,
right: 48,
left: 88,
left: 100,
height: 56
}
}
@ -175,7 +175,7 @@ export default class GanttGraph {
nameGap: 14,
nameRotate: 0,
nameTextStyle: {
fontSize: 16,
fontSize: 12,
color: '#000A'
},
axisLine: {
@ -325,4 +325,4 @@ export default class GanttGraph {
console.log(JSON.stringify(this.option, null, 2));
}
}
}

View File

@ -0,0 +1,302 @@
import * as echarts from 'echarts'
function getStartTime(timestamp) {
return new Date(new Date(timestamp).toLocaleDateString()).getTime();
}
function renderItem(params, api) {
var categoryIndex = api.value(0);
var start = api.coord([api.value(1), categoryIndex]);
var end = api.coord([api.value(2), categoryIndex]);
var height = api.size([0, 1])[1] * 0.5;
var rectShape = echarts.graphic.clipRectByRect(
{
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height,
},
{
x: params.coordSys.x,
y: params.coordSys.y - 16,
width: params.coordSys.width,
height: params.coordSys.height,
}
);
return (
rectShape && {
type: 'rect',
transition: ['shape'],
shape: rectShape,
style: api.style(),
}
);
}
// unused
function getXaxisRange(startTime) {
return Array(24)
.fill(startTime)
.map((item, index) => {
return new Date(item + index * 3600 * 1000)
.toLocaleTimeString()
.split(':')
.slice(0, 2)
.join(':');
});
}
function getTodayStart(today) {
const [y, m, d] = [
today.getFullYear(),
today.getMonth(),
today.getDate(),
];
// debugger;
return new Date(y, m, d).getTime();
}
/** 颜色配置 */
const types = [
{ name: '运行', color: '#288AFF' },
{ name: '故障', color: '#FC9C91' },
{ name: '计划停机', color: '#FFDC94' },
{ name: '空白', color: '#F2F4F9' },
];
export default class GanttGraph {
// tooltip - 基本是固定的
tooltip = {
trigger: 'item',
axisPointer: {
type: 'none',
},
formatter: (params) => {
// debugger;
return `
<div style="display: flex; flex-direction: column;">
<span>${new Date(params.value[1]).toLocaleTimeString()} ~ ${new Date(params.value[2]).toLocaleTimeString()}</span>
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="display: flex; align-items: center;">
<span class="icon" style="width: 8px; height: 8px; border-radius: 2px; background: ${params.color}"></span>
<span class="eq-name" style="margin-left: 4px;">${params.data.showName}</span>
</div>
<span class="run-status" style="margin-left: 8px; opacity: 0.6">${params.name}</span>
</div>
`
}
}
grid = []
xAxis = []
yAxis = []
series = []
constructor(el, startTime) {
this.el = el;
this.startTime = new Date(startTime);
// this.startTime = new Date(new Date('2023/10/8').toLocaleDateString());
// console.log('<> Gantt Created', this.startTime);
}
// 构造一个新的 grid
makeGrid() {
return {
top: 0,
right: 20,
left: 100,
bottom: 50,
}
}
// 构造一个 xAxis
makeXaxis() {
return [
{
axisTick: {
alignWithLabel: true,
inside: true,
},
type: 'time',
min: getTodayStart(this.startTime),
max: getStartTime(this.startTime.getTime() + 3600 * 24 * 1000),
splitNumber: 10,
axisLabel: {
margin: 12,
formatter: function (val) {
return new Date(val)
.toLocaleTimeString()
.split(':')
.slice(0, 2)
.join(':');
},
},
axisLine: {
lineStyle: {
color: '#0005',
},
},
boundaryGap: false,
// data: getXaxisRange(getTodayStart(new Date())),
},
]
}
// 构造一个 yAxis
makeYaxis(equipmentName) {
return [
// 主y轴
{
data: equipmentName,
}
]
}
// 构造一个 series
makeSeries(xdata) {
const bgStartTime = this.startTime.getTime();
const bgEndTime = bgStartTime + 3600 * 24 * 1000;
return [
{
type: 'custom',
renderItem: renderItem,
itemStyle: {
opacity: 0.8,
},
encode: {
x: [1, 2],
y: 0,
},
data: xdata,
},
]
}
init(data) {
if (!this.el) throw new Error('没有可供echarts初始化的容器')
if (typeof this.el == 'string') {
this.el = document.querySelector(this.el);
}
this.chart = echarts.init(this.el);
this.handleProps(data);
setTimeout(() => {
// debugger;
this.chart.setOption(this.option);
}, 200);
}
update(data) {
this.clear();
this.init(data);
}
resize() {
this.chart.resize();
}
get option() {
return {
tooltip: this.tooltip,
grid: this.grid,
xAxis: this.xAxis,
yAxis: this.yAxis,
series: this.series,
dataZoom: [
{
type: 'slider',
xAxisIndex: 0,
filterMode: 'weakFilter',
height: 20,
bottom: 0,
start: 0,
end: 80,
handleIcon:
'path://M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '80%',
showDetail: false
},
{
type: 'inside',
id: 'insideX',
xAxisIndex: 0,
filterMode: 'weakFilter',
start: 0,
end: 80,
zoomOnMouseWheel: true,
moveOnMouseMove: true
},
{
type: 'slider',
yAxisIndex: 0,
zoomLock: true,
width: 10,
right: 10,
top: 70,
bottom: 20,
start: 0,
end: 100,
handleSize: 0,
showDetail: false
},
{
type: 'inside',
id: 'insideY',
yAxisIndex: 0,
start: 0,
end: 100,
zoomOnMouseWheel: true,
moveOnMouseMove: true,
moveOnMouseWheel: true
}
],
}
}
// 每次 graphList 刷新都会重新渲染整个所有图表
// 可以改进的地方:添加一个 handleAdd() 方法,一次添加一个新的
handleProps(props) {
// props 是父组件的 graphList
console.log('props: ', props);
let ylist = []
let xdata = []
props.forEach((eqArr, index) => {
ylist.push(eqArr.key)
eqArr.forEach(item => {
xdata.push({
name: ['运行', '故障', '计划停机'][item.status],
showName: eqArr.key,
value: [index, item.startTime, item.startTime + item.duration * 60 * 1000, 0],
itemStyle: {
color: types[item.status].color,
}
}
)
})
});
this.grid.push(this.makeGrid());
this.xAxis.push(...this.makeXaxis());
this.yAxis.push(...this.makeYaxis(ylist));
this.series.push(...this.makeSeries(xdata))
}
// handleAdd
handleAdd() { }
clear() {
this.grid = [];
this.xAxis = [];
this.yAxis = [];
this.series = [];
this.chart.dispose();
}
// print option
print() {
console.log(JSON.stringify(this.option, null, 2));
}
}

View File

@ -47,8 +47,8 @@
</div>
</el-col>
</el-row>
<div class="main-area" style="flex: 1; display: flex; flex-direction: column">
<div class="graphs" v-show="graphList.length" id="status-chart" style="height: 1px; flex: 1"></div>
<div class="main-area" style="flex: 1; display: flex; flex-direction: column;">
<div class="graphs" v-show="graphList.length" id="status-chart" style="height: 1px; flex: 1;"></div>
<h2 v-if="!graphList || graphList.length == 0" class="no-data-bg"></h2>
</div>
</el-row>
@ -64,7 +64,7 @@
</template>
<script>
import Gantt from './chart';
import Gantt from './gantt';
export default {
name: 'SGStatus',

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: index.vue
author: liubin
date: 2023-08-31 09:14:19
@ -20,6 +20,7 @@
:table-props="table.tableProps"
:table-data="table.dataManager?.dataList ?? []"
:span-method="spanMethod"
:max-height="tableH"
@emitFun="(val) => handleEmitFun(table, val)"></base-table>
<pagination
:key="table.key + '__pagination'"
@ -35,8 +36,7 @@
" />
</div>
</div>
<div v-else class="no-data-bg">
</div>
<div v-else class="no-data-bg"></div>
</div>
</template>
@ -44,9 +44,11 @@
import LocalDataManager from './utils/local-data-manager';
// import response from './response';
import moment from 'moment';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
export default {
name: 'EquipmentFullParams',
mixins: [tableHeightMixin],
components: {},
props: {},
data() {
@ -94,7 +96,7 @@ export default {
},
],
queryParams: {
id: null,
equipmentId: null,
time: [new Date(aWeekAgo), new Date(today)],
},
tableList: [
@ -121,7 +123,7 @@ export default {
},
},
mounted() {
if (this.id) this.$set(this.queryParams, 'id', this.id);
if (this.id) this.$set(this.queryParams, 'equipmentId', this.id);
if (this.code)
this.$set(this.searchBarFormConfig[0], 'defaultSelect', this.code);
if (this.name)

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
<!--
<!--
filename: graph.vue
author: liubin
date: 2023-08-31 14:00:02
description:
description:
-->
<template>
@ -14,6 +14,7 @@
<script>
import * as echarts from 'echarts';
import edata from './data';
export default {
name: 'LineChartInEquipmentProcessAmount',
@ -30,6 +31,12 @@ export default {
right: 64,
bottom: 56,
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
title: {
show: false,
text: '各设备加工数量',
@ -40,18 +47,30 @@ export default {
left: 'center',
top: 24,
},
yAxis: {
type: 'category',
axisLine: {
show: true,
lineStyle: {
color: '#777',
toolbox: {
feature: {
dataZoom: {
xAxisIndex: false,
},
saveAsImage: {
pixelRatio: 2,
},
},
axisTick: {
show: false,
},
dataZoom: [
{
type: 'slider',
yAxisIndex: 0,
filterMode: 'none',
},
// data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
{
type: 'inside',
yAxisIndex: 0,
filterMode: 'none',
},
],
yAxis: {
type: 'category',
data: [],
name: '设备名',
nameTextStyle: {
@ -60,12 +79,6 @@ export default {
},
xAxis: {
type: 'value',
axisLine: {
show: true,
lineStyle: {
color: '#777',
},
},
name: '数量',
nameTextStyle: {
fontSize: 14,
@ -73,7 +86,6 @@ export default {
},
series: [
{
// data: [120, 200, 150, 80, 70, 110, 130],
data: [],
type: 'bar',
barWidth: 20,
@ -82,10 +94,8 @@ export default {
distance: 50,
formatter: '{c}',
},
showBackground: true,
backgroundStyle: {
color: 'rgba(180, 180, 180, 0.2)',
},
large: true,
largeThreshold: 20,
},
],
},
@ -96,7 +106,7 @@ export default {
handler: function (newVal, oldVal) {
if (!this.chart) this.chart = echarts.init(this.$refs.chart);
this.$nextTick(() => {
if (this.chart) this.chart.setOption(this.updateConfig(this.option));
if (this.chart) this.chart.setOption(this.updateConfig(this.option),true);
});
},
deep: true,

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: index.vue
author: liubin
date: 2023-08-30 14:02:49
@ -23,15 +23,13 @@
@mouseleave="factoryListOpen = false">
{{ currentFactory?.label || '点我选择工厂' }}
<div class="factory-list__wrapper" :class="{ open: factoryListOpen }">
<ul
class="factory-list"
v-if="sidebarContent.length"
@click.prevent="factoryChangeHandler">
<ul class="factory-list" v-if="sidebarContent.length">
<li
v-for="fc in sidebarContent"
:key="fc.id"
:data-value="fc.id"
class="factory-list__item"
@click.prevent="factoryChangeHandler(fc.id)"
:class="{ 'is-current': fc.id == currentFactory?.id }">
<span>
{{ fc.label }}
@ -83,6 +81,7 @@
:page="1"
:limit="999"
:table-data="list"
:max-height="tableH"
@emitFun="handleEmitFun">
<!-- <method-btn
v-if="tableBtn.length"
@ -114,10 +113,12 @@
<script>
import Graph from './graph.vue';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
export default {
name: 'EquipmentProcessAmount',
components: { Graph },
mixins: [tableHeightMixin],
props: {},
data() {
return {
@ -269,7 +270,7 @@ export default {
// { prop: 'externalCode', label: '' },
{ prop: 'equipmentId', label: '设备编码' },
{ prop: 'equipmentName', label: '设备名称' },
{ prop: 'totalQuantity', label: '加工数量' },
{ prop: 'totalQuantity', label: '加工数量[片]' },
],
mode: 'table', // table | graph
queryParams: {
@ -333,11 +334,10 @@ export default {
if (tab.name == 'graph') this.renderKey = Math.random();
},
factoryChangeHandler(event) {
factoryChangeHandler(id) {
this.factoryListOpen = false;
const fcId = event.target.dataset.value;
this.handleSidebarItemClick({ id: fcId, type: '工厂' });
this.currentFactory = this.sidebarContent.find((item) => item.id == fcId);
this.handleSidebarItemClick({ id: id, type: '工厂' });
this.currentFactory = this.sidebarContent.find((item) => item.id == id);
},
handleSidebarItemClick({ label, id, type }) {
@ -390,6 +390,7 @@ export default {
params: this.queryParams,
});
this.list = data;
if (this.activeName == 'graph') this.renderKey = Math.random();
},
},
};

View File

@ -1,4 +1,4 @@
<!--
<!--
filename: index.vue
author: liubin
date: 2023-08-04 14:44:58
@ -17,6 +17,7 @@
:span-method="mergeColumnHandler"
:table-props="tableProps"
:table-data="list"
:max-height="tableH"
@emitFun="handleEmitFun"></base-table>
<!-- :page="queryParams.pageNo"
:limit="queryParams.pageSize" -->
@ -26,10 +27,12 @@
<script>
import moment from 'moment';
import tableHeightMixin from '@/mixins/lb/tableHeightMixin';
export default {
name: 'QualityRecentHours',
components: {},
mixins: [tableHeightMixin],
props: {},
data() {
return {
@ -58,8 +61,13 @@ export default {
const props = [
{ prop: 'productLine', label: '产线' },
{ prop: 'specification', label: '规格' },
{ prop: 'equipmentName', label: '设备' },
{ prop: 'totalQuantity', label: '生产总数' },
{
prop: 'equipmentName',
width: 180,
showOverflowtooltip: true,
label: '设备',
},
{ prop: 'totalQuantity', width: 120, label: '生产总数[片]' },
];
for (const key of Object.keys(hourData).sort()) {
@ -67,13 +75,13 @@ export default {
// label: 'key',
label: moment(key).format('YYYY-MM-DD HH:mm:ss'),
children: [
{ prop: key + '__in', label: '进数据' },
{ prop: key + '__out', label: '出数据' },
{ prop: key + '__nok', label: '报废数据' },
{ prop: key + '__in', width: 100, label: '进数据[片]' },
{ prop: key + '__out', width: 100, label: '出数据[片]' },
{ prop: key + '__nok', width: 100, label: '报废数据[片]' },
{
prop: key + '__ratio',
label: '报废率',
filter: (val) => (val != null ? val + ' %' : '-'),
filter: (val) => (val != null ? val.toFixed(2) : '-'),
},
],
};
@ -88,11 +96,7 @@ export default {
this.list.splice(0);
let rowIndex = 0;
for (const line of list) {
const {
productLine,
specification = [],
data,
} = line;
const { productLine, specification = [], data } = line;
// span
this.spanInfo[rowIndex] = data.length;

View File

@ -72,16 +72,27 @@ export default {
].filter((v) => v),
tableProps: [
{
width: 128,
prop: 'lineName',
label: '产线名',
},
{
prop: 'workshopName',
label: '工段名',
showOverflowtooltip :true,
},
{
width: 200,
prop: 'equipmentName',
label: '设备名称',
},
{
width: 150,
showOverflowtooltip :true,
prop: 'equipmentCode',
label: '设备编码',
},
{ width: 128, prop: 'inQuantity', label: '投入数' },
{ width: 128, prop: 'outQuantity', label: '产出数' },
{ width: 128, prop: 'inQuantity', label: '投入数[片]' },
{ width: 128, prop: 'outQuantity', label: '产出数[片]' },
{
width: 128,
prop: 'run',