412 lines
8.2 KiB
Vue
412 lines
8.2 KiB
Vue
<!--
|
|
filename: index.vue
|
|
author: liubin
|
|
date: 2023-09-04 09:34:52
|
|
description: 设备质量分析
|
|
-->
|
|
|
|
<template>
|
|
<div class="app-container">
|
|
<!-- 搜索工作栏 -->
|
|
<SearchBar
|
|
:formConfigs="searchBarFormConfig"
|
|
ref="search-bar"
|
|
@headBtnClick="handleSearchBarBtnClick" />
|
|
|
|
<el-row>
|
|
<el-col class="custom-tabs">
|
|
<el-tabs
|
|
v-model="activeName"
|
|
:stretch="true"
|
|
@tab-click="handleTabClick">
|
|
<el-tab-pane :label="'数据列表'" name="table">
|
|
<!-- 列表 -->
|
|
<base-table
|
|
:table-props="tableProps"
|
|
:page="queryParams.pageNo"
|
|
:limit="queryParams.pageSize"
|
|
:table-data="list"
|
|
@emitFun="handleEmitFun"></base-table>
|
|
</el-tab-pane>
|
|
<el-tab-pane :label="'\u3000柱状图\u3000'" name="graph">
|
|
<div
|
|
v-if="activeName == 'graph'"
|
|
class="graph"
|
|
style="height: 40vh; display: flex; flex-direction: column">
|
|
<div class="blue-title">各设备加工数量</div>
|
|
<LineChart v-if="list && list.length" :list="list" />
|
|
<div v-else class="no-data-bg"></div>
|
|
</div>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import moment from 'moment';
|
|
import LineChart from './components/lineChart.vue';
|
|
|
|
export default {
|
|
name: 'QualityAnalysis',
|
|
components: { LineChart },
|
|
props: {},
|
|
data() {
|
|
const now = new Date();
|
|
const [y, m, d] = [now.getFullYear(), now.getMonth(), now.getDate()];
|
|
return {
|
|
dialogVisible: false,
|
|
urls: {
|
|
page: '/analysis/equipment-analysis/quality',
|
|
},
|
|
activeName: 'table', // defaults to 'table'
|
|
searchBarFormConfig: [
|
|
// 产品
|
|
{
|
|
__index: 'product',
|
|
type: 'select',
|
|
label: '产品',
|
|
placeholder: '请选择产品',
|
|
param: 'productId',
|
|
},
|
|
// 产线
|
|
{
|
|
__index: 'line',
|
|
type: 'select',
|
|
label: '产线',
|
|
placeholder: '请选择产线',
|
|
param: 'lineId',
|
|
},
|
|
// 时间段
|
|
{
|
|
type: 'datePicker',
|
|
label: '时间段',
|
|
dateType: 'daterange', // datetimerange
|
|
// format: 'yyyy-MM-dd HH:mm:ss',
|
|
format: 'yyyy-MM-dd',
|
|
// valueFormat: 'timestamp',
|
|
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
|
rangeSeparator: '-',
|
|
startPlaceholder: '开始日期',
|
|
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',
|
|
btnName: '查询',
|
|
name: 'search',
|
|
color: 'primary',
|
|
},
|
|
// {
|
|
// type: 'separate',
|
|
// },
|
|
// {
|
|
// type: 'button',
|
|
// btnName: '列表数据',
|
|
// name: 'tableVersion',
|
|
// color: 'text btn-table',
|
|
// },
|
|
// {
|
|
// type: 'separate',
|
|
// },
|
|
// {
|
|
// type: 'button',
|
|
// btnName: '图形分析',
|
|
// name: 'graphVersion',
|
|
// color: 'text btn-graph',
|
|
// },
|
|
],
|
|
// 动态的 props
|
|
tableProps: [
|
|
{
|
|
// width: 160,
|
|
prop: 'sectionName',
|
|
label: '工段',
|
|
},
|
|
{
|
|
// width: 160,
|
|
prop: 'equipmentName',
|
|
label: '设备名称',
|
|
},
|
|
{
|
|
// width: 160,
|
|
prop: 'products',
|
|
label: '产品名称',
|
|
},
|
|
{
|
|
// width: 160,
|
|
prop: 'inQuantity',
|
|
label: '进片数量',
|
|
},
|
|
{
|
|
// width: 160,
|
|
prop: 'outQuantity',
|
|
label: '出片数量',
|
|
},
|
|
{
|
|
// width: 160,
|
|
prop: 'nokQuantity',
|
|
label: '破损/不合格数',
|
|
},
|
|
{
|
|
// width: 160,
|
|
prop: 'passRate',
|
|
label: '合格率',
|
|
},
|
|
],
|
|
lineChartConfig: {
|
|
grid: {
|
|
top: 88,
|
|
left: 56,
|
|
right: 56,
|
|
bottom: 56,
|
|
},
|
|
legend: {
|
|
top: 0,
|
|
left: 0,
|
|
padding: 5,
|
|
icon: 'roundRect',
|
|
itemWidth: 12,
|
|
itemHeight: 12,
|
|
itemGap: 20,
|
|
textStyle: {
|
|
fontSize: 14,
|
|
lineHeight: 14,
|
|
},
|
|
},
|
|
xAxis: {
|
|
type: 'category',
|
|
data: ['设备1', '设备2', '设备3', '设备4', '设备5'],
|
|
},
|
|
yAxis: {
|
|
type: 'value',
|
|
name: '合格率',
|
|
nameLocation: 'end',
|
|
nameTextStyle: {
|
|
fontSize: 14,
|
|
align: 'right',
|
|
},
|
|
nameGap: 26,
|
|
},
|
|
series: [
|
|
{
|
|
name: '产线1',
|
|
data: [150, 230, 224, 218, 135],
|
|
type: 'line',
|
|
smooth: true,
|
|
},
|
|
{
|
|
name: '产线2',
|
|
data: [111, 224, 42, 11, 24],
|
|
type: 'line',
|
|
smooth: true,
|
|
},
|
|
{
|
|
name: '产线3',
|
|
data: [218, 112, 331, 44, 99],
|
|
type: 'line',
|
|
smooth: true,
|
|
},
|
|
{
|
|
name: '产线4',
|
|
data: [3, 221, 42, 553, 311],
|
|
type: 'line',
|
|
smooth: true,
|
|
},
|
|
],
|
|
},
|
|
// 查询参数
|
|
queryParams: {
|
|
pageNo: 1,
|
|
pageSize: 10,
|
|
lineId: null,
|
|
productId: null,
|
|
recordTime: [],
|
|
},
|
|
list: [],
|
|
};
|
|
},
|
|
computed: {},
|
|
created() {
|
|
this.fillLineOptions();
|
|
this.fillProductOptions();
|
|
},
|
|
mounted() {
|
|
this.$refs['search-bar'].headBtnClick('search');
|
|
},
|
|
methods: {
|
|
handleTabClick(tab, event) {
|
|
// console.log('tab event', tab, event);
|
|
// tab is el-tab vue component.
|
|
},
|
|
|
|
async fillLineOptions() {
|
|
const { data } = await this.$axios({
|
|
url: '/base/core-production-line/listAll',
|
|
method: 'get',
|
|
});
|
|
const cfg = this.searchBarFormConfig.find(
|
|
(item) => item.__index == 'line'
|
|
);
|
|
this.$set(
|
|
cfg,
|
|
'selectOptions',
|
|
data.map((item) => ({
|
|
id: item.id,
|
|
name: item.name,
|
|
}))
|
|
);
|
|
},
|
|
|
|
async fillProductOptions() {
|
|
const { data } = await this.$axios({
|
|
url: '/base/core-product/listAll',
|
|
method: 'get',
|
|
});
|
|
const cfg = this.searchBarFormConfig.find(
|
|
(item) => item.__index == 'product'
|
|
);
|
|
this.$set(
|
|
cfg,
|
|
'selectOptions',
|
|
data.map((item) => ({
|
|
id: item.id,
|
|
name: item.name,
|
|
}))
|
|
);
|
|
},
|
|
|
|
async getList() {
|
|
const { data } = await this.$axios({
|
|
url: '/analysis/equipment-analysis/quality',
|
|
method: 'get',
|
|
params: {
|
|
lineId: this.queryParams.lineId || null,
|
|
productId: this.queryParams.productId || null,
|
|
recordTime: this.queryParams.recordTime || null,
|
|
},
|
|
});
|
|
this.list = data.map((item) => ({
|
|
...item,
|
|
products: item.products?.join(','),
|
|
}));
|
|
},
|
|
|
|
handleSearchBarBtnClick(btn) {
|
|
// debugger;
|
|
switch (btn.btnName) {
|
|
case 'search':
|
|
this.queryParams.lineId = btn.lineId;
|
|
this.queryParams.productId = btn.productId;
|
|
this.queryParams.recordTime = btn.recordTime
|
|
? btn.recordTime.map((time) =>
|
|
moment(new Date(time)).format('YYYY-MM-DD HH:mm:ss')
|
|
)
|
|
: null;
|
|
this.$nextTick(() => {
|
|
this.getList();
|
|
});
|
|
break;
|
|
case 'tableVersion':
|
|
this.dialogClose();
|
|
break;
|
|
case 'graphVersion':
|
|
this.dialogShow();
|
|
break;
|
|
}
|
|
},
|
|
|
|
handleEmitFun({ action, payload }) {},
|
|
|
|
dialogShow() {
|
|
this.dialogVisible = true;
|
|
},
|
|
|
|
dialogClose() {
|
|
this.dialogVisible = false;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<style scoped lang="scss">
|
|
:deep(.searchBar) {
|
|
.el-button.btn-table {
|
|
color: rgb(0, 130, 130);
|
|
border: 1px solid rgb(0, 130, 130);
|
|
padding: 8px 10px;
|
|
border: 1px solid rgb(0, 130, 130);
|
|
padding: 8px 10px;
|
|
|
|
&:hover {
|
|
border-color: #fff;
|
|
color: #fff;
|
|
background: rgb(0, 130, 130);
|
|
}
|
|
}
|
|
.el-button.btn-graph {
|
|
color: rgb(130, 0, 130);
|
|
border: 1px solid rgb(130, 0, 130);
|
|
padding: 8px 10px;
|
|
|
|
&:hover {
|
|
border-color: #fff;
|
|
color: #fff;
|
|
background: rgb(130, 0, 130);
|
|
}
|
|
}
|
|
}
|
|
|
|
:deep(.custom-tabs) {
|
|
.el-tabs__header {
|
|
margin-bottom: 8px;
|
|
display: inline-block;
|
|
transform: translateY(-12px);
|
|
}
|
|
|
|
.el-tabs__item {
|
|
padding-left: 0 !important;
|
|
padding-right: 0 !important;
|
|
line-height: 36px !important;
|
|
height: 36px;
|
|
}
|
|
}
|
|
|
|
.blue-title {
|
|
position: relative;
|
|
padding: 4px 0;
|
|
padding-left: 12px;
|
|
font-size: 14px;
|
|
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0;
|
|
top: 6px;
|
|
height: 16px;
|
|
width: 4px;
|
|
border-radius: 1px;
|
|
background: #0b58ff;
|
|
}
|
|
}
|
|
</style>
|