From 02f675371094a80ccfebf2e8a2debc6054efe793 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期一, 24 十一月 2025 08:21:33 +0800
Subject: [PATCH] 提交

---
 项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue | 1009 ++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 762 insertions(+), 247 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue"
index bad8e33..b976153 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue"
@@ -12,50 +12,100 @@
   >
   <div class="barcode-scanner-container">
       
-      <!-- 鎵樼洏淇℃伅鏄剧ず -->
-      <div class="tray-info" v-if="trayBarcode">
-        <i class="el-icon-s-management"></i> 褰撳墠鎵樼洏: {{ trayBarcode }}
-       <!--  <el-button 
-          class="small-button"
-          type="text" 
-          @click="clearTray"
-          style="float: right;"
-        >
-          娓呴櫎鎵樼洏
-        </el-button> -->
+      <!-- 浠撳簱閫夋嫨 - 绱у噾甯冨眬 -->
+      <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="璇峰厛閫夋嫨浠撳簱"
+              clearable
+              filterable
+              @change="handleLocationChange"
+              style="width: 100%"
+              :loading="locationLoading"
+              size="medium"
+            >
+              <el-option
+                v-for="item in locationTypes"
+                :key="item.locationType"
+                :label="item.locationTypeDesc"
+                :value="item.locationType"
+              />
+            </el-select>
+          </el-form-item>
+        </el-form>
       </div>
       
-      <!-- 鎵爜鎴栨墜鍔ㄨ緭鍏ュ尯鍩� -->
-      <div class="input-section">
-        <el-card shadow="hover">
-          <div slot="header">
-            <span><i class="el-icon-scanner"></i> </span>
+      <!-- 鎵樼洏淇℃伅鏄剧ず - 绱у噾甯冨眬 -->
+      <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>
+      </div>
+      
+      <!-- 鎵爜鍖哄煙 - 绱у噾甯冨眬 -->
+      <div class="input-section compact">
+        <el-card shadow="hover" class="compact-card">
+          <div slot="header" class="compact-header">
+            <span><i class="el-icon-scanner"></i> 鎵爜鍖哄煙</span>
             <span class="scan-status">
-              <span class="scan-indicator"></span>鎵爜灏辩华
+              <span class="scan-indicator"></span>
+              {{ form.locationType && form.warehouseType ? '鎵爜灏辩华' : '璇峰厛閫夋嫨浠撳簱鍜屼粨搴撳尯鍩�' }}
             </span>
           </div>
           
           <!-- 鎵樼洏鏉$爜杈撳叆 -->
-          <div class="input-wrapper custom-input-group">
-    <div class="input-label">鏂欑鐮�</div>
+          <div class="input-wrapper custom-input-group compact-input">
+            <div class="input-label">鏂欑鐮�</div>
             <el-input
               ref="trayInput"
               v-model="trayBarcode"
               placeholder="璇锋壂鎻忔垨杈撳叆鏂欑鐮佸悗鎸夊洖杞﹂敭"
               clearable
+              :disabled="!form.locationType || !form.warehouseType"
               @keyup.enter.native="handleTraySubmit"
               @clear="handleTrayClear"
               @input="handleTrayInput"
-                 class="custom-input"
+              class="custom-input"
+              size="medium"
             >
-              <template slot="prepend">
-                <span>鏂欑銆傜爜</span>
-              </template>
               <template slot="append">
                 <el-button 
                   @click="handleTraySubmit"
                   type="primary"
                   icon="el-icon-position"
+                  :disabled="!form.locationType || !trayBarcode || !form.warehouseType"
+                  size="medium"
                 >
                   纭
                 </el-button>
@@ -64,29 +114,28 @@
           </div>
           
           <!-- 鐗╂枡鏉$爜杈撳叆 -->
-          <div class="input-wrapper custom-input-group">
+          <div class="input-wrapper custom-input-group compact-input">
             <div class="input-label">鐗╂枡鏉$爜</div>
             <el-input
               ref="barcodeInput"
               v-model="barcode"
               placeholder="璇锋壂鎻忔垨杈撳叆鐗╂枡鏉$爜鍚庢寜鍥炶溅閿�"
               clearable
-              :disabled="!trayBarcode"
+              :disabled="!form.locationType || !trayBarcode || !form.warehouseType"
               @keyup.enter.native="handleBarcodeSubmit"
               @clear="handleClear"
               @input="handleBarcodeInput"
-                    class="custom-input"
+              class="custom-input"
+              size="medium"
             >
-              <template slot="prepend">
-                <span>鐗╂枡鏉$爜</span>
-              </template>
               <template slot="append">
                 <el-button 
                   :loading="loading" 
                   @click="handleBarcodeSubmit"
                   type="primary"
                   icon="el-icon-search"
