From 7437dd7b944aaeb64e98a1e0a5943ec88db4afab Mon Sep 17 00:00:00 2001
From: lty <876263681@qq.com>
Date: 星期二, 03 二月 2026 15:37:00 +0800
Subject: [PATCH] #新增扫内部码入库和换码功能

---
 pages/basics/codePakin.vue | 1363 +++++++++++++++++++++++++++--------------------------------
 1 files changed, 621 insertions(+), 742 deletions(-)

diff --git a/pages/basics/codePakin.vue b/pages/basics/codePakin.vue
index db9a8e2..4693db6 100644
--- a/pages/basics/codePakin.vue
+++ b/pages/basics/codePakin.vue
@@ -1,164 +1,158 @@
 <template>
-  <view>
-    <scroll-view scroll-y catch:touchmove="touchmove">
-      <!-- 鎵樼洏鏉$爜 -->
-      <view class="square-2">
-        <view class="square-title">
-          <view class="title-sign"><view class="sign"></view></view>
-          <view class="title-text"><text>鎵樼洏鏉$爜</text></view>
+  <view class="page-container">
+    <scroll-view scroll-y class="page-scroll">
+      
+      <!-- 1. Pallet Barcode Section -->
+      <view class="card-box">
+        <view class="card-header">
+          <view class="header-indicator"></view>
+          <text class="header-title">Pallet Barcode</text>
         </view>
-        <view class="square-content">
-          <view class="content-input">
+        <view class="card-body">
+          <view class="input-wrapper">
             <input
               v-model="barcode"
               type="text"
-              placeholder="鎵爜 / 杈撳叆"
-              maxlength="10"
+              placeholder="Scan Pallet Barcode"
+              maxlength="20"
               :focus="barcodeFocus"
-              @input="barcodeInput"
-              placeholder-style="line-height: 85rpx;"
+              @confirm="barcodeInput"
+              class="custom-input"
             />
-            <uni-icons type="closeempty" size="20" color="#dadada" @click="removeBarcode" />
-          </view>
-        </view>
-      </view>
-	  <!-- 搴撲綅鏉$爜 -->
-	  <view class="square-2">
-	    <view class="square-title">
-	      <view class="title-sign"><view class="sign"></view></view>
-	      <view class="title-text"><text>搴撲綅鏉$爜</text></view>
-	    </view>
-	    <view class="square-content">
-	      <view class="content-input">
-	        <input
-	          v-model="locNo"
-	          type="text"
-	          placeholder="鎵爜 / 杈撳叆"
-	          maxlength="7"
-	          :focus="locNoFocus"
-	          @input="locNoInput"
-	          placeholder-style="line-height: 85rpx;"
-	        />
-	        <uni-icons type="closeempty" size="20" color="#dadada" @click="removeLocNo" />
-	      </view>
-	    </view>
-	  </view>
-
-      <!-- 鍟嗗搧鏉$爜 -->
-      <view class="square-2">
-        <view class="square-title">
-          <view class="title-sign"><view class="sign"></view></view>
-          <view class="title-text"><text>鍟嗗搧鏉$爜</text></view>
-        </view>
-        <view class="square-content">
-          <view class="content-input">
-            <input
-              v-model="code"
-              type="text"
-              placeholder="鎵爜 / 杈撳叆"
-              :focus="codeFocus"
-              @input="codeInput"
-              placeholder-style="line-height: 85rpx;"
-            />
-            <uni-icons type="closeempty" size="20" color="#dadada" @click="removeCode" />
+            <view class="icon-scan" @click="barcodeInput">
+               <uni-icons type="scan" size="24" color="#007aff" />
+            </view>
           </view>
         </view>
       </view>
 
-      <!-- 鍟嗗搧鍒楄〃澶达紙鍚搷浣滐級 -->
-      <view class="square-1">
-        <view class="square-title">
-          <view class="title-sign"><view class="sign"></view></view>
-          <view class="title-text" style="width: 200rpx;"><text>鍟嗗搧鍒楄〃</text></view>
-
-          <view v-show="matList.length" class="lable">
-            <label class="label-btn" style="width: 170rpx;line-height: 95rpx;">
-              <checkbox :checked="check" @click="allChecked">{{ checkText }}</checkbox>
+      <!-- 2. Scanning Options -->
+      <view class="card-box">
+        <view class="card-header">
+          <text class="header-title">Carton Scanning Option</text>
+        </view>
+        <view class="card-body">
+          <radio-group @change="modeChange" class="radio-group-vertical">
+            <label class="radio-row">
+              <radio value="one" :checked="scanMode === 'one'" color="#007aff" style="transform:scale(0.8)" />
+              <text class="radio-label">One Label per Carton</text>
             </label>
-            <label class="label-btn"><text @click="reChecked">鍙嶉��</text></label>
-            <label><uni-icons type="trash" size="25" color="#a5a5a5" @click="removeSelected" /></label>
-          </view>
-        </view>
-      </view>
-
-      <view class="square-none" v-show="matList.length === 0">
-        <view class="v-show">鏆傛棤鏇村鏁版嵁...</view>
-      </view>
-
-      <!-- 鍒楄〃锛堜娇鐢� checkbox-group 缁熶竴绠$悊锛� -->
-      <checkbox-group @change="checkboxChanged">
-        <view
-          v-for="(item, index) in matList"
-          :key="item.id || index"
-          class="data-list bg-false"
-          :class="'bg-' + (item.checked ? 'true' : 'false')"
-        >
-          <label class="left-check-box">
-            <checkbox :value="(item.id + '')" :checked="item.checked" style="display:block;" />
-          </label>
-
-          <view class="data-list-left">
-            <view class="matnr">
-              <text style="width: 500rpx;">缂栫爜锛歿{ item.matnr }}</text>
-              <text style="margin-left: 100rpx;">鍚嶇О锛歿{ item.maktx }}</text>
-            </view>
-            <view>
-              <text style="width: 500rpx;">PO锛歿{ item.standby1 }}</text>
-              <text style="margin-left: 100rpx;">SKU锛歿{ item.standby3 }}</text>
-            </view>
-            <view><text style="width: 500rpx;">UPC锛歿{ item.standby2 }}</text></view>
-            <view>
-              <text style="width: 500rpx;">閲囪喘鍗曪細{{ item.boxType3 }}</text>
-              <text style="margin-left: 100rpx;">
-                鏁伴噺锛歿{ item.current }} / {{ item.maxAnfme }}
-              </text>
-            </view>
-          </view>
-
-          <view class="data-list-right">
-            <label>
-              <uni-icons type="compose" size="20" color="#a5a5a5" @click="openRevise(item, index)" />
+            <label class="radio-row">
+              <radio value="multi" :checked="scanMode === 'multi'" color="#007aff" style="transform:scale(0.8)" />
+              <text class="radio-label">Multiple Labels per Carton</text>
             </label>
