From 4476740c214edb7ab667c48fcab00488fbdd9879 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期六, 15 十一月 2025 09:03:54 +0800
Subject: [PATCH] 提交
---
项目代码/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue | 777 ++++++++++++++++++++++++-----------------------------------
1 files changed, 318 insertions(+), 459 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue"
index ef26541..d9f3d25 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue"
@@ -3,516 +3,375 @@
<div class="page-header">
<el-page-header @back="goBack">
<template #content>
- <span class="title">鍑哄簱鎷i�夌‘璁� - {{ orderInfo.orderNo }}</span>
+ <span class="title">鍑哄簱鎷i�夌‘璁� - {{ this.$route.query.orderNo }}</span>
</template>
</el-page-header>
</div>
-
- <el-row :gutter="20" class="main-content">
- <el-col :span="8">
+
+ <div class="content-layout">
+ <!-- 宸︿晶锛氭壂鐮佸尯鍩� -->
+ <div class="left-section">
<div class="scan-section">
- <el-card header="鎵爜鍖哄煙">
- <el-form label-width="100px" size="small">
- <el-form-item label="鎵樼洏鏉$爜">
- <el-input
- v-model="scanForm.palletCode"
- placeholder="鎵弿鎴栬緭鍏ユ墭鐩樻潯鐮�"
- @keyup.enter="handlePalletScan"
- clearable
- >
- <template #append>
- <el-button @click="handlePalletScan">纭</el-button>
- </template>
- </el-input>
- </el-form-item>
+ <el-alert
+ title="璇蜂娇鐢ㄦ壂鐮佹灙鎵弿鎵樼洏鐮佸拰鐗╂枡鏉$爜锛屾壂鐮佹灙甯﹀洖杞﹀姛鑳斤紝鎵畬鐗╂枡鏉$爜鑷姩纭"
+ type="info"
+ :closable="false"
+ class="scan-alert"
+ />
- <el-form-item label="鐗╂枡鏉$爜">
- <el-input
- v-model="scanForm.barcode"
- placeholder="鎵弿鎴栬緭鍏ョ墿鏂欐潯鐮�"
- @keyup.enter="handleBarcodeScan"
- :disabled="!currentPallet"
- clearable
- >
- <template #append>
- <el-button @click="handleBarcodeScan" :disabled="!currentPallet">纭</el-button>
- </template>
- </el-input>
- </el-form-item>
+ <el-form :model="scanForm" label-width="100px" class="scan-form">
+ <el-form-item label="鎵樼洏鐮�" required>
+ <el-input
+ ref="palletInput"
+ v-model="scanForm.palletCode"
+ placeholder="璇锋壂鎻忔墭鐩樼爜"
+ @keyup.enter="handlePalletScan"
+ @blur="loadPalletSummary"
+ clearable
+ />
+ </el-form-item>
- <el-form-item label="鎷i�夋暟閲�">
- <el-input-number
- v-model="scanForm.quantity"
- :min="1"
- :max="maxPickQuantity"
- :disabled="!currentLockInfo"
- />
- </el-form-item>
+ <el-form-item label="鐗╂枡鏉$爜" required>
+ <el-input
+ ref="materialInput"
+ v-model="scanForm.materialBarcode"
+ placeholder="璇锋壂鎻忕墿鏂欐潯鐮�"
+ :disabled="!scanForm.palletCode"
+ @keyup.enter="handleMaterialScan"
+ clearable
+ />
+ </el-form-item>
+ </el-form>
- <!-- 鐗╂枡淇℃伅鏄剧ず -->
- <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">
- <p>褰撳墠鎵樼洏: {{ currentPallet.palletCode }}</p>
- <p>璐т綅: {{ currentPallet.locationCode }}</p>
- <p>鐘舵��: {{ currentPallet.statusText }}</p>
- </div>
- </el-card>
+ <!-- 鎵樼洏鎷h揣缁熻 -->
+ <div v-if="palletSummary" class="pallet-summary">
+ <el-card header="鎵樼洏鎷h揣缁熻">
+ <el-descriptions :column="3" border>
+ <el-descriptions-item label="鎵樼洏鍙�">
+ {{ scanForm.palletCode }}
+ </el-descriptions-item>
+ <el-descriptions-item label="鏈嫞璐ф潯鏁�">
+ <el-text type="warning">{{ palletSummary.unpickedCount }}</el-text>
+ </el-descriptions-item>
+ <el-descriptions-item label="鏈嫞璐ф�绘暟">
+ <el-text type="danger">{{ palletSummary.unpickedTotal }}</el-text>
+ </el-descriptions-item>
+ </el-descriptions>
+ </el-card>
+ </div>
<div class="action-buttons">
- <el-button
- type="warning"
- @click="handleBackToStock"
- :disabled="!currentPallet"
- style="margin-bottom: 10px;"
- >
- 鍥炲簱
+ <el-button type="primary" @click="handleConfirm" :loading="confirmLoading">
+ 鎵嬪姩纭
</el-button>
- <el-button
- type="success"
- @click="handleDirectOutbound"
- :disabled="!currentPallet"
- style="margin-bottom: 10px;"
- >
- 鐩存帴鍑哄簱
- </el-button>
- <el-button
- type="primary"
- @click="handleOpenSplit"
- :disabled="!currentLockInfo"
- >
- 鎷嗗寘
- </el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ <el-button @click="$emit('close')">鍙栨秷</el-button>
</div>
</div>
- </el-col>
+ </div>
- <el-col :span="16">
- <el-card header="鎷i�夌粨鏋�">
- <div class="summary-info">
- <el-alert
- :title="`鏈嫞璐�: ${unpickedCount} 鏉�, ${unpickedQuantity} 涓猔"
- type="warning"
- :closable="false"
- />
- </div>
-
+ <!-- 鍙充晶锛氬嚭搴撹鎯呭垪琛� -->
+ <div class="right-section">
+ <el-card class="outbound-details-card" header="鍑哄簱璇︽儏">
<vol-table
- :data="pickedList"
- :columns="pickedColumns"
- :pagination="false"
- :height="400"
- >
- <template #action="{ row }">
- <el-button type="text" @click="handleCancelPick(row)">鎾ら攢</el-button>
- </template>
- </vol-table>
+ ref="outboundTable"
+ :table-config="outboundTableConfig"
+ :height="300"
+ />
</el-card>
- </el-col>
- </el-row>
+ </div>
+ </div>
- <!-- 鎷嗗寘寮圭獥 -->
- <vol-box
- v-model="splitVisible"
- title="鎷嗗寘鎿嶄綔"
- :width="600"
- :height="500"
- >
- <SplitPackageModal
- v-if="splitVisible"
- :lockInfo="currentLockInfo"
- @success="handleSplitSuccess"
- @close="splitVisible = false"
- />
- </vol-box>
+ <!-- 宸插垎鎷h褰曞垪琛� -->
+ <div class="picked-records">
+ <el-card header="宸插垎鎷h褰�">
+ <vol-table
+ ref="pickedTable"
+ :table-config="pickedTableConfig"
+ :height="300"
+ />
+ </el-card>
+ </div>
</div>
</template>
<script>
-import SplitPackageModal from './SplitPackageModal.vue'
+import http from '@/api/http.js'
+import { ref, defineComponent } from "vue";
+import { ElMessage } from "element-plus";
+import { useRoute } from 'vue-router'
-export default {
- components: { SplitPackageModal },
+export default defineComponent({
+ name: 'PickingConfirm',
+ components: {
+
+ },
+ props: {
+ orderNo: {
+ type: String,
+ required: true
+ }
+ },
+ emits: ['confirm', 'close'],
data() {
return {
- orderInfo: {},
scanForm: {
palletCode: '',
- barcode: '',
- quantity: 1
+ materialBarcode: ''
},
- currentPallet: null,
- currentLockInfo: null,
- currentMaterialInfo: null, // 鏂板锛氬綋鍓嶇墿鏂欎俊鎭�
- pickedList: [],
- pickedColumns: [
- { field: 'barcode', title: '鐗╂枡鏉$爜', width: 150 },
- { field: 'materielCode', title: '鐗╂枡缂栫爜', width: 120 },
- { field: 'materielName', title: '鐗╂枡鍚嶇О', width: 150 },
- { field: 'pickQuantity', title: '鎷i�夋暟閲�', width: 100 },
- { field: 'palletCode', title: '鎵樼洏缂栧彿', width: 120 },
- { field: 'pickTime', title: '鎷i�夋椂闂�', width: 160 },
- { field: 'operator', title: '鎿嶄綔浜�', width: 100 },
- { field: 'action', title: '鎿嶄綔', width: 80, slot: true }
- ],
- splitVisible: false,
- maxPickQuantity: 0,
- allLockInfos: [] // 鏂板锛氫繚瀛樻墍鏈夐攣瀹氫俊鎭紝鐢ㄤ簬鏉$爜鍖归厤
- }
- },
- computed: {
- unpickedCount() {
- return this.orderInfo.unpickedCount || 0
- },
- unpickedQuantity() {
- return this.orderInfo.unpickedQuantity || 0
- }
- },
- methods: {
- goBack() {
- this.$router.back()
- },
-
- async loadOrderInfo() {
- const orderId = this.$route.query.orderId
- if (!orderId) return
-
- try {
- const result = await this.http.get(`api/OutboundOrder/GetById?id=${orderId}`)
- if (result.status) {
- this.orderInfo = result.data
- }
- } catch (error) {
- this.$message.error('鍔犺浇鍑哄簱鍗曚俊鎭け璐�')
- }
- },
-
- async handlePalletScan() {
- if (!this.scanForm.palletCode) {
- this.$message.warning('璇疯緭鍏ユ墭鐩樻潯鐮�')
- return
- }
-
- try {
- const result = await this.http.get(
- `api/OutboundPicking/GetPalletOutboundStatus?palletCode=${this.scanForm.palletCode}`
- )
- if (result.status) {
- this.currentPallet = result.data
- await this.loadPalletLockInfo()
- this.$message.success(`鎵樼洏 ${this.scanForm.palletCode} 璇嗗埆鎴愬姛`)
- } else {
- this.$message.error(result.message)
- }
- } catch (error) {
- this.$message.error('鎵樼洏璇嗗埆澶辫触')
- }
- },
-
- async loadPalletLockInfo() {
- if (!this.currentPallet) return
-
- try {
- const result = await this.http.get(
- `api/OutboundPicking/GetPalletLockInfos?palletCode=${this.currentPallet.palletCode}`
- )
- 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
- }
-
- // 濡傛灉娌℃湁绮剧‘鍖归厤锛屾煡鎵捐鏉$爜瀵瑰簲鐨勭墿鏂欐槸鍚﹀湪閿佸畾淇℃伅涓�
- // 杩欓噷闇�瑕佽皟鐢ㄥ悗绔帴鍙i獙璇佹潯鐮佸搴旂殑鐗╂枡
- 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('璇疯緭鍏ユ湁鏁堢殑鎷i�夋暟閲�')
- 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(`鎷i�夋暟閲忚秴杩囧彲鐢ㄦ暟閲忥紝鍓╀綑鍙嫞閫夛細${availableQuantity}`)
- return
- }
-
- // 鍑嗗璇锋眰鏁版嵁
- const request = {
- orderDetailId: targetLockInfo.orderDetailId,
- barcode: this.scanForm.barcode,
- materielCode: materialInfo.materielCode, // 浼犻�掔墿鏂欑紪鐮�
- pickQuantity: this.scanForm.quantity,
- locationCode: this.currentPallet.locationCode,
- palletCode: this.currentPallet.palletCode,
- stockId: targetLockInfo.stockId,
- outStockLockInfoId: targetLockInfo.id // 浼犻�掗攣瀹氫俊鎭疘D
- }
-
- const result = await this.http.post('api/OutboundPicking/ConfirmPicking', request)
- if (result.status) {
- this.$message.success('鎷i�夌‘璁ゆ垚鍔�')
-
- // 閲嶇疆琛ㄥ崟
- this.scanForm.barcode = ''
- this.scanForm.quantity = 1
- this.currentMaterialInfo = null
-
- // 鍒锋柊鏁版嵁
- this.loadOrderInfo()
- this.loadPickedHistory()
- this.loadPalletLockInfo()
- } else {
- this.$message.error(result.message)
- }
- } catch (error) {
- this.$message.error('鎷i�夌‘璁ゅけ璐�: ' + (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
- }
- },
-
- async handleBackToStock() {
- if (!this.currentPallet) return
-
- try {
- await this.$confirm(`纭畾灏嗘墭鐩� ${this.currentPallet.palletCode} 鍥炲簱鍚楋紵`, '鎻愮ず', {
- type: 'warning'
- })
-
- const result = await this.http.post('api/BackToStock/GenerateBackToStockTask', {
- palletCode: this.currentPallet.palletCode,
- currentLocation: '鎷i�変綅',
- operator: '褰撳墠鐢ㄦ埛'
- })
-
- if (result.status) {
- this.$message.success('鍥炲簱浠诲姟宸茬敓鎴�')
- this.resetCurrentPallet()
- }
- } catch (error) {
- // 鐢ㄦ埛鍙栨秷
- }
- },
-
- async handleDirectOutbound() {
- if (!this.currentPallet) return
-
- try {
- await this.$confirm(`纭畾灏嗘墭鐩� ${this.currentPallet.palletCode} 鐩存帴鍑哄簱鍚楋紵`, '鎻愮ず', {
- type: 'warning'
- })
-
- const result = await this.http.post('api/OutboundPicking/DirectOutbound', {
- palletCode: this.currentPallet.palletCode
- })
-
- if (result.status) {
- this.$message.success('鐩存帴鍑哄簱鎴愬姛')
- this.resetCurrentPallet()
- this.loadOrderInfo()
- }
- } catch (error) {
- // 鐢ㄦ埛鍙栨秷
- }
- },
-
- handleOpenSplit() {
- if (!this.currentLockInfo) {
- this.$message.warning('璇峰厛閫夋嫨閿佸畾淇℃伅')
- return
- }
- this.splitVisible = true
- },
-
- handleSplitSuccess() {
- this.$message.success('鎷嗗寘鎴愬姛')
- this.loadPalletLockInfo()
- },
-
- resetCurrentPallet() {
- this.currentPallet = null
- this.currentLockInfo = null
- this.currentMaterialInfo = null
- this.allLockInfos = []
- this.scanForm.palletCode = ''
- },
-
- async loadPickedHistory() {
- const orderId = this.$route.query.orderId
- if (!orderId) return
-
- try {
- const result = await this.http.get(`api/OutboundPicking/GetPickingHistory?orderId=${orderId}`)
- if (result.status) {
- this.pickedList = result.data
- }
- } catch (error) {
- console.error('鍔犺浇鎷i�夊巻鍙插け璐�:', error)
- }
- },
-
- async handleCancelPick(row) {
- try {
- await this.$confirm('纭畾鎾ら攢杩欐潯鎷i�夎褰曞悧锛�', '鎻愮ず', { type: 'warning' })
-
- const result = await this.http.post('api/OutboundPicking/CancelPicking', {
- pickingHistoryId: row.id
- })
-
- if (result.status) {
- this.$message.success('鎾ら攢鎴愬姛')
- this.loadPickedHistory()
- this.loadOrderInfo()
- }
- } catch (error) {
- // 鐢ㄦ埛鍙栨秷
- }
+ palletSummary: null,
+ confirmLoading: false,
+ pickedTableConfig: {
+ url: '/api/outbound/getPickingRecords',
+ query: { orderNo: this.orderNo },
+ columns: [
+ { prop: 'TaskNo', label: '浠诲姟鍙�', width: 150 },
+ { prop: 'Barcode', label: '鐗╂枡鏉$爜', width: 150 },
+ { prop: 'MaterielName', label: '鐗╂枡鍚嶇О', width: 150 },
+ { prop: 'PickQuantity', label: '鎷h揣鏁伴噺', width: 100 },
+ { prop: 'LocationCode', label: '璐т綅', width: 120 },
+ { prop: 'CreateTime', label: '鎷h揣鏃堕棿', width: 180 }
+ ]
+ },
+ // 鍑哄簱璇︽儏琛ㄦ牸閰嶇疆
+ outboundTableConfig: {
+ url: '/api/outbound/getOutboundDetails',
+ query: { orderNo: this.orderNo },
+ columns: [
+ { prop: 'OrderNo', label: '鍑哄簱鍗曞彿', width: 150 },
+ { prop: 'MaterialCode', label: '鐗╂枡缂栧彿', width: 120 },
+ { prop: 'MaterialBarcode', label: '鐗╂枡鏉$爜', width: 150 },
+ { prop: 'BatchNo', label: '鎵规鍙�', width: 120 },
+ { prop: 'AssignQuantity', label: '鍒嗛厤鍑哄簱閲�', width: 100 },
+ { prop: 'PalletCode', label: '鎵樼洏缂栧彿', width: 120 },
+ { prop: 'Unit', label: '鍗曚綅', width: 80 }
+ ]
+ },
+ orderInfo: {orderNo:''}
}
},
mounted() {
- this.loadOrderInfo()
- this.loadPickedHistory()
+ this.loadOrderInfo();
+ this.$nextTick(() => {
+ if (this.$refs.palletInput) {
+ this.$refs.palletInput.focus()
+ }
+ })
+ },
+ methods: {
+ loadOrderInfo() {
+ const orderId = this.$route.query.orderId
+ if (!orderId) return
+
+ try {
+ this.http.get(`/api/OutboundOrder/GetById?id=${orderId}`).then(response => {debugger;
+ if (response.status) {
+ this.orderInfo = response.data
+
+ }
+ })
+ } catch (error) {
+ ElMessage.error('鍔犺浇鍑哄簱鍗曚俊鎭け璐�')
+ }
+ },
+ goBack() {
+ this.$router.back()
+ },
+ async handlePalletScan() {
+ if (this.scanForm.palletCode) {
+ ElMessage.success(`宸叉壂鎻忔墭鐩�: ${this.scanForm.palletCode}`)
+ await this.loadPalletSummary()
+
+ this.$nextTick(() => {
+ if (this.$refs.materialInput) {
+ this.$refs.materialInput.focus()
+ }
+ })
+ }
+ },
+ async handleMaterialScan() {
+ if (!this.scanForm.palletCode) {
+ ElMessage.warning('璇峰厛鎵弿鎵樼洏鐮�')
+ this.$refs.palletInput.focus()
+ return
+ }
+
+ if (!this.scanForm.materialBarcode) {
+ ElMessage.warning('璇锋壂鎻忕墿鏂欐潯鐮�')
+ return
+ }
+
+ await this.executePickingConfirm()
+ },
+ async loadPalletSummary() {
+ if (!this.scanForm.palletCode) {
+ this.palletSummary = null
+ return
+ }
+
+ try {
+ const result = await http.get('/api/outbound/getPalletPickingSummary', {
+ params: {
+ orderNo: this.orderNo,
+ palletCode: this.scanForm.palletCode
+ }
+ })
+
+ if (result.success) {
+ // 澶勭悊缁熻淇℃伅
+ const summary = result.data
+ const assigned = summary.find(x => x.Status === '宸插垎閰�') || { TotalAssignQty: 0, TotalPickedQty: 0 }
+ const picked = summary.find(x => x.Status === '宸叉嫞閫�') || { TotalPickedQty: 0 }
+
+ this.palletSummary = {
+ unpickedCount: assigned.TotalAssignQty > 0 ? 1 : 0, // 绠�鍖栬绠�
+ unpickedTotal: assigned.TotalAssignQty - assigned.TotalPickedQty
+ }
+ }
+ } catch (error) {
+ console.error('鍔犺浇鎵樼洏缁熻澶辫触:', error)
+ }
+ },
+ async handleConfirm() {
+ if (!this.scanForm.palletCode || !this.scanForm.materialBarcode) {
+ ElMessage.warning('璇峰~鍐欏畬鏁寸殑鎵爜淇℃伅')
+ return
+ }
+
+ await this.executePickingConfirm()
+ },
+ async executePickingConfirm() {
+ this.confirmLoading = true
+
+ try {
+ // 鍏堟壘鍒板搴旂殑鍑哄簱閿佸畾淇℃伅
+ const lockInfoResult = await this.http.get('/api/outbound/getOutStockLockInfo', {
+ params: {
+ orderNo: this.orderNo,
+ palletCode: this.scanForm.palletCode,
+ materialBarcode: this.scanForm.materialBarcode
+ }
+ })
+
+ if (!lockInfoResult.success || !lockInfoResult.data || lockInfoResult.data.length === 0) {
+ ElMessage.error('鏈壘鍒板搴旂殑鍑哄簱閿佸畾淇℃伅')
+ return
+ }
+
+ const lockInfo = lockInfoResult.data[0]
+
+ const request = {
+ outStockLockId: lockInfo.Id,
+ taskNo: `TASK_${Date.now()}`,
+ palletCode: this.scanForm.palletCode,
+ materialBarcode: this.scanForm.materialBarcode,
+ locationCode: lockInfo.LocationCode
+ }
+
+ const result = await this.http.post('/api/outbound/pickingConfirm', request)
+
+ if (result.success) {
+ ElMessage.success('鍒嗘嫞纭鎴愬姛')
+ this.handleReset()
+ this.$emit('confirm')
+
+ // 鍒锋柊琛ㄦ牸
+ if (this.$refs.pickedTable) {
+ this.$refs.pickedTable.refresh()
+ }
+
+ // 鍒锋柊鍑哄簱璇︽儏琛ㄦ牸
+ if (this.$refs.outboundTable) {
+ this.$refs.outboundTable.refresh()
+ }
+
+ // 閲嶆柊鍔犺浇鎵樼洏缁熻
+ await this.loadPalletSummary()
+ } else {
+ ElMessage.error(result.ElMessage)
+ }
+ } catch (error) {
+ ElMessage.error('鍒嗘嫞纭澶辫触')
+ } finally {
+ this.confirmLoading = false
+ }
+ },
+ handleReset() {
+ this.scanForm.materialBarcode = ''
+ this.$nextTick(() => {
+ if (this.$refs.materialInput) {
+ this.$refs.materialInput.focus()
+ }
+ })
+ }
}
-}
+})
</script>
<style scoped>
.picking-confirm {
- padding: 20px;
+ display: flex;
+ flex-direction: column;
+ height: 70vh;
}
-.page-header {
- margin-bottom: 20px;
+.content-layout {
+ display: flex;
+ gap: 16px;
+ margin-bottom: 16px;
+ flex: 1;
+ min-height: 0; /* 閲嶈锛氶槻姝lex瀛愬厓绱犳孩鍑� */
}
-.title {
- font-size: 18px;
- font-weight: bold;
+.left-section {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.right-section {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
}
.scan-section {
- margin-bottom: 20px;
+ flex-shrink: 0;
+}
+
+.scan-alert {
+ margin-bottom: 16px;
+}
+
+.scan-form {
+ max-width: 500px;
+}
+
+.pallet-summary {
+ margin: 16px 0;
}
.action-buttons {
+ margin-top: 16px;
+}
+
+.outbound-details-card {
+ height: 100%;
display: flex;
flex-direction: column;
- gap: 10px;
}
-.action-buttons .el-button {
- width: 100%;
+.outbound-details-card :deep(.el-card__body) {
+ flex: 1;
+ padding: 0;
}
-.current-info {
- margin-top: 15px;
- padding: 10px;
- background-color: #f5f7fa;
- border-radius: 4px;
+.picked-records {
+ flex-shrink: 0;
+ height: 300px;
}
-.current-info p {
- margin: 5px 0;
- font-size: 14px;
-}
-
-.summary-info {
- margin-bottom: 15px;
+.picked-records :deep(.el-card__body) {
+ padding: 0;
}
</style>
\ No newline at end of file
--
Gitblit v1.9.3