-                  :disabled="!trayBarcode"
+                  :disabled="!form.locationType || !trayBarcode || !barcode || !from.warehouseType"
+                  size="medium"
                 >
                   {{ loading ? '鏌ヨ涓�...' : '鏌ヨ' }}
                 </el-button>
@@ -94,22 +143,24 @@
             </el-input>
           </div>
           
-          <div class="input-tips">
-            <p>鎻愮ず锛氬厛杈撳叆鎵樼洏鏉$爜锛岀劧鍚庤緭鍏ョ墿鏂欐潯鐮�</p>
-       
+          <div class="input-tips compact-tips">
+            <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>
       </div>
 
       <!-- 鍔犺浇鐘舵�� -->
-      <div v-if="loading" class="loading">
+      <div v-if="loading" class="loading compact">
         <el-progress :percentage="100" status="success" :show-text="false" />
         <p>姝e湪鏌ヨ鐗╂枡淇℃伅...</p>
       </div>
 
       <!-- 閿欒鎻愮ず -->
-      <div v-if="error" class="error-message">
+      <div v-if="error" class="error-message compact">
         <el-alert
           :title="error"
           type="error"
@@ -119,66 +170,47 @@
         />
       </div>
 
-      <!-- 鐗╂枡鍒楄〃 -->
-      <div class="material-list">
-        <el-card shadow="hover">
-          <div slot="header">
+      <!-- 鐗╂枡鍒楄〃 - 鍥哄畾楂樺害甯︽粴鍔ㄦ潯 -->
+      <div class="material-list compact">
+        <el-card shadow="hover" class="compact-card">
+          <div slot="header" class="compact-header">
             <span><i class="el-icon-tickets"></i> 缁勭洏鏁版嵁</span>
             <span class="list-actions">
-              <el-tag type="primary">鍏� {{ materials.length }} 鏉¤褰�</el-tag>
-              <el-tag v-if="trayBarcode" type="success">鎵樼洏: {{ trayBarcode }}</el-tag>
-    <!--           <el-button 
-                v-if="materials.length > 0"
-                class="small-button clear-all-btn"
-                type="danger" 
-                icon="el-icon-delete" 
-                @click="clearAllMaterials"
-              >
-                娓呯┖鍒楄〃
-              </el-button> -->
-          <!--     <el-button 
-                class="small-button clear-all-btn"
-                @click="debugMode = !debugMode"
-              >
-                {{ debugMode ? '闅愯棌璋冭瘯' : '鏄剧ず璋冭瘯' }}
-              </el-button> -->
+              <el-tag type="primary" size="small">鍏� {{ materials.length }} 鏉�</el-tag>
+              <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">
+          <div v-if="materials.length === 0" class="empty-state compact">
             <i class="el-icon-document"></i>
-            <p v-if="!trayBarcode">璇峰厛杈撳叆鎵樼洏鏉$爜</p>
+            <p v-if="!form.warehouseType">璇峰厛閫夋嫨浠撳簱</p>
+            <p v-if="!form.locationType">璇峰厛閫夋嫨浠撳簱鍖哄煙</p>
+            <p v-else-if="!trayBarcode">璇峰厛杈撳叆鏂欑鏉$爜</p>
             <p v-else>鏆傛棤鐗╂枡鏁版嵁锛岃鎵弿鎴栬緭鍏ョ墿鏂欐潯鐮�</p>
           </div>
           
-          <el-table
-            v-else
-            :data="materials"
-            stripe
-            style="width: 100%"
-          >
-            <el-table-column type="index" label="搴忓彿" width="60" align="center"></el-table-column>
-              <el-table-column prop="barcode" label="鏉$爜" min-width="140"></el-table-column>
-            <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" min-width="150"></el-table-column>
-            <el-table-column prop="batchNo" label="鎵规" min-width="150"></el-table-column>
-            <el-table-column prop="stockQuantity" label="鏁伴噺" min-width="130"></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"></el-table-column>
-            <el-table-column prop="warehouseCode" label="浠撳簱" min-width="120"></el-table-column>
-         
-     <!--        <el-table-column label="鎿嶄綔" width="100" align="center">
-              <template slot-scope="scope">
-                <el-button
-                  v-if="scope"
-                  class="small-button"
-                  type="danger"
-                  icon="el-icon-delete"
-                  circle
-                  @click="removeMaterial(scope.$index)"
-                ></el-button>
-              </template>
-            </el-table-column> -->
-          </el-table>
+          <div class="table-container" v-else>
+            <el-table
+              :data="materials"
+              stripe
+              style="width: 100%"
+              height="100%"
+              size="small"
+            >
+              <el-table-column type="index" label="搴忓彿" width="60" align="center"></el-table-column>
+              <el-table-column prop="barcode" label="鏉$爜" min-width="140" show-overflow-tooltip></el-table-column>
+              <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" min-width="150" show-overflow-tooltip></el-table-column>
+              <el-table-column prop="batchNo" label="鎵规" min-width="150" show-overflow-tooltip></el-table-column>
+              <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="warehouseType" label="浠撳簱" min-width="120" show-overflow-tooltip></el-table-column>
+            </el-table>
+          </div>
         </el-card>
       </div>
     </div>
