647556386
2025-12-17 9ae2a50827dadfde5c90eb304390987160c2f8d1
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/outbound/outPicking.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>
                                æ”¯æŒæ‰«æ‰˜ç›˜ç æ•´ç®±å‡ºåº“:扫描托盘码后可直接进行整箱物料拣选,无需再扫描物料标签码。
                            </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>
                                å·²åˆ†æ‹£ï¼š<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>
@@ -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>
@@ -253,7 +341,8 @@
            confirmDialogVisible: false,
            confirmMessage: '',
            currentAction: null,
            executeLoading: false
            executeLoading: false,
            matMixed: true
        }
    },
    computed: {
@@ -300,8 +389,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()
                            // è‡ªåŠ¨èšç„¦åˆ°ç‰©æ–™æ¡ç è¾“å…¥æ¡†
@@ -589,6 +679,71 @@
            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) {
            const statusMap = {
                0: 'info',    // å¾…处理
@@ -802,4 +957,118 @@
::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>