1
heshaofeng
2025-11-15 d88884b7072dff4269626c600ef11f9bb42dd9e3
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue
@@ -12,13 +12,38 @@
  >
  <div class="barcode-scanner-container">
      
      <!-- ä»“库选择 - ç´§å‡‘布局 -->
      <div class="location-section compact">
        <el-form :model="form" :rules="rules" ref="locationForm" class="compact-form">
          <el-form-item label="仓库" prop="warehouseType" class="location-select compact-item">
            <el-select
              v-model="form.warehouseType"
              placeholder="请选择仓库"
              clearable
              filterable
              @change="handleWarehouseChange"
              style="width: 100%"
              :loading="warehouseLoading"
              size="medium"
            >
              <el-option
                v-for="item in warehouseTypes"
                :key="item.warehouseType"
                :label="item.warehouseTypeDesc"
                :value="item.warehouseType"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <!-- ä»“库区域选择 - ç´§å‡‘布局 -->
      <div class="location-section compact">
        <el-form :model="form" :rules="rules" ref="locationForm" class="compact-form">
          <el-form-item label="仓库区域" prop="locationType" class="location-select compact-item">
            <el-select
              v-model="form.locationType"
              placeholder="请选择仓库区域"
              placeholder="请先选择仓库"
              clearable
              filterable
              @change="handleLocationChange"
@@ -40,6 +65,9 @@
      <!-- æ‰˜ç›˜ä¿¡æ¯æ˜¾ç¤º - ç´§å‡‘布局 -->
      <div class="tray-info compact" v-if="trayBarcode">
        <i class="el-icon-s-management"></i> å½“前料箱: {{ trayBarcode }}
        <span class="location-info" v-if="form.warehouseType">
          | ä»“库: {{ currentWarehouseName  }}
        </span>
        <span class="location-info" v-if="form.locationType">
          | ä»“库区域: {{ currentLocationDesc }}
        </span>
@@ -52,7 +80,7 @@
            <span><i class="el-icon-scanner"></i> æ‰«ç åŒºåŸŸ</span>
            <span class="scan-status">
              <span class="scan-indicator"></span>
              {{ form.locationType ? '扫码就绪' : '请先选择仓库区域' }}
              {{ form.locationType && form.warehouseType ? '扫码就绪' : '请先选择仓库和仓库区域' }}
            </span>
          </div>
          
@@ -64,7 +92,7 @@
              v-model="trayBarcode"
              placeholder="请扫描或输入料箱码后按回车键"
              clearable
              :disabled="!form.locationType"
              :disabled="!form.locationType || !form.warehouseType"
              @keyup.enter.native="handleTraySubmit"
              @clear="handleTrayClear"
              @input="handleTrayInput"
@@ -76,7 +104,7 @@
                  @click="handleTraySubmit"
                  type="primary"
                  icon="el-icon-position"
                  :disabled="!form.locationType || !trayBarcode"
                  :disabled="!form.locationType || !trayBarcode || !form.warehouseType"
                  size="medium"
                >
                  ç¡®è®¤
@@ -93,7 +121,7 @@
              v-model="barcode"
              placeholder="请扫描或输入物料条码后按回车键"
              clearable
              :disabled="!form.locationType || !trayBarcode"
              :disabled="!form.locationType || !trayBarcode || !form.warehouseType"
              @keyup.enter.native="handleBarcodeSubmit"
              @clear="handleClear"
              @input="handleBarcodeInput"
@@ -106,7 +134,7 @@
                  @click="handleBarcodeSubmit"
                  type="primary"
                  icon="el-icon-search"
                  :disabled="!form.locationType || !trayBarcode || !barcode"
                  :disabled="!form.locationType || !trayBarcode || !barcode || !from.warehouseType"
                  size="medium"
                >
                  {{ loading ? '查询中...' : '查询' }}