@@ -189,7 +221,6 @@
     </div> -->
     </vol-box>
 </template>
-
 <script>
 import http from '@/api/http.js';
 import VolBox from '@/components/basic/VolBox.vue';
@@ -197,6 +228,8 @@
 import VolTable from '@/components/basic/VolTable.vue';
 import { ElLoading, ElMessage,ElMessageBox  } from 'element-plus';
 import { ref, onMounted, onUnmounted } from 'vue'
+import InboundOrder from '../../../views/inbound/inboundOrder.vue';
+import { th } from 'element-plus/es/locales.mjs';
 
 export default {
   name: 'BarcodeScanner',
@@ -215,7 +248,7 @@
           loading: false,
           error: '',
           debugMode: false,
-          currentFocus: 'tray',
+          currentFocus: 'warehouse',
           
           // 鎵爜鏋浉鍏冲彉閲�
           scanCode: '',
@@ -225,6 +258,37 @@
           scanTimer: null,
           manualInputTimer: null,
           scanTarget: 'tray', // 褰撳墠鎵爜鐩爣: tray 鎴� material
+
+          // 搴撳瓨缁熻鐩稿叧鍙橀噺
+          totalStockSum: 0,  
+          totalStockCount: 0,
+          uniqueUnit: '',
+          sumLoading: false,
+          sumError: '',
+        // 浠撳簱鐩稿叧鍙橀噺
+          warehouseTypes: [], 
+          warehouseLoading: false, 
+        // 浠撳簱鍖哄煙鐩稿叧鍙橀噺
+        locationTypes: [],
+        locationLoading: false,
+        form: {
+            warehouseType: null,
+            locationType: null
+        },
+    rules: {
+      locationType: [
+        { 
+          validator: this.validateLocationType, 
+          trigger: 'change' 
+        }
+      ],
+      warehouseType: [
+          { 
+            massage:'璇烽�夋嫨浠撳簱',
+            trigger: 'change'
+          }
+        ]
+      }
     }
   },
   computed: {
@@ -232,7 +296,17 @@
       get() { return this.visible; },
       set(newVal) { this.$emit('update:visible', newVal); }
     },
-    currentDocNo() { return this.docNo; }
+    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)
+        return location ? location.locationTypeDesc : ''
+    }
   },
   watch: {
     visible(newVal, oldVal) {
@@ -244,7 +318,10 @@
       this.resetData();
       this.$nextTick(() => {
         setTimeout(() => {
-          this.focusTrayInput();
+         // this.focusTrayInput();
+          this.initwarehouseTypes(); // 鍒濆鍖栦粨搴�
+          this.initLocationTypes(); // 鍒濆鍖栦粨搴撳尯鍩�
+          this.fetchStockStatistics(); // 鍔犺浇缁熻鏁版嵁
         }, 300);
       });
     }
@@ -263,9 +340,17 @@
         this.palletForm = { palletCode: '', barcode: '' };
         this.backData = [];
         this.$refs.palletForm?.reset();
+        this.fetchStockStatistics(); // 鍗曟嵁鍙峰彉浜嗭紝鍒锋柊缁熻
       }
     }
   },
