4 changed files with 337 additions and 0 deletions
-
6src/api/po/po.js
-
1src/router/index.js
-
1src/views/modules/recv/po-recv.vue
-
329src/views/modules/recv/reprint-label.vue
@ -0,0 +1,329 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<div class="pda-container" v-loading.fullscreen.lock="fullscreenLoading"> |
||||
|
<div class="status-bar"> |
||||
|
<div class="goBack" @click="handleBack"><i class="el-icon-arrow-left"></i>上一页</div> |
||||
|
<div class="goBack">{{ viewMode === 'records' ? '补打标签' : 'HandlingUnit列表' }}</div> |
||||
|
<div class="network" style="color: #fff" @click="$router.push({ path: '/' })">🏠首页</div> |
||||
|
</div> |
||||
|
<div style="overflow-y: auto"> |
||||
|
<!-- 扫描PO单号 --> |
||||
|
<div v-if="viewMode === 'records'" class="scan-box" style="margin: 2px;"> |
||||
|
<el-input clearable v-model="scanCode" placeholder="扫描PO条码或输入PO号" |
||||
|
@keyup.enter.native="searchReceiveRecords" ref="scanCodeRef" /> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 接收记录列表 --> |
||||
|
<div v-if="viewMode === 'records' && receiveRecords.length > 0" class="item-list" style="margin: 2px;"> |
||||
|
<el-form label-position="top" style="margin: 3px;"> |
||||
|
<el-row :gutter="5" |
||||
|
v-for="(record, index) in receiveRecords" |
||||
|
:key="index" |
||||
|
:class="index < receiveRecords.length - 1 ? 'bottom-line-row' : ''" |
||||
|
@click.native="viewHandlingUnits(record)"> |
||||
|
<el-col :span="8"> |
||||
|
<el-form-item label="商品编码"><span>{{ record.partNo }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="8"> |
||||
|
<el-form-item label="行号/下达号"><span>{{ record.lineNo }}/{{ record.wdr || '*' }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="8"> |
||||
|
<el-form-item label=""> |
||||
|
<el-button type="text" class="viewButton" @click.stop="viewHandlingUnits(record)" |
||||
|
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>{{ record.description }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="6" :class="{ mt10: getTextWidth(record.description) > 34 }"> |
||||
|
<el-form-item label="接收数量"><span>{{ record.transQty }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="6" :class="{ mt10: getTextWidth(record.description) > 34 }"> |
||||
|
<el-form-item label="批号"><span>{{ record.batchNo }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="6" :class="{ mt10: getTextWidth(record.description) > 34 }"> |
||||
|
<el-form-item label="库位"><span>{{ record.locationNo }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="6" :class="{ mt10: getTextWidth(record.description) > 34 }"> |
||||
|
<el-form-item label="接收日期"><span>{{ formatDate(record.receiveDate) }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
</div> |
||||
|
|
||||
|
<!-- HandlingUnit列表 --> |
||||
|
<div v-if="viewMode === 'handlingUnits'" class="item-list" style="margin: 2px;"> |
||||
|
<div v-if="currentReceiveRecord" style="background: #f5f7fa; padding: 10px; margin-bottom: 10px; border-radius: 4px;"> |
||||
|
<div style="font-weight: bold; margin-bottom: 5px;">接收记录信息</div> |
||||
|
<div style="font-size: 14px; color: #666;"> |
||||
|
{{ currentReceiveRecord.partNo }} - {{ currentReceiveRecord.description }} |
||||
|
<br>接收单号: {{ currentReceiveRecord.receiptNo }} |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<el-form label-position="top" style="margin: 3px;" v-if="handlingUnits.length > 0"> |
||||
|
<el-row :gutter="5" |
||||
|
v-for="(unit, index) in handlingUnits" |
||||
|
:key="index" |
||||
|
:class="index < handlingUnits.length - 1 ? 'bottom-line-row' : ''"> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="Unit ID"><span>{{ unit.unitId }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="4"> |
||||
|
<el-form-item label="数量"><span>{{ unit.qty }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="8"> |
||||
|
<el-form-item label=""> |
||||
|
<el-button type="text" class="printButton" @click="reprintHandlingUnitLabel(unit)" |
||||
|
style="margin-top: 10px;margin-left: 20px" size="small">补打</el-button> |
||||
|
</el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="批号"><span>{{ unit.batchNo }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="库位"><span>{{ unit.locationId }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="状态"><span>{{ unit.status }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
<el-col :span="12"> |
||||
|
<el-form-item label="创建日期"><span>{{ formatDate(unit.createdDate) }}</span></el-form-item> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
|
||||
|
<div v-if="handlingUnits.length === 0 && !fullscreenLoading" |
||||
|
style="text-align: center; padding: 20px; color: #999;"> |
||||
|
该接收记录下没有HandlingUnit |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 无数据提示 --> |
||||
|
<div v-if="viewMode === 'records' && scanCode && receiveRecords.length === 0 && !fullscreenLoading" |
||||
|
style="text-align: center; padding: 20px; color: #999;"> |
||||
|
未找到该PO单号的接收记录 |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { getPoReceiveRecords, getHandlingUnitsByReceiptNo, printLabel } from "@/api/po/po.js"; |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
scanCode: '', |
||||
|
receiveRecords: [], |
||||
|
handlingUnits: [], |
||||
|
currentReceiptNo: '', |
||||
|
currentReceiveRecord: null, |
||||
|
viewMode: 'records', // 'records' | 'handlingUnits' |
||||
|
site: localStorage.getItem('site'), |
||||
|
warehouseId: localStorage.getItem('selectedWarehouse'), |
||||
|
fullscreenLoading: false, |
||||
|
// 打印相关配置 |
||||
|
reportId: 'PO_RECEIVE_LABEL', |
||||
|
zplCode: '', |
||||
|
paperSize: 'A4', |
||||
|
orientation: 'Portrait', |
||||
|
dpi: 300 |
||||
|
}; |
||||
|
}, |
||||
|
methods: { |
||||
|
// 计算"显示宽度" |
||||
|
getTextWidth(text) { |
||||
|
if (!text) return 0 |
||||
|
let len = 0 |
||||
|
for (let char of text) { |
||||
|
// 中文、全角符号 |
||||
|
if (/[\u4e00-\u9fa5\u3000-\u303F\uFF00-\uFFEF]/.test(char)) { |
||||
|
len += 2 |
||||
|
} else { |
||||
|
len += 1 |
||||
|
} |
||||
|
} |
||||
|
return len |
||||
|
}, |
||||
|
handleBack() { |
||||
|
if (this.viewMode === 'handlingUnits') { |
||||
|
// 从HandlingUnit列表返回到接收记录列表 |
||||
|
this.viewMode = 'records'; |
||||
|
this.handlingUnits = []; |
||||
|
this.currentReceiveRecord = null; |
||||
|
this.currentReceiptNo = ''; |
||||
|
} else { |
||||
|
// 从接收记录列表返回到上一页 |
||||
|
this.$router.back(); |
||||
|
} |
||||
|
}, |
||||
|
// 搜索PO接收记录 |
||||
|
searchReceiveRecords() { |
||||
|
if (!this.scanCode) { |
||||
|
this.receiveRecords = []; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
this.fullscreenLoading = true; |
||||
|
getPoReceiveRecords({ |
||||
|
poNumber: this.scanCode, |
||||
|
site: this.site, |
||||
|
warehouseId: this.warehouseId |
||||
|
}).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.receiveRecords = data.rows || []; |
||||
|
if (this.receiveRecords.length === 0) { |
||||
|
this.$message.warning('未找到该PO单号的接收记录'); |
||||
|
} |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '查询失败'); |
||||
|
this.receiveRecords = []; |
||||
|
} |
||||
|
}).catch(error => { |
||||
|
console.error('查询接收记录失败:', error); |
||||
|
this.$message.error('网络错误,请重试'); |
||||
|
this.receiveRecords = []; |
||||
|
}).finally(() => { |
||||
|
this.fullscreenLoading = false; |
||||
|
}); |
||||
|
}, |
||||
|
// 查看HandlingUnit列表 |
||||
|
viewHandlingUnits(record) { |
||||
|
this.currentReceiveRecord = record; |
||||
|
this.currentReceiptNo = record.receiptNo; |
||||
|
this.fullscreenLoading = true; |
||||
|
|
||||
|
getHandlingUnitsByReceiptNo({ |
||||
|
site: this.site, |
||||
|
receiptNo: record.receiptNo |
||||
|
}).then(({ data }) => { |
||||
|
if (data.code === 0) { |
||||
|
this.handlingUnits = data.rows || []; |
||||
|
this.viewMode = 'handlingUnits'; |
||||
|
if (this.handlingUnits.length === 0) { |
||||
|
this.$message.warning('该接收记录下没有HandlingUnit'); |
||||
|
} |
||||
|
} else { |
||||
|
this.$message.error(data.msg || '查询HandlingUnit失败'); |
||||
|
} |
||||
|
}).catch(error => { |
||||
|
console.error('查询HandlingUnit失败:', error); |
||||
|
this.$message.error('网络错误,请重试'); |
||||
|
}).finally(() => { |
||||
|
this.fullscreenLoading = false; |
||||
|
}); |
||||
|
}, |
||||
|
// 补打HandlingUnit标签 |
||||
|
async reprintHandlingUnitLabel(unit) { |
||||
|
if (this.fullscreenLoading) return; |
||||
|
|
||||
|
this.fullscreenLoading = true; |
||||
|
try { |
||||
|
await this.printViaServer(unit.unitId); |
||||
|
this.$message.success('补打标签任务已发送!'); |
||||
|
} catch (error) { |
||||
|
console.error('补打标签失败:', error); |
||||
|
this.$message.error(`补打标签失败: ${error.message || error}`); |
||||
|
} finally { |
||||
|
this.fullscreenLoading = false; |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* 通过服务器打印 |
||||
|
*/ |
||||
|
async printViaServer(unitId) { |
||||
|
try { |
||||
|
const printRequest = { |
||||
|
reportId: this.reportId, |
||||
|
zplCode: this.zplCode, |
||||
|
paperSize: this.paperSize, |
||||
|
orientation: this.orientation, |
||||
|
dpi: this.dpi, |
||||
|
userId: localStorage.getItem('userName'), |
||||
|
username: localStorage.getItem('userName'), |
||||
|
site: localStorage.getItem('site'), |
||||
|
unitId: unitId |
||||
|
} |
||||
|
const { data } = await printLabel(printRequest) |
||||
|
if (data.code === 200) { |
||||
|
return Promise.resolve(); |
||||
|
} else { |
||||
|
return Promise.reject(new Error(data.msg || '打印失败')); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
return Promise.reject(error); |
||||
|
} |
||||
|
}, |
||||
|
// 格式化日期 |
||||
|
formatDate(dateString) { |
||||
|
if (!dateString) return '-'; |
||||
|
try { |
||||
|
const date = new Date(dateString); |
||||
|
return date.getFullYear() + '-' + |
||||
|
String(date.getMonth() + 1).padStart(2, '0') + '-' + |
||||
|
String(date.getDate()).padStart(2, '0') + ' ' + |
||||
|
String(date.getHours()).padStart(2, '0') + ':' + |
||||
|
String(date.getMinutes()).padStart(2, '0'); |
||||
|
} catch (error) { |
||||
|
return dateString; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.$nextTick(() => { |
||||
|
if (this.$refs.scanCodeRef) { |
||||
|
this.$refs.scanCodeRef.focus(); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.mt10 { |
||||
|
margin-top: 10px; |
||||
|
} |
||||
|
.scan-box input { |
||||
|
width: 100%; |
||||
|
padding: 12px; |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
.item-list { |
||||
|
flex: 1; |
||||
|
overflow-y: auto; |
||||
|
margin: 10px 0; |
||||
|
border: 1px solid rgba(200, 200, 200, 0.8); |
||||
|
} |
||||
|
.item-list span { |
||||
|
color: #000; |
||||
|
font-size: 15px; |
||||
|
} |
||||
|
.bottom-line-row { |
||||
|
border-bottom: 1px solid rgba(200, 200, 200, 0.8); |
||||
|
} |
||||
|
.printButton, .viewButton { |
||||
|
font-size: 16px; |
||||
|
border-radius: 3px; |
||||
|
color: #17b3a3; |
||||
|
} |
||||
|
.item-list .el-row { |
||||
|
cursor: pointer; |
||||
|
transition: background 0.3s; |
||||
|
} |
||||
|
.item-list .el-row:hover { |
||||
|
background: #f5f7fa; |
||||
|
} |
||||
|
.form-section >>> .el-col { |
||||
|
margin-bottom: 12px; |
||||
|
} |
||||
|
.status-bar { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
background: #17b3a3; |
||||
|
color: white; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue