z8018
2025-12-25 664df90a747e5a97b4e1131a5f958ded3176250c
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/outbound/outPicking.vue
@@ -1,5 +1,7 @@
<template>
    <div class="picking-container">
    <div class="picking-container" v-loading="globalLoading" element-loading-text="处理中..."
        element-loading-background="rgba(255, 255, 255, 0.8)" element-loading-spinner="el-icon-loading"
        element-loading-custom-class="custom-loading">
        <!-- é¡¶éƒ¨è®¢å•信息 -->
        <el-card class="order-info-card" shadow="never">
            <div class="order-header">
@@ -8,8 +10,11 @@
                    <span class="order-label">订单号:</span>
                    <span class="order-value">{{ orderNo }}</span>
                </div>
                <div class="order-status" v-if="orderInfo">
                    <el-tag :type="getStatusType(orderInfo.status)" size="medium">
                <div class="order-status">
                    <!-- æµ‹è¯•按钮 -->
                    <el-tag v-if="orderInfo" :type="getStatusType(orderInfo.orderStatus)" size="medium"
                        style="margin-left: 10px;">
                        {{ orderInfo.statusName || '进行中' }}
                    </el-tag>
                </div>
@@ -21,7 +26,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 +82,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="hasWholeOut() ? 'success' : 'warning'" size="medium" effect="dark">
                                <i class="el-icon-box"></i>
                                æ˜¯å¦æ•´å‡ºï¼š{{ hasWholeOut() ? '是' : '否' }}
                            </el-tag>
                        </div>
                    </div>
                </div>
            </div>
        </el-card>
@@ -198,7 +244,56 @@
                    </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">
@@ -214,11 +309,95 @@
                </span>
            </template>
        </el-dialog>
        <!-- æ•´å‡ºç¡®è®¤å¯¹è¯æ¡† -->
        <el-dialog v-model="wholeOutDialogVisible" title="整出操作确认" width="500px"
            :before-close="handleWholeOutDialogClose" custom-class="whole-out-dialog" style="margin-right: 0px;">
            <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>
        </el-dialog>
    </div>
</template>
<script>
import printView from "@/extension/outbound/extend/printView.vue"
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
import { ElLoading } from 'element-plus'
export default {
    components: { printView },
    name: 'OutPicking',
    data() {
        return {
@@ -248,7 +427,12 @@
            confirmDialogVisible: false,
            confirmMessage: '',
            currentAction: null,
            executeLoading: false
            executeLoading: false,
            matMixed: true,
            wholeOutDialogVisible: false,
            wholeOutInfo: null,
            globalLoading: false,
            loadingInstance: null
        }
    },
    computed: {
@@ -268,6 +452,10 @@
                this.$router.back()
                return
            }
            // åŠ è½½è®¢å•ä¿¡æ¯
            this.loadOrderInfo()
            // è‡ªåŠ¨èšç„¦åˆ°æ‰˜ç›˜ç è¾“å…¥æ¡†
            this.$nextTick(() => {
                if (this.$refs.palletInput) {
@@ -275,30 +463,55 @@
                }
            })
        },
        async loadOrderInfo() {
            try {
                this.showFullScreenLoading()
                const response = await this.http.get(`/api/Outbound/GetOrderInfo?orderNo=${this.orderNo}`)
                if (response.status) {
                    this.orderInfo = response.data
                } else {
                }
            }
            catch (error) {
        loadPalletData() {
            } finally {
                this.hideFullScreenLoading()
            }
        },
        async loadPalletData() {
            if (!this.scanForm.palletCode) {
                this.unpickedData = []
                return
            }
            try {
                this.loadUnpickedData();
                this.loadPickedData();
                this.showFullScreenLoading()
                await Promise.all([
                    this.loadUnpickedData(),
                    this.loadPickedData()
                ]);
            } catch (error) {
                console.error('加载托盘数据失败:', error)
                this.unpickedData = []
            } finally {
                this.hideFullScreenLoading()
            }
        },
        loadUnpickedData() {
            try {
            return new Promise((resolve, reject) => {
                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()
                            // æ£€æŸ¥æ˜¯å¦éœ€è¦æ•´å‡ºç¡®è®¤
                            this.$nextTick(() => {
                                if (this.hasWholeOut()) {
                                    this.showWholeOutConfirm()
                                }
                            })
                            // è‡ªåŠ¨èšç„¦åˆ°ç‰©æ–™æ¡ç è¾“å…¥æ¡†
                            this.$nextTick(() => {
                                if (this.$refs.materialInput) {
@@ -306,42 +519,43 @@
                                }
                            })
                        } else {
                            this.$message.warning('该托盘无未拣选任务')
                            if (flag) {
                                this.$message.warning('该托盘无未拣选任务')
                            }
                            this.unpickedData = []
                        }
                        resolve()
                    } else {
                        this.$message.error(response.message || '获取托盘数据失败')
                        this.unpickedData = []
                        reject(response.message || '获取托盘数据失败')
                    }
                }
                )
            } catch (error) {
                console.error('加载未拣选数据失败:', error)
            }
                }).catch(error => {
                    reject(error)
                })
            })
        },
        loadPickedData() {
            try {
            return new Promise((resolve, reject) => {
                this.http.post(`/api/Outbound/QueryPickedList?orderNo=${this.orderNo}&palletCode=${this.scanForm.palletCode}`, {}).then(response => {
                    if (response.status) {
                        if (response.data.length > 0) {
                            this.pickedData = response.data
                            this.calculatePickedStats()
                        } else {
                            this.$message.warning('该托盘无未拣选任务')
                            this.unpickedData = []
                            this.pickedData = []
                        }
                        resolve()
                    } else {
                        this.$message.error(response.message || '获取托盘数据失败')
                        this.unpickedData = []
                        this.pickedData = []
                        reject(response.message || '获取托盘数据失败')
                    }
                }
                )
            } catch (error) {
                console.error('加载已拣选数据失败:', error)
            }
                }).catch(error => {
                    reject(error)
                })
            })
        },
        // è®¡ç®—未拣选