+  'form.warehouseType'(newVal) {
+      if (newVal) {
+        this.form.locationType = null; 
+      } else {
+        this.locationTypes = []; 
+      }
+    },
 
  mounted() {
  
@@ -274,7 +359,8 @@
         
         // 浣跨敤setTimeout纭繚DOM瀹屽叏娓叉煋鍚庡啀鑱氱劍
         setTimeout(() => {
-          this.focusTrayInput();
+         // this.focusTrayInput();
+                  this.focusLocationSelect();
         }, 300);
       },
       beforeDestroy() {
@@ -283,6 +369,241 @@
          this.clearAllTimers();
       },
       methods: {
+         /**
+   * 鑷畾涔変粨搴撳尯鍩熼獙璇�
+   * 鍏佽鍊间负0锛屽洜涓�0鏄悎娉曠殑locationType
+   */
+  validateLocationType(rule, value, callback) {
+    // 妫�鏌ュ�兼槸鍚︿负null銆乽ndefined鎴栫┖瀛楃涓诧紝浣嗗厑璁告暟瀛�0
+    if (!this.form.warehouseType) {
+      callback(new Error('璇峰厛閫夋嫨浠撳簱'));
+    } else if (value === null || value === undefined || value === '') {
+      callback(new Error('璇烽�夋嫨浠撳簱鍖哄煙'));
+    } else {
+      callback();
+    }
+  },
+         /**
+         * 鍒濆鍖栦粨搴撳尯鍩熸暟鎹�
+         */
+        async initLocationTypes() {
+            this.locationLoading = true;
+            this.error = '';
+            
+            try {
+                const response = await http.post('/api/LocationInfo/GetLocationTypes');
+                
+                if (response.status && Array.isArray(response.data)) {
+                    this.locationTypes = response.data;
+                    if (this.locationTypes.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.locationLoading = false;
+            }
+        },
+
+        /**
+         * 鍒濆鍖栦粨搴撴暟鎹�
+         */
+        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;
+            }
+        },
+
+
+ /**
+ * 浠撳簱鍖哄煙鍙樻洿澶勭悊
+ */
+handleLocationChange(value) {
+ console.log('閫夋嫨浠撳簱鍖哄煙:', value, '绫诲瀷:', typeof value, this.currentLocationDesc);
+  
+    // 绔嬪嵆娓呴櫎閿欒淇℃伅
+    this.error = '';
+    
+    // 鎵嬪姩瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+    this.$nextTick(() => {
+      if (this.$refs.locationForm) {
+        // 娓呴櫎璇ュ瓧娈电殑楠岃瘉鐘舵�侊紝鐒跺悗閲嶆柊楠岃瘉
+        this.$refs.locationForm.clearValidate('locationType');
+        
+        // 鐭殏寤惰繜鍚庨噸鏂伴獙璇侊紝纭繚DOM宸叉洿鏂�
+        setTimeout(() => {
+          this.$refs.locationForm.validateField('locationType', (errorMsg) => {
+            if (!errorMsg && (value === 0 || value)) {
+              console.log('浠撳簱鍖哄煙楠岃瘉閫氳繃:', value);
+              // 鍖哄煙閫夋嫨鍚庯紝鑷姩鑱氱劍鍒版墭鐩樿緭鍏ユ
+              this.focusLocationSelect();
+            }
+          });
+        }, 100);
+    }
+  });
+},
+
+/**
+ * 浠撳簱鍙樻洿澶勭悊
+ */
+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) {
+        this.sumError = '鍗曟嵁鍙蜂负绌猴紝鏃犳硶缁熻';
+        return;
+      }
+
+      this.sumLoading = true;
+      this.sumError = '';
+      try {
+        // 璋冪敤鍚庣缁熻鎺ュ彛锛堟浛鎹负浣犵殑瀹為檯鎺ュ彛璺緞锛�
+        const response = await http.post('/api/InboundOrder/UnPalletQuantity?orderNo='+this.docNo, {
+          
+        });
+
+        // 缁戝畾鏁版嵁锛堝尮閰� PalletSumQuantityDTO 缁撴瀯锛�
+        if (response.data) {
+          this.totalStockSum = response.data.stockSumQuantity || 0; // 鎬诲簱瀛樻暟閲�
+          this.totalStockCount = response.data.stockCount || 0;     // 鎬诲簱瀛樿褰曟暟
+          this.uniqueUnit = response.data.uniqueUnit || '';               // 璁¢噺鍗曚綅
+        }
+      } catch (err) {
+        this.sumError = '缁熻鍔犺浇澶辫触';
+        this.totalStockSum = 0;
+        this.totalStockCount = 0;
+        console.error('搴撳瓨缁熻鏌ヨ寮傚父锛�', err);
+      } finally {
+        this.sumLoading = false;
+      }
+    },
+/**
+ * 琛ㄥ崟楠岃瘉
+ */
+async validateForm() {
+  return new Promise((resolve) => {
+    if (!this.$refs.locationForm) {
+      this.error = '琛ㄥ崟鏈垵濮嬪寲';
+      this.$message.warning('璇峰厛閫夋嫨浠撳簱鍖哄煙');
+      resolve(false);
+      return;
+    }
+
+    this.$refs.locationForm.validate((valid) => {
+      if (valid) {
+        this.error = '';
+        resolve(true);
+      } else {
+        // 鎵嬪姩妫�鏌ocationType锛屾纭鐞嗗�间负0鐨勬儏鍐�
+        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 {
+          // 濡傛灉鍊煎瓨鍦紙鍖呮嫭0锛夛紝浣嗛獙璇佷笉閫氳繃锛屽彲鑳芥槸鍏朵粬楠岃瘉閿欒
+          this.error = '璇锋鏌ヨ〃鍗曞~鍐欐槸鍚︽纭�';
+        }
+        resolve(false);
+      }
+    });
+  });
+},
+       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('.location-select:nth-child(2) .el-input__inner');
+                if (selectEl) {
+                    selectEl.focus();
+                    this.currentFocus = 'location';
+                }
+            }
+        },
+        // 鑱氱劍鍒版墭鐩樿緭鍏ユ
+        focusTrayInput() {
+            if (this.$refs.trayInput && this.$refs.trayInput.$el) {
+                const inputEl = this.$refs.trayInput.$el.querySelector('input');
+                if (inputEl) {
+                    inputEl.focus();
+                    this.currentFocus = 'tray';
+                    this.scanTarget = 'tray';
+                }
+            }
+        },
+        
+        // 鑱氱劍鍒扮墿鏂欒緭鍏ユ
+        focusBarcodeInput() {
+            if (this.$refs.barcodeInput && this.$refs.barcodeInput.$el) {
+                const inputEl = this.$refs.barcodeInput.$el.querySelector('input');
+                if (inputEl) {
+                    inputEl.focus();
+                    this.currentFocus = 'material';
+                    this.scanTarget = 'material';
+                }
+            }
+        },
          // 閲嶇疆鎵�鏈夋暟鎹�
     resetData() {
       console.log('閲嶇疆寮规鏁版嵁');
@@ -295,9 +616,25 @@
       this.lastKeyTime = null;
       this.isManualInput = false;
       this.isScanning = false;
-      this.currentFocus = 'tray';
+      this.currentFocus = 'warehouse';
       this.scanTarget = 'tray';
       this.clearAllTimers();
+      this.totalStockSum = 0;
+      this.totalStockCount = 0;
+      this.sumLoading = false;
+      this.sumError = '';
+        this.form={
+          warehouseType:null,
+          locationType:null
+        }
+      this.warehouseTypes=[];
+      this.locationTypes=[];  
+          // 娓呴櫎琛ㄥ崟楠岃瘉鐘舵��
+  this.$nextTick(() => {
+    if (this.$refs.locationForm) {
+      this.$refs.locationForm.clearValidate();
+    }
+  });
     },
     
     // 娓呴櫎鎵�鏈夎鏃跺櫒
