| | |
| | | :disabled="!currentLockInfo" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <!-- ç©æä¿¡æ¯æ¾ç¤º --> |
| | | <el-form-item label="ç©æç¼ç " v-if="currentMaterialInfo"> |
| | | <el-input v-model="currentMaterialInfo.materielCode" readonly /> |
| | | </el-form-item> |
| | | <el-form-item label="ç©æåç§°" v-if="currentMaterialInfo"> |
| | | <el-input v-model="currentMaterialInfo.materielName" readonly /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div class="current-info" v-if="currentPallet"> |
| | |
| | | }, |
| | | currentPallet: null, |
| | | currentLockInfo: null, |
| | | currentMaterialInfo: null, // æ°å¢ï¼å½åç©æä¿¡æ¯ |
| | | pickedList: [], |
| | | pickedColumns: [ |
| | | { field: 'barcode', title: 'ç©ææ¡ç ', width: 150 }, |
| | |
| | | { field: 'action', title: 'æä½', width: 80, slot: true } |
| | | ], |
| | | splitVisible: false, |
| | | maxPickQuantity: 0 |
| | | maxPickQuantity: 0, |
| | | allLockInfos: [] // æ°å¢ï¼ä¿åææéå®ä¿¡æ¯ï¼ç¨äºæ¡ç å¹é
|
| | | } |
| | | }, |
| | | computed: { |
| | |
| | | if (!orderId) return |
| | | |
| | | try { |
| | | const result = await this.http.post(`api/OutboundOrder/GetById?id=${orderId}`) |
| | | const result = await this.http.get(`api/OutboundOrder/GetById?id=${orderId}`) |
| | | if (result.status) { |
| | | this.orderInfo = result.data |
| | | } |
| | |
| | | ) |
| | | if (result.status) { |
| | | this.currentPallet = result.data |
| | | this.loadPalletLockInfo() |
| | | await this.loadPalletLockInfo() |
| | | this.$message.success(`æç ${this.scanForm.palletCode} è¯å«æå`) |
| | | } else { |
| | | this.$message.error(result.message) |
| | |
| | | const result = await this.http.get( |
| | | `api/OutboundPicking/GetPalletLockInfos?palletCode=${this.currentPallet.palletCode}` |
| | | ) |
| | | if (result.status && result.data.length > 0) { |
| | | this.currentLockInfo = result.data[0] |
| | | this.maxPickQuantity = this.currentLockInfo.assignQuantity - this.currentLockInfo.pickedQty |
| | | if (result.status) { |
| | | this.allLockInfos = result.data |
| | | // é»è®¤éæ©ç¬¬ä¸ä¸ªéå®ä¿¡æ¯ |
| | | if (this.allLockInfos.length > 0) { |
| | | this.currentLockInfo = this.allLockInfos[0] |
| | | this.currentMaterialInfo = { |
| | | materielCode: this.currentLockInfo.materielCode, |
| | | materielName: this.currentLockInfo.materielName |
| | | } |
| | | this.maxPickQuantity = this.currentLockInfo.assignQuantity - this.currentLockInfo.pickedQty |
| | | } |
| | | } |
| | | } catch (error) { |
| | | console.error('å è½½éå®ä¿¡æ¯å¤±è´¥:', error) |
| | | } |
| | | }, |
| | | |
| | | // æ ¹æ®æ¡ç æ¥æ¾å¯¹åºçéå®ä¿¡æ¯åç©æä¿¡æ¯ |
| | | findLockInfoByBarcode(barcode) { |
| | | if (!this.allLockInfos || this.allLockInfos.length === 0) { |
| | | return null |
| | | } |
| | | |
| | | // é¦å
精确å¹é
å½åæ¡ç |
| | | let lockInfo = this.allLockInfos.find(x => x.currentBarcode === barcode) |
| | | if (lockInfo) { |
| | | return lockInfo |
| | | } |
| | | |
| | | // å¦ææ²¡æç²¾ç¡®å¹é
ï¼æ¥æ¾è¯¥æ¡ç 对åºçç©ææ¯å¦å¨éå®ä¿¡æ¯ä¸ |
| | | // è¿ééè¦è°ç¨å端æ¥å£éªè¯æ¡ç 对åºçç©æ |
| | | return null |
| | | }, |
| | | |
| | | async handleBarcodeScan() { |
| | | // å®ç°æ«ç 确认é»è¾ |
| | | if (!this.scanForm.barcode) { |
| | | this.$message.warning('请è¾å
¥ç©ææ¡ç ') |
| | | return |
| | | } |
| | | |
| | | if (!this.currentPallet) { |
| | | this.$message.warning('请å
æ«ææçæ¡ç ') |
| | | return |
| | | } |
| | | |
| | | if (this.scanForm.quantity <= 0) { |
| | | this.$message.warning('请è¾å
¥ææçæ£éæ°é') |
| | | return |
| | | } |
| | | |
| | | try { |
| | | // éªè¯æ¡ç å¹¶è·åç©æä¿¡æ¯ |
| | | const materialInfo = await this.validateBarcode(this.scanForm.barcode) |
| | | if (!materialInfo) { |
| | | this.$message.error('æ æçç©ææ¡ç ') |
| | | return |
| | | } |
| | | |
| | | // æ¥æ¾å¯¹åºçéå®ä¿¡æ¯ |
| | | const targetLockInfo = this.findLockInfoByBarcodeAndMaterial(this.scanForm.barcode, materialInfo.materielCode) |
| | | if (!targetLockInfo) { |
| | | this.$message.error('è¯¥ç©ææ¡ç ä¸å¨å½åæççéå®ä¿¡æ¯ä¸') |
| | | return |
| | | } |
| | | |
| | | // æ£æ¥æ£éæ°é |
| | | const availableQuantity = targetLockInfo.assignQuantity - targetLockInfo.pickedQty |
| | | if (this.scanForm.quantity > availableQuantity) { |
| | | this.$message.error(`æ£éæ°éè¶
è¿å¯ç¨æ°éï¼å©ä½å¯æ£éï¼${availableQuantity}`) |
| | | return |
| | | } |
| | | |
| | | // åå¤è¯·æ±æ°æ® |
| | | const request = { |
| | | orderDetailId: targetLockInfo.orderDetailId, |
| | | barcode: this.scanForm.barcode, |
| | | quantity: this.scanForm.quantity, |
| | | materielCode: materialInfo.materielCode, // ä¼ éç©æç¼ç |
| | | pickQuantity: this.scanForm.quantity, |
| | | locationCode: this.currentPallet.locationCode, |
| | | palletCode: this.currentPallet.palletCode, |
| | | orderId: this.orderInfo.id |
| | | stockId: targetLockInfo.stockId, |
| | | outStockLockInfoId: targetLockInfo.id // ä¼ ééå®ä¿¡æ¯ID |
| | | } |
| | | |
| | | const result = await this.http.post('api/OutboundPicking/ConfirmPicking', request) |
| | | if (result.status) { |
| | | this.$message.success('æ£é确认æå') |
| | | |
| | | // é置表å |
| | | this.scanForm.barcode = '' |
| | | this.scanForm.quantity = 1 |
| | | this.loadPickedHistory() |
| | | this.currentMaterialInfo = null |
| | | |
| | | // å·æ°æ°æ® |
| | | this.loadOrderInfo() |
| | | this.loadPickedHistory() |
| | | this.loadPalletLockInfo() |
| | | } else { |
| | | this.$message.error(result.message) |
| | | } |
| | | } catch (error) { |
| | | this.$message.error('æ£é确认失败') |
| | | this.$message.error('æ£é确认失败: ' + (error.message || 'æªç¥é误')) |
| | | } |
| | | }, |
| | | |
| | | // æ ¹æ®æ¡ç åç©æç¼ç æ¥æ¾éå®ä¿¡æ¯ |
| | | findLockInfoByBarcodeAndMaterial(barcode, materielCode) { |
| | | if (!this.allLockInfos || this.allLockInfos.length === 0) { |
| | | return null |
| | | } |
| | | |
| | | // é¦å
å°è¯ç²¾ç¡®å¹é
æ¡ç |
| | | let lockInfo = this.allLockInfos.find(x => |
| | | x.currentBarcode === barcode && x.materielCode === materielCode |
| | | ) |
| | | |
| | | if (lockInfo) { |
| | | return lockInfo |
| | | } |
| | | |
| | | // å¦æç²¾ç¡®å¹é
失败ï¼åªå¹é
ç©æç¼ç ï¼å
许ä»åä¸ç©æçä¸åæ¡ç æ£éï¼ |
| | | lockInfo = this.allLockInfos.find(x => |
| | | x.materielCode === materielCode && |
| | | (x.assignQuantity - x.pickedQty) > 0 |
| | | ) |
| | | |
| | | return lockInfo |
| | | }, |
| | | |
| | | // éªè¯æ¡ç å¹¶è·åç©æä¿¡æ¯ |
| | | async validateBarcode(barcode) { |
| | | try { |
| | | const result = await this.http.get(`api/OutboundPicking/ValidateBarcode?barcode=${barcode}`) |
| | | if (result.status) { |
| | | return result.data |
| | | } else { |
| | | this.$message.error(result.message) |
| | | return null |
| | | } |
| | | } catch (error) { |
| | | this.$message.error('æ¡ç éªè¯å¤±è´¥') |
| | | return null |
| | | } |
| | | }, |
| | | |
| | |
| | | |
| | | const result = await this.http.post('api/BackToStock/GenerateBackToStockTask', { |
| | | palletCode: this.currentPallet.palletCode, |
| | | currentLocation: 'æ£éä½' |
| | | currentLocation: 'æ£éä½', |
| | | operator: 'å½åç¨æ·' |
| | | }) |
| | | |
| | | if (result.status) { |
| | |
| | | resetCurrentPallet() { |
| | | this.currentPallet = null |
| | | this.currentLockInfo = null |
| | | this.currentMaterialInfo = null |
| | | this.allLockInfos = [] |
| | | this.scanForm.palletCode = '' |
| | | }, |
| | | |
| | |
| | | this.loadPickedHistory() |
| | | } |
| | | } |
| | | </script> |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .picking-confirm { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .page-header { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .title { |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .scan-section { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .action-buttons { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .action-buttons .el-button { |
| | | width: 100%; |
| | | } |
| | | |
| | | .current-info { |
| | | margin-top: 15px; |
| | | padding: 10px; |
| | | background-color: #f5f7fa; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .current-info p { |
| | | margin: 5px 0; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .summary-info { |
| | | margin-bottom: 15px; |
| | | } |
| | | </style> |