+          </radio-group>
+        </view>
+      </view>
+
+      <!-- 3. Scan Carton Label -->
+      <view class="card-box">
+        <view class="card-header">
+          <view class="header-indicator"></view>
+          <text class="header-title">Scan Carton Label</text>
+        </view>
+        <view class="card-body">
+          <view class="input-row">
+            <view class="input-wrapper flex-1">
+              <input
+                v-model="code"
+                type="text"
+                placeholder="Scan Carton Label"
+                :focus="codeFocus"
+                @confirm="codeInput"
+                class="custom-input"
+              />
+            </view>
+            <button class="cu-btn bg-blue shadow-blur sm margin-left-sm" @click="codeInput">Add</button>
           </view>
         </view>
-      </checkbox-group>
+      </view>
+
+      <!-- 4. Zone Selection & Queue Action -->
+      <view class="card-box">
+        <view class="card-body">
+          <!-- Zone Selector -->
+          <view class="form-row">
+            <text class="form-label">Zone:</text>
+            <picker @change="zoneChange" :value="zoneIndex" :range="zoneList" range-key="areaId" class="flex-1">
+              <view class="picker-box">
+                <text class="picker-text">{{ zoneList[zoneIndex] ? zoneList[zoneIndex].areaId : 'Select Zone' }}</text>
+                <uni-icons type="arrowdown" size="14" color="#666"></uni-icons>
+              </view>
+            </picker>
+          </view>
+          
+          <!-- Add Queue Button (Full Width) -->
+          <button class="cu-btn bg-blue block margin-top-sm lg shadow" @click="addToQueue">
+            <text class="text-bold">ADD TO QUEUE</text>
+          </button>
+        </view>
+      </view>
+
+      <!-- 5. Data Tables -->
+      <view class="tables-section">
+        
+        <!-- Left Table: Current Scanned -->
+        <view class="card-box no-padding">
+          <view class="table-header-row">
+            <text class="th col-2">Carton Label</text>
+            <text class="th col-1 text-center">Qty</text>
+            <text class="th col-05 text-center">Op</text>
+          </view>
+          <view class="table-body-scroll">
+             <view v-for="(item, index) in matList" :key="index" class="table-row">
+               <text class="td col-2 text-cut">{{ item.barcode }}</text>
+               <text class="td col-1 text-center">{{ item.anfme }}</text>
+               <view class="td col-05 text-center">
+                 <uni-icons type="trash" size="18" color="#dd524d" @click="removeCurrentItem(index)" />
+               </view>
+             </view>
+             <view v-if="matList.length === 0" class="empty-state">No data</view>
+          </view>
+          <view class="table-footer-info">
+             <text>Total Quantity: <text class="text-blue text-bold">{{ totalQty }}</text></text>
+          </view>
+        </view>
+
+        <!-- Right Table: Queue List -->
+        <view class="card-box no-padding margin-top-sm">
+          <view class="card-header small-header">
+            <text class="header-title text-sm">Queue List</text>
+          </view>
+          <scroll-view scroll-y class="queue-list-scroll">
+            <view v-for="(qItem, qIndex) in queueList" :key="qIndex" class="queue-card">
+              <view class="queue-header">
+                <view class="flex align-center">
+                  <uni-icons type="box" size="16" color="#007aff" class="margin-right-xs"/>
+                  <text class="text-bold text-dark">{{ qItem.barcode }}</text>
+                </view>
+                <view class="flex align-center">
+                  <text class="cu-tag bg-cyan light sm margin-right-xs">{{ qItem.zoneName }}</text>
+                  <uni-icons type="closeempty" size="18" color="#999" @click="removeFromQueue(qIndex)" />
+                </view>
+              </view>
+              <view class="queue-content">
+                <view v-for="(cItem, cIndex) in qItem.cartons" :key="cIndex" class="queue-detail-row">
+				  <text class="text-grey">Label:{{ cItem.barcode }}</text>
+                  <text class="text-grey">ItemNo:{{ cItem.matnr }}</text>
+                  <text class="text-grey">x{{ cItem.anfme }}</text>
+                </view>
+              </view>
+            </view>
+            <view v-if="queueList.length === 0" class="empty-state">Queue is empty</view>
+          </scroll-view>
+        </view>
+
+      </view>
+
+      <view style="height: 140rpx;"></view>
     </scroll-view>
 
-    <!-- 搴曢儴鎿嶄綔 -->
-    <view class="footer flex justify-around">
-      <label class="label-btn flex justify-center align-center">
-        <button class="cu-btn" @click="resst">閲嶇疆</button>
-      </label>
-      <label class="label-btn flex justify-center align-center">
-        <button class="cu-btn bg-blue" @click="comb">缁勬墭</button>
-      </label>
+    <!-- Bottom Footer -->
+    <view class="footer-actions">
+      <button class="cu-btn bg-blue shadow-blur lg flex-1 margin-right-sm" @click="moveToASRS">MOVE TO ASRS</button>
+      <button class="cu-btn line-grey lg flex-1" @click="cancelAll">X CANCEL</button>
     </view>
-
-    <!-- 淇敼鏁伴噺寮圭獥 -->
-    <uni-popup ref="revise" background-color="#fff" @change="change">
-      <view class="revise-box">
-        <view class="revise-box-top">
-          <view class="color-block-blue"></view>
-          <text class="title">缁勬墭鏁伴噺</text>
-        </view>
-
-        <view class="text-box">
-          <text>鍙粍鏁伴噺锛歿{ enableQty }}</text>
-        </view>
-
-        <view class="changeBox flex justify-around">
-          <view class="num-box">
-            <uni-number-box v-model="count" :min="minCount" :max="maxCount" color="#747474" @change="changeValue" />
-          </view>
-        </view>
-
-        <view class="revise-box-buttom">
-          <view>
-            <button class="cu-btn bg-blue" @click="confirm">纭</button>
-          </view>
-        </view>
-      </view>
-    </uni-popup>
   </view>
 </template>
 