@@ -319,7 +656,17 @@
       // 浣跨敤setTimeout纭繚DOM瀹屽叏娓叉煋鍚庡啀鑱氱劍
       this.$nextTick(() => {
         setTimeout(() => {
-          this.focusTrayInput();
+            this.initwarehouseTypes();
+            this.initLocationTypes(); // 鍒濆鍖栦粨搴撳尯鍩�
+             // 纭繚琛ㄥ崟寮曠敤瀛樺湪鍚庡啀鑱氱劍
+      if (this.$refs.locationForm) {
+        this.focusWarehouseSelect();
+      } else {
+        // 濡傛灉琛ㄥ崟寮曠敤杩樹笉瀛樺湪锛岀◢鍚庨噸璇�
+        setTimeout(() => {
+          this.focusWarehouseSelect();
+        }, 500);
+      }
         }, 300);
       });
     },
@@ -336,7 +683,9 @@
     },
     
     // 纭鎸夐挳
-    handleConfirm() {
+   async  handleConfirm() {
+           if (!await this.validateForm()) return;
+
       if (this.materials.length === 0) {
         this.$message.warning('璇疯嚦灏戞坊鍔犱竴涓墿鏂�');
         return;
@@ -348,6 +697,10 @@
       }
       
       const result = {
+        warehouseType:this.form.warehouseType,
+        warehouseName:this.currentWarehouseName,
+        locationType: this.form.locationType,
+        locationDesc: this.currentLocationDesc,
         trayBarcode: this.trayBarcode,
         materials: this.materials,
         docNo: this.docNo
@@ -357,84 +710,74 @@
       this.$emit('back-success', result);
       this.palletVisible = false;
     },
-        // 鑱氱劍鍒版墭鐩樿緭鍏ユ
-        focusTrayInput() {
-          if (this.$refs.trayInput && this.$refs.trayInput.$el) {
-            const inputEl = this.$refs.trayInput.$el.querySelector('input');
-            if (inputEl) {
-              inputEl.focus();
-              this.currentFocus = 'tray';
-              this.scanTarget = 'tray';
-            }
-          }
-        },
-        
-        // 鑱氱劍鍒扮墿鏂欒緭鍏ユ
-        focusBarcodeInput() {
-          if (this.$refs.barcodeInput && this.$refs.barcodeInput.$el) {
-            const inputEl = this.$refs.barcodeInput.$el.querySelector('input');
-            if (inputEl) {
-              inputEl.focus();
-              this.currentFocus = 'material';
-              this.scanTarget = 'material';
-            }
-          }
-        },
-        
-        // 澶勭悊鎵樼洏杈撳叆
+    // 澶勭悊鎵樼洏杈撳叆
         handleTrayInput() {
-          // 鏍囪涓烘墜鍔ㄨ緭鍏ユā寮�
-          this.isManualInput = true;
-          this.isScanning = false;
-          
-          // 娓呴櫎涔嬪墠鐨勮鏃跺櫒
-          if (this.manualInputTimer) {
-            clearTimeout(this.manualInputTimer);
-          }
-          
-          // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆涓烘壂鐮佹ā寮�
-          this.manualInputTimer = setTimeout(() => {
-            this.isManualInput = false;
-          }, 1000);
+            // 鏍囪涓烘墜鍔ㄨ緭鍏ユā寮�
+            this.isManualInput = true;
+            this.isScanning = false;
+            
+            // 娓呴櫎涔嬪墠鐨勮鏃跺櫒
+            if (this.manualInputTimer) {
+                clearTimeout(this.manualInputTimer);
+            }
+            
+            // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆涓烘壂鐮佹ā寮�
+            this.manualInputTimer = setTimeout(() => {
+                this.isManualInput = false;
+            }, 1000);
         },
         
         // 澶勭悊鐗╂枡杈撳叆
         handleBarcodeInput() {
-          // 鏍囪涓烘墜鍔ㄨ緭鍏ユā寮�
-          this.isManualInput = true;
-          this.isScanning = false;
-          
-          // 娓呴櫎涔嬪墠鐨勮鏃跺櫒
-          if (this.manualInputTimer) {
-            clearTimeout(this.manualInputTimer);
-          }
-          
-          // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆涓烘壂鐮佹ā寮�
-          this.manualInputTimer = setTimeout(() => {
-            this.isManualInput = false;
-          }, 1000);
-        },
-        
-        // 澶勭悊鎵樼洏鏉$爜鎻愪氦
-        handleTraySubmit() {
-          const currentTrayBarcode = this.trayBarcode.trim();
-          
-          if (!currentTrayBarcode) {
-            this.error = '璇疯緭鍏ユ垨鎵弿鎵樼洏鏉$爜';
-            return;
-          }
+            // 鏍囪涓烘墜鍔ㄨ緭鍏ユā寮�
+            this.isManualInput = true;
+            this.isScanning = false;
+            
+            // 娓呴櫎涔嬪墠鐨勮鏃跺櫒
+            if (this.manualInputTimer) {
+                clearTimeout(this.manualInputTimer);
+            }
+            
+            // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆涓烘壂鐮佹ā寮�
+            this.manualInputTimer = setTimeout(() => {
+                this.isManualInput = false;
+            }, 1000);
+        },      
+                 
+       // 澶勭悊鎵樼洏鏉$爜鎻愪氦
+async handleTraySubmit() {
+  // 鍏堢洿鎺ユ鏌ocationType锛岄伩鍏嶈〃鍗曢獙璇佺殑寮傛闂
+  if (!this.form.warehouseType) {
+    this.error = '璇峰厛閫夋嫨浠撳簱';
+    return;
+  }
+  if (!this.form.locationType) {
+    this.error = '璇峰厛閫夋嫨浠撳簱鍖哄煙';
+    //this.$message.warning('璇峰厛閫夋嫨浠撳簱鍖哄煙');
+    return;
+  }
+  
+  // 鐒跺悗鍐嶈繘琛屽畬鏁寸殑琛ㄥ崟楠岃瘉
+  if (!await this.validateForm()) return;
+  
+  const currentTrayBarcode = this.trayBarcode.trim();
+  
+  if (!currentTrayBarcode) {
+    this.error = '璇疯緭鍏ユ垨鎵弿鎵樼洏鏉$爜';
+    return;
+  }
 
-          this.error = '';
-          
-          // 璁剧疆鎵樼洏鏉$爜鍚庯紝鑷姩鑱氱劍鍒扮墿鏂欒緭鍏ユ
-          this.focusBarcodeInput();
-          
-          this.$message({
-            message: `鎵樼洏鏉$爜宸茶缃�: ${currentTrayBarcode}`,
-            type: 'success',
-            duration: 2000
-          });
-        },
+  this.error = '';
+  
+  // 璁剧疆鎵樼洏鏉$爜鍚庯紝鑷姩鑱氱劍鍒扮墿鏂欒緭鍏ユ
+  this.focusBarcodeInput();
+  
+  this.$message({
+    message: `鎵樼洏鏉$爜宸茶缃�: ${currentTrayBarcode}`,
+    type: 'success',
+    duration: 2000
+  });
+},
         
         // 娓呴櫎鎵樼洏
         clearTray() {
@@ -463,6 +806,7 @@
         
         // 澶勭悊鐗╂枡鏉$爜鎻愪氦
         async handleBarcodeSubmit() {
+                    if (!await this.validateForm()) return;
           const currentBarcode = this.barcode.trim();
           
           if (!this.trayBarcode) {
@@ -506,6 +850,8 @@
           this.materials.push({
             ...item, 
              trayCode: this.trayBarcode,
+               locationType: this.form.locationType,
+                            locationDesc: this.currentLocationDesc,
                scanTime: this.formatTime(new Date())
           });
         });
@@ -519,7 +865,7 @@
                 duration: 2000
               });
          
