feat: 优化质量查询页面功能

This commit is contained in:
XingCheng3
2026-07-16 16:45:54 +08:00
parent e64468e3db
commit efe99e9bb6

View File

@@ -1,6 +1,24 @@
<template>
<div style="width: 99%; height: 100%; background-color: #d7dee6; padding: 5px; border: 2px solid #9e9b9b; display: flex; flex-direction: column;">
<el-row :gutter="20" style="margin-bottom: 10px; display: flex; align-items: center; flex-shrink: 0;">
<div
style="
width: 99%;
height: 100%;
background-color: #d7dee6;
padding: 5px;
border: 2px solid #9e9b9b;
display: flex;
flex-direction: column;
"
>
<el-row
:gutter="20"
style="
margin-bottom: 10px;
display: flex;
align-items: center;
flex-shrink: 0;
"
>
<el-col :span="14">
<el-form :inline="true" size="small">
<el-form-item label="日期范围:" style="margin-bottom: 0">
@@ -15,7 +33,13 @@
/>
</el-form-item>
<el-form-item label="工件:" style="margin-bottom: 0">
<el-select v-model="workpieceId" filterable placeholder="请选择工件" clearable @change="handleWorkpieceChange">
<el-select
v-model="workpieceId"
filterable
placeholder="请选择工件"
clearable
@change="handleWorkpieceChange"
>
<el-option
v-for="item in workpieceList"
:key="item.工件编号"
@@ -31,7 +55,7 @@
<!-- <el-button type="warning" @click="showPhotoDialog">查看照片</el-button> -->
</el-col>
</el-row>
<el-row style="flex: 1; width: 100%; margin-top: 10px; min-height: 0;">
<el-row style="flex: 1; width: 100%; margin-top: 10px; min-height: 0">
<el-table
:data="orderCompletion_table1"
:header-cell-style="{ background: '#F5F5F5', fontSize: '24px' }"
@@ -78,34 +102,59 @@
</el-table-column>
<el-table-column align="center" label="是否合格">
<template slot-scope="scope">
<i v-if="scope.row.是否合格"><span style="font-size: x-large;font-weight: 700;color: #67c23a">OK</span></i>
<i v-else><span style="font-size: x-large;font-weight: 700;color: #ff0000">NG</span></i>
<i v-if="scope.row.是否合格"
><span
style="font-size: x-large; font-weight: 700; color: #67c23a"
>OK</span
></i
>
<i v-else
><span
style="font-size: x-large; font-weight: 700; color: #ff0000"
>NG</span
></i
>
</template>
</el-table-column>
<el-table-column align="center" label="查看">
<template slot-scope="scope">
<el-button size="mini" style="font-size: large" type="text" @click="choose(scope.row)">
<el-button
size="mini"
style="font-size: large"
type="text"
@click="choose(scope.row)"
>
质量数据
</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<div style="height: 5.4%;display: flex;align-items: center;justify-content: center;background-color: #fff;border-radius: 5px;margin: 5px;">
<div
style="
height: 5.4%;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
border-radius: 5px;
margin: 5px;
"
>
<el-col :span="6" class="totalInfo">
<img :src="require('@/assets/image/passOn.png')" width="20px">
<img :src="require('@/assets/image/passOn.png')" width="20px" />
<span>过站数量{{ passCount }}</span>
</el-col>
<el-col :span="6" class="totalInfo">
<img :src="require('@/assets/image/passOK.png')" width="20px">
<img :src="require('@/assets/image/passOK.png')" width="20px" />
<span>OK{{ ok }}</span>
</el-col>
<el-col :span="6" class="totalInfo">
<img :src="require('@/assets/image/passNG.png')" width="20px">
<img :src="require('@/assets/image/passNG.png')" width="20px" />
<span>NG{{ ng }}</span>
</el-col>
<el-col :span="6" class="totalInfo">
<img :src="require('@/assets/image/passRate.png')" width="20px">
<img :src="require('@/assets/image/passRate.png')" width="20px" />
<span>合格率{{ rate }}%</span>
</el-col>
</div>
@@ -126,7 +175,13 @@
border
max-height="365px"
size="small"
style="width: 100%; height: 100%; font-size: 20px; color: #000; border: 1px solid #9e9b9b"
style="
width: 100%;
height: 100%;
font-size: 20px;
color: #000;
border: 1px solid #9e9b9b;
"
>
<el-table-column align="center" label="测量位置" prop="名称" />
<el-table-column align="center" label="测量项目" prop="测量项目1" />
@@ -134,10 +189,7 @@
</el-table>
</div>
<div style="margin-top: 10px">
<el-button
style="width: 100px;height: 40px;"
@click="cancel()"
>
<el-button style="width: 100px; height: 40px" @click="cancel()">
关闭
</el-button>
</div>
@@ -167,13 +219,17 @@
</ul>
</div>
<div class="photo-view-container">
<img v-if="currentPhotoUrl" :src="currentPhotoUrl" class="photo-image">
<img
v-if="currentPhotoUrl"
:src="currentPhotoUrl"
class="photo-image"
/>
<div v-else class="no-photo">请从左侧选择一张照片</div>
</div>
</div>
<div style="text-align: center; margin-top: 10px">
<el-button
style="width: 100px;height: 40px;"
style="width: 100px; height: 40px"
@click="photoDialogVisible = false"
>
关闭
@@ -210,10 +266,16 @@
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" size="medium" style="padding: 10px 20px; font-size: 14px;" @click="drawCurve">绘制曲线</el-button>
<el-button
type="primary"
size="medium"
style="padding: 10px 20px; font-size: 14px"
@click="drawCurve"
>绘制曲线</el-button
>
</el-form-item>
</el-form>
<div ref="curveChart" style="width: 100%; height: 500px;"/>
<div ref="curveChart" style="width: 100%; height: 500px" />
<span slot="footer" class="dialog-footer">
<el-button @click="curveDialogVisible = false"> </el-button>
</span>
@@ -222,39 +284,39 @@
</template>
<script>
import * as echarts from 'echarts'
import * as echarts from "echarts";
// import { mapGetters } from 'vuex'
export default {
data() {
return {
dateRange: [], // 日期范围
workpieceId: '', // 工件编号
workpieceId: "", // 工件编号
workpieceList: [], // 工件列表
photoDialogVisible: false, // 照片查看弹窗
photoList: [], // 照片列表
currentPhotoUrl: '', // 当前查看的照片URL
currentPhotoUrl: "", // 当前查看的照片URL
curveDialogVisible: false,
curveDateRange: [],
curveTagList: [],
curveTagId: '',
curveTagId: "",
chartInstance: null,
checked: false,
Type: [{ label: '', value: '' }],
Type: [{ label: "", value: "" }],
count: true,
text1: '正常生产订单',
text2: '无订单生产',
text1: "正常生产订单",
text2: "无订单生产",
intdex: true,
xianshou: '',
xianshou: "",
orderCompletion_table1: [],
PersonaSex: [],
jixingName: [],
Sex: [],
title: '',
title: "",
publication: {
topic: '',
topic: "",
qos: 0,
payload: ''
payload: "",
},
// 质量数据列表
qualityData: [],
@@ -262,51 +324,62 @@ export default {
dataRefreshTimer: null,
dialogFormVisible1: false,
form1: {
订单号: '',
产品型号: '',
零件号: '',
计划数量: '',
完成数量: '',
计划时间: '',
状态: ''
订单号: "",
产品型号: "",
零件号: "",
计划数量: "",
完成数量: "",
计划时间: "",
状态: "",
},
rules: {
排序: [{ required: true, message: '序号为空', trigger: 'change' }],
订单号: [{ required: true, message: '订单号为空', trigger: 'change' }],
产品机型: [{ required: true, message: '产品机型为空', trigger: 'change' }],
零件号: [{ required: true, message: '机型代码为空', trigger: 'change' }],
计划数量: [{ required: true, message: '计划数量为空', trigger: 'change' }],
完成数量: [{ required: true, message: '完成数量为空', trigger: 'change' }],
计划时间: [{ required: true, message: '计划时间为空', trigger: 'change' }],
状态: [{ required: true, message: '状态为空', trigger: 'change' }]
}
}
排序: [{ required: true, message: "序号为空", trigger: "change" }],
订单号: [{ required: true, message: "订单号为空", trigger: "change" }],
产品机型: [
{ required: true, message: "产品机型为空", trigger: "change" },
],
零件号: [
{ required: true, message: "机型代码为空", trigger: "change" },
],
计划数量: [
{ required: true, message: "计划数量为空", trigger: "change" },
],
完成数量: [
{ required: true, message: "完成数量为空", trigger: "change" },
],
计划时间: [
{ required: true, message: "计划时间为空", trigger: "change" },
],
状态: [{ required: true, message: "状态为空", trigger: "change" }],
},
};
},
created() {
this.setDefaultDate()
this.getWorkpieceList()
this.startAutoRefresh()
this.setDefaultDate();
this.getWorkpieceList();
this.startAutoRefresh();
},
destroyed() {
this.clearAutoRefresh()
this.clearAutoRefresh();
},
computed: {
passCount() {
return this.orderCompletion_table1.length
return this.orderCompletion_table1.length;
},
ok() {
return this.orderCompletion_table1.filter(item => item.是否合格).length
return this.orderCompletion_table1.filter((item) => item.是否合格).length;
},
ng() {
return this.orderCompletion_table1.filter(item => !item.是否合格).length
return this.orderCompletion_table1.filter((item) => !item.是否合格)
.length;
},
rate() {
if (this.passCount === 0) {
return '0.00'
}
const passRate = (this.ok / this.passCount) * 100
return passRate.toFixed(2)
return "0.00";
}
const passRate = (this.ok / this.passCount) * 100;
return passRate.toFixed(2);
},
},
// watch: {
// orderCompletion_table: {
@@ -325,259 +398,279 @@ export default {
// },
methods: {
formatDate(date) {
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`
return `${date.getFullYear()}-${(date.getMonth() + 1)
.toString()
.padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
},
setDefaultDate() {
const end = new Date()
const start = new Date()
start.setDate(start.getDate() - 7) // 设置开始日期为七天前
const startDate = this.formatDate(start)
const endDate = this.formatDate(end)
this.dateRange = [startDate, endDate]
const end = new Date();
const start = new Date();
start.setDate(start.getDate() - 7); // 设置开始日期为七天前
const startDate = this.formatDate(start);
const endDate = this.formatDate(end);
this.dateRange = [startDate, endDate];
},
startAutoRefresh() {
this.clearAutoRefresh()
this.clearAutoRefresh();
this.dateCheckTimer = setInterval(() => {
this.checkDateRange()
}, 1000 * 60 * 60)
this.checkDateRange();
}, 1000 * 60 * 60);
this.dataRefreshTimer = setInterval(() => {
this.getWorkpieceList()
}, 1000 * 60 * 5)
this.getWorkpieceList();
}, 1000 * 60 * 5);
},
clearAutoRefresh() {
if (this.dateCheckTimer) {
clearInterval(this.dateCheckTimer)
this.dateCheckTimer = null
clearInterval(this.dateCheckTimer);
this.dateCheckTimer = null;
}
if (this.dataRefreshTimer) {
clearInterval(this.dataRefreshTimer)
this.dataRefreshTimer = null
clearInterval(this.dataRefreshTimer);
this.dataRefreshTimer = null;
}
},
checkDateRange() {
const today = this.formatDate(new Date())
if (!this.dateRange || this.dateRange.length !== 2 || this.dateRange[1] !== today) {
this.setDefaultDate()
this.getWorkpieceList()
const today = this.formatDate(new Date());
if (
!this.dateRange ||
this.dateRange.length !== 2 ||
this.dateRange[1] !== today
) {
this.setDefaultDate();
this.getWorkpieceList();
}
},
getWorkpieceList() {
if (!this.dateRange || this.dateRange.length !== 2) {
return
return;
}
const param = []
param[0] = ['开始日期', this.dateRange[0]]
param[1] = ['结束日期', this.dateRange[1]]
param[2] = ['工位号', this.$store.state.station.stationName]
const Data = this.CreateData('11', '测量数据发动机在线状态_时间段机型_查询', param)
this.ExecDatabase(Data).then(response => {
this.workpieceList = response.data
const param = [];
param[0] = ["开始日期", this.dateRange[0]];
param[1] = ["结束日期", this.dateRange[1]];
param[2] = ["工位号", this.$store.state.station.stationName];
const Data = this.CreateData(
"11",
"测量数据发动机在线状态_时间段机型_查询",
param
);
this.ExecDatabase(Data).then((response) => {
this.workpieceList = response.data;
if (this.workpieceList.length > 0) {
// this.workpieceId = this.workpieceList[0].工件编号
this.handleWorkpieceChange()
this.handleWorkpieceChange();
} else {
this.workpieceId = ''
this.orderCompletion_table1 = []
this.workpieceId = "";
this.orderCompletion_table1 = [];
}
})
});
},
handleDateChange() {
this.getWorkpieceList()
this.getWorkpieceList();
},
handleWorkpieceChange() {
this.getTable()
this.getTable();
},
showPhotoDialog() {
if (!this.workpieceId) {
this.$message.warning('请先选择一个工件')
return
this.$message.warning("请先选择一个工件");
return;
}
// TODO: 需要用户提供获取图片的存储过程
this.$message.info('正在加载图片列表... ')
this.$message.info("正在加载图片列表... ");
// 示例数据
this.photoList = [
{ name: '视觉图片1.jpg', url: '/CreamImg/视觉图片1.jpg' },
{ name: '视觉图片2.jpg', url: '/CreamImg/视觉图片2.jpg' }
]
{ name: "视觉图片1.jpg", url: "/CreamImg/视觉图片1.jpg" },
{ name: "视觉图片2.jpg", url: "/CreamImg/视觉图片2.jpg" },
];
if (this.photoList.length > 0) {
this.selectPhoto(this.photoList[0])
this.selectPhoto(this.photoList[0]);
} else {
this.currentPhotoUrl = ''
this.currentPhotoUrl = "";
}
this.photoDialogVisible = true
this.photoDialogVisible = true;
},
showCurveDialog() {
this.curveDialogVisible = true
this.setDefaultCurveDate()
this.getCurveTagItems()
this.curveDialogVisible = true;
this.setDefaultCurveDate();
this.getCurveTagItems();
},
setDefaultCurveDate() {
const end = new Date()
const start = new Date()
start.setDate(start.getDate() - 7)
const startDate = `${start.getFullYear()}-${(start.getMonth() + 1).toString().padStart(2, '0')}-${start.getDate().toString().padStart(2, '0')}`
const endDate = `${end.getFullYear()}-${(end.getMonth() + 1).toString().padStart(2, '0')}-${end.getDate().toString().padStart(2, '0')}`
this.curveDateRange = [startDate, endDate]
const end = new Date();
const start = new Date();
start.setDate(start.getDate() - 7);
const startDate = `${start.getFullYear()}-${(start.getMonth() + 1)
.toString()
.padStart(2, "0")}-${start.getDate().toString().padStart(2, "0")}`;
const endDate = `${end.getFullYear()}-${(end.getMonth() + 1)
.toString()
.padStart(2, "0")}-${end.getDate().toString().padStart(2, "0")}`;
this.curveDateRange = [startDate, endDate];
},
getCurveTagItems() {
const param = [['工位号', this.$store.state.station.stationName]]
const Data = this.CreateData('11', '工位_曲线数据_数据项_查询', param)
this.ExecDatabase(Data).then(response => {
this.curveTagList = response.data
const param = [["工位号", this.$store.state.station.stationName]];
const Data = this.CreateData("11", "工位_曲线数据_数据项_查询", param);
this.ExecDatabase(Data).then((response) => {
this.curveTagList = response.data;
if (this.curveTagList.length > 0) {
this.curveTagId = this.curveTagList[0].TagID
this.curveTagId = this.curveTagList[0].TagID;
}
})
});
},
drawCurve() {
if (!this.curveTagId) {
this.$message.warning('请选择一个测量项目')
return
this.$message.warning("请选择一个测量项目");
return;
}
if (!this.curveDateRange || this.curveDateRange.length !== 2) {
this.$message.warning('请选择日期范围')
return
this.$message.warning("请选择日期范围");
return;
}
const param = []
param[0] = ['工位号', this.$store.state.station.stationName]
param[1] = ['TagID', this.curveTagId]
param[2] = ['开始时间', this.curveDateRange[0]]
param[3] = ['结束时间', this.curveDateRange[1]]
const param = [];
param[0] = ["工位号", this.$store.state.station.stationName];
param[1] = ["TagID", this.curveTagId];
param[2] = ["开始时间", this.curveDateRange[0]];
param[3] = ["结束时间", this.curveDateRange[1]];
const Data = this.CreateData('11', '工位_曲线数据_数据_查询', param)
this.ExecDatabase(Data).then(response => {
const chartData = response.data
const Data = this.CreateData("11", "工位_曲线数据_数据_查询", param);
this.ExecDatabase(Data).then((response) => {
const chartData = response.data;
if (chartData.length === 0) {
this.$message.info('该时间段内无数据')
this.$message.info("该时间段内无数据");
if (this.chartInstance) {
this.chartInstance.clear()
this.chartInstance.clear();
}
return
return;
}
const xAxisData = chartData.map(item => item.操作时间)
const seriesData = chartData.map(item => ({
const xAxisData = chartData.map((item) => item.操作时间);
const seriesData = chartData.map((item) => ({
value: item.TagValue,
工件编号: item.工件编号,
操作时间: item.操作时间
}))
const upperLimit = chartData.length > 0 ? chartData[0].上限值 : null
const lowerLimit = chartData.length > 0 ? chartData[0].下限值 : null
操作时间: item.操作时间,
}));
const upperLimit = chartData.length > 0 ? chartData[0].上限值 : null;
const lowerLimit = chartData.length > 0 ? chartData[0].下限值 : null;
const markLineData = []
const markLineData = [];
if (upperLimit !== null) {
markLineData.push({
yAxis: upperLimit,
name: '上限值',
lineStyle: { color: '#ff0000', type: 'dashed' },
label: { formatter: '上限: {c}' }
})
name: "上限值",
lineStyle: { color: "#ff0000", type: "dashed" },
label: { formatter: "上限: {c}" },
});
}
if (lowerLimit !== null) {
markLineData.push({
yAxis: lowerLimit,
name: '下限值',
lineStyle: { color: '#67c23a', type: 'dashed' },
label: { formatter: '下限: {c}' }
})
name: "下限值",
lineStyle: { color: "#67c23a", type: "dashed" },
label: { formatter: "下限: {c}" },
});
}
const option = {
tooltip: {
trigger: 'axis',
trigger: "axis",
formatter: (params) => {
const data = params[0].data
return `工件编号: ${data.工件编号}<br/>测量时间: ${data.操作时间}<br/>测量值: ${data.value}`
}
const data = params[0].data;
return `工件编号: ${data.工件编号}<br/>测量时间: ${data.操作时间}<br/>测量值: ${data.value}`;
},
},
xAxis: {
type: 'category',
data: xAxisData
type: "category",
data: xAxisData,
},
yAxis: {
type: 'value',
scale: true
type: "value",
scale: true,
},
series: [{
series: [
{
data: seriesData,
type: 'line',
type: "line",
smooth: true,
markLine: {
silent: true,
symbol: 'none',
data: markLineData
}
}]
}
symbol: "none",
data: markLineData,
},
},
],
};
this.$nextTick(() => {
if (!this.chartInstance) {
this.chartInstance = echarts.init(this.$refs.curveChart)
this.chartInstance = echarts.init(this.$refs.curveChart);
}
this.chartInstance.setOption(option, true)
})
})
this.chartInstance.setOption(option, true);
});
});
},
onCurveDialogClose() {
if (this.chartInstance) {
this.chartInstance.dispose()
this.chartInstance = null
this.chartInstance.dispose();
this.chartInstance = null;
}
},
selectPhoto(photo) {
this.currentPhotoUrl = photo.url
this.currentPhotoUrl = photo.url;
},
tableRowClassName({ row }) {
if (row.合格标志 == '1') {
return 'green'
if (row.合格标志 == "1") {
return "green";
} else {
return 'red'
return "red";
}
},
getQualityData(row) {
const param = []
param[0] = ['工位号', this.$store.state.station.stationName]
param[1] = ['发动机号', row.发动机号]
const Data = this.CreateData('11', '测量数据合格_查询', param)
this.ExecDatabase(Data).then(response => {
this.qualityData = response.data
})
const param = [];
param[0] = ["工位号", this.$store.state.station.stationName];
param[1] = ["发动机号", row.发动机号];
const Data = this.CreateData("11", "测量数据合格_查询", param);
this.ExecDatabase(Data).then((response) => {
this.qualityData = response.data;
});
},
changeRadio() {
if (this.checked) {
this.intdex = false
this.intdex = false;
if (this.xianshou === 1) {
this.count = true
this.count = true;
}
} else if (!this.checked) {
this.intdex = true
this.intdex = true;
if (this.xianshou === 1) {
this.count = false
this.count = false;
}
}
},
cancel() {
this.dialogFormVisible1 = false
this.dialogFormVisible1 = false;
},
confirm11(form) {
const param = []
param[0] = ['工位号', this.$store.state.station.stationName]
param[1] = ['订单号', this.form1.订单号]
const Data2 = this.CreateData('12', '测量数据工位_监控系统_订单号_增加', param)
this.ExecDatabase(Data2).then(response => {
if (response.data[0].result === '1') {
const param = [];
param[0] = ["工位号", this.$store.state.station.stationName];
param[1] = ["订单号", this.form1.订单号];
const Data2 = this.CreateData(
"12",
"测量数据工位_监控系统_订单号_增加",
param
);
this.ExecDatabase(Data2).then((response) => {
if (response.data[0].result === "1") {
this.$notify.success({
title: '提示',
message: '订单选择成功!',
position: 'bottom-right',
offset: 170
})
title: "提示",
message: "订单选择成功!",
position: "bottom-right",
offset: 170,
});
} else {
this.$message.error('订单选择失败')
this.$message.error("订单选择失败");
}
this.getTable()
})
this.getTable();
});
// this.publication.topic = window.g.mqttPublishTopic
// this.publication.payload = 'WEB|SetMoby|' + this.$store.state.station.stationName + '|' + '1'
// const result = window.g.mqttClient.doPublish(this.publication)
@@ -596,28 +689,32 @@ export default {
// offset: 170
// })
// }
this.dialogFormVisible1 = false
this.dialogFormVisible1 = false;
},
getTable() {
const param = []
param[0] = ['开始日期', this.dateRange[0]]
param[1] = ['结束日期', this.dateRange[1]]
param[2] = ['工位号', this.$store.state.station.stationName]
param[3] = ['工件编号', this.workpieceId]
const Data = this.CreateData('11', '测量数据发动机在线状态_工位数据_查询', param)
this.ExecDatabase(Data).then(response => {
this.orderCompletion_table1 = response.data
})
const param = [];
param[0] = ["开始日期", this.dateRange[0]];
param[1] = ["结束日期", this.dateRange[1]];
param[2] = ["工位号", this.$store.state.station.stationName];
param[3] = ["工件编号", this.workpieceId];
const Data = this.CreateData(
"11",
"测量数据发动机在线状态_工位数据_查询",
param
);
this.ExecDatabase(Data).then((response) => {
this.orderCompletion_table1 = response.data;
});
},
choose(row) {
if (this.qualityData) {
this.qualityData = []
}
this.getQualityData(row)
this.dialogFormVisible1 = true
}
}
this.qualityData = [];
}
this.getQualityData(row);
this.dialogFormVisible1 = true;
},
},
};
</script>
<style scoped>