Files
shgx_tz_vue-sync/src/views/qualityManagement/FQC/firstFQC.vue
2024-01-26 16:58:40 +08:00

715 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<div class="animate__animated animate__shakeX title">车镜油漆缺陷采集系统首检</div>
<el-row>
<el-col :span="1">
<div style="height: 225px">
<div class="title_Line">抛光</div>
<div class="title_Line">打磨</div>
<div class="title_Line">报废</div>
</div>
<div style="height: 400px">
<div class="title_Line">抛光</div>
<div class="title_Line">打磨</div>
<div class="title_Line">报废</div>
</div>
</el-col>
<el-col :span="23">
<div>
<div class="grid">
<div class="a">
<div class="title_sub">{{ paint[0].inspectionModule }}</div>
<div class="grid_sub">
<div class="a_11" v-for="(item, index) of paint" :key="index">
<div @click="Accumulator(item, index)" class="button_" @mousedown="startimer(item.counter, 'paint', index)" @mouseup="clearTimer">
<div class="context">{{ item.inspectionName }}</div>
<div class="number">{{ item.counter }}</div>
</div>
</div>
</div>
</div>
<div class="b">
<div class="title_sub">{{ device[0].inspectionModule }}</div>
<div class="grid_sub">
<div class="a_11" v-for="(item, index) of device" :key="index">
<div
@click="Accumulator(item, index)"
class="button_"
@mousedown="startimer(item.counter, 'device', index)"
@mouseup="clearTimer"
>
<div class="context">{{ item.inspectionName }}</div>
<div class="number">{{ item.counter }}</div>
</div>
</div>
</div>
</div>
<div class="c">
<div class="title_sub">{{ blank[0].inspectionModule }}</div>
<div class="grid_sub">
<div class="a_11" v-for="(item, index) of blank" :key="index">
<div @click="Accumulator(item, index)" class="button_" @mousedown="startimer(item.counter, 'blank', index)" @mouseup="clearTimer">
<div class="context">{{ item.inspectionName }}</div>
<div class="number">{{ item.counter }}</div>
</div>
</div>
</div>
</div>
<div class="d">
<div class="title_sub">{{ program[0].inspectionModule }}</div>
<div class="grid_sub">
<div class="a_11" v-for="(item, index) of program" :key="index">
<div
@click="Accumulator(item, index)"
class="button_"
@mousedown="startimer(item.counter, 'program', index)"
@mouseup="clearTimer"
>
<div class="context">{{ item.inspectionName }}</div>
<div class="number">{{ item.counter }}</div>
</div>
</div>
</div>
</div>
<div class="e">
<div class="title_sub">{{ team[0].inspectionModule }}</div>
<div class="grid_sub">
<div class="a_11" v-for="(item, index) of team" :key="index">
<div @click="Accumulator(item, index)" class="button_" @mousedown="startimer(item.counter, 'team', index)" @mouseup="clearTimer">
<div class="context">{{ item.inspectionName }}</div>
<div class="number">{{ item.counter }}</div>
</div>
</div>
</div>
</div>
<div class="f">
<el-card class="box-card dataStatistics">
<div slot="header" class="clearfix">
<span class="title">工单号:{{ CurrentWorkorder.clientWorkorder }}</span>
<el-button-group style="float: right">
<el-button type="primary" size="mini" @click="getNext_current_workorder"
>下一个工单<i class="el-icon-arrow-right el-icon--right"></i
></el-button>
<el-button type="primary" icon="el-icon-arrow-left" size="mini" @click="getPrevious_current_workorder">上一个工单</el-button>
</el-button-group>
</div>
<el-button type="danger" size="medium" @click="getNext_current_workorder">本工单完成</el-button>
<table>
<tr>
<td>产品描述</td>
<td>{{ CurrentWorkorder.productDescription }}</td>
<td>零件号</td>
<td>{{ CurrentWorkorder.finishedPartNumber }}</td>
</tr>
<tr>
<td>规格</td>
<td>{{ CurrentWorkorder.specifications }}</td>
<td>颜色</td>
<td>{{ CurrentWorkorder.colour }}</td>
</tr>
<tr>
<td>班组</td>
<td>
<el-switch v-model="CurrentWorkorder.team" active-text="B" inactive-text="A"> {{ CurrentWorkorder.team }}</el-switch>
</td>
<td>投入数</td>
<td>{{ CurrentWorkorder.previousNumber }}</td>
</tr>
<tr>
<td>一次合格数</td>
<td>{{ calculate_firstPassNumber }}</td>
<td>一次合格率</td>
<td>{{ calculate_firstPassRate }}%</td>
</tr>
<tr>
<td>打磨数</td>
<td>{{ calculate_polisheNumber }}</td>
<td>报废数</td>
<td>{{ calculate_scrapNumber }}</td>
</tr>
<tr>
<td>抛光数</td>
<td>{{ calculate_defectNumber }}</td>
</tr>
</table>
</el-card>
</div>
</div>
</div>
</el-col>
</el-row>
<el-dialog title="修改" :visible.sync="DMLdialog.visiable" width="600px" append-to-body>
<el-input-number v-model="toUpdateNum" label="修改"></el-input-number>
<div slot="footer" class="dialog-footer">
<el-button @click="DMLdialog.visiable = false"> </el-button>
<el-button @click="confirm">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
GetcheckItemTable,
getcurrent_workorder,
get_next_current_workorder,
get_previous_current_workorder,
} from '@/api/qualityManagement/firstFQC.js'
import { mapGetters } from 'vuex'
export default {
name: 'firstFQC',
data() {
return {
paint: [{ inspectionModule: '' }],
device: [{ inspectionModule: '' }],
blank: [{ inspectionModule: '' }], // 毛坯
program: [{ inspectionModule: '' }], // 程序
team: [{ inspectionModule: '' }], //班组
CurrentWorkorder: {
clientWorkorder: '', // 客户工单
productDescription: '', // 产品描述
finishedPartNumber: 0,
specifications: 0,
colour: '',
team: '',
previousNumber: '',
firstPassNumber: 0,
firstPassRate: 0,
polisheNumber: 0,
scrapNumber: 0,
defectNumber: 0,
},
signal: null,
data: null,
timer: null,
DMLdialog: {
visiable: false,
},
toUpdateNum: 0, //弹窗更新值
toname: '',
toindex: 0, //索引
}
},
watch: {
// 监听工单号
'$store.getters.counterList_v1': {
immediate: true,
deep: true,
handler(newValue, oldValue) {
if (newValue.checkid && newValue.checkid.length > 0) {
let checkid_ = newValue.checkid.substring(0, 3)
switch (this.$store.getters.counterList_v1.Moudle) {
case '油漆':
this.paint.filter((it) => it.id == checkid_)[0].counter = this.$store.getters.counterList_v1.sum
break
case '设备':
this.device.filter((it) => it.id == checkid_)[0].counter = this.$store.getters.counterList_v1.sum
break
case '毛坯':
this.blank.filter((it) => it.id == checkid_)[0].counter = this.$store.getters.counterList_v1.sum
break
case '程序':
this.program.filter((it) => it.id == checkid_)[0].counter = this.$store.getters.counterList_v1.sum
break
case '班组操作':
this.team.filter((it) => it.id == checkid_)[0].counter = this.$store.getters.counterList_v1.sum
break
}
}
},
},
},
computed: {
// 计算合格数
calculate_firstPassNumber() {
// 计算缺陷数
let allCount = 0
this.paint.forEach((it) => {
allCount += it.counter
})
this.device.forEach((it) => {
allCount += it.counter
})
this.blank.forEach((it) => {
allCount += it.counter
})
this.program.forEach((it) => {
allCount += it.counter
})
this.team.forEach((it) => {
allCount += it.counter
})
this.CurrentWorkorder.firstPassNumber = this.CurrentWorkorder.previousNumber - allCount
return this.CurrentWorkorder.firstPassNumber
},
// 计算合格率
calculate_firstPassRate() {
this.CurrentWorkorder.firstPassRate = ((this.CurrentWorkorder.firstPassNumber / this.CurrentWorkorder.previousNumber) * 100).toFixed(3)
return this.CurrentWorkorder.firstPassRate
},
//计算打磨数 CurrentWorkorder.polisheNumber
calculate_polisheNumber() {
let allCount = 0
this.paint.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 2) {
allCount += item.counter
}
})
this.device.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 2) {
allCount += item.counter
}
})
this.blank.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 2) {
allCount += item.counter
}
})
this.program.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 2) {
allCount += item.counter
}
})
this.team.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 2) {
allCount += item.counter
}
})
this.CurrentWorkorder.polisheNumber = allCount
return this.CurrentWorkorder.polisheNumber
},
//计算报废数 CurrentWorkorder.scrapNumber
calculate_scrapNumber() {
let allCount = 0
this.paint.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 3) {
allCount += item.counter
}
})
this.device.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 3) {
allCount += item.counter
}
})
this.blank.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 3) {
allCount += item.counter
}
})
this.program.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 3) {
allCount += item.counter
}
})
this.team.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 3) {
allCount += item.counter
}
})
this.CurrentWorkorder.scrapNumber = allCount
return this.CurrentWorkorder.scrapNumber
},
//计算 抛光数 CurrentWorkorder.defectNumber
calculate_defectNumber() {
let allCount = 0
this.paint.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 1) {
allCount += item.counter
}
})
this.device.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 1) {
allCount += item.counter
}
})
this.blank.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 1) {
allCount += item.counter
}
})
this.program.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 1) {
allCount += item.counter
}
})
this.team.forEach((item) => {
if (parseInt(item.id / 10) % 10 === 1) {
allCount += item.counter
}
})
this.CurrentWorkorder.defectNumber = allCount
return this.CurrentWorkorder.defectNumber
},
},
created() {
this.getCheckItemList()
},
mounted() {
this.getcurrentWorkorder()
},
methods: {
//todo 获取检测项
getCheckItemList() {
GetcheckItemTable()
.then((result) => {
if (result.code == 200) {
this.paint = result.data.paint
this.paint.forEach((item) => {
if (item.counter == null) item.counter = 0
})
this.device = result.data.device
this.device.forEach((item) => {
if (item.counter == null) item.counter = 0
})
this.blank = result.data.blank
this.blank.forEach((item) => {
if (item.counter == null) item.counter = 0
})
this.program = result.data.program
this.program.forEach((item) => {
if (item.counter == null) item.counter = 0
})
this.team = result.data.team
this.team.forEach((item) => {
if (item.counter == null) item.counter = 0
})
}
})
.catch((err) => {})
},
//todo 累加器
Accumulator(item, index) {
switch (item.inspectionModule) {
case '油漆':
// 把数据传递到redis
this.signalr.SR.invoke('SaveCacheInformation_v1', this.CurrentWorkorder.clientWorkorder, '油漆', item.id + '').catch((err) => {
console.log(err)
})
// redis再将数据返回
break
case '设备':
this.signalr.SR.invoke('SaveCacheInformation_v1', this.CurrentWorkorder.clientWorkorder, '设备', item.id + '').catch((err) => {
console.log(err)
})
break
case '毛坯':
this.signalr.SR.invoke('SaveCacheInformation_v1', this.CurrentWorkorder.clientWorkorder, '毛坯', item.id + '').catch((err) => {
console.log(err)
})
break
case '程序':
this.signalr.SR.invoke('SaveCacheInformation_v1', this.CurrentWorkorder.clientWorkorder, '程序', item.id + '').catch((err) => {
console.log(err)
})
break
case '班组操作':
this.signalr.SR.invoke('SaveCacheInformation_v1', this.CurrentWorkorder.clientWorkorder, '班组操作', item.id + '').catch((err) => {
console.log(err)
})
break
default:
this.$notify.warning('异常操作,警告')
break
}
},
//todo 长按事件
startimer(value, name, index) {
this.timer = setTimeout(() => {
this.toUpdateNum = value
this.DMLdialog.visiable = true
this.toname = name
this.toindex = index
}, 1000)
},
clearTimer() {
clearTimeout(this.timer)
},
//todo 弹窗确认事件
confirm() {
switch (this.toname) {
case 'paint':
this.paint[this.toindex].counter = this.toUpdateNum
break
case 'blank':
this.device[this.toindex].counter = this.toUpdateNum
break
case 'team':
this.team[this.toindex].counter = this.toUpdateNum
break
case 'device':
this.device[this.toindex].counter = this.toUpdateNum
break
case 'program':
this.program[this.toindex].counter = this.toUpdateNum
break
}
this.DMLdialog.visiable = false
},
//todo 数据同步
/*
1.从后台获取数据
*/
//todo 初始话 signalR
/*initSignalR() {
this.signal = new signalR.HubConnectionBuilder()
//服务器地址
// .withUrl('http://192.168.0.110:8100/myHub', {})
.withUrl('http://localhost:8888/myHub', {})
.withAutomaticReconnect()
.configureLogging(signalR.LogLevel.Information)
.build()
// 接受集线器的方法
this.signal.on('receive_my', (res) => {
this.data = res
})
this.signal
.start()
.then(() => {
console.log('myhub连接成功')
//vue 发送请求
this.signal.invoke('SendPublicMessage', '1111').catch((err) => console.log('err', err))
})
.catch(() => {
console.log('myhub连接失败')
})
// this.signalr.SR.invoke('SendMessage', 'All', 'root', '123456').catch((err) => console.log('err', err))
},*/
//todo 获取当前工单号
getcurrentWorkorder() {
getcurrent_workorder().then((res) => {
if (res.code == 200) {
if (res.data != undefined) {
this.CurrentWorkorder = res.data
this.$message.success('更新今日工单号成功')
}
} else if (res.code == 210) {
this.$notify.warning('没有工单上线')
}
})
},
//todo 获取下一个工单号
getNext_current_workorder() {
get_next_current_workorder().then((res) => {
if (res.code == 200) {
if (res.data != null) {
this.CurrentWorkorder = res.data
this.$message.success('获取工单号成功')
} else {
this.$notify.warning('已经是最后一个工单,没有工单了')
}
} else if (res.code == 210) {
this.$notify.warning('已经是最后一个工单,没有工单了')
}
})
},
//todo 获取上一个工单号
getPrevious_current_workorder() {
get_previous_current_workorder().then((res) => {
if (res.code == 200) {
if (res.data != null) {
this.CurrentWorkorder = res.data
this.$message.success('获取工单号成功')
} else {
this.$notify.warning('没有生产工单')
}
} else if (res.code == 210) {
this.$notify.warning('没有生产工单')
}
})
},
},
}
</script>
<style lang="scss" scoped>
.title {
font-family: Arial, sans-serif;
font-size: 30px;
color: #303133;
line-height: 1.5;
text-align: center;
}
.grid {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 0.5em;
.a {
.title_sub {
font-family: Arial, sans-serif;
font-size: 1.5rem;
color: #303133;
text-align: center;
}
.grid_sub {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0.5em;
}
}
.b {
.title_sub {
font-family: Arial, sans-serif;
font-size: 1.5rem;
color: #303133;
text-align: center;
}
.grid_sub {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0.5em;
}
}
.c {
.title_sub {
font-family: Arial, sans-serif;
font-size: 1.5rem;
color: #303133;
text-align: center;
}
.grid_sub {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0.5em;
}
}
.d {
.title_sub {
font-family: Arial, sans-serif;
font-size: 1.5rem;
color: #303133;
text-align: center;
}
.grid_sub {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0.5em;
}
}
.e {
.title_sub {
font-family: Arial, sans-serif;
font-size: 1.5rem;
color: #303133;
text-align: center;
}
.grid_sub {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0.5em;
}
}
.f {
}
}
.grid > * {
height: 320px;
background-color: #ebeef5;
color: white;
border-radius: 0.5em;
}
.grid_sub > * {
height: 80px;
background-color: #11a983;
width: 60px;
color: white;
border-radius: 0.2em;
transition: all 0.2s ease-in-out;
&:hover {
cursor: pointer;
box-shadow: 0 0 0 rgba(0, 0, 0, 0.2), 0 0 0 #c6e2ff, inset 18px 18px 30px rgba(0, 0, 0, 0.1), inset -18px -18px 30px #c6e2ff;
}
}
.title_Line {
color: #409eff;
font-family: Arial, sans-serif;
font-size: 1rem;
text-align: center;
margin-top: 50px;
}
.context {
margin: 0.5em 1em;
font-size: 0.8rem;
}
.button_ {
width: 100%;
height: 100%;
text-align: center;
position: relative;
.number {
font-size: 2rem;
text-align: center;
color: red;
font-weight: bold;
position: absolute;
bottom: 5px;
width: 100%;
}
}
.dataStatistics {
.title {
font-size: 1.2rem;
font-weight: bold;
color: #303133;
}
table {
border-collapse: collapse;
width: 100%;
}
th,
td {
border: 1px solid #000;
padding: 8px;
text-align: left;
font-size: 0.7rem;
}
th {
background-color: #409eff;
color: #fff;
}
::v-deep .el-button {
float: right;
}
}
</style>