-            
+            this.fetchStockStatistics(); 
             // 娓呯┖鐗╂枡杈撳叆妗嗗苟淇濇寔鑱氱劍
             this.barcode = '';
             this.scanCode = ''; // 娓呯┖鎵爜缂撳瓨
@@ -543,7 +889,10 @@
            {
             palletCode: this.trayBarcode,
             orderNo: this.docNo,
-            barcodes: barcode
+            barcodes: barcode,
+            locationTypeDesc:  this.currentLocationDesc,
+            locationType: this.form.locationType, // 娣诲姞浠撳簱鍖哄煙淇℃伅
+            warehouseType:this.form.warehouseType
           } 
         );
         
@@ -564,7 +913,7 @@
  if(!response.status){
    this.error = response.message || '鏌ヨ鏉$爜淇℃伅澶辫触锛岃閲嶈瘯';
  }
-        // 纭繚杩斿洖鐨勬暟鎹寘鍚墍鏈夊繀闇�鐨勫瓧娈�
+
         return  materialData;
         
       } catch (error) {
@@ -639,6 +988,8 @@
               type: 'success',
               message: '鍒犻櫎鎴愬姛!'
             });
+            this.fetchStockStatistics(); 
+
           }).catch(() => {
             // 鍙栨秷鍒犻櫎
           });
