| | |
| | | <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> |
| | | æ¯ææ«æçç æ´ç®±åºåºï¼æ«ææçç åå¯ç´æ¥è¿è¡æ´ç®±ç©ææ£éï¼æ éåæ«æç©ææ ç¾ç ã |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </el-alert> |
| | | |
| | |
| | | </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> |
| | | 已忣ï¼<b>{{ calculateTotalSortedQuantity() }}</b> |
| | | </el-tag> |
| | | </div> |
| | | <div class="stat-item"> |
| | | <el-tag type="warning" size="medium" effect="dark"> |
| | | <i class="el-icon-time"></i> |
| | | æªåæ£ï¼<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> |
| | | |
| | |
| | | </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> |
| | | |
| | | <!-- ç¡®è®¤å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="confirmDialogVisible" title="æä½ç¡®è®¤" width="400px" :before-close="handleDialogClose"> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | import printView from "@/extension/outbound/extend/printView.vue" |
| | | export default { |
| | | components: { printView }, |
| | | name: 'OutPicking', |
| | | data() { |
| | | return { |
| | |
| | | confirmDialogVisible: false, |
| | | confirmMessage: '', |
| | | currentAction: null, |
| | | executeLoading: false |
| | | executeLoading: false, |
| | | matMixed: true |
| | | } |
| | | }, |
| | | computed: { |
| | |
| | | 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() |
| | | |
| | | // èªå¨èç¦å°ç©ææ¡ç è¾å
¥æ¡ |
| | |
| | | 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.resetMaterialBarcode() |
| | | // this.loadUnpickedData() |
| | |
| | | } |
| | | |
| | | return 'æªç»å½ç¨æ·' |
| | | }, |
| | | |
| | | // 计ç®åæ£æ»æ° |
| | | calculateTotalAssignQuantity() { |
| | | return this.unpickedData.reduce((sum, item) => { |
| | | return sum + (item.assignQuantity || 0) |
| | | }, 0) |
| | | }, |
| | | |
| | | // 计ç®å·²åæ£æ»æ° |
| | | calculateTotalSortedQuantity() { |
| | | return this.unpickedData.reduce((sum, item) => { |
| | | return sum + (item.sortedQuantity || 0) |
| | | }, 0) |
| | | }, |
| | | |
| | | // è®¡ç®æªåæ£æ»æ° |
| | | 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) { |
| | |
| | | ::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; |
| | | } |
| | | </style> |