<template>
|
<div class="app-container">
|
<!-- 搜索表单 -->
|
<el-form ref="queryForm" :model="queryParams" :inline="true" size="small">
|
<el-form-item label="检验类型" prop="insType">
|
<el-select v-model="queryParams.insType" placeholder="请选择检验类型" clearable style="width: 150px">
|
<el-option label="原材料" value="rawMaterial" />
|
<el-option label="半成品" value="semiProduct" />
|
<el-option label="成品" value="finishedProduct" />
|
</el-select>
|
</el-form-item>
|
<el-form-item label="供应商" prop="supplier">
|
<el-input v-model="queryParams.supplier" placeholder="请输入供应商" clearable style="width: 180px" @keyup.enter.native="handleQuery" />
|
</el-form-item>
|
<el-form-item label="工序" prop="process">
|
<el-input v-model="queryParams.process" placeholder="请输入工序" clearable style="width: 150px" @keyup.enter.native="handleQuery" />
|
</el-form-item>
|
<el-form-item label="时间范围" prop="timeRange">
|
<el-date-picker
|
v-model="timeRange"
|
type="daterange"
|
range-separator="-"
|
start-placeholder="开始时间"
|
end-placeholder="结束时间"
|
value-format="yyyy-MM-dd"
|
style="width: 240px"
|
/>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">查询</el-button>
|
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
<el-button type="success" icon="el-icon-download" @click="handleExport">导出</el-button>
|
</el-form-item>
|
</el-form>
|
|
<!-- Tab切换 -->
|
<el-tabs v-model="activeTab" @tab-click="handleTabChange">
|
<el-tab-pane label="原材料合格率" name="rawMaterial">
|
<el-card shadow="hover">
|
<div slot="header">原材料不同批次检验合格率</div>
|
<Echart
|
:xAxis="rawMaterialXAxis"
|
:yAxis="rawMaterialYAxis"
|
:series="rawMaterialSeries"
|
:tooltip="{ trigger: 'axis' }"
|
:legend="{ data: ['合格率', '批次数'] }"
|
:grid="{ left: '3%', right: '4%', bottom: '3%', containLabel: true }"
|
:chartStyle="{ height: '350px' }"
|
/>
|
</el-card>
|
<lims-table
|
:tableData="rawMaterialTableData"
|
:column="rawMaterialTableColumn"
|
:page="rawMaterialPage"
|
:tableLoading="rawMaterialLoading"
|
@pagination="handleRawMaterialPagination"
|
/>
|
</el-tab-pane>
|
|
<el-tab-pane label="供应商统计" name="supplier">
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-card shadow="hover">
|
<div slot="header">供应商不合格次数统计</div>
|
<Echart
|
:xAxis="supplierXAxis"
|
:yAxis="supplierYAxis"
|
:series="supplierSeries"
|
:tooltip="{ trigger: 'axis' }"
|
:grid="{ left: '3%', right: '4%', bottom: '3%', containLabel: true }"
|
:chartStyle="{ height: '350px' }"
|
/>
|
</el-card>
|
</el-col>
|
<el-col :span="12">
|
<el-card shadow="hover">
|
<div slot="header">不合格项目帕累托图</div>
|
<Echart
|
:xAxis="paretoXAxis"
|
:yAxis="paretoYAxis"
|
:series="paretoSeries"
|
:tooltip="{ trigger: 'axis' }"
|
:legend="{ data: ['不合格次数', '累计占比'] }"
|
:grid="{ left: '3%', right: '4%', bottom: '3%', containLabel: true }"
|
:chartStyle="{ height: '350px' }"
|
/>
|
</el-card>
|
</el-col>
|
</el-row>
|
</el-tab-pane>
|
|
<el-tab-pane label="工序合格率" name="process">
|
<el-row :gutter="20">
|
<el-col :span="12">
|
<el-card shadow="hover">
|
<div slot="header">各工序合格率</div>
|
<Echart
|
:xAxis="processXAxis"
|
:yAxis="processYAxis"
|
:series="processSeries"
|
:tooltip="{ trigger: 'axis' }"
|
:grid="{ left: '3%', right: '4%', bottom: '3%', containLabel: true }"
|
:chartStyle="{ height: '350px' }"
|
/>
|
</el-card>
|
</el-col>
|
<el-col :span="12">
|
<el-card shadow="hover">
|
<div slot="header">机台不合格次数统计</div>
|
<Echart
|
:xAxis="machineXAxis"
|
:yAxis="machineYAxis"
|
:series="machineSeries"
|
:tooltip="{ trigger: 'axis' }"
|
:grid="{ left: '3%', right: '4%', bottom: '3%', containLabel: true }"
|
:chartStyle="{ height: '350px' }"
|
/>
|
</el-card>
|
</el-col>
|
</el-row>
|
<lims-table
|
:tableData="processTableData"
|
:column="processTableColumn"
|
:page="processPage"
|
:tableLoading="processLoading"
|
@pagination="handleProcessPagination"
|
/>
|
</el-tab-pane>
|
</el-tabs>
|
</div>
|
</template>
|
|
<script>
|
import Echart from '@/components/echarts/echarts.vue'
|
import limsTable from '@/components/Table/lims-table.vue'
|
import {
|
getRawMaterialPassRate,
|
getSupplierUnqualified,
|
getParetoData,
|
getProcessPassRate,
|
getMachineUnqualified,
|
exportPassRate
|
} from '@/api/report/passRate'
|
|
export default {
|
name: 'PassRate',
|
components: { Echart, limsTable },
|
data() {
|
return {
|
queryParams: {},
|
timeRange: [],
|
activeTab: 'rawMaterial',
|
// 原材料合格率
|
rawMaterialLoading: false,
|
rawMaterialTableData: [],
|
rawMaterialPage: { total: 0, size: 10, current: 1 },
|
rawMaterialTableColumn: [
|
{ label: '批次号', prop: 'batchCode', minWidth: '140px' },
|
{ label: '物料名称', prop: 'materialName', minWidth: '150px' },
|
{ label: '供应商', prop: 'supplier', minWidth: '150px' },
|
{ label: '检验数量', prop: 'totalCount', minWidth: '100px' },
|
{ label: '合格数量', prop: 'passCount', minWidth: '100px' },
|
{ label: '不合格数量', prop: 'unpassCount', minWidth: '100px' },
|
{ label: '合格率', prop: 'passRate', minWidth: '100px', dataType: 'tag', formatData: (val) => `${val}%`, formatType: (val) => val >= 90 ? 'success' : val >= 70 ? 'warning' : 'danger' }
|
],
|
// 原材料图表
|
rawMaterialXAxis: [{ type: 'category', data: [], axisLabel: { rotate: 30 } }],
|
rawMaterialYAxis: [{ type: 'value', max: 100 }, { type: 'value', position: 'right' }],
|
rawMaterialSeries: [
|
{ name: '合格率', type: 'bar', data: [] },
|
{ name: '批次数', type: 'line', yAxisIndex: 1, data: [] }
|
],
|
// 供应商图表
|
supplierXAxis: [{ type: 'category', data: [], axisLabel: { rotate: 30 } }],
|
supplierYAxis: [{ type: 'value' }],
|
supplierSeries: [{ name: '不合格次数', type: 'bar', data: [] }],
|
// 帕累托图
|
paretoXAxis: [{ type: 'category', data: [] }],
|
paretoYAxis: [{ type: 'value' }, { type: 'value', max: 100, position: 'right' }],
|
paretoSeries: [
|
{ name: '不合格次数', type: 'bar', data: [] },
|
{ name: '累计占比', type: 'line', yAxisIndex: 1, data: [] }
|
],
|
// 工序图表
|
processLoading: false,
|
processTableData: [],
|
processPage: { total: 0, size: 10, current: 1 },
|
processTableColumn: [
|
{ label: '工序名称', prop: 'processName', minWidth: '120px' },
|
{ label: '检验数量', prop: 'totalCount', minWidth: '100px' },
|
{ label: '合格数量', prop: 'passCount', minWidth: '100px' },
|
{ label: '不合格数量', prop: 'unpassCount', minWidth: '100px' },
|
{ label: '合格率', prop: 'passRate', minWidth: '100px', dataType: 'tag', formatData: (val) => `${val}%`, formatType: (val) => val >= 90 ? 'success' : val >= 70 ? 'warning' : 'danger' }
|
],
|
processXAxis: [{ type: 'category', data: [] }],
|
processYAxis: [{ type: 'value', max: 100 }],
|
processSeries: [{ name: '合格率', type: 'bar', data: [] }],
|
// 机台图表
|
machineXAxis: [{ type: 'category', data: [] }],
|
machineYAxis: [{ type: 'value' }],
|
machineSeries: [{ name: '不合格次数', type: 'bar', data: [] }]
|
}
|
},
|
mounted() {
|
this.getRawMaterialData()
|
},
|
methods: {
|
handleTabChange(tab) {
|
if (tab.name === 'rawMaterial') {
|
this.getRawMaterialData()
|
} else if (tab.name === 'supplier') {
|
this.getSupplierData()
|
this.getParetoData()
|
} else if (tab.name === 'process') {
|
this.getProcessData()
|
this.getMachineData()
|
}
|
},
|
getRawMaterialData() {
|
this.rawMaterialLoading = true
|
const params = this.buildParams()
|
getRawMaterialPassRate({ ...params, ...this.rawMaterialPage })
|
.then(res => {
|
this.rawMaterialTableData = res.data.records || []
|
this.rawMaterialPage.total = res.data.total || 0
|
// 图表数据
|
const chartData = (res.data.chartData || []).slice(0, 15)
|
this.rawMaterialXAxis[0].data = chartData.map(item => item.batchCode)
|
this.rawMaterialSeries[0].data = chartData.map(item => item.passRate)
|
this.rawMaterialSeries[1].data = chartData.map(item => item.batchCount)
|
})
|
.finally(() => (this.rawMaterialLoading = false))
|
},
|
getSupplierData() {
|
const params = this.buildParams()
|
getSupplierUnqualified(params).then(res => {
|
const data = res.data || []
|
this.supplierXAxis[0].data = data.map(item => item.supplier)
|
this.supplierSeries[0].data = data.map(item => item.unpassCount)
|
})
|
},
|
getParetoData() {
|
const params = this.buildParams()
|
getParetoData(params).then(res => {
|
this.paretoXAxis[0].data = res.data.categories || []
|
this.paretoSeries[0].data = res.data.values || []
|
this.paretoSeries[1].data = res.data.cumulativePercent || []
|
})
|
},
|
getProcessData() {
|
this.processLoading = true
|
const params = this.buildParams()
|
getProcessPassRate({ ...params, ...this.processPage })
|
.then(res => {
|
this.processTableData = res.data.records || []
|
this.processPage.total = res.data.total || 0
|
// 图表数据
|
const chartData = res.data.chartData || []
|
this.processXAxis[0].data = chartData.map(item => item.processName)
|
this.processSeries[0].data = chartData.map(item => item.passRate)
|
})
|
.finally(() => (this.processLoading = false))
|
},
|
getMachineData() {
|
const params = this.buildParams()
|
getMachineUnqualified(params).then(res => {
|
const data = res.data || []
|
this.machineXAxis[0].data = data.map(item => item.machineCode)
|
this.machineSeries[0].data = data.map(item => item.unpassCount)
|
})
|
},
|
buildParams() {
|
const params = { ...this.queryParams }
|
if (this.timeRange && this.timeRange.length === 2) {
|
params.startTime = this.timeRange[0]
|
params.endTime = this.timeRange[1]
|
}
|
return params
|
},
|
handleQuery() {
|
if (this.activeTab === 'rawMaterial') {
|
this.rawMaterialPage.current = 1
|
this.getRawMaterialData()
|
} else if (this.activeTab === 'supplier') {
|
this.getSupplierData()
|
this.getParetoData()
|
} else {
|
this.processPage.current = 1
|
this.getProcessData()
|
this.getMachineData()
|
}
|
},
|
resetQuery() {
|
this.queryParams = {}
|
this.timeRange = []
|
this.handleQuery()
|
},
|
handleExport() {
|
const params = { ...this.buildParams(), type: this.activeTab }
|
exportPassRate(params).then(res => {
|
this.downloadFile(res, '合格率统计.xlsx')
|
})
|
},
|
handleRawMaterialPagination({ page, limit }) {
|
this.rawMaterialPage.current = page
|
this.rawMaterialPage.size = limit
|
this.getRawMaterialData()
|
},
|
handleProcessPagination({ page, limit }) {
|
this.processPage.current = page
|
this.processPage.size = limit
|
this.getProcessData()
|
},
|
downloadFile(data, fileName) {
|
const blob = new Blob([data])
|
const url = window.URL.createObjectURL(blob)
|
const link = document.createElement('a')
|
link.href = url
|
link.download = fileName
|
link.click()
|
window.URL.revokeObjectURL(url)
|
}
|
}
|
}
|
</script>
|