@@ -116,9 +144,10 @@
          </div>
          
          <div class="input-tips compact-tips">
            <p>提示:请先选择仓库区域,然后输入料箱码,最后输入物料条码</p>
            <p v-if="!form.locationType" class="warning-text">⚠️ è¯·å…ˆé€‰æ‹©ä»“库区域</p>
            <p v-if="form.locationType && !trayBarcode" class="warning-text">⚠️ è¯·å…ˆè¾“入料箱码</p>
            <p>提示:请先选择仓库 â†’ é€‰æ‹©ä»“库区域 â†’ è¾“入料箱码 â†’ è¾“入物料条码</p>
            <p v-if="!form.warehouseType" class="warning-text">⚠️ è¯·å…ˆé€‰æ‹©ä»“库</p>
            <p v-if="!form.locationType && !form.warehouseType" class="warning-text">⚠️ è¯·å…ˆé€‰æ‹©ä»“库区域</p>
            <p v-if="form.warehouseType && form.locationType && !trayBarcode" class="warning-text">⚠️ è¯·å…ˆè¾“入料箱码</p>
          </div>
        
        </el-card>
@@ -151,12 +180,14 @@
              <el-tag type="primary" size="small">未组盘 {{ totalStockCount }}</el-tag>
              <el-tag type="primary" size="small">未入库数量 {{ totalStockSum }}{{ uniqueUnit }}</el-tag>
              <el-tag v-if="trayBarcode" type="success" size="small">托盘: {{ trayBarcode }}</el-tag>
              <el-tag v-if="form.warehouseType" type="info" size="small">仓库: {{ currentWarehouseName }}</el-tag>
              <el-tag v-if="form.locationType" type="info" size="small">区域: {{ currentLocationDesc }}</el-tag>
            </span>
          </div>
          
          <div v-if="materials.length === 0" class="empty-state compact">
            <i class="el-icon-document"></i>
            <p v-if="!form.warehouseType">请先选择仓库</p>
            <p v-if="!form.locationType">请先选择仓库区域</p>
            <p v-else-if="!trayBarcode">请先输入料箱条码</p>
            <p v-else>暂无物料数据,请扫描或输入物料条码</p>
@@ -177,7 +208,7 @@
              <el-table-column prop="stockQuantity" label="数量" min-width="130" align="right"></el-table-column>
              <el-table-column prop="unit" label="单位" width="80" align="center"></el-table-column>
              <el-table-column prop="supplyCode" label="供应商" min-width="130" show-overflow-tooltip></el-table-column>
              <el-table-column prop="warehouseCode" label="仓库" min-width="120" show-overflow-tooltip></el-table-column>
              <el-table-column prop="warehouseType" label="仓库" min-width="120" show-overflow-tooltip></el-table-column>
            </el-table>
          </div>
        </el-card>
@@ -217,7 +248,7 @@
          loading: false,
          error: '',
          debugMode: false,
          currentFocus: 'tray',
          currentFocus: 'warehouse',
          
          // æ‰«ç æžªç›¸å…³å˜é‡
          scanCode: '',