@@ -375,12 +589,11 @@
            this.pickedTotal = this.pickedCount
        },
        handlePalletScan() {
        handlePalletScan(flag = true) {
            if (this.scanForm.palletCode) {
                // this.$message.success(`托盘码: ${this.scanForm.palletCode}`)
                this.loadPalletData()
                this.loadPalletData(flag)
            } else {
            }
        },
@@ -400,36 +613,39 @@
            this.handleConfirmPick()
        },
        handleConfirmPick() {
        async handleConfirmPick() {
            if (!this.scanForm.palletCode || !this.scanForm.materialBarcode) {
                this.$message.warning('请先扫描托盘码和物料条码')
                return
            }
            this.confirmLoading = true
            this.showFullScreenLoading()
            try {
                this.http.post('/api/Outbound/CompleteOutboundWithBarcode', {
                const response = await this.http.post('/api/Outbound/CompleteOutboundWithBarcode', {
                    orderNo: this.orderNo,
                    palletCode: this.scanForm.palletCode,
                    barcode: this.scanForm.materialBarcode,
                    operator: this.getUserName()
                }).then(response => {
                    if (response.status) {
                        this.$message.success('拣选确认成功')
                        this.resetMaterialBarcode()
                        // this.loadUnpickedData()
                        // this.loadPickedData()
                        this.loadPalletData()
                    } else {
                        this.$message.error(response.message || '拣选确认失败')
                    }
                })
                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()
                    // this.loadPickedData()
                    await this.loadPalletData(false)
                } else {
                    this.$message.error(response.message || '拣选确认失败')
                }
            } catch (error) {
                console.error('拣选确认失败:', error)
                this.$message.error('拣选确认失败')
            } finally {
                this.confirmLoading = false
                this.hideFullScreenLoading()
            }
        },
@@ -455,45 +671,104 @@
            this.confirmDialogVisible = true
        },
        executeConfirm() {
        async executeConfirm() {
            this.executeLoading = true
            this.showFullScreenLoading()
            try {
                let apiUrl = ''
                let params = {
                    orderNo: this.orderNo,
                    palletCode: this.scanForm.palletCode
                    palletCode: this.scanForm.palletCode,
                    station: stationManager.getStation()
                }
                if (this.currentAction === 'emptyBox') {
                    apiUrl = '/api/Outbound/EmptyBox'
                } else if (this.currentAction === 'returnToWarehouse') {
                    apiUrl = '/api/Outbound/ReturnToWarehouse'
                }
                this.http.post(apiUrl, params).then(response => {
                const response = await this.http.post(apiUrl, params)
                    if (response.status) {
                        this.$message.success('操作成功')
                        this.confirmDialogVisible = false
                        this.resetForm()
                        // this.loadUnpickedData()
                        // this.loadPickedData()
                    } else {
                        this.$message.error(response.message || '操作失败')
                    }
                })
                if (response.status) {
                    this.$message.success('操作成功')
                    this.confirmDialogVisible = false
                    this.resetForm()
                    // this.loadUnpickedData()
                    // this.loadPickedData()
                } else {
                    this.$message.error(response.message || '操作失败')
                }
            } catch (error) {
                console.error('操作失败:', error)
                this.$message.error('操作失败')
            } finally {
                this.executeLoading = false
                this.hideFullScreenLoading()
            }
        },
        handleDialogClose() {
            if (!this.executeLoading) {
                this.confirmDialogVisible = false
            }
        },
        // æ•´å‡ºç¡®è®¤ç›¸å…³æ–¹æ³•
        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;
            }
        },
        async executeWholeOut() {
            if (!this.wholeOutInfo) {
                this.$message.error('整出信息无效');
                return;
            }
            this.executeLoading = true;
            this.showFullScreenLoading();
            try {
                // è°ƒç”¨æ•´å‡ºæŽ¥å£ï¼Œè¿™é‡Œä½¿ç”¨ç‰©æ–™ç¼–码作为条码
                const response = await this.http.post('/api/Outbound/CompleteOutboundWithPallet', {
                    orderNo: this.orderNo,
                    palletCode: this.scanForm.palletCode,
                    operator: this.getUserName()
                });
                if (response.status) {
                    this.$message.success('整出操作成功');
                    this.wholeOutDialogVisible = false;
                    this.wholeOutInfo = null;
                    await this.loadPalletData();
                } else {
                    this.$message.error(response.message || '整出操作失败');
                }
            } catch (error) {
                this.$message.error('整出操作失败');
            } finally {
                this.executeLoading = false;
                this.hideFullScreenLoading();
            }
        },
