|
|
|
@ -2,13 +2,13 @@ |
|
|
|
<div> |
|
|
|
<div class="pda-container"> |
|
|
|
<div class="status-bar"> |
|
|
|
<div class="goBack" @click="goBack"><i class="el-icon-arrow-left"></i>上一页</div> |
|
|
|
<div class="goBack" @click="handleBack"><i class="el-icon-arrow-left"></i>上一页</div> |
|
|
|
<div class="goBack">{{ functionTitle }}</div> |
|
|
|
<div class="network" style="color: #fff" @click="$router.push({ path: '/' })">🏠首页</div> |
|
|
|
</div> |
|
|
|
<div style="overflow-y: auto"> |
|
|
|
<!-- 功能选择 --> |
|
|
|
<div class="function-selector" v-if="!selectedFunction"> |
|
|
|
<div class="function-selector" v-if="processFlag === 1"> |
|
|
|
<div class="function-card" @click="selectFunction('direct')"> |
|
|
|
<div class="function-icon">📦</div> |
|
|
|
<div class="function-title">直接发料</div> |
|
|
|
@ -29,17 +29,14 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 直接发料 --> |
|
|
|
<div class="direct-issue" v-if="selectedFunction === 'direct'"> |
|
|
|
<div class="direct-issue" v-if="processFlag === 2 && selectedFunction === 'direct'"> |
|
|
|
<!-- 工单输入 --> |
|
|
|
<div class="input-section" v-if="!workOrderMaterials.length"> |
|
|
|
<div class="input-section"> |
|
|
|
<div class="input-group"> |
|
|
|
<label>工单号</label> |
|
|
|
<div class="input-with-scan"> |
|
|
|
<input |
|
|
|
v-model="directIssueForm.workOrderNo" |
|
|
|
placeholder="请输入或扫描工单号" |
|
|
|
@keyup.enter="loadWorkOrderMaterials" |
|
|
|
/> |
|
|
|
<input v-model="directIssueForm.workOrderNo" placeholder="请输入或扫描工单号" |
|
|
|
@keyup.enter="loadWorkOrderMaterials" /> |
|
|
|
<button @click="loadWorkOrderMaterials" class="scan-btn">确认</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
@ -47,17 +44,10 @@ |
|
|
|
|
|
|
|
<!-- 物料列表 --> |
|
|
|
<div class="materials-section" v-if="workOrderMaterials.length"> |
|
|
|
<div class="section-header"> |
|
|
|
<h3>工单物料 ({{ directIssueForm.workOrderNo }})</h3> |
|
|
|
<button @click="resetWorkOrder" class="reset-btn">重新选择</button> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="material-list"> |
|
|
|
<div v-for="(material, index) in workOrderMaterials" :key="index" |
|
|
|
class="material-item" |
|
|
|
<div v-for="(material, index) in workOrderMaterials" :key="index" class="material-item" |
|
|
|
:class="{ selected: (selectedMaterial?selectedMaterial.partNo:'') === (material&&material.partNo?material.partNo:'') }" |
|
|
|
@click="selectMaterial(material)" |
|
|
|
> |
|
|
|
@click="goToScanLabel(material)"> |
|
|
|
<div class="material-info"> |
|
|
|
<div class="part-no">{{ material.partNo }}</div> |
|
|
|
<div class="part-desc">{{ material.partDesc }}</div> |
|
|
|
@ -74,85 +64,16 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 扫描标签 --> |
|
|
|
<div class="scan-section" v-if="selectedMaterial"> |
|
|
|
<div class="section-header"> |
|
|
|
<h3>扫描物料标签</h3> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="input-group"> |
|
|
|
<label>物料标签</label> |
|
|
|
<div class="input-with-scan"> |
|
|
|
<input |
|
|
|
v-model="scannedLabel" |
|
|
|
placeholder="请扫描物料标签" |
|
|
|
@keyup.enter="parseMaterialLabel" |
|
|
|
/> |
|
|
|
<button @click="parseMaterialLabel" class="scan-btn">解析</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 标签信息 --> |
|
|
|
<div class="label-info" v-if="labelInfo"> |
|
|
|
<div class="info-row"> |
|
|
|
<span class="label">物料编码:</span> |
|
|
|
<span class="value">{{ labelInfo.partNo }}</span> |
|
|
|
</div> |
|
|
|
<div class="info-row"> |
|
|
|
<span class="label">物料描述:</span> |
|
|
|
<span class="value">{{ labelInfo.partDesc }}</span> |
|
|
|
</div> |
|
|
|
<div class="info-row"> |
|
|
|
<span class="label">批次号:</span> |
|
|
|
<span class="value">{{ labelInfo.batchNo }}</span> |
|
|
|
</div> |
|
|
|
<div class="info-row"> |
|
|
|
<span class="label">库位:</span> |
|
|
|
<span class="value">{{ labelInfo.locationId }}</span> |
|
|
|
</div> |
|
|
|
<div class="info-row"> |
|
|
|
<span class="label">可用数量:</span> |
|
|
|
<span class="value">{{ labelInfo.availableQty }}</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 发料数量 --> |
|
|
|
<div class="qty-input" v-if="labelInfo"> |
|
|
|
<div class="input-group"> |
|
|
|
<label>发料数量</label> |
|
|
|
<input |
|
|
|
v-model="issueQty" |
|
|
|
type="number" |
|
|
|
:max="Math.min(selectedMaterial.remainQty, labelInfo.availableQty)" |
|
|
|
placeholder="请输入发料数量" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="input-group"> |
|
|
|
<label>备注</label> |
|
|
|
<input v-model="directIssueForm.remark" placeholder="可选" /> |
|
|
|
</div> |
|
|
|
|
|
|
|
<button @click="confirmDirectIssue" class="confirm-btn" :disabled="!issueQty"> |
|
|
|
确认发料 |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 拣选装托盘 --> |
|
|
|
<div class="picking-pallet" v-if="selectedFunction === 'picking'"> |
|
|
|
<div class="picking-pallet" v-if="processFlag === 2 && selectedFunction === 'picking'"> |
|
|
|
<!-- 申请单输入 --> |
|
|
|
<div class="input-section" v-if="!currentPallet.palletId"> |
|
|
|
<div class="input-group"> |
|
|
|
<label>申请单号</label> |
|
|
|
<div class="input-with-scan"> |
|
|
|
<input |
|
|
|
v-model="palletForm.notifyNo" |
|
|
|
placeholder="请输入申请单号" |
|
|
|
@keyup.enter="createPallet" |
|
|
|
/> |
|
|
|
<input v-model="palletForm.notifyNo" placeholder="请输入申请单号" @keyup.enter="createPallet" /> |
|
|
|
<button @click="createPallet" class="scan-btn">创建托盘</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
@ -184,11 +105,7 @@ |
|
|
|
<div class="input-group"> |
|
|
|
<label>扫描箱/卷</label> |
|
|
|
<div class="input-with-scan"> |
|
|
|
<input |
|
|
|
v-model="scannedUnit" |
|
|
|
placeholder="请扫描处理单元条码" |
|
|
|
@keyup.enter="bindUnit" |
|
|
|
/> |
|
|
|
<input v-model="scannedUnit" placeholder="请扫描处理单元条码" @keyup.enter="bindUnit" /> |
|
|
|
<button @click="bindUnit" class="scan-btn">绑定</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
@ -225,17 +142,13 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 申请单发料 --> |
|
|
|
<div class="request-issue" v-if="selectedFunction === 'request'"> |
|
|
|
<div class="request-issue" v-if="processFlag === 2 && selectedFunction === 'request'"> |
|
|
|
<!-- 申请单输入 --> |
|
|
|
<div class="input-section" v-if="!requestMaterials.length"> |
|
|
|
<div class="input-section"> |
|
|
|
<div class="input-group"> |
|
|
|
<label>申请单号</label> |
|
|
|
<div class="input-with-scan"> |
|
|
|
<input |
|
|
|
v-model="requestIssueForm.notifyNo" |
|
|
|
placeholder="请输入申请单号" |
|
|
|
@keyup.enter="loadRequestMaterials" |
|
|
|
/> |
|
|
|
<input v-model="requestIssueForm.notifyNo" placeholder="请输入申请单号" @keyup.enter="loadRequestMaterials" /> |
|
|
|
<button @click="loadRequestMaterials" class="scan-btn">确认</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
@ -243,54 +156,20 @@ |
|
|
|
|
|
|
|
<!-- 申请单物料列表 --> |
|
|
|
<div class="materials-section" v-if="requestMaterials.length"> |
|
|
|
<div class="section-header"> |
|
|
|
<h3>申请单物料 ({{ requestIssueForm.notifyNo }})</h3> |
|
|
|
<button @click="resetRequest" class="reset-btn">重新选择</button> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="material-list"> |
|
|
|
<div |
|
|
|
v-for="material in requestMaterials" |
|
|
|
:key="`${material.partNo}-${material.itemNo}`" |
|
|
|
class="material-item" |
|
|
|
:class="{ selected: selectedRequestMaterial.itemNo === material.itemNo }" |
|
|
|
@click="selectRequestMaterial(material)" |
|
|
|
> |
|
|
|
<div class="material-info"> |
|
|
|
<div class="part-no">{{ material.partNo }}</div> |
|
|
|
<div class="part-desc">{{ material.partDesc }}</div> |
|
|
|
<div class="work-order">工单: {{ material.workOrderNo }}</div> |
|
|
|
<div class="qty-info"> |
|
|
|
申请: {{ material.requestQty }} | |
|
|
|
已发: {{ material.issuedQty }} | |
|
|
|
剩余: {{ material.remainQty }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="material-status"> |
|
|
|
<span v-if="material.remainQty > 0" class="status-pending">待发料</span> |
|
|
|
<span v-else class="status-complete">已完成</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 扫描标签和发料 --> |
|
|
|
<div class="scan-section" v-if="selectedRequestMaterial"> |
|
|
|
<!-- <div class="scan-section"> |
|
|
|
<div class="section-header"> |
|
|
|
<h3>扫描物料标签</h3> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="input-group"> |
|
|
|
<label>物料标签</label> |
|
|
|
<div class="input-with-scan"> |
|
|
|
<input |
|
|
|
v-model="scannedLabel" |
|
|
|
placeholder="请扫描物料标签" |
|
|
|
@keyup.enter="parseMaterialLabel" |
|
|
|
/> |
|
|
|
<input v-model="scannedLabel" placeholder="请扫描物料标签" @keyup.enter="parseMaterialLabel" /> |
|
|
|
<button @click="parseMaterialLabel" class="scan-btn">解析</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> --> |
|
|
|
|
|
|
|
<!-- 标签信息和发料确认 --> |
|
|
|
<div class="label-info" v-if="labelInfo"> |
|
|
|
@ -310,17 +189,17 @@ |
|
|
|
<div class="qty-input"> |
|
|
|
<div class="input-group"> |
|
|
|
<label>发料数量</label> |
|
|
|
<input |
|
|
|
v-model="issueQty" |
|
|
|
type="number" |
|
|
|
<input v-model="issueQty" type="number" |
|
|
|
:max="Math.min(selectedRequestMaterial.remainQty, labelInfo.availableQty)" |
|
|
|
placeholder="请输入发料数量" |
|
|
|
/> |
|
|
|
placeholder="请输入发料数量" /> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="input-group"> |
|
|
|
<label>备注</label> |
|
|
|
<input v-model="requestIssueForm.remark" placeholder="可选" /> |
|
|
|
<div class="input-with-scan"> |
|
|
|
<textarea v-model="requestIssueForm.remark" placeholder="可选" /> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<button @click="confirmRequestIssue" class="confirm-btn" :disabled="!issueQty"> |
|
|
|
@ -329,6 +208,26 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div v-for="material in requestMaterials" :key="`${material.partNo}-${material.itemNo}`" |
|
|
|
class="material-item" @click="selectRequestMaterial(material)"> |
|
|
|
<div class="material-info"> |
|
|
|
<div class="part-no">{{ material.partNo }}</div> |
|
|
|
<div class="part-desc">{{ material.partDesc }}</div> |
|
|
|
<div class="work-order">工单: {{ material.workOrderNo }}</div> |
|
|
|
<div class="qty-info"> |
|
|
|
申请: {{ material.requestQty }} | |
|
|
|
已发: {{ material.issuedQty }} | |
|
|
|
剩余: {{ material.remainQty }} |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="material-status"> |
|
|
|
<span v-if="material.remainQty > 0" class="status-pending">待发料</span> |
|
|
|
<span v-else class="status-complete">已完成</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 加载提示 --> |
|
|
|
@ -341,6 +240,35 @@ |
|
|
|
<div class="message" v-if="message" :class="messageType"> |
|
|
|
{{ message }} |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 扫描标签页面 --> |
|
|
|
<div v-if="processFlag === 3" class="scan-label-page"> |
|
|
|
|
|
|
|
<div class="input-section"> |
|
|
|
|
|
|
|
<div class="label-info" v-if="scanLabelData.labelInfo"> |
|
|
|
<div class="info-row"><span class="label">物料编码:</span><span |
|
|
|
class="value">{{ scanLabelData.labelInfo.partNo }}</span></div> |
|
|
|
<div class="info-row"><span class="label">批次号:</span><span |
|
|
|
class="value">{{ scanLabelData.labelInfo.batchNo }}</span></div> |
|
|
|
<div class="info-row"><span class="label">可用数量:</span><span |
|
|
|
class="value">{{ scanLabelData.labelInfo.availableQty }}</span></div> |
|
|
|
</div> |
|
|
|
<div class="qty-input" v-if="scanLabelData.labelInfo"> |
|
|
|
<div class="input-group"> |
|
|
|
<label>发料数量</label> |
|
|
|
<input v-model="scanLabelData.issueQty" type="number" :max="scanLabelData.labelInfo.availableQty" |
|
|
|
placeholder="请输入发料数量" /> |
|
|
|
</div> |
|
|
|
<div class="input-group"> |
|
|
|
<label>备注</label> |
|
|
|
<el-input type="textarea" v-model="scanLabelData.remark" placeholder="可选" /> |
|
|
|
</div> |
|
|
|
<button @click="confirmScanLabelIssue" class="confirm-btn" :disabled="!scanLabelData.issueQty">确认发料</button> |
|
|
|
</div> |
|
|
|
<div class="message" v-if="scanLabelData.message" :class="scanLabelData.messageType"> |
|
|
|
{{ scanLabelData.message }}</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
@ -356,13 +284,14 @@ import { |
|
|
|
createPickingPallet, |
|
|
|
bindUnitsToPallet, |
|
|
|
printPalletLabel, |
|
|
|
getPalletInfo |
|
|
|
getPalletInfo, |
|
|
|
} from '@/api/production/production-issue' |
|
|
|
|
|
|
|
export default { |
|
|
|
name: 'ProductionIssuePDA', |
|
|
|
data() { |
|
|
|
return { |
|
|
|
processFlag: 1, // 1=功能选择, 2=主表单, 3=物料列表, 4=扫描标签 |
|
|
|
selectedFunction: null, |
|
|
|
loading: false, |
|
|
|
loadingText: '', |
|
|
|
@ -375,7 +304,7 @@ export default { |
|
|
|
workOrderNo: '', |
|
|
|
operatorName: 'PDA_USER', |
|
|
|
remark: '', |
|
|
|
selectedMaterials: [] |
|
|
|
selectedMaterials: [], |
|
|
|
}, |
|
|
|
workOrderMaterials: [], |
|
|
|
selectedMaterial: { |
|
|
|
@ -383,7 +312,7 @@ export default { |
|
|
|
partDesc: '', |
|
|
|
requiredQty: 0, |
|
|
|
issuedQty: 0, |
|
|
|
remainQty: 0 |
|
|
|
remainQty: 0, |
|
|
|
}, |
|
|
|
|
|
|
|
// 申请单发料 |
|
|
|
@ -393,7 +322,7 @@ export default { |
|
|
|
workOrderNo: '', |
|
|
|
operatorName: 'PDA_USER', |
|
|
|
remark: '', |
|
|
|
selectedMaterials: [] |
|
|
|
selectedMaterials: [], |
|
|
|
}, |
|
|
|
requestMaterials: [], |
|
|
|
selectedRequestMaterial: null, |
|
|
|
@ -404,7 +333,7 @@ export default { |
|
|
|
notifyNo: '', |
|
|
|
operatorName: 'PDA_USER', |
|
|
|
printerName: '', |
|
|
|
remark: '' |
|
|
|
remark: '', |
|
|
|
}, |
|
|
|
currentPallet: {}, |
|
|
|
scannedUnit: '', |
|
|
|
@ -412,33 +341,98 @@ export default { |
|
|
|
// 通用 |
|
|
|
scannedLabel: '', |
|
|
|
labelInfo: null, |
|
|
|
issueQty: null |
|
|
|
issueQty: null, |
|
|
|
showScanLabel: false, |
|
|
|
scanLabelContext: {}, |
|
|
|
scanLabelData: {}, |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
functionTitle() { |
|
|
|
if (!this.selectedFunction) return '生产发料'; |
|
|
|
if (this.selectedFunction === 'direct') return '直接发料'; |
|
|
|
if (this.selectedFunction === 'picking') return '拣选装托盘'; |
|
|
|
if (this.selectedFunction === 'request') return '申请单发料'; |
|
|
|
return '生产发料'; |
|
|
|
} |
|
|
|
if (!this.selectedFunction) return '生产发料' |
|
|
|
if (this.selectedFunction === 'direct') return '直接发料' |
|
|
|
if (this.selectedFunction === 'picking') return '拣选装托盘' |
|
|
|
if (this.selectedFunction === 'request') return '申请单发料' |
|
|
|
return '生产发料' |
|
|
|
}, |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
handleBack() { |
|
|
|
if (this.processFlag === 3) { |
|
|
|
this.processFlag = 2 |
|
|
|
this.showScanLabel = false |
|
|
|
} else if (this.processFlag === 2) { |
|
|
|
this.processFlag = 1 |
|
|
|
this.selectedFunction = null |
|
|
|
} else if (this.processFlag === 1) { |
|
|
|
this.$router.push('/') |
|
|
|
} |
|
|
|
}, |
|
|
|
selectFunction(func) { |
|
|
|
this.selectedFunction = func |
|
|
|
this.resetAll() |
|
|
|
this.processFlag = 2 |
|
|
|
}, |
|
|
|
|
|
|
|
goBack() { |
|
|
|
if (!this.selectedFunction) { |
|
|
|
this.$router.push('/') |
|
|
|
} else { |
|
|
|
this.selectedFunction = null |
|
|
|
this.resetAll() |
|
|
|
goToScanLabel(material) { |
|
|
|
if (material.remainQty <= 0) { |
|
|
|
this.showMessage('该物料已发料完成', 'warning') |
|
|
|
return |
|
|
|
} |
|
|
|
this.scanLabelContext = { |
|
|
|
type: 'direct', |
|
|
|
workOrderNo: this.directIssueForm.workOrderNo, |
|
|
|
partNo: material.partNo, |
|
|
|
material, |
|
|
|
} |
|
|
|
this.scanLabelData = { |
|
|
|
scannedLabel: '', |
|
|
|
labelInfo: { |
|
|
|
partNo: this.partNo, |
|
|
|
batchNo: 'BATCH001', |
|
|
|
availableQty: 100, |
|
|
|
}, |
|
|
|
issueQty: null, |
|
|
|
remark: '', |
|
|
|
message: '', |
|
|
|
messageType: 'info', |
|
|
|
} |
|
|
|
this.showScanLabel = true |
|
|
|
this.processFlag = 3 |
|
|
|
}, |
|
|
|
selectRequestMaterial(material) { |
|
|
|
if (material.remainQty <= 0) { |
|
|
|
this.showMessage('该物料已发料完成', 'warning') |
|
|
|
return |
|
|
|
} |
|
|
|
this.selectedRequestMaterial = material |
|
|
|
this.requestIssueForm.workOrderNo = material.workOrderNo |
|
|
|
this.scannedLabel = '' |
|
|
|
this.labelInfo = null |
|
|
|
this.issueQty = null |
|
|
|
this.scanLabelContext = { |
|
|
|
type: 'request', |
|
|
|
notifyNo: this.requestIssueForm.notifyNo, |
|
|
|
partNo: material.partNo, |
|
|
|
material, |
|
|
|
} |
|
|
|
this.scanLabelData = { |
|
|
|
scannedLabel: '', |
|
|
|
labelInfo: { |
|
|
|
partNo: this.partNo, |
|
|
|
batchNo: 'BATCH001', |
|
|
|
availableQty: 100, |
|
|
|
}, |
|
|
|
issueQty: null, |
|
|
|
remark: '', |
|
|
|
message: '', |
|
|
|
messageType: 'info', |
|
|
|
} |
|
|
|
this.showScanLabel = true |
|
|
|
this.processFlag = 3 |
|
|
|
}, |
|
|
|
closeScanLabel() { |
|
|
|
this.handleBack() |
|
|
|
}, |
|
|
|
|
|
|
|
resetAll() { |
|
|
|
this.workOrderMaterials = [] |
|
|
|
this.requestMaterials = [] |
|
|
|
@ -464,7 +458,7 @@ export default { |
|
|
|
try { |
|
|
|
const response = await getWorkOrderMaterials({ |
|
|
|
site: this.directIssueForm.site, |
|
|
|
workOrderNo: this.directIssueForm.workOrderNo |
|
|
|
workOrderNo: this.directIssueForm.workOrderNo, |
|
|
|
}) |
|
|
|
|
|
|
|
if (response.data.code === 0) { |
|
|
|
@ -482,26 +476,6 @@ export default { |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
selectMaterial(material) { |
|
|
|
if (material.remainQty <= 0) { |
|
|
|
this.showMessage('该物料已发料完成', 'warning') |
|
|
|
return |
|
|
|
} |
|
|
|
this.selectedMaterial = material |
|
|
|
this.scannedLabel = '' |
|
|
|
this.labelInfo = null |
|
|
|
this.issueQty = null |
|
|
|
}, |
|
|
|
|
|
|
|
resetWorkOrder() { |
|
|
|
this.directIssueForm.workOrderNo = '' |
|
|
|
this.workOrderMaterials = [] |
|
|
|
this.selectedMaterial = null |
|
|
|
this.scannedLabel = '' |
|
|
|
this.labelInfo = null |
|
|
|
this.issueQty = null |
|
|
|
}, |
|
|
|
|
|
|
|
async confirmDirectIssue() { |
|
|
|
if (!this.issueQty || this.issueQty <= 0) { |
|
|
|
this.showMessage('请输入有效的发料数量', 'error') |
|
|
|
@ -514,11 +488,13 @@ export default { |
|
|
|
try { |
|
|
|
const issueData = { |
|
|
|
...this.directIssueForm, |
|
|
|
selectedMaterials: [{ |
|
|
|
selectedMaterials: [ |
|
|
|
{ |
|
|
|
...this.selectedMaterial, |
|
|
|
issueQty: this.issueQty |
|
|
|
}], |
|
|
|
scannedLabel: this.scannedLabel |
|
|
|
issueQty: this.issueQty, |
|
|
|
}, |
|
|
|
], |
|
|
|
scannedLabel: this.scannedLabel, |
|
|
|
} |
|
|
|
|
|
|
|
const response = await directIssue(issueData) |
|
|
|
@ -544,7 +520,7 @@ export default { |
|
|
|
|
|
|
|
// 申请单发料相关方法 |
|
|
|
async loadRequestMaterials() { |
|
|
|
if (!this.requestIssueForm.notifyNo) { |
|
|
|
/* if (!this.requestIssueForm.notifyNo) { |
|
|
|
this.showMessage('请输入申请单号', 'error') |
|
|
|
return |
|
|
|
} |
|
|
|
@ -555,7 +531,7 @@ export default { |
|
|
|
try { |
|
|
|
const response = await getRequestMaterials({ |
|
|
|
site: this.requestIssueForm.site, |
|
|
|
notifyNo: this.requestIssueForm.notifyNo |
|
|
|
notifyNo: this.requestIssueForm.notifyNo, |
|
|
|
}) |
|
|
|
|
|
|
|
if (response.data.code === 0) { |
|
|
|
@ -570,29 +546,31 @@ export default { |
|
|
|
this.showMessage('加载申请单物料失败', 'error') |
|
|
|
} finally { |
|
|
|
this.loading = false |
|
|
|
} |
|
|
|
} */ |
|
|
|
|
|
|
|
let materials = [ |
|
|
|
{ |
|
|
|
partNo: 'PART001', |
|
|
|
partDesc: '物料描述1', |
|
|
|
workOrderNo: 'WO001', |
|
|
|
requestQty: 100, |
|
|
|
issuedQty: 50, |
|
|
|
remainQty: 50, |
|
|
|
itemNo: 'ITEM001', |
|
|
|
}, |
|
|
|
|
|
|
|
selectRequestMaterial(material) { |
|
|
|
if (material.remainQty <= 0) { |
|
|
|
this.showMessage('该物料已发料完成', 'warning') |
|
|
|
return |
|
|
|
} |
|
|
|
this.selectedRequestMaterial = material |
|
|
|
this.requestIssueForm.workOrderNo = material.workOrderNo |
|
|
|
this.scannedLabel = '' |
|
|
|
this.labelInfo = null |
|
|
|
this.issueQty = null |
|
|
|
{ |
|
|
|
partNo: 'PART002', |
|
|
|
partDesc: '物料描述2', |
|
|
|
workOrderNo: 'WO002', |
|
|
|
requestQty: 200, |
|
|
|
issuedQty: 100, |
|
|
|
remainQty: 100, |
|
|
|
itemNo: 'ITEM002', |
|
|
|
}, |
|
|
|
] |
|
|
|
|
|
|
|
resetRequest() { |
|
|
|
this.requestIssueForm.notifyNo = '' |
|
|
|
this.requestIssueForm.workOrderNo = '' |
|
|
|
this.requestMaterials = [] |
|
|
|
this.selectedRequestMaterial = null |
|
|
|
this.scannedLabel = '' |
|
|
|
this.labelInfo = null |
|
|
|
this.issueQty = null |
|
|
|
//this.requestMaterials = materials |
|
|
|
this.$set(this, 'requestMaterials', materials) |
|
|
|
}, |
|
|
|
|
|
|
|
async confirmRequestIssue() { |
|
|
|
@ -607,11 +585,13 @@ export default { |
|
|
|
try { |
|
|
|
const issueData = { |
|
|
|
...this.requestIssueForm, |
|
|
|
selectedMaterials: [{ |
|
|
|
selectedMaterials: [ |
|
|
|
{ |
|
|
|
...this.selectedRequestMaterial, |
|
|
|
issueQty: this.issueQty |
|
|
|
}], |
|
|
|
scannedLabel: this.scannedLabel |
|
|
|
issueQty: this.issueQty, |
|
|
|
}, |
|
|
|
], |
|
|
|
scannedLabel: this.scannedLabel, |
|
|
|
} |
|
|
|
|
|
|
|
const response = await requestIssue(issueData) |
|
|
|
@ -637,7 +617,7 @@ export default { |
|
|
|
|
|
|
|
// 托盘拣选相关方法 |
|
|
|
async createPallet() { |
|
|
|
if (!this.palletForm.notifyNo) { |
|
|
|
/* if (!this.palletForm.notifyNo) { |
|
|
|
this.showMessage('请输入申请单号', 'error') |
|
|
|
return |
|
|
|
} |
|
|
|
@ -648,7 +628,7 @@ export default { |
|
|
|
try { |
|
|
|
const response = await createPickingPallet({ |
|
|
|
...this.palletForm, |
|
|
|
palletType: 'PALLET' |
|
|
|
palletType: 'PALLET', |
|
|
|
}) |
|
|
|
|
|
|
|
if (response.data.code === 0) { |
|
|
|
@ -656,7 +636,7 @@ export default { |
|
|
|
palletId: response.data.palletId, |
|
|
|
notifyNo: this.palletForm.notifyNo, |
|
|
|
scannedUnits: [], |
|
|
|
unitCount: 0 |
|
|
|
unitCount: 0, |
|
|
|
} |
|
|
|
this.showMessage('托盘创建成功: ' + response.data.palletId, 'success') |
|
|
|
} else { |
|
|
|
@ -666,6 +646,12 @@ export default { |
|
|
|
this.showMessage('创建托盘失败', 'error') |
|
|
|
} finally { |
|
|
|
this.loading = false |
|
|
|
} */ |
|
|
|
this.currentPallet = { |
|
|
|
palletId: 'qeqweqeqweq', |
|
|
|
notifyNo: 'SOIA00000035', |
|
|
|
scannedUnits: [], |
|
|
|
unitCount: 0, |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
@ -688,7 +674,7 @@ export default { |
|
|
|
const response = await bindUnitsToPallet({ |
|
|
|
site: this.palletForm.site, |
|
|
|
palletId: this.currentPallet.palletId, |
|
|
|
scannedUnits: [this.scannedUnit] |
|
|
|
scannedUnits: [this.scannedUnit], |
|
|
|
}) |
|
|
|
|
|
|
|
if (response.data.code === 0) { |
|
|
|
@ -719,7 +705,7 @@ export default { |
|
|
|
const response = await printPalletLabel({ |
|
|
|
site: this.palletForm.site, |
|
|
|
palletId: this.currentPallet.palletId, |
|
|
|
printerName: this.palletForm.printerName |
|
|
|
printerName: this.palletForm.printerName, |
|
|
|
}) |
|
|
|
|
|
|
|
if (response.data.code === 0) { |
|
|
|
@ -736,7 +722,7 @@ export default { |
|
|
|
|
|
|
|
// 通用方法 |
|
|
|
async parseMaterialLabel() { |
|
|
|
if (!this.scannedLabel) { |
|
|
|
/* if (!this.scannedLabel) { |
|
|
|
this.showMessage('请扫描物料标签', 'error') |
|
|
|
return |
|
|
|
} |
|
|
|
@ -763,7 +749,14 @@ export default { |
|
|
|
this.labelInfo = null |
|
|
|
} finally { |
|
|
|
this.loading = false |
|
|
|
} */ |
|
|
|
this.labelInfo = { |
|
|
|
partNo: this.selectedMaterial.partNo, |
|
|
|
batchNo: 'BATCH001', |
|
|
|
availableQty: 100, |
|
|
|
} |
|
|
|
this.issueQty = null // 重置发料数量 |
|
|
|
this.showMessage('标签解析成功', 'success') |
|
|
|
}, |
|
|
|
|
|
|
|
showMessage(text, type = 'info') { |
|
|
|
@ -772,8 +765,78 @@ export default { |
|
|
|
setTimeout(() => { |
|
|
|
this.message = '' |
|
|
|
}, 3000) |
|
|
|
}, |
|
|
|
|
|
|
|
async confirmScanLabelIssue() { |
|
|
|
if (!this.scanLabelData.issueQty || this.scanLabelData.issueQty <= 0) { |
|
|
|
this.scanLabelData.message = '请输入有效的发料数量' |
|
|
|
this.scanLabelData.messageType = 'error' |
|
|
|
return |
|
|
|
} |
|
|
|
this.loading = true |
|
|
|
this.scanLabelData.message = '' |
|
|
|
try { |
|
|
|
if (this.scanLabelContext.type === 'direct') { |
|
|
|
// 直接发料 |
|
|
|
const issueData = { |
|
|
|
...this.directIssueForm, |
|
|
|
selectedMaterials: [ |
|
|
|
{ |
|
|
|
...this.scanLabelContext.material, |
|
|
|
issueQty: this.scanLabelData.issueQty |
|
|
|
} |
|
|
|
], |
|
|
|
scannedLabel: this.scanLabelData.scannedLabel, |
|
|
|
remark: this.scanLabelData.remark |
|
|
|
} |
|
|
|
const response = await directIssue(issueData) |
|
|
|
if (response.data.code === 0) { |
|
|
|
this.scanLabelData.message = '发料成功' |
|
|
|
this.scanLabelData.messageType = 'success' |
|
|
|
await this.loadWorkOrderMaterials() |
|
|
|
setTimeout(() => { |
|
|
|
this.showScanLabel = false |
|
|
|
this.processFlag = 2 |
|
|
|
}, 1000) |
|
|
|
} else { |
|
|
|
this.scanLabelData.message = response.data.msg || '发料失败' |
|
|
|
this.scanLabelData.messageType = 'error' |
|
|
|
} |
|
|
|
} else if (this.scanLabelContext.type === 'request') { |
|
|
|
// 申请单发料 |
|
|
|
const issueData = { |
|
|
|
...this.requestIssueForm, |
|
|
|
selectedMaterials: [ |
|
|
|
{ |
|
|
|
...this.scanLabelContext.material, |
|
|
|
issueQty: this.scanLabelData.issueQty |
|
|
|
} |
|
|
|
], |
|
|
|
scannedLabel: this.scanLabelData.scannedLabel, |
|
|
|
remark: this.scanLabelData.remark |
|
|
|
} |
|
|
|
const response = await requestIssue(issueData) |
|
|
|
if (response.data.code === 0) { |
|
|
|
this.scanLabelData.message = '发料成功' |
|
|
|
this.scanLabelData.messageType = 'success' |
|
|
|
await this.loadRequestMaterials() |
|
|
|
setTimeout(() => { |
|
|
|
this.showScanLabel = false |
|
|
|
this.processFlag = 2 |
|
|
|
}, 1000) |
|
|
|
} else { |
|
|
|
this.scanLabelData.message = response.data.msg || '发料失败' |
|
|
|
this.scanLabelData.messageType = 'error' |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
this.scanLabelData.message = '发料异常' |
|
|
|
this.scanLabelData.messageType = 'error' |
|
|
|
} finally { |
|
|
|
this.loading = false |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
@ -797,7 +860,7 @@ export default { |
|
|
|
background: white; |
|
|
|
border-radius: 8px; |
|
|
|
padding: 20px; |
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
|
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
|
|
|
cursor: pointer; |
|
|
|
transition: all 0.3s; |
|
|
|
text-align: center; |
|
|
|
@ -805,7 +868,7 @@ export default { |
|
|
|
|
|
|
|
.function-card:hover { |
|
|
|
transform: translateY(-2px); |
|
|
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15); |
|
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); |
|
|
|
} |
|
|
|
|
|
|
|
.function-icon { |
|
|
|
@ -826,12 +889,16 @@ export default { |
|
|
|
} |
|
|
|
|
|
|
|
/* 输入区域 */ |
|
|
|
.input-section, .materials-section, .scan-section, .pallet-info, .print-section { |
|
|
|
.input-section, |
|
|
|
.materials-section, |
|
|
|
.scan-section, |
|
|
|
.pallet-info, |
|
|
|
.print-section { |
|
|
|
background: white; |
|
|
|
border-radius: 8px; |
|
|
|
padding: 15px; |
|
|
|
margin-bottom: 15px; |
|
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
|
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
|
|
|
} |
|
|
|
|
|
|
|
.section-header { |
|
|
|
@ -843,7 +910,8 @@ export default { |
|
|
|
border-bottom: 1px solid #eee; |
|
|
|
} |
|
|
|
|
|
|
|
.section-header h3, .section-header h4 { |
|
|
|
.section-header h3, |
|
|
|
.section-header h4 { |
|
|
|
margin: 0; |
|
|
|
color: #333; |
|
|
|
} |
|
|
|
@ -882,7 +950,9 @@ export default { |
|
|
|
font-size: 16px; |
|
|
|
} |
|
|
|
|
|
|
|
.scan-btn, .confirm-btn, .print-btn { |
|
|
|
.scan-btn, |
|
|
|
.confirm-btn, |
|
|
|
.print-btn { |
|
|
|
background: #17b3a3; |
|
|
|
color: white; |
|
|
|
border: none; |
|
|
|
@ -893,11 +963,14 @@ export default { |
|
|
|
white-space: nowrap; |
|
|
|
} |
|
|
|
|
|
|
|
.scan-btn:hover, .confirm-btn:hover, .print-btn:hover { |
|
|
|
.scan-btn:hover, |
|
|
|
.confirm-btn:hover, |
|
|
|
.print-btn:hover { |
|
|
|
background: #13998c; |
|
|
|
} |
|
|
|
|
|
|
|
.confirm-btn:disabled, .print-btn:disabled { |
|
|
|
.confirm-btn:disabled, |
|
|
|
.print-btn:disabled { |
|
|
|
background: #6c757d; |
|
|
|
cursor: not-allowed; |
|
|
|
} |
|
|
|
@ -979,7 +1052,8 @@ export default { |
|
|
|
} |
|
|
|
|
|
|
|
/* 标签信息 */ |
|
|
|
.label-info, .info-card { |
|
|
|
.label-info, |
|
|
|
.info-card { |
|
|
|
background: #f8f9fa; |
|
|
|
border-radius: 6px; |
|
|
|
padding: 15px; |
|
|
|
@ -1013,7 +1087,7 @@ export default { |
|
|
|
margin-top: 15px; |
|
|
|
} |
|
|
|
|
|
|
|
.qty-input input[type="number"] { |
|
|
|
.qty-input input[type='number'] { |
|
|
|
width: 100%; |
|
|
|
padding: 10px; |
|
|
|
border: 1px solid #ddd; |
|
|
|
@ -1052,7 +1126,7 @@ export default { |
|
|
|
top: 50%; |
|
|
|
left: 50%; |
|
|
|
transform: translate(-50%, -50%); |
|
|
|
background: rgba(0,0,0,0.8); |
|
|
|
background: rgba(0, 0, 0, 0.8); |
|
|
|
color: white; |
|
|
|
padding: 20px; |
|
|
|
border-radius: 8px; |
|
|
|
@ -1071,8 +1145,12 @@ export default { |
|
|
|
} |
|
|
|
|
|
|
|
@keyframes spin { |
|
|
|
0% { transform: rotate(0deg); } |
|
|
|
100% { transform: rotate(360deg); } |
|
|
|
0% { |
|
|
|
transform: rotate(0deg); |
|
|
|
} |
|
|
|
100% { |
|
|
|
transform: rotate(360deg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.loading-text { |
|
|
|
@ -1144,4 +1222,7 @@ export default { |
|
|
|
align-self: flex-end; |
|
|
|
} |
|
|
|
} |
|
|
|
.confirm-btn { |
|
|
|
width: 100%; |
|
|
|
} |
|
|
|
</style> |