@@ -234,11 +265,14 @@
          uniqueUnit: '',
          sumLoading: false,
          sumError: '',
        // ä»“库相关变量
          warehouseTypes: [],
          warehouseLoading: false,
        // ä»“库区域相关变量
        locationTypes: [],
        locationLoading: false,
        form: {
            warehouseType: null,
            locationType: null
        },
    rules: {
@@ -247,8 +281,14 @@
          validator: this.validateLocationType, 
          trigger: 'change' 
        }
      ]
    }
      ],
      warehouseType: [
          {
            massage:'请选择仓库',
            trigger: 'change'
          }
        ]
      }
    }
  },
  computed: {
@@ -257,6 +297,11 @@
      set(newVal) { this.$emit('update:visible', newVal); }
    },
    currentDocNo() { return this.docNo; },
        // å½“前选择的仓库名称
    currentWarehouseName() {
      const warehouse = this.warehouseTypes.find(item => item.warehouseType === this.form.warehouseType);
      return warehouse ? warehouse.warehouseTypeDesc : '';
    },
        // å½“前选择的仓库区域描述
    currentLocationDesc() {
        const location = this.locationTypes.find(item => item.locationType === this.form.locationType)
@@ -274,7 +319,8 @@
      this.$nextTick(() => {
        setTimeout(() => {
         // this.focusTrayInput();
            this.initLocationTypes(); // åˆå§‹åŒ–仓库区域
          this.initwarehouseTypes(); // åˆå§‹åŒ–仓库
          this.initLocationTypes(); // åˆå§‹åŒ–仓库区域
          this.fetchStockStatistics(); // åŠ è½½ç»Ÿè®¡æ•°æ®
        }, 300);
      });
@@ -298,6 +344,13 @@
      }
    }
  },
  'form.warehouseType'(newVal) {
      if (newVal) {
        this.form.locationType = null;
      } else {
        this.locationTypes = [];
      }
    },
 mounted() {
 
@@ -322,10 +375,11 @@
   */
  validateLocationType(rule, value, callback) {
    // æ£€æŸ¥å€¼æ˜¯å¦ä¸ºnull、undefined或空字符串,但允许数字0
    if (value === null || value === undefined || value === '') {
    if (!this.form.warehouseType) {
      callback(new Error('请先选择仓库'));
    } else if (value === null || value === undefined || value === '') {
      callback(new Error('请选择仓库区域'));
    } else {
      // å€¼ä¸º0或其他有效值都通过验证
      callback();
    }
  },
@@ -358,6 +412,36 @@
            }
        },
        /**
         * åˆå§‹åŒ–仓库数据
         */
        async initwarehouseTypes() {
            this.warehouseLoading = true;
            this.error = '';
            try {
                const response = await http.post('/api/Warehouse/GetwarehouseTypes');
                if (response.status && Array.isArray(response.data)) {
                    this.warehouseTypes = response.data;
                    if (this.warehouseTypes.length === 0) {
                        this.error = '未获取到仓库数据';
                    } else {
                        // å¦‚果有默认区域,可以在这里设置
                        // this.form.locationType = this.locationTypes[0].locationType;
                    }
                } else {
                    this.error = '获取仓库数据失败';
                }
            } catch (error) {
                console.error('获取仓库失败:', error);
                this.error = `获取仓库失败: ${error.message || '网络错误'}`;
            } finally {
                this.warehouseLoading = false;
            }
        },
 /**
 * ä»“库区域变更处理
 */
@@ -379,14 +463,42 @@
            if (!errorMsg && (value === 0 || value)) {
              console.log('仓库区域验证通过:', value);
              // åŒºåŸŸé€‰æ‹©åŽï¼Œè‡ªåŠ¨èšç„¦åˆ°æ‰˜ç›˜è¾“å…¥æ¡†
              this.focusTrayInput();
              this.focusLocationSelect();
            }
          });
        }, 100);
    }
  });
},
        // æ–°å¢žï¼šæŸ¥è¯¢åŽç«¯åº“存统计数据(调用之前的 SumQuantity æŽ¥å£ï¼‰
/**
 * ä»“库变更处理
 */