@@ -682,135 +1033,299 @@
     .barcode-scanner-container {
       max-width: 1200px;
       margin: 0 auto;
-      padding: 20px;
+      padding: 10px;
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+      gap: 8px;
     }
+    
+    /* 绱у噾甯冨眬鏍峰紡 */
+    .compact {
+      margin-bottom: 0;
+    }
+    
+    .compact-form {
+      margin-bottom: 0;
+    }
+    
+    .compact-item {
+      margin-bottom: 0;
+    }
+    
+    .compact-card {
+      margin-bottom: 0;
+    }
+    
+    .compact-card >>> .el-card__body {
+      padding: 12px;
+    }
+    
+    .compact-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 0 !important;
+    }
+    
+    .compact-header >>> .el-card__header {
+      padding: 8px 12px;
+    }
+    
+    .compact-input {
+      margin: 8px 0;
+    }
+    
+    .compact-tips {
+      margin-top: 8px;
+      font-size: 11px;
+    }
+    
+    /* 浠撳簱鍖哄煙閫夋嫨 - 绱у噾 */
+    .location-section.compact {
+      margin-bottom: 8px;
+    }
+    
+    .location-section.compact >>> .el-form-item {
+      margin-bottom: 0;
+    }
+    
+    /* 鎵樼洏淇℃伅 - 绱у噾 */
+    .tray-info.compact {
+      padding: 6px 10px;
+      margin-bottom: 8px;
+      font-size: 13px;
+    }
+    
+    /* 鎵爜鍖哄煙 - 绱у噾 */
+    .input-section.compact {
+      margin-bottom: 8px;
+      flex-shrink: 0;
+    }
+    
+    /* 鐗╂枡鍒楄〃 - 鍥哄畾楂樺害甯︽粴鍔� */
+    .material-list.compact {
+      flex: 1;
+      min-height: 0; /* 閲嶈锛氬厑璁竑lex瀛愰」鏀剁缉 */
+      display: flex;
+      flex-direction: column;
+    }
+    
+    .material-list.compact >>> .el-card {
+      display: flex;
+      flex-direction: column;
+      height: 100%;
+    }
+    
+    .material-list.compact >>> .el-card__body {
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      padding: 0;
+      min-height: 0;
+    }
+    
+    .table-container {
+      flex: 1;
+      min-height: 0;
+      overflow: hidden;
+    }
+    
+    .material-list.compact >>> .el-table {
+      flex: 1;
+    }
+    
+    .material-list.compact >>> .el-table__body-wrapper {
+      overflow-y: auto;
+    }
+    
+    /* 绱у噾鐨勭┖鐘舵�� */
+    .empty-state.compact {
+      padding: 20px 0;
+      flex: 1;
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: center;
+    }
+    
+    .empty-state.compact i {
+      font-size: 36px;
+      margin-bottom: 8px;
+    }
+    
+    .empty-state.compact p {
+      font-size: 13px;
+    }
+    
+    /* 鍏朵粬鍘熸湁鏍峰紡璋冩暣 */
     .page-title {
       text-align: center;
-      margin-bottom: 30px;
+      margin-bottom: 15px;
     }
-    .input-section {
-      margin-bottom: 30px;
-    }
+    
     .scan-status {
-      float: right;
       font-size: 12px;
       color: #67C23A;
     }
+    
     .scan-indicator {
       display: inline-block;
-      width: 10px;
-      height: 10px;
+      width: 8px;
+      height: 8px;
       border-radius: 50%;
       background-color: #67C23A;
       margin-right: 5px;
       animation: pulse 1.5s infinite;
     }
+    
     @keyframes pulse {
       0% { opacity: 1; }
       50% { opacity: 0.4; }
       100% { opacity: 1; }
     }