@@ -521,7 +796,6 @@
                })
            } catch (error) {
                if (error !== 'cancel') {
                    console.error('撤销失败:', error)
                    this.$message.error('撤销失败')
                }
            }
@@ -539,7 +813,9 @@
        },
        refreshPickedTable() {
            this.loadPickedData()
            this.loadPickedData().catch(error => {
                console.error('刷新已拣选列表失败:', error)
            })
        },
        resetMaterialBarcode() {
@@ -576,31 +852,137 @@
                    return user.userName || user.username || '未登录用户'
                }
            } catch (error) {
                console.error('获取用户信息失败:', error)
            }
            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',    // å¾…处理
                10: 'warning', // è¿›è¡Œä¸­
                1: 'warning', // è¿›è¡Œä¸­
                20: 'primary', // æ‹£é€‰ä¸­
                30: 'success', // å·²å®Œæˆ
                40: 'danger'   // å¼‚常
            }
            return statusMap[status] || 'info'
        },
        // æ˜¾ç¤ºå…¨å±é®ç½©å±‚
        showFullScreenLoading() {
            if (this.loadingInstance) {
                this.loadingInstance.close()
            }
            this.loadingInstance = ElLoading.service({
                lock: true,
                text: '处理中...',
                background: 'rgba(0, 0, 0, 0.7)',
                customClass: 'custom-full-loading'
            })
        },
        // éšè—å…¨å±é®ç½©å±‚
        hideFullScreenLoading() {
            if (this.loadingInstance) {
                this.loadingInstance.close()
                this.loadingInstance = null
            } else {
            }
        },
        // æµ‹è¯•遮罩层显示
        testLoading() {
            // æµ‹è¯•两种方式
            this.globalLoading = true
            // åŒæ—¶ä¹Ÿæµ‹è¯•全屏loading
            this.showFullScreenLoading()
            setTimeout(() => {
                this.globalLoading = false
                this.hideFullScreenLoading()
            }, 3000)
        }
    }
}
</script>
<style>
.el-dialog__header {
    margin: 0;
}
</style>
<style scoped>
.picking-container {
    padding: 20px;
    background-color: #f5f5f5;
    min-height: 100vh;
    position: relative;
    overflow: hidden;
}
/* è®¢å•信息卡片 */
@@ -795,4 +1177,321 @@
::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;
    }
}
/* Element Plus Loading é®ç½©å±‚样式修复 */
::v-deep .custom-loading {
    background-color: rgba(0, 0, 0, 0.7) !important;
    z-index: 9999 !important;
}
::v-deep .custom-loading .el-loading-mask {
    background-color: rgba(0, 0, 0, 0.7) !important;
}
::v-deep .custom-loading .el-loading-spinner {
    z-index: 10000 !important;
}
::v-deep .custom-loading .el-loading-text {
    color: #ffffff !important;
    font-weight: bold !important;
    font-size: 16px !important;
}
/* å…¨å±€ Loading æ ·å¼ */
::v-deep .el-loading-mask {
    background-color: rgba(0, 0, 0, 0.7) !important;
    z-index: 9999 !important;
}
::v-deep .el-loading-spinner {
    z-index: 10000 !important;
}
::v-deep .el-loading-text {
    color: #ffffff !important;
    font-weight: bold !important;
}
/* å…¨å±Loading自定义样式 */
::v-deep .custom-full-loading {
    z-index: 999999 !important;
}
::v-deep .custom-full-loading .el-loading-mask {
    z-index: 999999 !important;
}
::v-deep .custom-full-loading .el-loading-spinner {
    z-index: 1000000 !important;
}
::v-deep .custom-full-loading .el-loading-text {
    color: #ffffff !important;
    font-weight: bold !important;
    font-size: 18px !important;
}
/* ç¡®ä¿å¯¹è¯æ¡†ä¸ä¼šé®ç›–loading */
::v-deep .el-dialog {
    z-index: 2000 !important;
}
::v-deep .el-dialog__wrapper {
    z-index: 2000 !important;
}
/* ç¡®ä¿å®¹å™¨ç›¸å¯¹å®šä½ */
.picking-container {
    position: relative !important;
    min-height: 100vh;
}
</style>