From d1df8e56fd794ec9a71a2fbd6aadbab72d1e0815 Mon Sep 17 00:00:00 2001
From: 647556386 <647556386@qq.com>
Date: 星期五, 19 十二月 2025 14:51:46 +0800
Subject: [PATCH] 1
---
项目代码/WIDESEA_WMSClient/src/views/outbound/out copyPicking.vue | 558 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 553 insertions(+), 5 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/out copyPicking.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/out copyPicking.vue"
index 8a0384f..955300d 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/out copyPicking.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/out copyPicking.vue"
@@ -21,7 +21,13 @@
<div class="scan-section">
<el-alert title="璇蜂娇鐢ㄦ壂鐮佹灙鎵弿锛屾敮鎸佸洖杞﹁嚜鍔ㄧ‘璁�" type="info" :closable="false" show-icon class="scan-alert">
<template #default>
- <span>1. 璇峰厛鎵弿鎵樼洏鐮� 鈫� 2. 鍐嶆壂鎻忕墿鏂欐潯鐮�</span>
+ <div>
+ <div>1. 璇峰厛鎵弿鎵樼洏鐮� 鈫� 2. 鍐嶆壂鎻忕墿鏂欐爣绛剧爜</div>
+ <div style="margin-top: 8px; font-size: 13px; color: #666;">
+ <i class="el-icon-info" style="color: #409EFF;"></i>
+ 鏀寔鎵墭鐩樼爜鏁寸鍑哄簱锛氭壂鎻忔墭鐩樼爜鍚庡彲鐩存帴杩涜鏁寸鐗╂枡鎷i�夛紝鏃犻渶鍐嶆壂鎻忕墿鏂欐爣绛剧爜銆�
+ </div>
+ </div>
</template>
</el-alert>
@@ -71,6 +77,41 @@
</el-col>
</el-row>
</el-form>
+
+ <!-- 鍒嗘嫞缁熻淇℃伅 -->
+ <div class="picking-stats" v-if="scanForm.palletCode && unpickedData.length > 0">
+ <el-divider content-position="left">
+ <span style="color: #409EFF; font-size: 14px;">
+ <i class="el-icon-data-analysis"></i> 鎵樼洏鍒嗘嫞缁熻
+ </span>
+ </el-divider>
+ <div class="stats-container">
+ <div class="stat-item">
+ <el-tag type="primary" size="medium" effect="dark">
+ <i class="el-icon-s-order"></i>
+ 鍒嗘嫞鎬绘暟锛�<b>{{ calculateTotalAssignQuantity() }}</b>
+ </el-tag>
+ </div>
+ <div class="stat-item">
+ <el-tag type="success" size="medium" effect="dark">
+ <i class="el-icon-circle-check"></i>
+ 宸插垎鎷o細<b>{{ calculateTotalSortedQuantity() }}</b>
+ </el-tag>
+ </div>
+ <div class="stat-item">
+ <el-tag type="warning" size="medium" effect="dark">
+ <i class="el-icon-time"></i>
+ 鏈垎鎷o細<b>{{ calculateTotalUnsortedQuantity() }}</b>
+ </el-tag>
+ </div>
+ <div class="stat-item">
+ <el-tag type="success" size="medium" effect="dark">
+ <i class="el-icon-box"></i>
+ 鏄惁鏁村嚭锛歿{ hasWholeOut() ? '鏄�' : '鍚�' }}
+ </el-tag>
+ </div>
+ </div>
+ </div>
</div>
</el-card>
@@ -198,6 +239,53 @@
</el-card>
</el-col>
</el-row>
+
+ <!-- 鎵樼洏鐗╂枡搴撳瓨淇℃伅 -->
+ <!-- <div class="pallet-inventory" v-if="scanForm.palletCode && unpickedData.length > 0">
+ <el-divider content-position="left">
+ <span style="color: #67C23A; font-size: 14px;">
+ <i class="el-icon-goods"></i> 鎵樼洏鐗╂枡搴撳瓨淇℃伅
+ </span>
+ </el-divider>
+ <div class="inventory-container">
+ <el-table :data="unpickedData" size="small" :show-header="true" :border="true" stripe
+ highlight-current-row max-height="200" class="inventory-table">
+ <el-table-column type="index" label="搴忓彿" width="50" align="center" />
+ <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" width="100" show-overflow-tooltip />
+ <el-table-column prop="materielName" label="鐗╂枡鍚嶇О" width="120" show-overflow-tooltip />
+ <el-table-column prop="batchNo" label="鎵规鍙�" width="90" />
+ <el-table-column label="褰撳墠搴撳瓨" width="80" align="right">
+ <template #default="scope">
+ <el-text type="primary" tag="b">{{ scope.row.currentStock || 0 }}</el-text>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍒嗘嫞鏁伴噺" width="80" align="right">
+ <template #default="scope">
+ <el-text type="warning">{{ scope.row.assignQuantity }}</el-text>
+ </template>
+ </el-table-column>
+ <el-table-column label="宸插垎鎷�" width="70" align="right">
+ <template #default="scope">
+ <el-text type="success">{{ scope.row.sortedQuantity || 0 }}</el-text>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍓╀綑搴撳瓨" width="80" align="right">
+ <template #default="scope">
+ <el-text type="info">{{ calculateRemainingStock(scope.row) }}</el-text>
+ </template>
+ </el-table-column>
+ <el-table-column prop="unit" label="鍗曚綅" width="100" align="center" />
+ <el-table-column prop="locationCode" label="搴撲綅" width="150" />
+ <el-table-column label="鐘舵��" width="80" align="center">
+ <template #default="scope">
+ <el-tag :type="getStockStatusType(scope.row)" size="mini">
+ {{ getStockStatusText(scope.row) }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ </div> -->
</div>
<print-view ref="printView" @parentcall="parentcall"></print-view>
@@ -212,6 +300,81 @@
<el-button @click="confirmDialogVisible = false">鍙栨秷</el-button>
<el-button type="primary" @click="executeConfirm" :loading="executeLoading">
纭畾
+ </el-button>
+ </span>
+ </template>
+ </el-dialog>
+
+ <!-- 鏁村嚭纭瀵硅瘽妗� -->
+ <el-dialog v-model="wholeOutDialogVisible" title="鏁村嚭鎿嶄綔纭" width="500px" :before-close="handleWholeOutDialogClose" custom-class="whole-out-dialog">
+ <div class="whole-out-content" v-if="wholeOutInfo">
+ <!-- 璀﹀憡鎻愮ず -->
+ <el-alert title="璇ユ墭鐩樺寘鍚渶瑕佹暣鍑虹殑鐗╂枡" type="warning" :closable="false" show-icon class="whole-out-alert">
+ <template #default>
+ <div>鏁村嚭鎿嶄綔灏嗕竴娆℃�ф嫞閫夎鐗╂枡鐨勬墍鏈夊簱瀛橈紝璇风‘璁や俊鎭棤璇悗鎵ц</div>
+ </template>
+ </el-alert>
+
+ <!-- 鎵樼洏淇℃伅 -->
+ <div class="info-section">
+ <h4 class="section-title">
+ <i class="el-icon-box"></i>
+ 鎵樼洏淇℃伅
+ </h4>
+ <div class="info-grid">
+ <div class="info-item">
+ <label>鎵樼洏鐮侊細</label>
+ <span class="info-value">{{ wholeOutInfo.palletCode }}</span>
+ </div>
+ <div class="info-item">
+ <label>搴撲綅锛�</label>
+ <span class="info-value">{{ wholeOutInfo.locationCode || '鏈寚瀹�' }}</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鏁村嚭鐗╂枡璇︽儏 -->
+ <div class="info-section">
+ <h4 class="section-title">
+ <i class="el-icon-s-grid"></i>
+ 鏁村嚭鐗╂枡璇︽儏
+ </h4>
+ <div class="info-grid">
+ <div class="info-item">
+ <label>鐗╂枡缂栫爜锛�</label>
+ <span class="info-value">{{ wholeOutInfo.materielCode }}</span>
+ </div>
+ <div class="info-item">
+ <label>鐗╂枡鍚嶇О锛�</label>
+ <span class="info-value">{{ wholeOutInfo.materielName }}</span>
+ </div>
+ <div class="info-item">
+ <label>鎵规鍙凤細</label>
+ <span class="info-value">{{ wholeOutInfo.batchNo }}</span>
+ </div>
+ <div class="info-item">
+ <label>鏁村嚭鏁伴噺锛�</label>
+ <span class="info-value highlight">{{ wholeOutInfo.assignQuantity }} {{ wholeOutInfo.unit }}</span>
+ </div>
+ <div class="info-item">
+ <label>褰撳墠搴撳瓨锛�</label>
+ <span class="info-value">{{ wholeOutInfo.currentStock || wholeOutInfo.originalQuantity }} {{ wholeOutInfo.unit }}</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鎿嶄綔鎻愮ず -->
+ <div class="operation-tip">
+ <i class="el-icon-info"></i>
+ <span>纭鎵ц鏁村嚭鎿嶄綔鍚楋紵姝ゆ搷浣滃皢涓�娆℃�ф嫞閫夎鐗╂枡鐨勬墍鏈夊簱瀛樸��</span>
+ </div>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="wholeOutDialogVisible = false" size="medium">鍙栨秷</el-button>
+ <el-button type="warning" @click="executeWholeOut" :loading="executeLoading" size="medium">
+ <i class="el-icon-check"></i>
+ 纭鏁村嚭
</el-button>
</span>
</template>
@@ -253,7 +416,10 @@
confirmDialogVisible: false,
confirmMessage: '',
currentAction: null,
- executeLoading: false
+ executeLoading: false,
+ matMixed: true,
+ wholeOutDialogVisible: false,
+ wholeOutInfo: null
}
},
computed: {
@@ -300,8 +466,9 @@
try {
this.http.post(`/api/Outbound/QueryPickingTasks?orderNo=${this.orderNo}&palletCode=${this.scanForm.palletCode}`, {}).then(response => {
if (response.status) {
- if (response.data.length > 0) {
- this.unpickedData = response.data
+ if (response.data.outStockLockInfos.length > 0) {
+ this.unpickedData = response.data.outStockLockInfos;
+ this.matMixed = response.data.isMatMixed;
this.calculateUnpickedStats()
// 鑷姩鑱氱劍鍒扮墿鏂欐潯鐮佽緭鍏ユ
@@ -384,7 +551,12 @@
// this.$message.success(`鎵樼洏鐮�: ${this.scanForm.palletCode}`)
this.loadPalletData()
-
+ // 妫�鏌ユ槸鍚﹂渶瑕佹暣鍑虹‘璁�
+ this.$nextTick(() => {
+ if (this.hasWholeOut() && this.matMixed) {
+ this.showWholeOutConfirm()
+ }
+ })
}
},
@@ -504,6 +676,69 @@
}
},
+ // 鏁村嚭纭鐩稿叧鏂规硶
+ showWholeOutConfirm() {
+ // 鑾峰彇闇�瑕佹暣鍑虹殑鐗╂枡淇℃伅
+ const wholeOutItem = this.unpickedData.find(item => item.assignQuantity === item.originalQuantity);
+ if (wholeOutItem) {
+ this.wholeOutInfo = {
+ palletCode: this.scanForm.palletCode,
+ locationCode: wholeOutItem.locationCode,
+ materielCode: wholeOutItem.materielCode,
+ materielName: wholeOutItem.materielName,
+ batchNo: wholeOutItem.batchNo,
+ assignQuantity: wholeOutItem.assignQuantity,
+ currentStock: wholeOutItem.currentStock,
+ originalQuantity: wholeOutItem.originalQuantity,
+ unit: wholeOutItem.unit
+ };
+ this.wholeOutDialogVisible = true;
+ }
+ },
+
+ handleWholeOutDialogClose() {
+ if (!this.executeLoading) {
+ this.wholeOutDialogVisible = false;
+ this.wholeOutInfo = null;
+ }
+ },
+
+ executeWholeOut() {
+ if (!this.wholeOutInfo) {
+ this.$message.error('鏁村嚭淇℃伅鏃犳晥');
+ return;
+ }
+
+ this.executeLoading = true;
+
+ try {
+ // 璋冪敤鏁村嚭鎺ュ彛锛岃繖閲屼娇鐢ㄧ墿鏂欑紪鐮佷綔涓烘潯鐮�
+ this.http.post('/api/Outbound/CompleteOutboundWithBarcode', {
+ orderNo: this.orderNo,
+ palletCode: this.scanForm.palletCode,
+ barcode: this.wholeOutInfo.materielCode, // 浣跨敤鐗╂枡缂栫爜杩涜鏁村嚭
+ operator: this.getUserName()
+ }).then(response => {
+ if (response.status) {
+ if (response.data.scannedDetail.isUnpacked && response.data.scannedDetail.materialCodes.length > 0) {
+ this.$refs.printView.open(response.data.scannedDetail.materialCodes);
+ }
+ this.$message.success('鏁村嚭鎿嶄綔鎴愬姛');
+ this.wholeOutDialogVisible = false;
+ this.wholeOutInfo = null;
+ this.loadPalletData();
+ } else {
+ this.$message.error(response.message || '鏁村嚭鎿嶄綔澶辫触');
+ }
+ });
+ } catch (error) {
+ console.error('鏁村嚭鎿嶄綔澶辫触:', error);
+ this.$message.error('鏁村嚭鎿嶄綔澶辫触');
+ } finally {
+ this.executeLoading = false;
+ }
+ },
+
quickPick(row) {
this.scanForm.materialBarcode = row.materielCode
this.handleConfirmPick()
@@ -587,6 +822,71 @@
}
return '鏈櫥褰曠敤鎴�'
+ },
+
+ // 璁$畻鍒嗘嫞鎬绘暟
+ calculateTotalAssignQuantity() {
+ return this.unpickedData.reduce((sum, item) => {
+ return sum + (item.assignQuantity || 0)
+ }, 0)
+ },
+
+ // 璁$畻宸插垎鎷f�绘暟
+ calculateTotalSortedQuantity() {
+ return this.unpickedData.reduce((sum, item) => {
+ return sum + (item.sortedQuantity || 0)
+ }, 0)
+ },
+
+ // 璁$畻鏈垎鎷f�绘暟
+ calculateTotalUnsortedQuantity() {
+ return this.unpickedData.reduce((sum, item) => {
+ const assignQty = item.assignQuantity || 0
+ const sortedQty = item.sortedQuantity || 0
+ return sum + Math.max(0, assignQty - sortedQty)
+ }, 0)
+ },
+
+ // 妫�鏌ユ槸鍚﹀寘鍚暣鍑�
+ hasWholeOut() {
+ return this.unpickedData.some(item => item.assignQuantity === item.originalQuantity) && this.matMixed;
+ },
+
+ // 璁$畻鍓╀綑搴撳瓨
+ calculateRemainingStock(row) {
+ const currentStock = row.currentStock || 0
+ const assignQty = row.assignQuantity || 0
+ return Math.max(0, currentStock - assignQty)
+ },
+
+ // 鑾峰彇搴撳瓨鐘舵�佺被鍨�
+ getStockStatusType(row) {
+ const currentStock = row.currentStock || 0
+ const assignQty = row.assignQuantity || 0
+ const sortedQty = row.sortedQuantity || 0
+
+ if (sortedQty >= assignQty) {
+ return 'success' // 宸插畬鎴�
+ } else if (currentStock < assignQty) {
+ return 'danger' // 搴撳瓨涓嶈冻
+ } else {
+ return 'warning' // 杩涜涓�
+ }
+ },
+
+ // 鑾峰彇搴撳瓨鐘舵�佹枃鏈�
+ getStockStatusText(row) {
+ const currentStock = row.currentStock || 0
+ const assignQty = row.assignQuantity || 0
+ const sortedQty = row.sortedQuantity || 0
+
+ if (sortedQty >= assignQty) {
+ return '宸插畬鎴�'
+ } else if (currentStock < assignQty) {
+ return '搴撳瓨涓嶈冻'
+ } else {
+ return '鍒嗘嫞涓�'
+ }
},
getStatusType(status) {
@@ -802,4 +1102,252 @@
::v-deep .el-descriptions__content {
color: #606266;
}
+
+/* 琛ㄦ牸澧炲己鏍峰紡 */
+::v-deep .el-table th {
+ background-color: #fafafa;
+ font-weight: 600;
+ color: #303133;
+}
+
+::v-deep .el-table .el-text {
+ font-weight: 500;
+}
+
+/* 鏍囩鏍峰紡澧炲己 */
+::v-deep .el-tag--small {
+ font-weight: 500;
+}
+
+/* 鎻愮ず淇℃伅鏍峰紡澧炲己 */
+.scan-alert ::v-deep .el-alert__content {
+ width: 100%;
+}
+
+.scan-alert ::v-deep .el-alert__description {
+ margin-top: 8px;
+}
+
+/* 鍒嗘嫞缁熻淇℃伅鏍峰紡 */
+.picking-stats {
+ margin-top: 20px;
+ padding: 0 10px;
+}
+
+.stats-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ align-items: center;
+}
+
+.stat-item {
+ display: inline-flex;
+ align-items: center;
+}
+
+.stat-item .el-tag {
+ display: flex;
+ align-items: center;
+ padding: 6px 12px;
+ font-size: 13px;
+ border-radius: 20px;
+}
+
+.stat-item .el-tag i {
+ margin-right: 6px;
+ font-size: 14px;
+}
+
+.stat-item b {
+ margin-left: 4px;
+ font-size: 14px;
+}
+
+/* 鍒嗗壊绾挎牱寮� */
+::v-deep .el-divider__text {
+ background-color: #f5f5f5;
+ padding: 0 20px;
+}
+
+/* 鎵樼洏搴撳瓨淇℃伅鏍峰紡 */
+.pallet-inventory {
+ margin-top: 20px;
+ padding: 0 10px;
+}
+
+.inventory-container {
+ margin-top: 10px;
+}
+
+.inventory-table {
+ width: 100%;
+}
+
+.inventory-table ::v-deep .el-table__header {
+ background-color: #f0f9ff;
+}
+
+.inventory-table ::v-deep .el-table__header th {
+ background-color: #e1f3ff;
+ color: #1f2937;
+ font-weight: 600;
+ font-size: 12px;
+ padding: 8px 0;
+}
+
+.inventory-table ::v-deep .el-table__body td {
+ padding: 6px 0;
+ font-size: 12px;
+}
+
+.inventory-table ::v-deep .el-table__row {
+ cursor: pointer;
+}
+
+.inventory-table ::v-deep .el-table__row:hover {
+ background-color: #f0f9ff;
+}
+
+/* 搴撳瓨琛ㄦ牸涓殑鏍囩鏍峰紡 */
+.inventory-table ::v-deep .el-tag--mini {
+ font-size: 11px;
+ padding: 1px 6px;
+ height: 18px;
+ line-height: 16px;
+}
+
+/* 鏁村嚭纭寮圭獥鏍峰紡 */
+::v-deep .whole-out-dialog {
+ border-radius: 8px;
+}
+
+::v-deep .whole-out-dialog .el-dialog__header {
+ background: linear-gradient(135deg, #E6A23C 0%, #d9971a 100%);
+ color: white;
+ padding: 15px 20px;
+ border-radius: 8px 8px 0 0;
+}
+
+::v-deep .whole-out-dialog .el-dialog__title {
+ color: white;
+ font-weight: bold;
+ font-size: 16px;
+}
+
+::v-deep .whole-out-dialog .el-dialog__headerbtn .el-dialog__close {
+ color: white;
+ font-size: 18px;
+}
+
+.whole-out-content {
+ padding: 0 10px;
+}
+
+.whole-out-alert {
+ margin-bottom: 20px;
+}
+
+.whole-out-alert ::v-deep .el-alert__description {
+ margin-top: 5px;
+ font-size: 14px;
+ color: #666;
+}
+
+.info-section {
+ margin-bottom: 20px;
+}
+
+.section-title {
+ color: #303133;
+ font-size: 15px;
+ font-weight: bold;
+ margin-bottom: 10px;
+ padding-bottom: 5px;
+ border-bottom: 2px solid #E6A23C;
+ display: flex;
+ align-items: center;
+}
+
+.section-title i {
+ margin-right: 8px;
+ color: #E6A23C;
+ font-size: 16px;
+}
+
+.info-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+}
+
+.info-item {
+ display: flex;
+ align-items: center;
+ padding: 8px 0;
+ border-bottom: 1px solid #f0f0f0;
+}
+
+.info-item label {
+ font-weight: 500;
+ color: #606266;
+ min-width: 80px;
+ font-size: 14px;
+}
+
+.info-item .info-value {
+ color: #303133;
+ font-size: 14px;
+ flex: 1;
+}
+
+.info-item .info-value.highlight {
+ color: #E6A23C;
+ font-weight: bold;
+ font-size: 15px;
+}
+
+.operation-tip {
+ background-color: #fff7e6;
+ border: 1px solid #ffd591;
+ border-radius: 6px;
+ padding: 12px 15px;
+ margin-top: 20px;
+ display: flex;
+ align-items: center;
+}
+
+.operation-tip i {
+ color: #E6A23C;
+ margin-right: 8px;
+ font-size: 16px;
+ flex-shrink: 0;
+}
+
+.operation-tip span {
+ color: #606266;
+ font-size: 14px;
+ line-height: 1.5;
+}
+
+/* 鍝嶅簲寮忚皟鏁� */
+@media (max-width: 768px) {
+ .info-grid {
+ grid-template-columns: 1fr;
+ gap: 8px;
+ }
+
+ .info-item {
+ padding: 6px 0;
+ }
+
+ .info-item label {
+ min-width: 70px;
+ font-size: 13px;
+ }
+
+ .info-item .info-value {
+ font-size: 13px;
+ }
+}
</style>
\ No newline at end of file
--
Gitblit v1.9.3