+    
     .input-wrapper {
       position: relative;
-      margin-bottom: 15px;
     }
+    
     .input-tips {
-      margin-top: 10px;
-      font-size: 12px;
+      margin-top: 6px;
       color: #909399;
     }
-    .loading {
-      text-align: center;
-      margin: 20px 0;
+    
+    .warning-text {
+        color: #E6A23C;
+        font-weight: bold;
     }
-    .loading p {
-      margin-top: 10px;
+    
+    .loading.compact {
+      text-align: center;
+      margin: 10px 0;
+      padding: 5px;
+    }
+    
+    .loading.compact p {
+      margin-top: 5px;
       color: #409EFF;
+      font-size: 12px;
     }
-    .error-message {
-      margin-bottom: 20px;
+    
+    .error-message.compact {
+      margin: 5px 0;
     }
-    .material-list {
-      margin-top: 30px;
+    
+    .error-message.compact >>> .el-alert {
+      padding: 6px 12px;
     }
+    
     .list-actions {
-      float: right;
+      display: flex;
+      align-items: center;
+      gap: 4px;
     }
+    
+    .list-actions >>> .el-tag {
+      height: 24px;
+      line-height: 22px;
+      padding: 0 6px;
+    }
+    
     .clear-all-btn {
-      margin-left: 10px;
+      margin-left: 8px;
     }
-    .empty-state {
-      text-align: center;
-      padding: 40px 0;
-      color: #909399;
-    }
-    .empty-state i {
-      font-size: 48px;
-      margin-bottom: 10px;
-    }
+    
     .material-code {
       font-family: 'Courier New', monospace;
       font-weight: bold;
       color: #409EFF;
     }
-    .tray-info {
-      background: #f0f9ff;
-      padding: 10px 15px;
-      border-radius: 4px;
-      margin-bottom: 15px;
-      border-left: 4px solid #409EFF;
+    
+    .location-info {
+        color: #606266;
+        font-weight: normal;
     }
+    
     .debug-info {
       background: #f5f7fa;
-      padding: 10px;
+      padding: 8px;
       border-radius: 4px;
-      margin-top: 10px;
-      font-size: 12px;
+      margin-top: 8px;
+      font-size: 11px;
       color: #909399;
     }
+    
     .small-button {
-      padding: 7px 9px;
-      font-size: 12px;
+      padding: 6px 8px;
+      font-size: 11px;
     }
-.custom-input-group {
-  display: flex;
-  align-items: center;
-  width: 100%;
-  margin: 20px 0;
-  border: 1px solid #DCDFE6;
-  border-radius: 4px;
-  overflow: hidden;
-  background: #fff;
-}
 
-.input-label {
-  padding: 0 15px;
-  background: #F5F7FA;
-  border-right: 1px solid #DCDFE6;
-  color: #606266;
-  font-size: 14px;
-  white-space: nowrap;
-  height: 40px;
-  line-height: 40px;
-  flex-shrink: 0;
-}
+    /* 杈撳叆妗嗙粍鏍峰紡璋冩暣 */
+    .custom-input-group {
+      display: flex;
+      align-items: center;
+      width: 100%;
+      margin: 8px 0;
+      border: 1px solid #DCDFE6;
+      border-radius: 4px;
+      overflow: hidden;
+      background: #fff;
+    }
 
-.input-container {
-  display: flex;
-  flex: 1;
-  align-items: center;
-}
+    .input-label {
+      padding: 0 12px;
+      background: #F5F7FA;
+      border-right: 1px solid #DCDFE6;
+      color: #606266;
+      font-size: 13px;
+      white-space: nowrap;
+      height: 36px;
+      line-height: 36px;
+      flex-shrink: 0;
+      min-width: 70px;
+      text-align: center;
+    }
 
-.custom-input {
-  flex: 1;
-}
+    .input-container {
+      display: flex;
+      flex: 1;
+      align-items: center;
+    }
 
-.custom-input ::v-deep .el-input__inner {
-  border: none;
-  border-radius: 0;
-  height: 40px;
-  line-height: 40px;
-}
+    .custom-input {
+      flex: 1;
+    }
 
- 
+    .custom-input >>> .el-input__inner {
+      border: none;
+      border-radius: 0;
+      height: 36px;
+      line-height: 36px;
+      font-size: 13px;
+    }
+    
+    /* 鍝嶅簲寮忚皟鏁� */
+    @media (max-width: 768px) {
+      .barcode-scanner-container {
+        padding: 5px;
+      }
+      
+      .custom-input-group {
+        flex-direction: column;
+        border: none;
+      }
+      
+      .input-label {
+        width: 100%;
+        border-right: none;
+        border-bottom: 1px solid #DCDFE6;
+        margin-bottom: 5px;
+      }
+      
+      .input-container {
+        width: 100%;
+        border: 1px solid #DCDFE6;
+        border-radius: 4px;
+      }
+    }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3