@@ -169,27 +163,38 @@
   data() {
     return {
       commonUrl: null,
+      
+      // Pallet
       barcode: "",
       barcodeFocus: true,
-      focus: false,
-      type: "center",
-      order: null,
-      matList: [], // 姣忎釜 item: { id, matnr, maktx, standby1, standby2, standby3, boxType3, current, maxAnfme, checked }
-      count: 0,
-      minCount: 0,
-      maxCount: 0,
-      rowNum: null,
-      enableQty: 0,
-      check: false,
-      checkText: "鍏ㄩ��",
-      orderNo: "",
-      orderNoList: [],
-      showDropdown: false,
+      
+      // Scan Mode
+      scanMode: "multi", // 'one' | 'multi'
+      
+      // Carton Input
       code: "",
-      codeFocus: true,
-	  locNo: "",
-	  locNoFocus: true,
+      codeFocus: false,
+      
+      // Zone
+      zoneList: [], 
+      zoneIndex: -1,
+      
+      // Current List (Left Table)
+      matList: [], // { matnr: string, qty: number }
+      
+      // Queue List (Right Table)
+      queueList: [], // { barcode: string, zoneId: string, zoneName: string, cartons: [] }
+      
+      // System
+      baseIP: "",
+      basePORT: "",
+      baseUrl: "",
     };
+  },
+  computed: {
+    totalQty() {
+      return this.matList.reduce((sum, item) => sum + (Number(item.qty) || 0), 0);
+    }
   },
   mounted() {
     const UIP = uni.getStorageSync("UIP");
@@ -199,637 +204,511 @@
     const PROJ = uni.getStorageSync("UPROJ");
     this.baseUrl = PROJ;
     this.getUrl();
+    
+    // Load Zones
+    this.getZoneList();
   },
   methods: {
-    // 鏋勫缓 base url
     getUrl() {
       this.commonUrl = this.baseHttp + this.baseIP + ":" + this.basePORT + "/" + this.baseUrl;
     },
 
-    /* -------------------------
-       鑾峰彇璁㈠崟鏄庣粏锛堟帴鍙h繑鍥� combMats锛�
-       鍒濆鍖栨瘡涓� item 鐨� current / maxAnfme / checked
-       ------------------------- */
-    getOrderDetlByOrderNo() {
-      if (!this.orderNo) {
-        uni.showToast({ title: "璇烽�夋嫨璁㈠崟", icon: "none" });
-        return;
-      }
-      const that = this;
+    // 1. Get Zone List
+    getZoneList() {
+      uni.showLoading({ title: "Loading Zones..." });
       uni.request({
-        url: that.commonUrl + "/mobile/order/search/orderNo/auth",
-        data: { orderNo: that.orderNo },
-        header: { token: uni.getStorageSync("token") },
-        success(result) {
-          const res = result.data;
-          if (res.code === 200 && res.data && res.data[0]) {
-            uni.showLoading();
-            // 鍘熷 combMats 鍙兘鍖呭惈 backend 鐨� anfme锛屼綔涓� max 浣跨敤
-            that.matList = (res.data[0].combMats || []).map(it => {
-              // 瑙勮寖瀛楁鍚嶏紙boxType3 / boxtype3锛�
-              it.boxType3 = it.boxType3 || it.boxtype3 || "";
-              return {
-                ...it,
-                maxAnfme: Number(it.anfme || 0), // 鍚庣鏈�澶у彲缁勬墭鏁伴噺
-                current: 0, // 褰撳墠宸茬粍鏁伴噺锛堝墠绔淮鎶わ級
-                checked: false,
-              };
-            });
-            that.initAnfme();
-            uni.hideLoading();
-          } else if (res.code == 403) {
-            uni.showToast({ title: res.msg, icon: "none", position: "top" });
-            setTimeout(() => uni.reLaunch({ url: "../login/login" }), 1000);
-          } else {
-            uni.showToast({ title: res.msg || "鑾峰彇澶辫触", icon: "none" });
-          }
-        },
-      });
-    },
-
-    // 鍒濆鍖栵細鎶婂悗绔殑 anfme 淇濆瓨涓� enableQty锛堟樉绀虹敤锛夛紝骞舵妸 current 缃� 0
-    initAnfme() {
-      for (let i = 0; i < this.matList.length; i++) {
-        this.matList[i].enableQty = this.matList[i].maxAnfme || 0;
-        // ensure current exists
-        if (typeof this.matList[i].current !== "number") this.matList[i].current = 0;
-        if (typeof this.matList[i].checked !== "boolean") this.matList[i].checked = false;
-      }
-      this.checkList();
-    },
-
-    /* -------------------------
-       鎵爜/杈撳叆閫昏緫
-       barcodeInput: 鎵樼洏鐮侊紙鏍¢獙闀垮害锛�
-       codeInput: 鍟嗗搧鐮侊紙瑙f瀽骞惰姹傛槑缁嗘帴鍙� / 鍚堝苟鍒� matList锛�
-       ------------------------- */
-    barcodeInput() {
-      const len = this.barcode.length;
-      if (len !== 6) {
-        // 6 浣嶆墭鐩樼爜瑙勫垯锛氳嫢闈� 6 浣嶅垯涓嶇粰浜堣繘涓�姝ュ鐞嗭紝浣嗕笉瑕侀绻佸脊妗嗭紝鍙湁鏄庣‘閿欒鏃跺脊
-        // 杩欓噷淇濇寔鍘熷垽瀹氶�昏緫锛氬鏋滈暱搴︿笉鏄� 6 鍒欐彁绀�
-        uni.showToast({ title: "鎵樼洏鐮佹湁璇閲嶈瘯", icon: "none", position: "top" });
-        this.barcodeFocuss();
-        return;
-      }
-      // 鑻ラ暱搴﹀悎瑙勶紝鍙仛鐒﹀埌鍟嗗搧杈撳叆
-      this.focuss();
-    },
-	locNoInput() {
-	  const len = this.locNo.length;
-	  if (len !== 7) {
-	    // 6 浣嶆墭鐩樼爜瑙勫垯锛氳嫢闈� 6 浣嶅垯涓嶇粰浜堣繘涓�姝ュ鐞嗭紝浣嗕笉瑕侀绻佸脊妗嗭紝鍙湁鏄庣‘閿欒鏃跺脊
-	    // 杩欓噷淇濇寔鍘熷垽瀹氶�昏緫锛氬鏋滈暱搴︿笉鏄� 6 鍒欐彁绀�
-	    uni.showToast({ title: "搴撲綅鏈夎璇烽噸璇�", icon: "none", position: "top" });
-	    this.locNoFocuss();
-	    return;
-	  }
-	  // 鑻ラ暱搴﹀悎瑙勶紝鍙仛鐒﹀埌鍟嗗搧杈撳叆
-	  this.focuss();
-	},
-
-	codeInput() {
-	  const that = this;
-	  const m = (that.code || "").split(";");
-	  if (!m[1] || !m[5] || !m[7] || !m[9]) {
-		  uni.showToast({ title: "鏉$爜鏈夎", icon: "none", position: "top" });
-		  this.codeFocuss();
-		  return;
-		}
-	  const supplier = m[10] === "supplier" ? m[11] : "1";
-
-		uni.request({
-		url: that.commonUrl + "/mobile/order/search/orderDetl/auth",
-		method: "POST",
-		header: { token: uni.getStorageSync("token") },
-		data: JSON.stringify({
-		orderNo: m[1],
-		sku: m[5],
-		item: m[7],
-		upc: m[9],
-		supplier: supplier, // 鉁� 姘歌繙鏈夊��
-		}),
-		method: "POST",
-		header: { token: uni.getStorageSync("token") },
-		success(result) {
-		  const res = result.data;
-		  if (res.code === 200 && res.data && Array.isArray(res.data.combMats)) {
-			
-			const firstBoxType = that.matList[0]?.boxType3; // 绗竴涓墿鏂欑殑 boxType3
-			let inconsistent = false;
-
-			res.data.combMats.forEach(serverItem => {
-			  serverItem.boxType3 = serverItem.boxType3 || serverItem.boxtype3 || "";
-
-			  // 鉂� 妫�鏌� boxType3 鏄惁涓�鑷�
-			  if (firstBoxType && serverItem.boxType3 !== firstBoxType) {
-				inconsistent = true;
-				return;
-			  }
-
-			  const max = Number(serverItem.anfme || 0);
-			  if (max <= 0) {
-				uni.showToast({ title: "褰撳墠鐗╂枡鍗曟嵁鏃犳暟鎹�", icon: "none" });
-				return;
-			  }
-
-			  const existItem = that.matList.find(
-				m =>
-				  m.matnr === serverItem.matnr &&
-				  (m.standby2 || "") === (serverItem.standby2 || "") &&
-				  (m.standby3 || "") === (serverItem.standby3 || "") &&
-				  (m.boxType3 || "") === (serverItem.boxType3 || "")
-			  );
-
-			  if (existItem) {
-				existItem.current = Math.min(existItem.current + 1, existItem.maxAnfme);
-			  } else {
-				that.matList.push({
-				  ...serverItem,
-				  maxAnfme: max,
-				  current: 1,
-				  checked: false,
-				});
-			  }
-			});
-
-			if (inconsistent) {
-			  uni.showToast({ title: "鍗曟嵁涓嶄竴鑷达紝璇锋鏌�", icon: "none", position: "top" });
-			  that.codeFocuss();
-			  return;
-			}
-
-			that.codeFocuss();
-			that.checkList();
-		  } else if (res.code == 403) {
-			uni.showToast({ title: res.msg, icon: "none", position: "top" });
-			setTimeout(() => uni.reLaunch({ url: "../login/login" }), 1000);
-		  } else {
-			uni.showToast({ title: res.msg || "鑾峰彇鏉$爜鍟嗗搧澶辫触", icon: "none" });
-		  }
-		},
-		fail() {
-		  uni.showToast({ title: "璇锋眰澶辫触", icon: "none" });
-		},
-	  });
-	},
-
-
-    // 澶辩劍 / 閲嶇疆鐒︾偣鐨勬柟娉�
-    codeFocuss() {
-      this.codeFocus = false;
-      setTimeout(() => {
-        this.code = "";
-        this.codeFocus = true;
-      }, 100);
-    },
-	locNoFocuss() {
-	  this.locNoFocus = false;
-	  setTimeout(() => {
-	    this.locNo = "";
-	    this.locNoFocus = true;
-	  }, 100);
-	},
-    barcodeFocuss() {
-      this.barcodeFocus = false;
-      setTimeout(() => {
-        this.barcode = "";
-        this.barcodeFocus = true;
-      }, 100);
-    },
-    focuss() {
-      this.focus = false;
-      setTimeout(() => {
-        this.matnrId = "";
-        this.focus = true;
-      }, 100);
-    },
-
-    /* -------------------------
-       缂栬緫鏁伴噺寮圭獥锛堟墦寮�/纭锛�
-       ------------------------- */
-    openRevise(item, index) {
-      // 鏇存柊 maxCount / enableQty / count
-      this.rowNum = index;
-      this.enableQty = item.maxAnfme || 0;
-      this.minCount = 0;
-      this.maxCount = item.maxAnfme || 0;
-      this.count = item.current || 0;
-      this.$refs.revise.open();
-    },
-
-    confirm() {
-      // 闄愬埗鑼冨洿鐒跺悗鍐欏洖 matList
-      const idx = this.rowNum;
-      if (idx == null || !this.matList[idx]) {
-        this.$refs.revise.close();
-        return;
-      }
-      let v = Number(this.count) || 0;
-      v = Math.max(0, Math.min(v, this.matList[idx].maxAnfme || 0));
-      this.matList[idx].current = v;
-      this.$refs.revise.close();
-    },
-
-    changeValue() {
-      // 鍙湪杩欓噷娣诲姞瀹炴椂鏍¢獙锛堝綋鍓嶄娇鐢� uni-number-box 鑷甫 min/max锛�
-    },
-
-    /* -------------------------
-       缁勬墭锛堟彁浜わ級
-       ------------------------- */
-    comb() {
-      uni.vibrateShort();
-      const that = this;
-
-      if (!that.barcode) {
-        uni.showToast({ title: "璇锋壂鎻忔墭鐩樻潯鐮�", icon: "none", position: "top" });
-        return;
-      }
-	  if (!that.locNo) {
-	    uni.showToast({ title: "璇锋壂鎻忓簱浣嶆潯鐮�", icon: "none", position: "top" });
-	    return;
-	  }
-      if (that.barcode.length !== 6) {
-        uni.showToast({ title: "鎵樼洏鐮佸繀椤讳负6浣�", icon: "none", position: "top" });
-        return;
-      }
-      if (!that.matList.length) {
-        uni.showToast({ title: "璇锋坊鍔犲晢鍝佸垪琛�", icon: "none", position: "top" });
-        return;
-      }
-
-      // 鍙彇 current > 0 鐨勬潯鐩紝骞舵槧灏勪负鍚庣闇�瑕佺殑瀛楁锛堟敞鎰忚繖閲屼粛浣跨敤鍚庣鏈熸湜瀛楁鍚� anfme锛�
-      const validMats = that.matList
-        .filter(item => Number(item.current || 0) > 0)
-        .map(item => {
-          return {
-            ...item,
-            anfme: Number(item.current || 0),
-          };
-        });
-
-      if (!validMats.length) {
-        uni.showToast({ title: "鎵�鏈夊晢鍝佺粍鎵樻暟閲忎负0锛屾棤娉曠粍鎵�", icon: "none", position: "top" });
-        return;
-      }
-
-      // 鏇存柊鐣岄潰鍒楄〃涓轰粎鍓╂湁鏁堟潯鐩紙鍒犻櫎鏁伴噺涓�0鐨勶級
-      that.matList = that.matList.filter(item => Number(item.current || 0) > 0);
-
-      uni.showLoading();
-      uni.request({
-        url: that.commonUrl + "/mobile/comb/agv/auth",
-        data: JSON.stringify({
-          billNo: that.orderNo,
-          orderNo: that.orderNo,
-          barcode: that.barcode,
-		  locNo: that.locNo,
-          combMats: validMats,
-        }),
+        url: this.commonUrl + "/area/list/auth",
         method: "POST",
+        data: {
+        },
         header: { token: uni.getStorageSync("token") },
-        success(result) {
+        success: res => {
           uni.hideLoading();
-          const res = result.data;
-          if (res.code === 200) {
-            uni.showToast({ title: res.msg, position: "top", duration: 1000 });
-            that.resst();
-          } else if (res.code == 403) {
-            uni.showToast({ title: res.msg, icon: "none", position: "top" });
-            setTimeout(() => uni.reLaunch({ url: "../login/login" }), 1000);
+          const r = res.data;
+          if (r.code === 200) {
+            this.zoneList = (r.data && r.data.records) ? r.data.records : [];
+            // Default select first if available
+            if (this.zoneList.length > 0) {
+              this.zoneIndex = 0;
+            }
+          } else if (r.code === 403) {
+            uni.showToast({ title: r.msg || "Re-login required", icon: "none" });
+            setTimeout(() => {
+              uni.reLaunch({ url: "/pages/login/login" });
+            }, 1000);
           } else {
-            uni.showToast({ title: res.msg || "缁勬墭澶辫触", icon: "none" });
+            uni.showToast({ title: r.msg || "Fetch failed", icon: "none" });
           }
         },
         fail() {
           uni.hideLoading();
-          uni.showToast({ title: "璇锋眰澶辫触", icon: "none" });
+          uni.showToast({ title: "Request failed", icon: "none" });
         },
       });
     },
 
-    /* -------------------------
-       鍒犻櫎宸查�� / 閲嶇疆
-       ------------------------- */
-    removeSelected() {
-      this.matList = this.matList.filter(item => !item.checked);
-      this.checkList();
-      uni.vibrateShort();
+    // 2. Zone Change
+    zoneChange(e) {
+      this.zoneIndex = e.detail.value;
     },
 
-    resst() {
-      this.matList = [];
-      this.barcode = "";
-	  this.locNo = ""
-      this.order = "";
-      this.orderNo = "";
-      this.barcodeFocuss();
-      uni.vibrateShort();
-      this.checkList();
+    // 3. Mode Change
+    modeChange(e) {
+      this.scanMode = e.detail.value;
+      // If switching to 'one' and we have > 1 items, warn or clear?
+      // Requirement says: "One label per carton... only allows one data"
+      if (this.scanMode === 'one' && this.matList.length > 1) {
+        uni.showToast({ title: "Switched to One Label mode. Clearing extra items.", icon: "none" });
+        this.matList = [this.matList[0]];
+      }
     },
 
-    /* -------------------------
-       checkbox 鐩稿叧锛堢粺涓�绠$悊锛歝heckbox-group -> change锛�
-       ------------------------- */
-    checkboxChanged(e) {
-      const values = e.detail.value || [];
-      this.matList.forEach(item => {
-        item.checked = values.includes(item.id + "");
+    // 4. Pallet Barcode Input
+    barcodeInput() {
+      if (!this.barcode) return;
+      // Validate if needed
+      this.barcodeFocus = false;
+      this.$nextTick(() => {
+        this.codeFocus = true; // Jump to carton scan
       });
-      this.checkList();
-      uni.vibrateShort();
     },
 
-    // 鍙嶉��
-    reChecked() {
-      if (!this.matList.length) return;
-      this.matList.forEach(item => {
-        item.checked = !item.checked;
-      });
-      this.checkList();
-      uni.vibrateShort();
-    },
-
-    // 鍏ㄩ�� / 鍙栨秷鍏ㄩ��
-    allChecked() {
-      this.check = !this.check;
-      this.matList.forEach(item => (item.checked = this.check));
-      this.checkText = this.check ? "鍙栨秷鍏ㄩ��" : "鍏ㄩ��";
-      uni.vibrateShort();
-    },
-
-    // 鏇存柊椤甸潰椤堕儴鍏ㄩ�夋枃妗堢姸鎬�
-    checkList() {
-      if (!this.matList.length) {
-        this.check = false;
-        this.checkText = "鍏ㄩ��";
+    // 5. Carton Code Input
+    codeInput() {
+      if (!this.code) {
+        this.codeFocus = false;
+        this.$nextTick(() => this.codeFocus = true);
         return;
       }
-      const all = this.matList.every(item => item.checked);
-      this.check = all;
-      this.checkText = all ? "鍙栨秷鍏ㄩ��" : "鍏ㄩ��";
-    },
 
-    /* -------------------------
-       鏍规嵁杈撳叆鏌ヨ鍗曞缓璁紙鏈敼鍔級
-       ------------------------- */
-    getOrderDet(orderNo) {
-      if (!orderNo || orderNo.trim() === "") return;
+      // Check Mode Constraints
+      if (this.scanMode === 'one') {
+        if (this.matList.length >= 1) {
+          uni.showToast({ title: "One Label Mode: Only 1 carton allowed per pallet.", icon: "none" });
+          this.code = "";
+          this.codeFocus = false;
+          this.$nextTick(() => this.codeFocus = true);
+          return;
+        }
+      }
+
+      if (this.queueList.some(q => q.barcode === this.barcode)) {
+        uni.showToast({ title: "Pallet Barcode has been in queue", icon: "none" });
+        this.code = "";
+        this.codeFocus = false;
+        this.$nextTick(() => this.codeFocus = true);
+        return;
+      }
+
+      const cartonLabel = this.code;
+       if (this.queueList.some(q => (q.cartons || []).some(c => c.barcode === cartonLabel))) {
+         uni.showToast({ title: "Label has been in queue", icon: "none" });
+         this.code = "";
+         this.codeFocus = false;
+         this.$nextTick(() => this.codeFocus = true);
+         return;
+       }
+      uni.showLoading({ title: "Scanning..." });
+
       uni.request({
-        url: this.commonUrl + "/mobile/order/search/orderNoList/auth",
-        method: "GET",
-        data: { orderNo },
-        header: { token: uni.getStorageSync("token") },
-        success: res => {
-          const list = res.data.data || [];
-          this.orderNoList = list.map(o => o.orderNo);
+        url: this.commonUrl + "/mobile/cartonScan/auth",
+        method: "POST",
+        data: {
+            cartonLabel: cartonLabel
         },
-      });
-    },
-
-    onOrderSelect(order) {
-      this.orderNo = order;
-    },
-
-    findOrder() {
-      if (!this.order) return;
-      const that = this;
-      uni.request({
-        url: that.commonUrl + "/mobile/order/search/orderNo/auth",
-        data: { orderNo: that.order },
         header: { token: uni.getStorageSync("token") },
-        success(result) {
-          const res = result.data;
-          if (res.code === 200 && res.data && res.data[0]) {
-            uni.showLoading();
-            that.matList = (res.data[0].combMats || []).map(it => {
-              it.boxType3 = it.boxType3 || it.boxtype3 || "";
-              return {
-                ...it,
-                maxAnfme: Number(it.anfme || 0),
-                current: 0,
-                checked: false,
-              };
-            });
-            that.orderNo = that.order;
-            that.initAnfme();
+        success: (res) => {
             uni.hideLoading();
-          } else if (res.code == 403) {
-            uni.showToast({ title: res.msg, icon: "none", position: "top" });
-            setTimeout(() => uni.reLaunch({ url: "../login/login" }), 1000);
-          } else {
-            uni.showToast({ title: res.msg || "鏌ユ棤鏁版嵁", icon: "none" });
-          }
+            const r = res.data;
+            if (r.code === 200) {
+                const data = r.data || {};
+                const newItem = {
+                    matnr: data.matnr || data.cartonLabel || cartonLabel,
+					barcode: data.barcode || cartonLabel,
+					cartonLabel:data.barcode || cartonLabel,
+                    anfme: data.anfme || 0,
+                    orderNo: data.orderNo, // Store orderNo from API
+                    ...data // Store other fields
+                };
+                
+                // Check if exists in current list
+                const exist = this.matList.find(m => m.barcode === newItem.barcode);
+                if (exist) {
+                    exist.anfme = newItem.anfme;
+                } else {
+                    this.matList.push(newItem);
+                }
+                
+                uni.vibrateShort();
+            } else if (r.code === 403) {
+                uni.showToast({ title: r.msg || "Re-login required", icon: "none" });
+                setTimeout(() => {
+                    uni.reLaunch({ url: "/pages/login/login" });
+                }, 1000);
+            } else {
+                uni.showToast({ title: r.msg || "Scan failed", icon: "none" });
+            }
+            
+            // Clear and Refocus
+            this.code = "";
+            this.codeFocus = false;
+            this.$nextTick(() => this.codeFocus = true);
         },
+        fail: () => {
+            uni.hideLoading();
+            uni.showToast({ title: "Request failed", icon: "none" });
+            this.code = "";
+            this.codeFocus = false;
+            this.$nextTick(() => this.codeFocus = true);
+        }
+      });
+    },
+    
+    removeCurrentItem(index) {
+        this.matList.splice(index, 1);
+    },
+
+    // 6. Add to Queue
+    addToQueue() {
+      if (!this.barcode) {
+        uni.showToast({ title: "Please scan Pallet Barcode", icon: "none" });
+        return;
+      }
+      if (this.matList.length === 0) {
+        uni.showToast({ title: "Please scan Carton Labels", icon: "none" });
+        return;
+      }
+      if (this.zoneIndex < 0 || !this.zoneList[this.zoneIndex]) {
+        uni.showToast({ title: "Please select a Zone", icon: "none" });
+        return;
+      }
+
+      const zone = this.zoneList[this.zoneIndex];
+
+      // Extract orderNo from first carton if available (assuming same order per pallet or taking first)
+      const firstCarton = this.matList[0] || {};
+      const orderNo = firstCarton.orderNo || "";
+
+      this.queueList.push({
+        barcode: this.barcode,
+        zoneId: zone.id, // Submit ID
+        zoneName: zone.areaId, // Display areaId
+        orderNo: orderNo, // Add orderNo
+        cartons: JSON.parse(JSON.stringify(this.matList)) // Deep copy
+      });
+
+      // Clear Inputs
+      this.barcode = "";
+      this.matList = [];
+      this.barcodeFocus = true; // Focus back to pallet
+      
+      uni.showToast({ title: "Added to Queue", icon: "success" });
+    },
+
+    removeFromQueue(index) {
+      this.queueList.splice(index, 1);
+    },
+
+    // 7. Move to ASRS (Submit)
+    moveToASRS() {
+      if (this.queueList.length === 0) {
+        uni.showToast({ title: "Queue is empty", icon: "none" });
+        return;
+      }
+
+      const that = this;
+      uni.showLoading({ title: "Submitting..." });
+
+      // Submit to API
+      uni.request({
+        url: that.commonUrl + "/mobile/cartonComb/auth",
+        method: "POST",
+        data: that.queueList,
+        header: { 
+            token: uni.getStorageSync("token"),
+            'content-type': 'application/json' 
+        },
+        success: (res) => {
+            uni.hideLoading();
+            const r = res.data;
+            if (r.code === 200) {
+                uni.showToast({ title: "Moved to ASRS Successfully", icon: "success" });
+                that.queueList = []; // Clear Queue
+                that.cancelAll(); // Reset form
+            } else if (r.code === 403) {
+                uni.showToast({ title: r.msg || "Re-login required", icon: "none" });
+                setTimeout(() => {
+                    uni.reLaunch({ url: "/pages/login/login" });
+                }, 1000);
+            } else {
+                uni.showToast({ title: r.msg || "Submission failed", icon: "none" });
+            }
+        },
+        fail: () => {
+            uni.hideLoading();
+            uni.showToast({ title: "Network request failed", icon: "none" });
+        }
       });
     },
 
-    // 绉婚櫎 code / barcode 绛夊皬宸ュ叿
-    removeBarcode() {
-      this.barcode = "";
-      uni.vibrateShort();
-      this.barcodeFocus = false;
-      this.$nextTick(() => (this.barcodeFocus = true));
-    },
-	removeLocNo() {
-	  this.locNo = "";
-	  uni.vibrateShort();
-	  this.locNoFocus = false;
-	  this.$nextTick(() => (this.locNoFocus = true));
-	},
-    removeCode() {
-      this.code = "";
-      uni.vibrateShort();
-      this.codeFocus = false;
-      this.$nextTick(() => (this.codeFocus = true));
-    },
-  },
+    // 8. Cancel
+    cancelAll() {
+        this.barcode = "";
+        this.matList = [];
+        this.queueList = []; // User said "Cancel ... clear queue list"
+        this.code = "";
+        this.scanMode = "multi"; // Reset default?
+        this.barcodeFocus = true;
+    }
+  }
 };
 </script>
 
-<style>
-/* 浣犵殑鏍峰紡鎴戜繚鐣欏苟鍋氬皬骞呮竻鐞� */
-.square-1 .lable {
-  display: inline-block;
-  float: right;
+<style scoped>
+.page-container {
+  background-color: #f1f1f1;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+}
+
+.page-scroll {
+  flex: 1;
+  padding: 20rpx;
+  box-sizing: border-box;
+}
+
+/* Card Styling */
+.card-box {
+  background-color: #ffffff;
+  border-radius: 12rpx;
+  margin-bottom: 20rpx;
+  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.03);
+  overflow: hidden;
+}
+
+.card-header {
+  padding: 20rpx;
+  border-bottom: 1rpx solid #f0f0f0;
+  display: flex;
+  align-items: center;
+}
+
+.header-indicator {
+  width: 8rpx;
+  height: 28rpx;
+  background-color: #007aff;
+  border-radius: 4rpx;
+  margin-right: 16rpx;
+}
+
+.header-title {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #333;
+}
+
+.small-header {
+  padding: 15rpx 20rpx;
+  background-color: #fafafa;
+}
+
+.card-body {
+  padding: 20rpx;
+}
+
+/* Inputs */
+.input-wrapper {
+  background-color: #f5f7fa;
+  border-radius: 8rpx;
+  padding: 0 20rpx;
+  height: 80rpx;
+  display: flex;
+  align-items: center;
+  border: 1rpx solid #e0e0e0;
+}
+
+.custom-input {
+  flex: 1;
   height: 100%;
-  width: 400rpx;
+  font-size: 28rpx;
+  color: #333;
 }
-.square-1 .lable label {
-  display: inline-block;
-  float: left;
-  height: 100%;
-  width: 90rpx;
-  line-height: 100rpx;
-}
-.pak-seach-box {
-  background-color: #FFFFFF;
-  margin: 15rpx 15rpx 0rpx 15rpx;
-  width: 96%;
-  height: 150rpx;
-  border-radius: 20rpx;
-}
-.box-top {
-  display: block;
-  height: 60rpx;
-  width: 720rpx;
-}
-.color-block-blue {
-  background-color: #1E9FFF;
-  display: inline-block;
-  float: left;
-  margin: 15rpx 15rpx 0 15rpx;
-  width: 12rpx;
-  height: 40rpx;
-  border: 5rpx solid #1E9FFF;
-  border-radius: 20rpx;
-}
-.title {
-  display: inline-block;
-  float: left;
-  font-size: 34rpx;
-  font-weight: 700;
-  height: 50rpx;
-  line-height: 50rpx;
-  margin-top: 10rpx;
-}
-.box-buttom {
-  display: inline-block;
-  background-color: #ededed;
-  width: 96%;
-  height: 60rpx;
-  border-radius: 20rpx;
-  margin: 15rpx 15rpx 0rpx 15rpx;
-}
-.box-buttom input {
-  width: 75%;
-  float: left;
-  margin: 8rpx 10rpx 0rpx 25rpx;
-}
-.box-buttom .search-icon {
-  width: 60rpx;
-  height: 60rpx;
-  float: right;
-  margin-top: 5rpx;
-  margin-right: 10rpx;
-}
-.pak-seach-box button {
-  background-color: #1E9FFF;
-  color: #ffffff;
-  display: inline-block;
-  float: right;
-  width: 150rpx;
-  height: 60rpx;
-  margin: 15rpx 15rpx 0rpx 15rpx;
-  line-height: 60rpx;
-}
-.pakin-btn {
-  background-color: #1E9FFF;
-}
-.pak-data-box {
-  background-color: #F1F1F1;
-  margin: 15rpx 15rpx 0rpx 15rpx;
-  width: 96%;
-  height: 70rpx;
-  border-radius: 20rpx;
-}
-.pak-data-box .box-top {
-  background-color: #FFFFFF;
-  height: 70rpx;
-  border-radius: 20rpx 20rpx 20rpx 20rpx;
-}
-.bg-false {
-  background-color: #FFFFFF;
-}
-.bg-true {
-  background-color: #ebebeb;
-}
-.data-list {
-  border-bottom: 1px solid #d8d8d8;
-  height: 180rpx;
-  margin: 15rpx;
-  border-radius: 20rpx;
-}
-.data-list:first-child {
-  margin-top: 20rpx;
-}
-.data-list:last-child {
-  margin-bottom: 160rpx;
-}
-.left-check-box {
-  display: inline-block;
-  float: left;
-  height: 100%;
-  width: 100rpx;
-  text-align: center;
-  line-height: 170rpx;
-}
-.data-list-left {
-  display: inline-block;
-  float: left;
-  height: 180rpx;
-  width: 500rpx;
-  color: #676767;
-}
-.matnr {
-  padding-top: 10rpx;
-}
-.data-list-right {
-  display: inline-block;
-  float: right;
-  width: 100rpx;
-  height: 180rpx;
-  line-height: 180rpx;
-}
-.data-list-right label {
-  display: inline-block;
-  float: left;
-  width: 100rpx;
-  height: 180rpx;
-}
-.revise-box {
-  width: 500rpx;
-  height: 500rpx;
-}
-.revise-box-top {
-  width: 100%;
-  height: 100rpx;
-  background-color: #fff;
+
+.icon-scan {
   padding: 10rpx;
 }
-.changeBox {
-  width: 100%;
-  height: 100rpx;
-  line-height: 120rpx;
+
+.input-row {
+  display: flex;
+  align-items: center;
+}
+
+/* Radio Group */
+.radio-group-vertical {
+  display: flex;
+  flex-direction: column;
+}
+
+.radio-row {
+  display: flex;
+  align-items: center;
+  padding: 10rpx 0;
+}
+
+.radio-label {
+  font-size: 28rpx;
+  margin-left: 10rpx;
+  color: #333;
+}
+
+/* Zone & Form */
+.form-row {
+  display: flex;
+  align-items: center;
+}
+
+.form-label {
+  font-weight: bold;
+  font-size: 28rpx;
+  margin-right: 20rpx;
+  color: #333;
+}
+
+.picker-box {
+  background-color: #f5f7fa;
+  border: 1rpx solid #e0e0e0;
+  border-radius: 8rpx;
+  height: 70rpx;
+  padding: 0 20rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.picker-text {
+  font-size: 28rpx;
+  color: #333;
+}
+
+/* Tables */
+.tables-section {
+  display: flex;
+  flex-direction: column;
+}
+
+.no-padding {
+  padding: 0;
+}
+
+.table-header-row {
+  display: flex;
+  background-color: #f0f2f5;
+  padding: 15rpx 20rpx;
+  font-weight: bold;
+  font-size: 26rpx;
+  color: #666;
+}
+
+.table-body-scroll {
+  max-height: 300rpx;
+  overflow-y: auto;
+}
+
+.table-row {
+  display: flex;
+  padding: 20rpx;
+  border-bottom: 1rpx solid #eee;
+  align-items: center;
+  font-size: 26rpx;
+}
+
+.col-2 { flex: 2; }
+.col-1 { flex: 1; }
+.col-05 { flex: 0.5; }
+
+.text-center { text-align: center; }
+.text-cut { 
+  overflow: hidden; 
+  white-space: nowrap; 
+  text-overflow: ellipsis; 
+}
+
+.empty-state {
+  padding: 40rpx;
   text-align: center;
-  background-color: #FFF;
-  margin-top: 20rpx;
-  border-bottom: 1px solid #e3e3e3;
+  color: #999;
+  font-size: 26rpx;
 }
-.text-box {
-  width: 100%;
-  height: 100rpx;
-  line-height: 120rpx;
-  text-align: center;
-  background-color: #FFF;
-  margin-top: 20rpx;
-  border-bottom: 1px solid #e3e3e3;
+
+.table-footer-info {
+  padding: 15rpx 20rpx;
+  text-align: right;
+  font-size: 26rpx;
+  background-color: #fff;
+  border-top: 1rpx solid #f0f0f0;
 }
-.changeBox .num-box {
-  display: inline-block;
-  float: left;
+
+/* Queue List */
+.queue-list-scroll {
+  max-height: 400rpx;
+  padding: 10rpx;
+  background-color: #f8faff;
 }
-.changeBox button {
-  float: left;
+
+.queue-card {
+  background-color: #fff;
+  border: 1rpx solid #eee;
+  border-radius: 8rpx;
+  margin-bottom: 10rpx;
+  overflow: hidden;
 }
-.revise-box-buttom {
-  position: absolute;
-  width: 100%;
-  height: 100rpx;
-  line-height: 100rpx;
-  background-color: #FFFFFF;
+
+.queue-header {
+  padding: 15rpx;
+  background-color: #eef6ff;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 26rpx;
+}
+
+.queue-content {
+  padding: 10rpx 15rpx;
+}
+
+.queue-detail-row {
+  display: flex;
+  justify-content: space-between;
+  font-size: 24rpx;
+  padding: 5rpx 0;
+}
+
+/* Footer Actions */
+.footer-actions {
+  position: fixed;
   bottom: 0;
-  text-align: center;
+  left: 0;
+  right: 0;
+  height: 120rpx;
+  background-color: #fff;
+  display: flex;
+  align-items: center;
+  padding: 0 20rpx;
+  box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05);
+  z-index: 99;
 }
+
+/* Utilities */
+.flex-1 { flex: 1; }
+.margin-top-sm { margin-top: 20rpx; }
+.margin-left-sm { margin-left: 20rpx; }
+.margin-right-sm { margin-right: 20rpx; }
+.margin-right-xs { margin-right: 10rpx; }
+.text-bold { font-weight: bold; }
+.text-blue { color: #007aff; }
+.text-dark { color: #333; }
+.text-grey { color: #888; }
+.text-sm { font-size: 24rpx; }
+
 </style>

--
Gitblit v1.9.1