handleWarehouseChange(value) {
 console.log('选择仓库:', value, '类型:', typeof value, this.currentWarehouseName);
    // ç«‹å³æ¸…除错误信息
    this.error = '';
    // æ‰‹åŠ¨è§¦å‘è¡¨å•éªŒè¯æ›´æ–°
    this.$nextTick(() => {
      if (this.$refs.locationForm) {
        // æ¸…除该字段的验证状态,然后重新验证
        this.$refs.locationForm.clearValidate('warehouseType');
        // çŸ­æš‚延迟后重新验证,确保DOM已更新
        setTimeout(() => {
          this.$refs.locationForm.validateField('warehouseType', (errorMsg) => {
            if (!errorMsg && (value === 0 || value)) {
              console.log('仓库验证通过:', value);
              this.focusLocationSelect();
            }
          });
        }, 100);
    }
  });
},
    async fetchStockStatistics() {
      // å•据号为空时不查询
      if (!this.docNo) {
@@ -435,7 +547,10 @@
        resolve(true);
      } else {
        // æ‰‹åŠ¨æ£€æŸ¥locationType,正确处理值为0的情况
        if (this.form.locationType === null || this.form.locationType === undefined || this.form.locationType === '') {
        if(!this.from.warehouseType){
          this.error='请先选择仓库';
        }
        else if(this.form.locationType === null || this.form.locationType === undefined || this.form.locationType === '') {
          this.error = '请先选择仓库区域';
          //this.$message.warning('请先选择仓库区域');
        } else {
@@ -447,10 +562,19 @@
    });
  });
},
       focusWarehouseSelect() {
            if (this.$refs.locationForm) {
                const selectEl = this.$el.querySelector('.location-select:first-child .el-input__inner');
                if (selectEl) {
                    selectEl.focus();
                    this.currentFocus = 'warehouse';
                }
            }
        },
        // èšç„¦åˆ°ä»“库区域选择
        focusLocationSelect() {
            if (this.$refs.locationForm) {
                const selectEl = this.$el.querySelector('.el-select .el-input__inner');
                const selectEl = this.$el.querySelector('.location-select:nth-child(2) .el-input__inner');
                if (selectEl) {
                    selectEl.focus();
                    this.currentFocus = 'location';
@@ -492,14 +616,19 @@
      this.lastKeyTime = null;
      this.isManualInput = false;
      this.isScanning = false;
      this.currentFocus = 'location';
      this.currentFocus = 'warehouse';
      this.scanTarget = 'tray';
      this.clearAllTimers();
      this.totalStockSum = 0;
      this.totalStockCount = 0;
      this.sumLoading = false;
      this.sumError = '';
        this.form.locationType = null;
        this.form={
          warehouseType:null,
          locationType:null
        }
      this.warehouseTypes=[];
      this.locationTypes=[];
          // æ¸…除表单验证状态
  this.$nextTick(() => {
    if (this.$refs.locationForm) {
@@ -527,14 +656,15 @@
      // ä½¿ç”¨setTimeout确保DOM完全渲染后再聚焦
      this.$nextTick(() => {
        setTimeout(() => {
            this.initwarehouseTypes();
            this.initLocationTypes(); // åˆå§‹åŒ–仓库区域
             // ç¡®ä¿è¡¨å•引用存在后再聚焦
      if (this.$refs.locationForm) {
        this.focusLocationSelect();
        this.focusWarehouseSelect();
      } else {
        // å¦‚果表单引用还不存在,稍后重试
        setTimeout(() => {
          this.focusLocationSelect();
          this.focusWarehouseSelect();
        }, 500);
      }
        }, 300);
@@ -567,6 +697,8 @@
      }
      
      const result = {
        warehouseType:this.form.warehouseType,
        warehouseName:this.currentWarehouseName,
        locationType: this.form.locationType,
        locationDesc: this.currentLocationDesc,
        trayBarcode: this.trayBarcode,
@@ -615,6 +747,10 @@
       // å¤„理托盘条码提交
async handleTraySubmit() {
  // å…ˆç›´æŽ¥æ£€æŸ¥locationType,避免表单验证的异步问题
  if (!this.form.warehouseType) {
    this.error = '请先选择仓库';
    return;
  }
  if (!this.form.locationType) {
    this.error = '请先选择仓库区域';
    //this.$message.warning('请先选择仓库区域');
@@ -755,7 +891,8 @@
            orderNo: this.docNo,
            barcodes: barcode,
            locationTypeDesc:  this.currentLocationDesc,
                    locationType: this.form.locationType // æ·»åŠ ä»“åº“åŒºåŸŸä¿¡æ¯
            locationType: this.form.locationType, // æ·»åŠ ä»“åº“åŒºåŸŸä¿¡æ¯
            warehouseType:this.form.warehouseType
          } 
        );