You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
447 lines
12 KiB
447 lines
12 KiB
<template>
|
|
<div>
|
|
<div class="pda-container">
|
|
<div class="status-bar">
|
|
<div class="goBack" @click="handleBack"><i class="el-icon-arrow-left"></i>上一页</div>
|
|
<div class="goBack">检验不合格处理</div>
|
|
<div class="network" style="color: #fff" @click="$router.push({ path: '/' })">🏠首页</div>
|
|
</div>
|
|
<div style="overflow-y: auto">
|
|
<!-- Step 1: 扫描或查询检验单据 -->
|
|
<div v-if="processFlag === 1">
|
|
<div class="scan-box" style="margin: 2px;">
|
|
<el-input clearable v-model="scanCode" placeholder="扫描采购单条码"
|
|
@keyup.enter.native="handleScan" ref="scanCodeRef" />
|
|
</div>
|
|
<div class="item-list" v-if="unqualifiedList.length > 0" style="margin: 2px;">
|
|
<el-form label-position="top" style="margin: 3px;">
|
|
<el-row :gutter="5" @click.native="selectProcessItem(unqualifiedDetail)"
|
|
v-for="(unqualifiedDetail, index) in unqualifiedList" :key="index"
|
|
:class="index < unqualifiedList.length - 1 ? 'bottom-line-row' : ''">
|
|
<el-col :span="6">
|
|
<el-form-item label="物料编码"><span>{{ unqualifiedDetail.partNo }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="8">
|
|
<el-form-item label="单据号"><span>{{ unqualifiedDetail.transNo }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-form-item label="类型">
|
|
<span >
|
|
{{ getProcessTypeText(unqualifiedDetail.processType) }}
|
|
</span>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="">
|
|
<el-button type="text" class="processButton" @click="selectProcessItem(unqualifiedDetail)"
|
|
style="margin-top: 10px;margin-left: 20px" size="small">处理</el-button>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="24">
|
|
<el-form-item label="物料描述"><span>{{ unqualifiedDetail.partDesc }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item :label="getQtyLabel(unqualifiedDetail.processType)">
|
|
<span :style="getQtyStyle(unqualifiedDetail.processType)">{{ unqualifiedDetail.unqualifiedQty }}</span>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="批次号"><span>{{ unqualifiedDetail.batchNo }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="PO号"><span>{{ unqualifiedDetail.orderRef1 }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="检验日期"><span>{{ formatDate(unqualifiedDetail.inspectionDate) }}</span></el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
</div>
|
|
|
|
<!-- 扫描的HandlingUnit明细列表 -->
|
|
<div class="scanned-items" v-if="scannedItems.length > 0" style="margin: 2px;">
|
|
<div class="section-title">已扫描明细</div>
|
|
<div class="item-list">
|
|
<el-form label-position="top" style="margin: 3px;">
|
|
<el-row :gutter="5" v-for="(item, index) in scannedItems" :key="index"
|
|
:class="index < scannedItems.length - 1 ? 'bottom-line-row' : ''">
|
|
<el-col :span="8">
|
|
<el-form-item label="物料编码"><span>{{ item.partNo }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="8">
|
|
<el-form-item label="HandlingUnit"><span>{{ item.unitId }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="8">
|
|
<el-form-item label="">
|
|
<el-button type="text" style="color: #F56C6C;" @click="removeScannedItem(index)"
|
|
size="small">移除</el-button>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-form-item label="物料描述"><span>{{ item.partDesc }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="数量"><span>{{ item.qty }}</span></el-form-item>
|
|
</el-col>
|
|
<el-col :span="6">
|
|
<el-form-item label="批次号"><span>{{ item.batchNo }}</span></el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
</el-form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { getUnqualifiedInspectionList, scanHandlingUnitLabel } from "@/api/po/po.js";
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
processFlag: 1, // 1-不合格列表, 2-处理确认
|
|
scanCode: '',
|
|
unqualifiedList: [],
|
|
scannedItems: [],
|
|
selectedItem: {},
|
|
site: localStorage.getItem('site')
|
|
};
|
|
},
|
|
methods: {
|
|
handleBack() {
|
|
if (this.processFlag === 1) {
|
|
this.$router.back();
|
|
} else if (this.processFlag === 2) {
|
|
this.processFlag = 1;
|
|
this.scannedItems = [];
|
|
} else {
|
|
this.processFlag = 1;
|
|
}
|
|
},
|
|
|
|
// 处理扫描
|
|
handleScan() {
|
|
if (!this.scanCode.trim()) {
|
|
return;
|
|
}
|
|
|
|
// 判断是否为采购单条码或HandlingUnit条码
|
|
if (this.scanCode.startsWith('PO') || this.scanCode.startsWith('REC')) {
|
|
// 采购单或接收单条码,查询不合格单据
|
|
this.searchUnqualifiedList();
|
|
} else {
|
|
// HandlingUnit条码,扫描添加明细
|
|
this.scanHandlingUnit();
|
|
}
|
|
},
|
|
|
|
// 查询检验不合格单据
|
|
searchUnqualifiedList() {
|
|
const params = {
|
|
site: this.site
|
|
};
|
|
if (this.scanCode && (this.scanCode.startsWith('PO') || this.scanCode.startsWith('REC'))) {
|
|
params.transNo = this.scanCode;
|
|
}
|
|
|
|
getUnqualifiedInspectionList(params).then(({ data }) => {
|
|
if (data.code === 0) {
|
|
this.unqualifiedList = data.rows || [];
|
|
if (this.unqualifiedList.length === 0) {
|
|
this.$message.success("暂无检验不合格待处理单据");
|
|
}
|
|
} else {
|
|
this.$message.error(data.msg || "查询失败");
|
|
}
|
|
}).catch(error => {
|
|
this.$message.error("查询失败");
|
|
console.error(error);
|
|
});
|
|
|
|
this.scanCode = '';
|
|
},
|
|
|
|
// 扫描HandlingUnit条码
|
|
scanHandlingUnit() {
|
|
const params = {
|
|
site: this.site,
|
|
unitId: this.scanCode.trim()
|
|
};
|
|
|
|
scanHandlingUnitLabel(params).then(({ data }) => {
|
|
if (data.code === 0 && data.data) {
|
|
const huInfo = data.data;
|
|
|
|
// 检查是否已经扫描过
|
|
const exists = this.scannedItems.find(item => item.unitId === huInfo.unitId);
|
|
if (exists) {
|
|
this.$message.warning('该HandlingUnit已扫描,请勿重复扫描');
|
|
this.scanCode = '';
|
|
return;
|
|
}
|
|
|
|
// 添加到扫描列表
|
|
this.scannedItems.push({
|
|
unitId: huInfo.unitId,
|
|
partNo: huInfo.partNo,
|
|
partDesc: huInfo.partDesc,
|
|
qty: huInfo.qty,
|
|
batchNo: huInfo.batchNo,
|
|
locationId: huInfo.locationId
|
|
});
|
|
|
|
this.$message.success('扫描成功');
|
|
} else {
|
|
this.$message.error(data.msg || 'HandlingUnit不存在或查询失败');
|
|
}
|
|
}).catch(error => {
|
|
this.$message.error("扫描失败");
|
|
console.error(error);
|
|
});
|
|
|
|
this.scanCode = '';
|
|
},
|
|
|
|
// 选择处理项目
|
|
selectProcessItem(item) {
|
|
this.selectedItem = { ...item };
|
|
|
|
// 跳转到统一的不合格处理页面,通过processType参数区分处理类型
|
|
this.$router.push({
|
|
path: '/unqualified-process',
|
|
query: {
|
|
transNo: item.transNo,
|
|
itemNo: item.itemNo,
|
|
processType: item.processType,
|
|
partNo: item.partNo,
|
|
unqualifiedQty: item.unqualifiedQty,
|
|
scannedItems: JSON.stringify(this.scannedItems)
|
|
}
|
|
});
|
|
},
|
|
|
|
// 移除扫描的项目
|
|
removeScannedItem(index) {
|
|
this.scannedItems.splice(index, 1);
|
|
this.$message.success('移除成功');
|
|
},
|
|
|
|
// 获取处理类型文本
|
|
getProcessTypeText(processType) {
|
|
const typeMap = {
|
|
'RETURN': '退货',
|
|
'SCRAP': '报废',
|
|
'EXCHANGE': '换货'
|
|
};
|
|
return typeMap[processType] || '未知';
|
|
},
|
|
|
|
// 获取数量标签
|
|
getQtyLabel(processType) {
|
|
const labelMap = {
|
|
'RETURN': '退货数量',
|
|
'SCRAP': '报废数量',
|
|
'EXCHANGE': '换货数量'
|
|
};
|
|
return labelMap[processType] || '数量';
|
|
},
|
|
|
|
// 获取数量样式
|
|
getQtyStyle(processType) {
|
|
const styleMap = {
|
|
'RETURN': 'color: #E6A23C; font-weight: 500;', // 橙色
|
|
'SCRAP': 'color: #F56C6C; font-weight: 500;', // 红色
|
|
'EXCHANGE': 'color: #409EFF; font-weight: 500;' // 蓝色
|
|
};
|
|
return styleMap[processType] || 'color: #666; font-weight: 500;';
|
|
},
|
|
|
|
|
|
// 获取当前日期
|
|
getCurrentDate() {
|
|
const now = new Date();
|
|
return now.getFullYear() + '-' +
|
|
String(now.getMonth() + 1).padStart(2, '0') + '-' +
|
|
String(now.getDate()).padStart(2, '0');
|
|
},
|
|
|
|
// 格式化日期
|
|
formatDate(date) {
|
|
if (!date) return '';
|
|
const d = new Date(date);
|
|
return d.getFullYear() + '-' +
|
|
String(d.getMonth() + 1).padStart(2, '0') + '-' +
|
|
String(d.getDate()).padStart(2, '0');
|
|
}
|
|
},
|
|
|
|
mounted() {
|
|
this.$nextTick(() => {
|
|
if (this.$refs.scanCodeRef) {
|
|
this.$refs.scanCodeRef.focus();
|
|
}
|
|
});
|
|
// 默认加载检验不合格列表
|
|
this.searchUnqualifiedList();
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
|
|
.goBack {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.scan-box input {
|
|
width: 100%;
|
|
padding: 12px;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.filter-box {
|
|
text-align: center;
|
|
padding: 10px;
|
|
}
|
|
|
|
.item-list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
margin: 10px 0;
|
|
border: 1px solid rgba(200, 200, 200, 0.8);
|
|
background: white;
|
|
}
|
|
|
|
.item-list span {
|
|
color: #000;
|
|
font-size: 15px;
|
|
}
|
|
|
|
.bottom-line-row {
|
|
border-bottom: 1px solid rgba(200, 200, 200, 0.8);
|
|
}
|
|
|
|
.processButton {
|
|
font-size: 16px;
|
|
border-radius: 3px;
|
|
color: #17b3a3;
|
|
}
|
|
|
|
.process-type-selector {
|
|
background: white;
|
|
padding: 15px;
|
|
border-radius: 5px;
|
|
border: 1px solid rgba(200, 200, 200, 0.8);
|
|
}
|
|
|
|
.process-type-selector .el-radio-group {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
}
|
|
|
|
.process-type-selector .el-radio {
|
|
margin-right: 0;
|
|
}
|
|
|
|
.section-title {
|
|
background: #17b3a3;
|
|
color: white;
|
|
padding: 8px 15px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
border-radius: 3px 3px 0 0;
|
|
}
|
|
|
|
/* 处理类型样式 */
|
|
.process-type-return {
|
|
background: #FDF6EC;
|
|
color: #E6A23C;
|
|
padding: 2px 8px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
border: 1px solid #F5DAB1;
|
|
}
|
|
|
|
.process-type-scrap {
|
|
background: #FEF0F0;
|
|
color: #F56C6C;
|
|
padding: 2px 8px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
border: 1px solid #FAB6B6;
|
|
}
|
|
|
|
.process-type-exchange {
|
|
background: #ECF5FF;
|
|
color: #409EFF;
|
|
padding: 2px 8px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
border: 1px solid #B3D8FF;
|
|
}
|
|
|
|
.process-type-unknown {
|
|
background: #F5F7FA;
|
|
color: #909399;
|
|
padding: 2px 8px;
|
|
border-radius: 12px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
border: 1px solid #DCDFE6;
|
|
}
|
|
|
|
.item-list .el-row {
|
|
cursor: pointer;
|
|
transition: background 0.3s;
|
|
padding: 10px;
|
|
}
|
|
|
|
.item-list .el-row:hover {
|
|
background: #f5f7fa;
|
|
}
|
|
|
|
.form-section {
|
|
background: white;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.form-section >>> .el-col {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.bottom-nav {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
padding: 10px;
|
|
background: white;
|
|
border-top: 1px solid #ddd;
|
|
}
|
|
|
|
.bottom-nav .el-button {
|
|
flex: 1;
|
|
margin: 0 5px;
|
|
}
|
|
|
|
/* 响应式调整 */
|
|
@media (max-width: 768px) {
|
|
.status-bar {
|
|
font-size: 14px;
|
|
padding: 8px 10px;
|
|
}
|
|
|
|
.scan-box input {
|
|
padding: 10px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.item-list span {
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
</style>
|