<template>
|
<div class="page">
|
<V-WorkOrderInfo :info="info"></V-WorkOrderInfo>
|
<div class="page_h"></div>
|
<div class="page_lx_item padding">
|
<span>检验类型</span>
|
<div class="page_lx_item_is">
|
<div class="page_lx_item_is_i" :class="{ 'active': item.active }" v-for="(item, index) in typeList" :key="index" @click="clickTag(index)">
|
<span>{{item.name}}</span>
|
</div>
|
</div>
|
</div>
|
<div class="page_h"></div>
|
<div class="page_content">
|
<div class="page_content_title">{{infos.cmodel1BigName}} {{infos.code}}</div>
|
<div class="page_content_item">
|
<span>合格数量</span>
|
<div class="page_content_item_i">
|
<input v-model="data.qualified" type="number" placeholder="0" />
|
<span v-if="info.umodel">{{info.umodel.name}}</span>
|
</div>
|
</div>
|
<div class="page_content_item">
|
<span>不良数量</span>
|
<div class="page_content_item_i">
|
<input v-model="data.unqualified" placeholder="0" type="number" />
|
<span v-if="info.umodel">{{info.umodel.name}}</span>
|
</div>
|
</div>
|
<div class="page_content_item" v-if="isShow" @click="openGZ">
|
<span>不良工装</span>
|
<div class="page_content_item_is">
|
<span :style="data.defectiveToolingName ? 'color: #000;' : ''">{{data.defectiveToolingName ? data.defectiveToolingName : '点击选择工装'}}</span>
|
<van-icon name="arrow" color="#999999" size="18" />
|
</div>
|
</div>
|
<div class="page_content_sm" v-if="isShow">
|
<div class="page_content_sm_box" @click="openSM('1')">
|
<img src="@/assets/icon/jianyan_ic_saoma@2x.png" alt="" />
|
<span>扫描工装</span>
|
</div>
|
</div>
|
</div>
|
<div class="page_lx">
|
<div class="page_lx_item" v-if="isShow" @click="openBL">
|
<span>不良原因</span>
|
<div class="page_lx_item_i">
|
<span :style="data.defectDescriptionName ? 'color: #000;' : ''">{{data.defectDescriptionName ? data.defectDescriptionName : '点击选择不良原因'}}</span>
|
<van-icon name="arrow" />
|
</div>
|
</div>
|
</div>
|
<div class="page_remark">
|
<textarea v-model="remark" placeholder="请输入检验备注说明信息,非必填"></textarea>
|
</div>
|
<div class="page_zw"></div>
|
<div class="page_footer">
|
<div class="page_footer_jx" @click="openSM('2')">继续检验</div>
|
<button class="page_footer_tj" v-preventReClick @click="submit">提交</button>
|
</div>
|
<!-- 不良原因 -->
|
<van-popup v-model:show="show1" position="bottom" round :style="{ height: '40%' }">
|
<van-picker
|
title="选择不良原因"
|
:columns="columns1"
|
@confirm="onConfirm1"
|
@cancel="onCancel1"
|
/>
|
</van-popup>
|
<!-- 扫码 -->
|
<v-ScanCode
|
:openCode="openCode"
|
:infos="['请扫描工装码']"
|
@closePopup="closePopup"
|
@onDecode="onDecode" />
|
<!-- 工装器具 -->
|
<Tooling :show="gzShow" :attribute="info.type === 2 ? Attribute.BF : Attribute.BL + ',' + Attribute.BF" @close="close1" @value="getValue" />
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, reactive, onMounted, nextTick, watch } from 'vue'
|
import { useRoute, useRouter } from "vue-router"
|
import { createJY } from '@/apis/QualityAPI'
|
import { Toast } from 'vant'
|
import { QRCodeType, Attribute } from '@/enum'
|
import { queryById, getListByCondition, checkAllList, getBarcodeContent } from '@/apis/WorkOrderAPI'
|
import VWorkOrderInfo from '@/components/common/WorkOrderInfo.vue'
|
import Tooling from '@/components/common/Tooling.vue'
|
import * as dd from "dingtalk-jsapi";
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
// 区分扫码
|
let index = ref<string>()
|
|
// 控制不良显示隐藏
|
const isShow = ref<boolean>(false)
|
|
let gzShow = ref<boolean>(false)
|
|
// 控制扫码显示隐藏
|
const openCode = ref<boolean>(false)
|
|
// 工装弹框显示隐藏
|
const show = ref<boolean>(false)
|
|
// 不良原因弹框显示隐藏
|
const show1 = ref<boolean>(false)
|
|
// 工装下拉数据
|
const columns: any = ref([])
|
|
// 不良原因下拉数据
|
const columns1: any = ref([])
|
|
// 工单详情数据
|
let info: any = ref({})
|
|
// 工装器具详情
|
let infos: any = ref({})
|
|
// 检验提交数据
|
let data: any = reactive({
|
id: '', // 工装id
|
qualified: '', // 合格
|
unqualified: '', // 不合格
|
defectiveTooling: '',// 不合格工装
|
defectiveToolingName: '', // 不合格工装名称
|
defectDescription: '',// 不合格说明
|
defectDescriptionName: '', // 不良原因名称
|
type: '1' // 检验类型
|
})
|
|
let remark = ref<string>('') // 备注
|
|
// 检验类型
|
const typeList: any = ref([])
|
|
const close1 = () => {
|
gzShow.value = false
|
}
|
|
// 获取工装数据
|
const getValue = (item: any) => {
|
data.defectiveTooling = item.id
|
data.defectiveToolingName = item.code
|
gzShow.value = false
|
}
|
|
// 获取扫码值
|
const onDecode = (datas: string[]): void => {
|
if (index.value === '1') {
|
getBarcodeContent({
|
barcode: datas[0]
|
}).then(resa => {
|
if (resa.code === 200 && resa.data.barcodeType === QRCodeType.GZ) {
|
getListByCondition({
|
id: resa.data.id
|
}).then(res => {
|
if (res.code === 200 && res.data && res.data.length !== 0) {
|
if (info.value.type === 2) { // 返工返修
|
if (res.data[0].smodelLabel === Attribute.BF) {
|
if (res.data[0].status !== 0) {
|
data.defectiveTooling = res.data[0].id
|
data.defectiveToolingName = res.data[0].code
|
} else {
|
Toast.fail({ message: '扫描的工装状态不能为已报废' })
|
}
|
} else {
|
Toast.fail({ message: '只能扫描报废属性的工装' })
|
}
|
} else {
|
if (res.data[0].smodelLabel === Attribute.BL || res.data[0].smodelLabel === Attribute.BF) {
|
if (res.data[0].status !== 0) {
|
data.defectiveTooling = res.data[0].id
|
data.defectiveToolingName = res.data[0].code
|
} else {
|
Toast.fail({ message: '扫描的工装状态不能为已报废' })
|
}
|
} else {
|
Toast.fail({ message: '只能扫描不良或者报废属性的工装' })
|
}
|
}
|
}
|
})
|
} else {
|
Toast.fail({ message: '请扫描正确的工装码' })
|
}
|
})
|
} else if (index.value === '2') {
|
getBarcodeContent({
|
barcode: datas[0]
|
}).then(res => {
|
if (res.code === 200 && res.data.barcodeType === QRCodeType.GZ) {
|
data.qualified = ''
|
data.unqualified = 0
|
data.defectiveTooling = ''
|
data.defectiveToolingName = ''
|
data.defectDescription = ''
|
data.defectDescriptionName = ''
|
data.type = '1'
|
typeList.value.forEach((item: any, index: number) => {
|
item.active = index === 0;
|
})
|
getListByConditions(res.data.id)
|
} else {
|
Toast.fail({ message: '请扫描正确的工装码' })
|
}
|
})
|
}
|
nextTick(() => {
|
openCode.value = false
|
})
|
}
|
|
// 关闭扫码组件
|
const closePopup = (): void => {
|
openCode.value = false
|
}
|
|
// 确认选择工装
|
const onConfirm = (value: any, index: any) => {
|
data.defectiveTooling = value.id
|
data.defectiveToolingName = value.text
|
show.value = false
|
}
|
|
// 关闭工装弹框
|
const onCancel = () => {
|
show.value = false
|
}
|
|
// 确认选择不良原因
|
const onConfirm1 = (value: any) => {
|
data.defectDescription = value.id
|
data.defectDescriptionName = value.text
|
show1.value = false
|
}
|
|
// 关闭不良原因弹框
|
const onCancel1 = () => {
|
show1.value = false
|
}
|
|
// 打开工装
|
const openGZ = () => {
|
// show.value = true
|
gzShow.value = true
|
}
|
|
// 继续检验
|
const openSM = (type: string) => {
|
if (type === '1') { // 扫描工装
|
index.value = type
|
openCode.value = true
|
} else if (type === '2') { // 继续检验
|
if (!data.qualified) {
|
data.qualified = 0
|
}
|
if (!data.unqualified) {
|
data.unqualified = 0
|
}
|
if (data.qualified === 0 && data.unqualified === 0) {
|
return Toast({ message: '合格数量不能同时为0!', duration: 2000 })
|
}
|
if (data.unqualified > 0) {
|
if (!data.defectiveTooling) return Toast.fail({ message: '不良工装不能为空!', duration: 2000 })
|
if (!data.defectDescription) return Toast.fail({ message: '不良说明不能为空!', duration: 2000 })
|
}
|
let checkType: any;
|
typeList.value.forEach((item: any) => {
|
if (item.active) {
|
checkType = item.id
|
}
|
})
|
createJY({
|
workorderId: route.query.gdId,
|
appliancesId: data.id,
|
qualifiedNum: data.qualified,
|
unqualifiedNum: data.unqualified,
|
qualifiedApplianceId: data.defectiveTooling,
|
checkInfo: data.defectDescription,
|
checkType: checkType
|
}).then(res => {
|
if (res.code === 200) {
|
// 清空操作
|
data.qualified = ''
|
data.unqualified = 0
|
data.defectiveTooling = ''
|
data.defectiveToolingName = ''
|
data.defectDescription = ''
|
data.defectDescriptionName = ''
|
data.type = '1'
|
// 还原类型
|
typeList.value.forEach((item: any, index: number) => {
|
item.active = index === 0;
|
})
|
|
index.value = type
|
|
Toast.success({ message: '检验成功!', duration: 2000 })
|
|
setTimeout(() => {
|
openCode.value = true
|
}, 2000)
|
}
|
})
|
}
|
|
}
|
|
// 打开不良原因
|
const openBL = () => {
|
show1.value = true
|
}
|
|
// 切换类型
|
const clickTag = (index: number): void => {
|
typeList.value.forEach((item: any, i: number) => {
|
item.active = index === i;
|
})
|
}
|
|
// 获取工单详情
|
const queryByIds = () => {
|
queryById(route.query.gdId)
|
.then(res => {
|
if (res.code === 200) {
|
info.value = res.data
|
let router: any = route.query.type
|
let title: string = ''
|
if (router == 1) { // 巡线
|
title = '生产巡线'
|
typeList.value.push({ name: '巡线', id: '0', active: true })
|
} else if (router == 2) { // 巡检
|
title = '品质检验'
|
typeList.value.push({ name: '巡检', id: '1', active: true })
|
if (res.data.status === 3) { // 已检验状态才展示完工检验入口
|
typeList.value.push({ name: '完工检验', id: '2', active: false })
|
}
|
}
|
document.title = title
|
// 判断是否在钉钉内
|
if (dd.env.platform !== 'notInDingTalk') {
|
// 如果是钉钉登录,设置钉钉导航栏标题为router里meta标签里设置的title
|
dd.biz.navigation.setTitle({
|
title: title,
|
// @ts-ignore
|
onSuccess: (result: any) => {
|
console.log('设置钉钉title成功')
|
},
|
onFail: (err: any) => {
|
console.log('设置钉钉title失败')
|
}
|
})
|
}
|
}
|
})
|
}
|
|
// 查询工装器具详情
|
const getListByConditions = (id: any): void => {
|
getListByCondition({
|
id
|
}).then(res => {
|
if (res.code === 200 && res.data && res.data.length !== 0) {
|
infos.value = res.data[0]
|
data.id = infos.value.id
|
}
|
})
|
}
|
|
// 不良原因数据
|
const checkAllLists = () => {
|
checkAllList({ bmodelCateType: '3' })
|
.then(res => {
|
if (res.code === 200 && res.data && res.data.length !== 0) {
|
res.data.forEach((item: any) => {
|
columns1.value.push({ text: item.combinationName, id: item.id })
|
})
|
}
|
})
|
}
|
|
// 查询不良/报废工装
|
const getListByConditions1 = () => {
|
getListByCondition({
|
smodelLabel: `${Attribute.BL},${Attribute.BF}`
|
}).then(res => {
|
if (res.code === 200 && res.data && res.data.length !== 0) {
|
res.data.forEach((item: any) => {
|
columns.value.push({ text: item.code, id: item.id })
|
})
|
}
|
})
|
}
|
|
// 提交检验
|
const submit = () => {
|
if (!data.qualified) {
|
data.qualified = 0
|
}
|
if (!data.unqualified) {
|
data.unqualified = 0
|
}
|
if (data.qualified === 0 && data.unqualified === 0) {
|
return Toast({ message: '合格数量不能同时为0!', duration: 2000 })
|
}
|
if (data.unqualified > 0) {
|
if (!data.defectiveTooling) return Toast({ message: '不良工装不能为空!', duration: 2000 })
|
if (!data.defectDescription) return Toast({ message: '不良原因不能为空!', duration: 2000 })
|
}
|
let checkType: any;
|
typeList.value.forEach((item: any) => {
|
if (item.active) {
|
checkType = item.id
|
}
|
})
|
createJY({
|
workorderId: route.query.gdId,
|
appliancesId: data.id,
|
qualifiedNum: data.qualified,
|
unqualifiedNum: data.unqualified,
|
qualifiedApplianceId: data.defectiveTooling,
|
checkInfo: data.defectDescription,
|
remark: remark.value,
|
checkType: checkType
|
}).then(res => {
|
if (res.code === 200) {
|
Toast.success({ message: '检验成功!', duration: 2000, forbidClick: true })
|
setTimeout(() => {
|
router.go(-1)
|
}, 2000)
|
}
|
})
|
}
|
|
// 监听不良数量
|
watch(() => data.unqualified, (news, old) => {
|
isShow.value = news > 0;
|
if (news > 0) {
|
data.defectiveTooling = ''
|
data.defectiveToolingName = ''
|
data.defectDescription = ''
|
data.defectDescriptionName = ''
|
}
|
}, { deep: true })
|
|
onMounted(() => {
|
queryByIds()
|
getListByConditions(route.query.gzId)
|
checkAllLists()
|
getListByConditions1()
|
})
|
</script>
|
|
<style lang="scss" scoped>
|
.page {
|
width: 100%;
|
background: #F7F7F7;
|
height: 100%;
|
position: absolute;
|
.page_info {
|
padding: 30px;
|
background: white;
|
.page_info_title {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
.purple {
|
color: $nav-color !important;
|
}
|
.green {
|
color: $nav-stateColor6 !important;
|
}
|
.yellow {
|
color: $nav-stateColor1 !important;
|
}
|
span {
|
&:first-child {
|
font-size: 32px;
|
font-weight: 500;
|
color: #333333;
|
}
|
&:last-child {
|
font-size: 26px;
|
font-weight: 400;
|
color: #03AF76;
|
}
|
}
|
}
|
.page_info_code {
|
margin: 24px 0;
|
font-size: 24px;
|
font-weight: 400;
|
color: #666666;
|
}
|
.page_info_nr {
|
padding: 30px;
|
background: #F7F7F7;
|
border-radius: 16px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
flex-wrap: wrap;
|
.page_info_nr_item {
|
width: 50%;
|
display: flex;
|
align-items: flex-start;
|
margin-top: 24px;
|
&:nth-child(1) {
|
margin-top: 0;
|
}
|
&:nth-child(2) {
|
margin-top: 0;
|
}
|
span {
|
&:nth-child(1) {
|
font-size: 24px;
|
font-weight: 400;
|
color: #666666;
|
flex-shrink: 0;
|
}
|
&:nth-child(2) {
|
font-size: 24px;
|
font-weight: 400;
|
color: #222222;
|
}
|
}
|
}
|
}
|
.page_info_yq {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-top: 30px;
|
.page_info_yq_nr {
|
display: flex;
|
align-items: center;
|
span {
|
&:nth-child(1) {
|
font-size: 26px;
|
font-weight: 400;
|
color: #666666;
|
}
|
&:nth-child(2) {
|
font-size: 26px;
|
font-weight: 400;
|
color: #222222;
|
}
|
}
|
}
|
}
|
}
|
.page_h {
|
height: 20px;
|
}
|
.padding {
|
padding: 0 30px !important;
|
}
|
.page_lx_item {
|
background: white;
|
height: 98px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
span {
|
font-size: 30px;
|
font-weight: 400;
|
color: #222222;
|
}
|
.page_lx_item_is {
|
display: flex;
|
align-items: center;
|
.active {
|
background: $nav-color !important;
|
span {
|
color: #ffffff !important;
|
}
|
}
|
.page_lx_item_is_i {
|
padding: 18px 32px;
|
background: #F2F2F2;
|
border-radius: 8px;
|
margin-right: 20px;
|
&:last-child {
|
margin: 0;
|
}
|
span {
|
font-size: 26px;
|
font-weight: 400;
|
color: #333333;
|
}
|
}
|
}
|
.page_lx_item_i {
|
display: flex;
|
align-items: center;
|
span {
|
font-size: 28px;
|
font-weight: 400;
|
color: #999999;
|
margin-right: 10px;
|
}
|
}
|
}
|
.page_content {
|
padding: 30px 30px 0 30px;
|
background: white;
|
.page_content_title {
|
font-size: 32px;
|
font-weight: 500;
|
color: $nav-color;
|
}
|
.page_content_item {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
height: 98px;
|
border-bottom: 1px solid #E5E5E5;
|
&:last-child {
|
border: none;
|
}
|
span {
|
font-size: 30px;
|
font-weight: 400;
|
color: #222222;
|
}
|
.page_content_item_is {
|
display: flex;
|
align-items: center;
|
span {
|
font-size: 28px;
|
font-weight: 400;
|
color: #999999;
|
margin-right: 10px;
|
}
|
}
|
.page_content_item_i {
|
display: flex;
|
align-items: center;
|
input {
|
padding: 0 30px;
|
text-align: right;
|
width: 180px;
|
height: 60px;
|
border-radius: 8px;
|
border: 1PX solid #CCCCCC;
|
font-size: 28px;
|
font-weight: 400;
|
color: #000000;
|
margin-right: 20px;
|
}
|
span {
|
font-size: 28px;
|
font-weight: 400;
|
color: #666666;
|
}
|
}
|
}
|
.page_content_sm {
|
width: 100%;
|
text-align: right;
|
margin-top: 20px;
|
display: flex;
|
justify-content: flex-end;
|
.page_content_sm_box {
|
display: flex;
|
align-items: center;
|
img {
|
width: 28px;
|
height: 28px;
|
margin-right: 12px;
|
}
|
span {
|
font-size: 28px;
|
font-weight: 400;
|
color: $nav-color;
|
}
|
}
|
}
|
}
|
.page_remark {
|
width: 100%;
|
height: 200px;
|
padding: 30px;
|
box-sizing: border-box;
|
background: #ffffff;
|
margin-top: 30px;
|
textarea {
|
width: 100%;
|
height: 100%;
|
resize: none;
|
padding: 10px;
|
box-sizing: border-box;
|
font-size: 26px;
|
color: black;
|
border-radius: 10px;
|
border: 1PX solid #bdbdbd;
|
}
|
}
|
.page_lx {
|
padding: 0 30px;
|
background: white;
|
.page_lx_item {
|
height: 98px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
border-bottom: 1px solid #E5E5E5;
|
&:last-child {
|
border: none;
|
}
|
span {
|
font-size: 30px;
|
font-weight: 400;
|
color: #222222;
|
}
|
.page_lx_item_is {
|
display: flex;
|
align-items: center;
|
.active {
|
background: $nav-color !important;
|
span {
|
color: #ffffff !important;
|
}
|
}
|
.page_lx_item_is_i {
|
padding: 18px 32px;
|
background: #F2F2F2;
|
border-radius: 8px;
|
margin-right: 20px;
|
&:last-child {
|
margin: 0;
|
}
|
span {
|
font-size: 26px;
|
font-weight: 400;
|
color: #333333;
|
}
|
}
|
}
|
.page_lx_item_i {
|
display: flex;
|
align-items: center;
|
span {
|
font-size: 28px;
|
font-weight: 400;
|
color: #999999;
|
margin-right: 10px;
|
}
|
}
|
}
|
}
|
.page_zw {
|
height: 160px;
|
}
|
.page_footer {
|
width: 100%;
|
padding: 0 30px 67px 30px;
|
box-sizing: border-box;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
position: fixed;
|
bottom: 0;
|
left: 0;
|
.page_footer_jx {
|
width: 334px;
|
height: 88px;
|
background: #FFFFFF;
|
box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.08);
|
border-radius: 8px;
|
font-size: 30px;
|
font-weight: 500;
|
color: #4275FC;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
.page_footer_tj {
|
width: 334px;
|
height: 88px;
|
border: none;
|
background: #4275FC;
|
box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.08);
|
border-radius: 8px;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
font-size: 30px;
|
font-weight: 500;
|
color: #FFFFFF;
|
}
|
}
|
}
|
</style>
|