From c4d89e32e105c9618e18618d97442b30b68c5f77 Mon Sep 17 00:00:00 2001
From: 647556386 <647556386@qq.com>
Date: 星期日, 30 十一月 2025 09:56:39 +0800
Subject: [PATCH] 虚拟出入库功能

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs |   31 +
 项目代码/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js                                     |  705 +++++++++++++-------------
 项目代码/WIDESEA_WMSClient/package.json                                                                |    1 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs                   |  212 ++++++++
 项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue                            |    7 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs                 |   20 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs             |    4 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/NoStockOutModel.cs                    |   46 +
 项目代码/WIDESEA_WMSClient/config/buttons.js                                                           |   10 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrderDetail.cs               |    5 
 项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/NoStockOut.vue                                |  512 ++++++++++++++----
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj              |    1 
 12 files changed, 1,069 insertions(+), 485 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/config/buttons.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/config/buttons.js"
index 67c05e7..11b7c6b 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/config/buttons.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/config/buttons.js"
@@ -180,6 +180,16 @@
     onClick: function () {
     }
 },
+
+{
+    name: "铏氭嫙鍑哄叆搴�",
+    icon: 'el-icon-setting',
+    class: '',
+    value: 'NoStockOut',
+    type: 'success',
+    onClick: function () {
+    }
+},
 ]
 
 export default buttons
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/package.json" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/package.json"
index e81efa4..d729177 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/package.json"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/package.json"
@@ -16,6 +16,7 @@
     "core-js": "^3.6.5",
     "echarts": "^5.0.2",
     "element-plus": "^2.2.14",
+    "element-ui": "^2.15.14",
     "jsbarcode": "^3.11.6",
     "less": "^4.1.1",
     "qrcode": "^1.5.4",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/NoStockOut.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/NoStockOut.vue"
index 252da58..d058411 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/NoStockOut.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/NoStockOut.vue"
@@ -5,29 +5,85 @@
       :lazy="true"
       width="65%"
       :padding="20"
-      title="鏃犲簱瀛樺嚭搴�"
+      title="铏氭嫙鍑哄叆搴�"
       class="custom-vol-box"
     >
       <div>
+        <!-- 鍗曟嵁閫夋嫨鍖哄煙锛堝彲杈撳叆鎼滅储锛� -->
+        <el-form :inline="true" :model="orderForm" style="margin-bottom: 20px; align-items: flex-end;">
+          <el-form-item label="鍑哄簱鍗曟嵁:" name="outboundOrderId">
+            <el-select
+              v-model="orderForm.outboundOrderId"
+              placeholder="璇烽�夋嫨鎴栨壂鎻忓嚭搴撳崟鎹彿"
+              clearable
+              style="width: 220px; margin-right: 10px;"
+              @change="handleOrderChange"
+              @visible-change="handleOutboundVisibleChange"
+              :loading="loading"
+              filterable
+              :filter-method="filterOutboundOrders"
+              @input="handleOutboundScanInput"  
+              ref="outboundSelectRef"        
+            >
+              <el-option
+                v-for="order in filteredOutboundOrders"
+                :key="order.id"
+                :label="order.orderNo"
+                :value="order.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="閲囪喘鍗曟嵁:" name="purchaseOrderId">
+            <el-select
+              v-model="orderForm.purchaseOrderId"
+              placeholder="璇烽�夋嫨鎴栨壂鎻忛噰璐崟鎹彿"
+              clearable
+              style="width: 220px; margin-right: 10px;"
+              @change="handleOrderChange"
+              @visible-change="handlePurchaseVisibleChange"
+              :loading="loading"
+              filterable
+              :filter-method="filterPurchaseOrders"
+              @input="handlePurchaseScanInput" 
+              ref="purchaseSelectRef"
+            >
+              <el-option
+                v-for="order in filteredPurchaseOrders"
+                :key="order.id"
+                :label="order.orderNo"
+                :value="order.id"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+        </el-form>
+
         <!-- 涓婃柟杈撳叆妗� -->
-        <el-form :inline="true" :model="formData" ref="formData" style="margin-bottom: 20px; align-items: flex-end;">
+        <el-form :inline="true" :model="formData" ref="formRef" style="margin-bottom: 20px; align-items: flex-end;">
           <el-form-item
             label="鎵弿鏉$爜:"
             style="width: 80%"
-            prop="barcode"
+            name="barcode"
+            :rules="[{ required: true, message: '璇锋壂鎻忔垨杈撳叆鏉$爜', trigger: 'blur' }]"
           >
             <el-input
-              ref="barcodeInput"
+              ref="barcodeInputRef"
               v-model="formData.barcode"
               placeholder="璇蜂娇鐢ㄦ壂鐮佹灙鎵弿鏉$爜锛屾垨鎵嬪姩杈撳叆"
               @keyup.enter="handleScan"
               autofocus
               class="custom-input"
+              :disabled="!orderForm.outboundOrderId || !orderForm.purchaseOrderId"
             ></el-input>
           </el-form-item>
           <el-form-item>
-            <el-button type="primary" size="small" @click="handleScan" class="custom-button">
-              <i class="el-icon-search"></i> 纭鎵弿
+            <el-button 
+              type="primary" 
+              size="small" 
+              @click="handleScan" 
+              class="custom-button"
+              :disabled="!orderForm.outboundOrderId || !orderForm.purchaseOrderId || loading"
+            >
+              <Search /> 纭鎵弿
             </el-button>
           </el-form-item>
         </el-form>
@@ -37,27 +93,23 @@
           <el-card shadow="hover" style="margin-bottom: 10px; border: none;" class="custom-card">
             <div class="card-header">
               <span class="header-title">宸叉壂鎻忔潯鐮佸垪琛紙鍏眥{ scannedBarcodes.length }}鏉★級</span>
-              <el-button
-                class="clear-all-btn"
-                @click="clearAll"
-                :disabled="scannedBarcodes.length === 0"
-              >娓呯┖鎵�鏈�</el-button>
             </div>
             <div class="card-body">
               <el-scrollbar height="400px" class="custom-scrollbar">
-                <!-- 浣跨敤 transition-group 鍖呰9浠ュ疄鐜板姩鐢� -->
                 <transition-group name="barcode-item-transition">
-                  <div class="barcode-item" v-for="(barcode, index) in scannedBarcodes" :key="barcode" :data-index="index">
-                    <span class="barcode-text">{{ index + 1 }}. {{ barcode }}</span>
+                  <div class="barcode-item" v-for="(item, index) in scannedBarcodes" :key="item.barcode" :data-index="index">
+                    <span class="barcode-text">{{ index + 1 }}. {{ item.barcode }}</span>
                     <el-button
                       class="delete-btn"
-                      @click="removeItem(index)"
-                    >鍒犻櫎</el-button>
+                      @click="removeItem(index, item.barcode)"
+                      icon="Delete"
+                      circle
+                      :disabled="loading"
+                    ></el-button>
                   </div>
                 </transition-group>
                 <div class="empty-tip" v-if="scannedBarcodes.length === 0">
-                  <i class="el-icon-information"></i>
-                  <span>鏆傛棤鎵弿璁板綍锛岃鎵弿鏉$爜</span>
+                  <span>鏆傛棤鎵弿璁板綍锛岃鍏堥�夋嫨鍗曟嵁鍚庢壂鎻忔潯鐮�</span>
                 </div>
               </el-scrollbar>
             </div>
@@ -67,10 +119,16 @@
 
       <template #footer>
         <div class="footer-actions">
-          <el-button type="primary" size="small" @click="submit" :disabled="scannedBarcodes.length === 0" class="submit-btn">
-            <i class="el-icon-check"></i> 鎻愪氦鍑哄簱
+          <el-button 
+            type="primary" 
+            size="small" 
+            @click="submit" 
+            :disabled="scannedBarcodes.length === 0 || !orderForm.outboundOrderId || !orderForm.purchaseOrderId || loading" 
+            class="submit-btn"
+          >
+            <Check /> 鎻愪氦鍑哄簱
           </el-button>
-          <el-button type="text" size="small" @click="showDetailBox = false" class="cancel-btn">
+          <el-button type="text" size="small" @click="showDetailBox = false" class="cancel-btn" :disabled="loading">
             鍙栨秷
           </el-button>
         </div>
@@ -79,99 +137,307 @@
   </div>
 </template>
 
-<script>
+<script setup>
+import { ref, reactive, onMounted, nextTick } from 'vue';
+import { ElMessage } from 'element-plus';
+
 import VolBox from "@/components/basic/VolBox.vue";
+import http from '@/api/http';
 
-export default {
-  components: { VolBox },
-  data() {
-    return {
-      showDetailBox: false,
-      formData: {
-        barcode: "",
-      },
-      scannedBarcodes: [],
-    };
-  },
-  methods: {
-    open() {
-      this.showDetailBox = true;
-      this.scannedBarcodes = [];
-      this.formData.barcode = "";
-      this.$nextTick(() => {
-        this.$refs.barcodeInput.focus();
-      });
-    },
+// 鍝嶅簲寮忔暟鎹�
+const showDetailBox = ref(false);
+const orderForm = reactive({
+  outboundOrderId: "",
+  purchaseOrderId: ""
+});
+const formData = reactive({
+  barcode: "",
+});
+const scannedBarcodes = ref([]);
+const outboundOrders = ref([]);
+const purchaseOrders = ref([]);
+const filteredOutboundOrders = ref([]);
+const filteredPurchaseOrders = ref([]);
+const loading = ref(false);
 
-    handleScan() {
-      const barcode = this.formData.barcode.trim();
-      if (!barcode) {
-        this.$refs.barcodeInput.focus();
-        return;
-      }
-      if (this.scannedBarcodes.includes(barcode)) {
-        this.$message.warning(`鏉$爜 ${barcode} 宸叉壂鎻忚繃锛岃鍕块噸澶嶆壂鎻廯);
-        this.formData.barcode = "";
-        this.$refs.barcodeInput.focus();
-        return;
-      }
+// 妯℃澘寮曠敤
+const formRef = ref(null);
+const barcodeInputRef = ref(null);
+const outboundSelectRef = ref(null); // 鏂板锛氬嚭搴撳崟select鐨剅ef
+const purchaseSelectRef = ref(null); // 鏂板锛氶噰璐崟select鐨剅ef
 
-      this.scannedBarcodes.push(barcode);
-      this.formData.barcode = "";
+// 鐢ㄤ簬闃叉杈撳叆浜嬩欢鍜宑hange浜嬩欢鍐茬獊鐨勯攣
+const isProcessingScan = ref(false);
 
-      this.$nextTick(() => {
-        this.$refs.barcodeInput.focus();
-      });
-    },
+// 缁勪欢鎸傝浇鏃跺垵濮嬪寲杩囨护鍚庣殑鍒楄〃
+onMounted(() => {
+  filteredOutboundOrders.value = [...outboundOrders.value];
+  filteredPurchaseOrders.value = [...purchaseOrders.value];
+});
 
-    removeItem(index) {
-      this.scannedBarcodes.splice(index, 1);
-    },
-
-    clearAll() {
-      this.$confirm("纭畾瑕佹竻绌烘墍鏈夋壂鎻忚褰曞悧锛�", "鎻愮ず", {
-        confirmButtonText: "纭畾",
-        cancelButtonText: "鍙栨秷",
-        type: "warning",
-      }).then(() => {
-        this.scannedBarcodes = [];
-      }).catch(() => {
-        this.$refs.barcodeInput.focus();
-      });
-    },
-
-    submit() {
-      if (this.scannedBarcodes.length === 0) {
-        this.$message.warning("璇峰厛鎵弿鑷冲皯涓�鏉℃潯鐮�");
-        this.$refs.barcodeInput.focus();
-        return;
-      }
-
-      const params = {
-        barcodes: this.scannedBarcodes,
-      };
-
-      this.http
-        .post("/api/OutboundOrder/NoStockOut", params, "鏁版嵁澶勭悊涓�...")
-        .then((res) => {
-          if (!res.status) {
-            this.$message.error(res.message);
-            this.$refs.barcodeInput.focus();
-            return;
-          }
-          this.$message.success("鍑哄簱鎴愬姛");
-          this.showDetailBox = false;
-          this.$emit("parentCall", ($vue) => {
-            $vue.refresh();
-          });
-        })
-        .catch((err) => {
-          this.$message.error(`璇锋眰澶辫触锛�${err.message || "鏈煡閿欒"}`);
-          this.$refs.barcodeInput.focus();
-        });
-    },
-  },
+// 鎵撳紑寮圭獥
+const open = () => {
+  showDetailBox.value = true;
+  scannedBarcodes.value = [];
+  formData.barcode = "";
+  orderForm.outboundOrderId = "";
+  orderForm.purchaseOrderId = "";
+  nextTick(() => {
+    barcodeInputRef.value?.focus();
+  });
 };
+
+// 鍔犺浇鍑哄簱鍗曟嵁鍒楄〃
+const loadOutboundOrders = async () => {
+  if (outboundOrders.value.length > 0) return;
+  try {
+    loading.value = true;
+    const res = await http.get("/api/OutboundPicking/GetAvailablePickingOrders");
+    
+    if (res.code === 0) {
+      outboundOrders.value = res.data.map(orderNo => ({
+        id: orderNo,
+        orderNo: orderNo
+      }));
+      filteredOutboundOrders.value = [...outboundOrders.value];
+    } else {
+      ElMessage.error("鍔犺浇鍑哄簱鍗曟嵁澶辫触锛�" + (res.message || '鏈煡閿欒'));
+    }
+  } catch (error) {
+    ElMessage.error("鍔犺浇鍑哄簱鍗曟嵁寮傚父锛�" + error.message);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 鍔犺浇閲囪喘鍗曟嵁鍒楄〃
+const loadPurchaseOrders = async () => {
+  if (purchaseOrders.value.length > 0) return;
+  try {
+    loading.value = true;
+    const res = await http.get("/api/OutboundPicking/GetAvailablePurchaseOrders");
+    
+    if (res.status === true) {
+      purchaseOrders.value = res.data.map(orderNo => ({
+        id: orderNo,
+        orderNo: orderNo
+      }));
+      filteredPurchaseOrders.value = [...purchaseOrders.value];
+    } else {
+      ElMessage.error("鍔犺浇閲囪喘鍗曟嵁澶辫触锛�" + (res.message || '鏈煡閿欒'));
+    }
+  } catch (error) {
+    ElMessage.error("鍔犺浇閲囪喘鍗曟嵁寮傚父锛�" + error.message);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 鍑哄簱鍗曟嵁杩囨护鏂规硶
+const filterOutboundOrders = (value) => {
+  if (!value) {
+    filteredOutboundOrders.value = [...outboundOrders.value];
+  } else {
+    const lowerValue = value.toLowerCase();
+    filteredOutboundOrders.value = outboundOrders.value.filter(order => 
+      order.orderNo.toLowerCase().includes(lowerValue)
+    );
+  }
+};
+
+// 閲囪喘鍗曟嵁杩囨护鏂规硶
+const filterPurchaseOrders = (value) => {
+  if (!value) {
+    filteredPurchaseOrders.value = [...purchaseOrders.value];
+  } else {
+    const lowerValue = value.toLowerCase();
+    filteredPurchaseOrders.value = purchaseOrders.value.filter(order => 
+      order.orderNo.toLowerCase().includes(lowerValue)
+    );
+  }
+};
+
+// 鍑哄簱鍗曟嵁涓嬫媺妗嗘樉绀�/闅愯棌鏃惰Е鍙�
+const handleOutboundVisibleChange = (visible) => {
+  if (visible) {
+    loadOutboundOrders();
+  } else {
+    // 褰撲笅鎷夋鍏抽棴鏃讹紝濡傛灉鏄壂鎻忔搷浣滃鑷寸殑锛屾竻绌鸿緭鍏ユ
+    if (isProcessingScan.value) {
+        nextTick(() => {
+            outboundSelectRef.value?.clearInput();
+            isProcessingScan.value = false;
+        });
+    }
+  }
+};
+
+// 閲囪喘鍗曟嵁涓嬫媺妗嗘樉绀�/闅愯棌鏃惰Е鍙�
+const handlePurchaseVisibleChange = (visible) => {
+  if (visible) {
+    loadPurchaseOrders();
+  } else {
+    // 褰撲笅鎷夋鍏抽棴鏃讹紝濡傛灉鏄壂鎻忔搷浣滃鑷寸殑锛屾竻绌鸿緭鍏ユ
+    if (isProcessingScan.value) {
+        nextTick(() => {
+            purchaseSelectRef.value?.clearInput();
+            isProcessingScan.value = false;
+        });
+    }
+  }
+};
+
+// 鍗曟嵁閫夋嫨鍙樺寲鏃惰Е鍙�
+const handleOrderChange = () => {
+  // 濡傛灉鏄墜鍔ㄩ�夋嫨锛屽垯涓嶆竻绌鸿緭鍏ユ
+  isProcessingScan.value = false;
+  
+  scannedBarcodes.value = [];
+  nextTick(() => {
+    barcodeInputRef.value?.focus();
+  });
+};
+
+/**
+ * 澶勭悊鍑哄簱鍗曟壂鎻忚緭鍏�
+ * @param {string} scanText - 鎵弿鏋緭鍏ョ殑鏂囨湰
+ */
+const handleOutboundScanInput = async (scanText) => {
+  // 閬垮厤澶勭悊绌哄瓧绗︿覆鎴栫敱change浜嬩欢瑙﹀彂鐨勫唴閮ㄦ搷浣�
+  if (!scanText || isProcessingScan.value) return;
+
+  // 鏌ユ壘瀹屽叏鍖归厤鐨勮鍗�
+  const matchedOrder = outboundOrders.value.find(order => order.orderNo === scanText);
+
+  if (matchedOrder) {
+    isProcessingScan.value = true; // 鏍囪涓烘鍦ㄥ鐞嗘壂鎻�
+    // 鎵嬪姩璧嬪��
+    orderForm.outboundOrderId = matchedOrder.id;
+    ElMessage.success(`鎴愬姛閫夋嫨鍑哄簱鍗曪細${matchedOrder.orderNo}`);
+    
+    // 寤惰繜鑱氱劍鍒颁笅涓�涓緭鍏ユ锛岀‘淇濊祴鍊煎畬鎴�
+    setTimeout(() => {
+        purchaseSelectRef.value?.focus();
+    }, 100);
+  }
+  // 濡傛灉娌℃湁鍖归厤椤癸紝涓嶅仛浠讳綍浜嬶紝璁〆l-select淇濇寔杩囨护鐘舵�侊紝鐢ㄦ埛鍙互鎵嬪姩閫夋嫨
+};
+
+/**
+ * 澶勭悊閲囪喘鍗曟壂鎻忚緭鍏�
+ * @param {string} scanText - 鎵弿鏋緭鍏ョ殑鏂囨湰
+ */
+const handlePurchaseScanInput = async (scanText) => {
+  if (!scanText || isProcessingScan.value) return;
+
+  const matchedOrder = purchaseOrders.value.find(order => order.orderNo === scanText);
+
+  if (matchedOrder) {
+    isProcessingScan.value = true; // 鏍囪涓烘鍦ㄥ鐞嗘壂鎻�
+    orderForm.purchaseOrderId = matchedOrder.id;
+    ElMessage.success(`鎴愬姛閫夋嫨閲囪喘鍗曪細${matchedOrder.orderNo}`);
+    
+    setTimeout(() => {
+        barcodeInputRef.value?.focus();
+    }, 100);
+  }
+};
+
+
+// 鎵弿鏉$爜澶勭悊
+const handleScan = async () => {
+  if (!formRef.value) return;
+  await formRef.value.validateField('barcode');
+
+  const barcode = formData.barcode.trim();
+  
+  if (scannedBarcodes.value.some(item => item.barcode === barcode)) {
+    ElMessage.warning(`鏉$爜 ${barcode} 宸叉壂鎻忚繃锛岃鍕块噸澶嶆壂鎻廯);
+    formData.barcode = "";
+    nextTick(() => barcodeInputRef.value?.focus());
+    return;
+  }
+
+  try {
+    loading.value = true;
+    const res = await http.post("/api/OutboundPicking/BarcodeValidate", {
+      outOder: orderForm.outboundOrderId,
+      inOder: orderForm.purchaseOrderId,
+      barCode: barcode
+    });
+
+    if (res.status === true) {
+      scannedBarcodes.value.push({ barcode });
+      ElMessage.success("鎵弿鎴愬姛");
+      formData.barcode = "";
+    } else {
+      ElMessage.error("鎵弿澶辫触锛�" + (res.message || '楠岃瘉澶辫触'));
+    }
+  } catch (error) {
+    ElMessage.error("鎵弿楠岃瘉寮傚父锛�" + error.message);
+  } finally {
+    loading.value = false;
+    nextTick(() => barcodeInputRef.value?.focus());
+  }
+};
+
+// 绉婚櫎鍗曟潯鎵弿璁板綍
+const removeItem = async (index, barcode) => {
+  try {
+    loading.value = true;
+    const res = await http.post("/api/OutboundPicking/DeleteBarcode", {
+      outOder: orderForm.outboundOrderId,
+      inOder: orderForm.purchaseOrderId,
+      barCode: barcode
+    });
+
+    if (res.status === true) {
+      scannedBarcodes.value.splice(index, 1);
+      ElMessage.success("鍒犻櫎鎴愬姛");
+    } else {
+      ElMessage.error("鍒犻櫎澶辫触锛�" + (res.message || '鍒犻櫎澶辫触'));
+    }
+  } catch (error) {
+    ElMessage.error("鍒犻櫎鏉$爜寮傚父锛�" + error.message);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 鎻愪氦鍑哄簱
+const submit = async () => {
+  if (scannedBarcodes.value.length === 0) {
+    ElMessage.warning("璇峰厛鎵弿鑷冲皯涓�鏉℃潯鐮�");
+    return;
+  }
+
+  const barcodes = scannedBarcodes.value.map(item => item.barcode);
+
+  try {
+    loading.value = true;
+    const res = await http.post("/api/OutboundPicking/NoStockOutSubmit", {
+      OutOderSubmit: orderForm.outboundOrderId,
+      InOderSubmit: orderForm.purchaseOrderId,
+      BarCodeSubmit: barcodes
+    });
+
+    if (res.status === true) {
+      ElMessage.success("鍑哄簱鎻愪氦鎴愬姛");
+      showDetailBox.value = false;
+    } else {
+      ElMessage.error("鍑哄簱鎻愪氦澶辫触锛�" + (res.message || '鎻愪氦澶辫触'));
+    }
+  } catch (error) {
+    ElMessage.error("鍑哄簱鎻愪氦寮傚父锛�" + error.message);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 鏆撮湶缁欑埗缁勪欢鐨勬柟娉�
+defineExpose({
+  open
+});
 </script>
 
 <style scoped>
@@ -219,31 +485,22 @@
   font-size: 15px;
   color: #333;
 }
-.clear-all-btn {
-  color: #f56c6c;
-  font-size: 13px;
-  transition: color 0.2s;
-}
-.clear-all-btn:hover {
-  color: #e53e3e;
-  background: rgba(245, 108, 108, 0.1);
-}
 
 .card-body {
   padding: 0;
 }
 
 /* 鑷畾涔夋粴鍔ㄦ潯 */
-.custom-scrollbar ::v-deep .el-scrollbar__thumb {
+.custom-scrollbar :deep(.el-scrollbar__thumb) {
   background: rgba(0, 0, 0, 0.2);
   border-radius: 4px;
   width: 4px;
 }
-.custom-scrollbar ::v-deep .el-scrollbar__bar:hover .el-scrollbar__thumb {
+.custom-scrollbar :deep(.el-scrollbar__bar:hover .el-scrollbar__thumb) {
   background: rgba(0, 0, 0, 0.3);
   width: 6px;
 }
-.custom-scrollbar ::v-deep .el-scrollbar__wrap {
+.custom-scrollbar :deep(.el-scrollbar__wrap) {
   overflow-x: hidden;
 }
 
@@ -260,7 +517,7 @@
 }
 /* 涓哄鏁拌娣诲姞杞诲井鐨勮儗鏅壊锛屽寮哄彲璇绘�� */
 .barcode-item:nth-child(odd) {
-  background-color: #e1e1e1;
+  background-color: #f9f9f9;
 }
 .barcode-text {
   flex: 1;
@@ -274,16 +531,15 @@
 
 .delete-btn {
   color: #ea1919;
-  font-size: 20px;
+  font-size: 16px;
   transition: all 0.2s;
-  transform: scale(0.8);
+  opacity: 0.7;
 }
 .barcode-item:hover .delete-btn {
   opacity: 1;
-  transform: scale(1);
 }
 .delete-btn:hover {
-  color: #f56c6c !important; /* 浣跨敤 !important 瑕嗙洊 Element UI 榛樿鏍峰紡 */
+  color: #f56c6c !important;
   background: rgba(245, 108, 108, 0.1);
 }
 
@@ -296,22 +552,22 @@
   flex-direction: column;
   align-items: center;
   justify-content: center;
+  gap: 15px;
 }
 .empty-tip i {
   font-size: 40px;
-  margin-bottom: 15px;
   color: #dcdfe6;
 }
 
 /* 鑷畾涔夎緭鍏ユ */
-.custom-input ::v-deep .el-input__inner {
+.custom-input :deep(.el-input__inner) {
   border-radius: 6px;
   border-color: #e4e7ed;
   transition: all 0.3s;
   height: 36px;
   line-height: 36px;
 }
-.custom-input ::v-deep .el-input__inner:focus {
+.custom-input :deep(.el-input__inner:focus) {
   border-color: #409eff;
   box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
 }
@@ -355,7 +611,7 @@
 </style>
 
 <style>
-/* ... (鍏ㄥ眬鏍峰紡閮ㄥ垎淇濇寔涓嶅彉) ... */
+/* 鍏ㄥ眬鏍峰紡閮ㄥ垎淇濇寔涓嶅彉 */
 .text-button:hover {
   background-color: #f0f9eb !important;
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue"
index b1630d8..07275a9 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue"
@@ -203,13 +203,6 @@
           icon: "el-icon-s-grid",
         },
         {
-          prop: "NoStockOut",
-          title: "鏃犲簱瀛樺嚭搴�",
-          type: "icon",
-          width: 100,
-          icon: "el-icon-setting",
-        },
-        {
           prop: "viewDetail",
           title: "鍑哄簱璇︾粏",
           type: "icon",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
index 2e9ea3c..23c4f2b 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
@@ -1,365 +1,376 @@
 
 //姝s鏂囦欢鏄敤鏉ヨ嚜瀹氫箟鎵╁睍涓氬姟浠g爜锛屽彲浠ユ墿灞曚竴浜涜嚜瀹氫箟椤甸潰鎴栬�呴噸鏂伴厤缃敓鎴愮殑浠g爜
 import http from '@/api/http.js'
-import { h,createVNode, render,reactive ,ref } from 'vue';
-import { ElDialog , ElForm, ElFormItem, ElInput, ElButton, ElMessage ,ElSelect, ElOption} from 'element-plus';
+import { h, createVNode, render, reactive, ref } from 'vue';
+import { ElDialog, ElForm, ElFormItem, ElInput, ElButton, ElMessage, ElSelect, ElOption } from 'element-plus';
 
 import gridBody from './extend/outOrderDetail.vue'
+import gridHeader from './extend/NoStockOut.vue'
 let extension = {
-    components: {
-      //鏌ヨ鐣岄潰鎵╁睍缁勪欢
-      gridHeader: '',
-      gridBody: gridBody,
-      gridFooter: '',
-      //鏂板缓銆佺紪杈戝脊鍑烘鎵╁睍缁勪欢
-      modelHeader: '',
-      modelBody: '',
-      modelFooter: ''
-    },
-    tableAction: '', //鎸囧畾鏌愬紶琛ㄧ殑鏉冮檺(杩欓噷濉啓琛ㄥ悕,榛樿涓嶇敤濉啓)
-    buttons: { view: [
-       /* {
-        name: '鍑哄簱',
-        type: 'primary',
-        value: '鍑哄簱',
-        onClick: function () { // 淇锛氱敤ElMessage鏇夸唬this.$message
-          const selectedRows = this.$refs.table.getSelected();
-          if (selectedRows.length === 0) {
-            ElMessage.warning('璇峰厛閫夋嫨瑕佺敓鎴愪换鍔$殑琛�');
-            return;
-          }
-          if (selectedRows.length > 1) {
-            ElMessage.warning('鍙兘閫夋嫨涓�琛�');
-            return;
-          }
-    
-
-          // 鎵�鏈夋牎楠岄�氳繃锛岃Е鍙戜富缁勪欢鎵撳紑鍑哄簱寮圭獥
-          console.log('鎵�鏈夋牎楠岄�氳繃锛岃Е鍙憃penOutboundDialog浜嬩欢锛屽崟鎹暟鎹細', selectedRows[0]);
-         
-          this.$emit('openOutboundDialog', {
-            transNo: selectedRows[0].transNo,       // 鍑哄簱鍗曠紪鍙�
-            createDate: selectedRows[0].createDate || new Date().toLocaleDateString()  // 鍑哄簱鏃ユ湡
-          });
-        }
-      }, */
-      {
-  name: '绌烘墭鐩樺嚭搴�',
-  type: 'primary',
-  value: '绌烘墭鐩樺嚭搴�',
-  onClick: function () {
-    
+  components: {
+    //鏌ヨ鐣岄潰鎵╁睍缁勪欢
+    gridHeader: gridHeader,
+    gridBody: gridBody,
+    gridFooter: '',
+    //鏂板缓銆佺紪杈戝脊鍑烘鎵╁睍缁勪欢
+    modelHeader: '',
+    modelBody: '',
+    modelFooter: ''
+  },
+  tableAction: '', //鎸囧畾鏌愬紶琛ㄧ殑鏉冮檺(杩欓噷濉啓琛ㄥ悕,榛樿涓嶇敤濉啓)
+  buttons: {
+    view: [
+      /* {
+       name: '鍑哄簱',
+       type: 'primary',
+       value: '鍑哄簱',
+       onClick: function () { // 淇锛氱敤ElMessage鏇夸唬this.$message
+         const selectedRows = this.$refs.table.getSelected();
+         if (selectedRows.length === 0) {
+           ElMessage.warning('璇峰厛閫夋嫨瑕佺敓鎴愪换鍔$殑琛�');
+           return;
+         }
+         if (selectedRows.length > 1) {
+           ElMessage.warning('鍙兘閫夋嫨涓�琛�');
+           return;
+         }
    
-    const platformOptions = Array.from({ length: 1 }, (_, i) => {
-      const num = 1;
-      return { label: `绔欏彴${num}`, value: `1-2` };
-    });
 
-    const quantityOptions = Array.from({ length: 6 }, (_, i) => ({
-      label: (i + 1).toString(), 
-      value: i + 1 
-    }));
-
-    const warehouseOptions = ref([]);
-    const isLoadingWarehouses = ref(false);
-
-    const getWarehouseList = async () => {
-      isLoadingWarehouses.value = true;
-      try {
-        const { data, status } = await http.post('/api/LocationInfo/GetLocationTypes'); 
-        if (status && Array.isArray(data)) {
-          // 鏍煎紡鍖栦粨搴撻�夐」锛氶�傞厤ElSelect鐨刲abel-value鏍煎紡
-          warehouseOptions.value = data.map(item => ({
-            label: item.locationTypeDesc,
-            value: item.locationType  
-          }));
-        } else {
-          ElMessage.error('鑾峰彇鍖哄煙鍒楄〃澶辫触');
-          warehouseOptions.value = [];
-        }
-      } catch (err) {
-        ElMessage.error('鍖哄煙鏁版嵁璇锋眰寮傚父锛岃绋嶅悗閲嶈瘯');
-        warehouseOptions.value = [];
-      } finally {
-        isLoadingWarehouses.value = false;
-      }
-    };
-
-    const mountNode = document.createElement('div');
-    document.body.appendChild(mountNode);
-
-    
-    const formData = reactive({
-      warehouseCode:'',
-      palletCode: '',
-      selectedPlatform: platformOptions[0].value,
-      quantity:1 
-    });
-
-    const vnode = createVNode(ElDialog, {
-      title: '绌烘墭鐩樺嚭搴�',
-      width: '500px', 
-      modelValue: true,
-      appendToBody: true,
-      onOpened: async () => {
-        await getWarehouseList();
-        const inputRef = vnode.component.refs.boxCodeInput;
-        inputRef?.focus();
-      },
-      'onUpdate:modelValue': (isVisible) => {
-        if (!isVisible) {
-          render(null, mountNode);
-          document.body.removeChild(mountNode);
-        }
-      },
-      style: {
-        padding: '20px 0', 
-        borderRadius: '8px' 
-      }
-    }, {
-      default: () => h(ElForm, {
-        model: formData,
-        rules: {
-          warehouseCode:[
-            { required: true, message: '璇烽�夋嫨鍖哄煙', trigger: ['change', 'blur'] }
-          ],
-          palletCode: [
-            { type: 'string', message: '鏂欑鍙峰繀椤讳负瀛楃涓�', trigger: 'blur' }
-          ],
-          selectedPlatform: [
-            { required: true, message: '璇烽�夋嫨鍑哄簱绔欏彴', trigger: 'change' }
-          ],
-          quantity:[
-            { required: true, message: '璇烽�夋嫨绌虹鏁伴噺', trigger: 'change'}
-          ]                       
-        },
-        ref: 'batchOutForm',
-        labelWidth: '100px', 
-        style: {
-          padding: '0 30px', 
-        }
-       }, 
-       [
-      //   h(ElFormItem, {
-      //     label: '浠撳簱鍖哄煙',
-      //     prop: 'warehouseCode',
-      //     style: {
-      //       marginBottom: '24px' 
-      //     }
-      //   }, [
-      //     h(ElSelect, {
-      //       placeholder: '璇烽�夋嫨浠撳簱鍖哄煙',
-      //       modelValue: formData.warehouseCode,
-      //       'onUpdate:modelValue': (val) => {
-      //         formData.warehouseCode = val;
-      //       },
-      //       style: {
-      //         width: '100%',
-      //         height: '40px', 
-      //         borderRadius: '4px',
-      //         borderColor: '#dcdfe6'
-      //       }
-      //     }, warehouseOptions.value.map(platform => 
-      //       h(ElOption, { label: platform.label, value: platform.value })
-      //     ))
-      //   ]),
-        h(ElFormItem, {
-          label: '鍑哄簱绔欏彴',
-          prop: 'selectedPlatform',
-          style: {
-            marginBottom: '24px' 
-          }
-        }, [
-          h(ElSelect, {
-            placeholder: '璇烽�夋嫨鍑哄簱绔欏彴',
-            modelValue: formData.selectedPlatform,
-            'onUpdate:modelValue': (val) => {
-              formData.selectedPlatform = val;
-            },
-            style: {
-              width: '100%',
-              height: '40px', 
-              borderRadius: '4px',
-              borderColor: '#dcdfe6'
-            }
-          }, platformOptions.map(platform => 
-            h(ElOption, { label: platform.label, value: platform.value })
-          ))
-        ]),
-      //   h(ElFormItem,{
-      //     label:'鍑哄簱鏁伴噺',
-      //     prop:'quantity',
-      //     style:{
-      //       marginBottom:'24px'
-      //     }
-      //   },[h(ElSelect,{
-      //     placeholder:'璇烽�夋嫨绌虹鏁伴噺',
-      //     modelValue:formData.quantity,
-      //     'onUpdate:modelValue':(val)=>{
-      //       formData.quantity=val;
-      //     },
-      //     style:{
-      //       width:'100%',
-      //       height:'40px',
-      //       borderRadius:'4px',
-      //       borderColor:'#dcdfe6'
-      //     },
-      //     filterable:false
-      //   },
-      //   quantityOptions.map(option=>
-      //     h(ElOption,{
-      //       label:option.label,
-      //       value:option.value
-      //     })
-      //   )
-      // )]),                                 
-        h(ElFormItem, {
-          label: '鏂欑鍙�',
-          prop: 'palletCode',
-          style: {
-            marginBottom: '16px' 
-          }
-        }, [
-          h(ElInput, {
-            type: 'text',
-            placeholder: '鍙�夎緭鍏ユ枡绠卞彿锛屼笉濉垯鑷姩鍒嗛厤绌烘枡绠�',
-            modelValue: formData.palletCode,
-            'onUpdate:modelValue': (val) => {
-              formData.palletCode = val;
-            },
-            style: {
-              width: '100%',
-              height: '40px', 
-              borderRadius: '4px',
-              borderColor: '#dcdfe6'
-            },
-            attrs: {
-              placeholderStyle: 'color: #909399;' 
-            }
-          })
-        ]),
+         // 鎵�鏈夋牎楠岄�氳繃锛岃Е鍙戜富缁勪欢鎵撳紑鍑哄簱寮圭獥
+         console.log('鎵�鏈夋牎楠岄�氳繃锛岃Е鍙憃penOutboundDialog浜嬩欢锛屽崟鎹暟鎹細', selectedRows[0]);
         
-        h('div', {
-          style: {
-            textAlign: 'right',
-            marginTop: '8px',
-            paddingRight: '4px' 
-          }
-        }, [
-          h(ElButton, {
-            type: 'text',
-            onClick: () => {
-              render(null, mountNode);
-              document.body.removeChild(mountNode);
-              ElMessage.info('鍙栨秷鍑哄簱鎿嶄綔');
-            },
-            style: {
-              marginRight: '8px',
-              color: '#606266' 
-            }
-          }, '鍙栨秷'),
-          h(ElButton, {
-            type: 'primary',
-            onClick: async () => {
-              const formRef = vnode.component.refs.batchOutForm;
-              try {
-                await formRef.validate();
-              } catch (err) {
-                return;
+         this.$emit('openOutboundDialog', {
+           transNo: selectedRows[0].transNo,       // 鍑哄簱鍗曠紪鍙�
+           createDate: selectedRows[0].createDate || new Date().toLocaleDateString()  // 鍑哄簱鏃ユ湡
+         });
+       }
+     }, */
+      {
+        name: '绌烘墭鐩樺嚭搴�',
+        type: 'primary',
+        value: '绌烘墭鐩樺嚭搴�',
+        onClick: function () {
+
+
+          const platformOptions = Array.from({ length: 1 }, (_, i) => {
+            const num = 1;
+            return { label: `绔欏彴${num}`, value: `1-2` };
+          });
+
+          const quantityOptions = Array.from({ length: 6 }, (_, i) => ({
+            label: (i + 1).toString(),
+            value: i + 1
+          }));
+
+          const warehouseOptions = ref([]);
+          const isLoadingWarehouses = ref(false);
+
+          const getWarehouseList = async () => {
+            isLoadingWarehouses.value = true;
+            try {
+              const { data, status } = await http.post('/api/LocationInfo/GetLocationTypes');
+              if (status && Array.isArray(data)) {
+                // 鏍煎紡鍖栦粨搴撻�夐」锛氶�傞厤ElSelect鐨刲abel-value鏍煎紡
+                warehouseOptions.value = data.map(item => ({
+                  label: item.locationTypeDesc,
+                  value: item.locationType
+                }));
+              } else {
+                ElMessage.error('鑾峰彇鍖哄煙鍒楄〃澶辫触');
+                warehouseOptions.value = [];
               }
+            } catch (err) {
+              ElMessage.error('鍖哄煙鏁版嵁璇锋眰寮傚父锛岃绋嶅悗閲嶈瘯');
+              warehouseOptions.value = [];
+            } finally {
+              isLoadingWarehouses.value = false;
+            }
+          };
 
-              http.post('/api/Task/PalletOutboundTask?palletCode='+formData.palletCode+'&endStation='+formData.selectedPlatform, {
-                
-              }).then(({ data, status, message }) => {
-                if (status) {
+          const mountNode = document.createElement('div');
+          document.body.appendChild(mountNode);
 
-                  ElMessage.success(`鍑哄簱鎴愬姛`);
-                  this.refresh();
-                  render(null, mountNode);
-                  document.body.removeChild(mountNode);
-                } else {
-                  ElMessage.error(message || data?.message || '鍑哄簱澶辫触');
-                }
-              }).catch(() => {
-                ElMessage.error('璇锋眰澶辫触锛岃绋嶅悗閲嶈瘯');
-              });
+
+          const formData = reactive({
+            warehouseCode: '',
+            palletCode: '',
+            selectedPlatform: platformOptions[0].value,
+            quantity: 1
+          });
+
+          const vnode = createVNode(ElDialog, {
+            title: '绌烘墭鐩樺嚭搴�',
+            width: '500px',
+            modelValue: true,
+            appendToBody: true,
+            onOpened: async () => {
+              await getWarehouseList();
+              const inputRef = vnode.component.refs.boxCodeInput;
+              inputRef?.focus();
+            },
+            'onUpdate:modelValue': (isVisible) => {
+              if (!isVisible) {
+                render(null, mountNode);
+                document.body.removeChild(mountNode);
+              }
             },
             style: {
-              borderRadius: '4px',
-              padding: '8px 20px' 
+              padding: '20px 0',
+              borderRadius: '8px'
             }
-          }, '纭畾')
-        ])
-      ])
-    });
+          }, {
+            default: () => h(ElForm, {
+              model: formData,
+              rules: {
+                warehouseCode: [
+                  { required: true, message: '璇烽�夋嫨鍖哄煙', trigger: ['change', 'blur'] }
+                ],
+                palletCode: [
+                  { type: 'string', message: '鏂欑鍙峰繀椤讳负瀛楃涓�', trigger: 'blur' }
+                ],
+                selectedPlatform: [
+                  { required: true, message: '璇烽�夋嫨鍑哄簱绔欏彴', trigger: 'change' }
+                ],
+                quantity: [
+                  { required: true, message: '璇烽�夋嫨绌虹鏁伴噺', trigger: 'change' }
+                ]
+              },
+              ref: 'batchOutForm',
+              labelWidth: '100px',
+              style: {
+                padding: '0 30px',
+              }
+            },
+              [
+                //   h(ElFormItem, {
+                //     label: '浠撳簱鍖哄煙',
+                //     prop: 'warehouseCode',
+                //     style: {
+                //       marginBottom: '24px' 
+                //     }
+                //   }, [
+                //     h(ElSelect, {
+                //       placeholder: '璇烽�夋嫨浠撳簱鍖哄煙',
+                //       modelValue: formData.warehouseCode,
+                //       'onUpdate:modelValue': (val) => {
+                //         formData.warehouseCode = val;
+                //       },
+                //       style: {
+                //         width: '100%',
+                //         height: '40px', 
+                //         borderRadius: '4px',
+                //         borderColor: '#dcdfe6'
+                //       }
+                //     }, warehouseOptions.value.map(platform => 
+                //       h(ElOption, { label: platform.label, value: platform.value })
+                //     ))
+                //   ]),
+                h(ElFormItem, {
+                  label: '鍑哄簱绔欏彴',
+                  prop: 'selectedPlatform',
+                  style: {
+                    marginBottom: '24px'
+                  }
+                }, [
+                  h(ElSelect, {
+                    placeholder: '璇烽�夋嫨鍑哄簱绔欏彴',
+                    modelValue: formData.selectedPlatform,
+                    'onUpdate:modelValue': (val) => {
+                      formData.selectedPlatform = val;
+                    },
+                    style: {
+                      width: '100%',
+                      height: '40px',
+                      borderRadius: '4px',
+                      borderColor: '#dcdfe6'
+                    }
+                  }, platformOptions.map(platform =>
+                    h(ElOption, { label: platform.label, value: platform.value })
+                  ))
+                ]),
+                //   h(ElFormItem,{
+                //     label:'鍑哄簱鏁伴噺',
+                //     prop:'quantity',
+                //     style:{
+                //       marginBottom:'24px'
+                //     }
+                //   },[h(ElSelect,{
+                //     placeholder:'璇烽�夋嫨绌虹鏁伴噺',
+                //     modelValue:formData.quantity,
+                //     'onUpdate:modelValue':(val)=>{
+                //       formData.quantity=val;
+                //     },
+                //     style:{
+                //       width:'100%',
+                //       height:'40px',
+                //       borderRadius:'4px',
+                //       borderColor:'#dcdfe6'
+                //     },
+                //     filterable:false
+                //   },
+                //   quantityOptions.map(option=>
+                //     h(ElOption,{
+                //       label:option.label,
+                //       value:option.value
+                //     })
+                //   )
+                // )]),                                 
+                h(ElFormItem, {
+                  label: '鏂欑鍙�',
+                  prop: 'palletCode',
+                  style: {
+                    marginBottom: '16px'
+                  }
+                }, [
+                  h(ElInput, {
+                    type: 'text',
+                    placeholder: '鍙�夎緭鍏ユ枡绠卞彿锛屼笉濉垯鑷姩鍒嗛厤绌烘枡绠�',
+                    modelValue: formData.palletCode,
+                    'onUpdate:modelValue': (val) => {
+                      formData.palletCode = val;
+                    },
+                    style: {
+                      width: '100%',
+                      height: '40px',
+                      borderRadius: '4px',
+                      borderColor: '#dcdfe6'
+                    },
+                    attrs: {
+                      placeholderStyle: 'color: #909399;'
+                    }
+                  })
+                ]),
 
-    vnode.appContext = this.$.appContext;
-    render(vnode, mountNode);
-  }
-}
-    ], box: [], detail: [] }, //鎵╁睍鐨勬寜閽�
-    methods: {
-       //涓嬮潰杩欎簺鏂规硶鍙互淇濈暀涔熷彲浠ュ垹闄�
-      onInit() {  
-        //鎵╁睍椤甸潰鍒濆鍖栨搷浣�
-        this.columns.push({
-          field: '鎿嶄綔',
-          title: '鎿嶄綔',
-          width: 90,
-          fixed: 'right',
-          align: 'center',
-          formatter: (row) => {
-              return (
-                  '<i style="cursor: pointer;color: #2d8cf0;"class="el-icon-view">鏌ョ湅鏄庣粏</i>'
-              );
-          },
-          click: (row) => {
-            const table = this.$refs.table.$refs.table;
-            if(table){
-              table.clearSelection();
-              table.toggleRowSelection(row,true);
-            }
-              const rowId =row.id;
-              console.log(rowId);
-              this.$refs.gridBody.open(row);
-          }
-      });
-      },
-      onInited() {
-        //妗嗘灦鍒濆鍖栭厤缃悗
-        //濡傛灉瑕侀厤缃槑缁嗚〃,鍦ㄦ鏂规硶鎿嶄綔
-        //this.detailOptions.columns.forEach(column=>{ });
-      },
-      searchBefore(param) {
-        //鐣岄潰鏌ヨ鍓�,鍙互缁檖aram.wheres娣诲姞鏌ヨ鍙傛暟
-        //杩斿洖false锛屽垯涓嶄細鎵ц鏌ヨ
-        return true;
-      },
-      searchAfter(result) {
-        //鏌ヨ鍚庯紝result杩斿洖鐨勬煡璇㈡暟鎹�,鍙互鍦ㄦ樉绀哄埌琛ㄦ牸鍓嶅鐞嗚〃鏍肩殑鍊�
-        return true;
-      },
-      addBefore(formData) {
-        //鏂板缓淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛紝鍙互缁欑粰琛ㄥ崟璁剧疆鍊硷紝鑷繁杈撳嚭鐪媐ormData鐨勫��
-        return true;
-      },
-      updateBefore(formData) {
-        //缂栬緫淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛ㄣ�佸垹闄よ鐨処d
-        return true;
-      },
-      rowClick({ row, column, event }) {
-        //鏌ヨ鐣岄潰鐐瑰嚮琛屼簨浠�
-        this.$refs.table.$refs.table.toggleRowSelection(row); //鍗曞嚮琛屾椂閫変腑褰撳墠琛�;
-      },
-      modelOpenAfter(row) {
-        //鐐瑰嚮缂栬緫銆佹柊寤烘寜閽脊鍑烘鍚庯紝鍙互鍦ㄦ澶勫啓閫昏緫锛屽锛屼粠鍚庡彴鑾峰彇鏁版嵁
-        //(1)鍒ゆ柇鏄紪杈戣繕鏄柊寤烘搷浣滐細 this.currentAction=='Add';
-        //(2)缁欏脊鍑烘璁剧疆榛樿鍊�
-        //(3)this.editFormFields.瀛楁='xxx';
-        //濡傛灉闇�瑕佺粰涓嬫媺妗嗚缃粯璁ゅ�硷紝璇烽亶鍘唗his.editFormOptions鎵惧埌瀛楁閰嶇疆瀵瑰簲data灞炴�х殑key鍊�
-        //鐪嬩笉鎳傚氨鎶婅緭鍑虹湅锛歝onsole.log(this.editFormOptions)
+                h('div', {
+                  style: {
+                    textAlign: 'right',
+                    marginTop: '8px',
+                    paddingRight: '4px'
+                  }
+                }, [
+                  h(ElButton, {
+                    type: 'text',
+                    onClick: () => {
+                      render(null, mountNode);
+                      document.body.removeChild(mountNode);
+                      ElMessage.info('鍙栨秷鍑哄簱鎿嶄綔');
+                    },
+                    style: {
+                      marginRight: '8px',
+                      color: '#606266'
+                    }
+                  }, '鍙栨秷'),
+                  h(ElButton, {
+                    type: 'primary',
+                    onClick: async () => {
+                      const formRef = vnode.component.refs.batchOutForm;
+                      try {
+                        await formRef.validate();
+                      } catch (err) {
+                        return;
+                      }
+
+                      http.post('/api/Task/PalletOutboundTask?palletCode=' + formData.palletCode + '&endStation=' + formData.selectedPlatform, {
+
+                      }).then(({ data, status, message }) => {
+                        if (status) {
+
+                          ElMessage.success(`鍑哄簱鎴愬姛`);
+                          this.refresh();
+                          render(null, mountNode);
+                          document.body.removeChild(mountNode);
+                        } else {
+                          ElMessage.error(message || data?.message || '鍑哄簱澶辫触');
+                        }
+                      }).catch(() => {
+                        ElMessage.error('璇锋眰澶辫触锛岃绋嶅悗閲嶈瘯');
+                      });
+                    },
+                    style: {
+                      borderRadius: '4px',
+                      padding: '8px 20px'
+                    }
+                  }, '纭畾')
+                ])
+              ])
+          });
+
+          vnode.appContext = this.$.appContext;
+          render(vnode, mountNode);
+        }
       }
+    ], box: [], detail: []
+  }, //鎵╁睍鐨勬寜閽�
+  methods: {
+    //涓嬮潰杩欎簺鏂规硶鍙互淇濈暀涔熷彲浠ュ垹闄�
+    onInit() {
+      //鎵╁睍椤甸潰鍒濆鍖栨搷浣�
+      this.columns.push({
+        field: '鎿嶄綔',
+        title: '鎿嶄綔',
+        width: 90,
+        fixed: 'right',
+        align: 'center',
+        formatter: (row) => {
+          return (
+            '<i style="cursor: pointer;color: #2d8cf0;"class="el-icon-view">鏌ョ湅鏄庣粏</i>'
+          );
+        },
+        click: (row) => {
+          const table = this.$refs.table.$refs.table;
+          if (table) {
+            table.clearSelection();
+            table.toggleRowSelection(row, true);
+          }
+          const rowId = row.id;
+          console.log(rowId);
+          this.$refs.gridBody.open(row);
+        }
+      });
+
+      let TaskHandCompletedBtn = this.buttons.find(x => x.value == 'NoStockOut');
+      if (TaskHandCompletedBtn) {
+        TaskHandCompletedBtn.onClick = function () {
+          this.$refs.gridHeader.open();
+        }
+      }
+
+
+    },
+    onInited() {
+      //妗嗘灦鍒濆鍖栭厤缃悗
+      //濡傛灉瑕侀厤缃槑缁嗚〃,鍦ㄦ鏂规硶鎿嶄綔
+      //this.detailOptions.columns.forEach(column=>{ });
+    },
+    searchBefore(param) {
+      //鐣岄潰鏌ヨ鍓�,鍙互缁檖aram.wheres娣诲姞鏌ヨ鍙傛暟
+      //杩斿洖false锛屽垯涓嶄細鎵ц鏌ヨ
+      return true;
+    },
+    searchAfter(result) {
+      //鏌ヨ鍚庯紝result杩斿洖鐨勬煡璇㈡暟鎹�,鍙互鍦ㄦ樉绀哄埌琛ㄦ牸鍓嶅鐞嗚〃鏍肩殑鍊�
+      return true;
+    },
+    addBefore(formData) {
+      //鏂板缓淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛紝鍙互缁欑粰琛ㄥ崟璁剧疆鍊硷紝鑷繁杈撳嚭鐪媐ormData鐨勫��
+      return true;
+    },
+    updateBefore(formData) {
+      //缂栬緫淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛ㄣ�佸垹闄よ鐨処d
+      return true;
+    },
+    rowClick({ row, column, event }) {
+      //鏌ヨ鐣岄潰鐐瑰嚮琛屼簨浠�
+      this.$refs.table.$refs.table.toggleRowSelection(row); //鍗曞嚮琛屾椂閫変腑褰撳墠琛�;
+    },
+    modelOpenAfter(row) {
+      //鐐瑰嚮缂栬緫銆佹柊寤烘寜閽脊鍑烘鍚庯紝鍙互鍦ㄦ澶勫啓閫昏緫锛屽锛屼粠鍚庡彴鑾峰彇鏁版嵁
+      //(1)鍒ゆ柇鏄紪杈戣繕鏄柊寤烘搷浣滐細 this.currentAction=='Add';
+      //(2)缁欏脊鍑烘璁剧疆榛樿鍊�
+      //(3)this.editFormFields.瀛楁='xxx';
+      //濡傛灉闇�瑕佺粰涓嬫媺妗嗚缃粯璁ゅ�硷紝璇烽亶鍘唗his.editFormOptions鎵惧埌瀛楁閰嶇疆瀵瑰簲data灞炴�х殑key鍊�
+      //鐪嬩笉鎳傚氨鎶婅緭鍑虹湅锛歝onsole.log(this.editFormOptions)
     }
-  };
-  export default extension;
-  
\ No newline at end of file
+  }
+};
+export default extension;
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs"
index 860e955..1dfddae 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs"
@@ -24,5 +24,25 @@
         Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode);
         Task<WebResponseContent> ConfirmPicking(string orderNo, string palletCode, string barcode);
         Task<WebResponseContent> ReturnRemaining(string orderNo, string palletCode, string reason);
+
+        /// <summary>
+        /// 鍗曟嵁鏌ユ壘
+        /// </summary>
+        /// <returns></returns>
+        WebResponseContent GetAvailablePurchaseOrders();
+        WebResponseContent GetAvailablePickingOrders();
+
+        /// <summary>
+        /// 鎵爜楠岃瘉
+        /// </summary>
+        WebResponseContent BarcodeValidate(NoStockOutModel noStockOut);
+        /// <summary>
+        /// 鏉$爜鍒犻櫎
+        /// </summary>
+        /// <param name="noStockOut"></param>
+        /// <returns></returns>
+        WebResponseContent DeleteBarcode(NoStockOutModel noStockOut);
+
+        WebResponseContent NoStockOutSubmit(NoStockOutSubmit noStockOutSubmit);
     }
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrderDetail.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrderDetail.cs"
index 92661a4..6f5a669 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrderDetail.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_InboundOrderDetail.cs"
@@ -140,5 +140,10 @@
         /// </summary>
         [SugarColumn(IsNullable = true, ColumnDescription = "澶囨敞")]
         public string Remark { get; set; }
+
+        /// <summary>
+        /// 铏氭嫙鍑哄叆搴撴暟閲�
+        /// </summary>
+        public decimal NoStockOutQty { get; set; }
     }
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs"
index 3b8024e..a12854c 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs"
@@ -143,5 +143,9 @@
         public decimal NeedOutQuantity => OrderQuantity - MoveQty;
 
         public decimal PickedQty { get; set; }
+        /// <summary>
+        /// 铏氭嫙鍑哄叆搴撴暟閲�
+        /// </summary>
+        public decimal NoStockOutQty { get; set; }
     }
 }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/NoStockOutModel.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/NoStockOutModel.cs"
new file mode 100644
index 0000000..6ebc3ff
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/NoStockOutModel.cs"
@@ -0,0 +1,46 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WIDESEA_Model.Models
+{
+    /// <summary>
+    /// 铏氭嫙鍑哄叆搴撳疄浣撶被
+    /// </summary>
+    public class NoStockOutModel
+    {
+        /// <summary>
+        /// 鍏ュ簱鍗�
+        /// </summary>
+        public string inOder { get; set; }
+        /// <summary>
+        /// 鍑哄簱鍗�
+        /// </summary>
+        public string outOder { get; set; }
+        /// <summary>
+        /// 鏉$爜
+        /// </summary>
+        public string barCode { get; set; }
+    }
+    /// <summary>
+    /// 鎻愪氦鍑哄簱瀹炰綋绫�
+    /// </summary>
+    public class NoStockOutSubmit
+    {
+        /// <summary>
+        /// 鎻愪氦鍏ュ簱鍗�
+        /// </summary>
+        public string InOderSubmit { get; set; }
+        /// <summary>
+        /// 鎻愪氦鍑哄簱鍗�
+        /// </summary>
+        public string OutOderSubmit { get; set; }
+        /// <summary>
+        /// 鎻愪氦鏉$爜闆嗗悎
+        /// </summary>
+        public List<string> BarCodeSubmit { get; set; }
+    }
+
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
index eddd986..5cc1885 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
@@ -21,6 +21,7 @@
 using WIDESEA_DTO.Inbound;
 using WIDESEA_DTO.Outbound;
 using WIDESEA_IBasicService;
+using WIDESEA_IInboundService;
 using WIDESEA_IOutboundService;
 using WIDESEA_IStockService;
 using WIDESEA_Model.Models;
@@ -47,7 +48,8 @@
         private readonly IESSApiService _eSSApiService;
         private readonly IInvokeMESService _invokeMESService;
         private readonly IDailySequenceService _dailySequenceService;
-
+        private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
+        private readonly IInboundOrderDetailService _inboundOrderDetailService;
         private readonly ILogger<OutboundPickingService> _logger;
 
         private Dictionary<string, string> stations = new Dictionary<string, string>
@@ -67,7 +69,7 @@
         public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService,
             IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService,
             IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService, IOutboundOrderService outboundOrderService,
-            IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService) : base(BaseDal)
+            IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService, IRepository<Dt_InboundOrder> inboundOrderRepository, IInboundOrderDetailService inboundOrderDetailService) : base(BaseDal)
         {
             _unitOfWorkManage = unitOfWorkManage;
             _stockInfoService = stockInfoService;
@@ -83,6 +85,8 @@
             _logger = logger;
             _invokeMESService = invokeMESService;
             _dailySequenceService = dailySequenceService;
+            _inboundOrderRepository = inboundOrderRepository;
+            _inboundOrderDetailService = inboundOrderDetailService;
         }
 
         // 鑾峰彇鏈嫞閫夊垪琛�
@@ -1611,10 +1615,212 @@
             }
             return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�", new { SplitResults = new List<SplitResult>() });
         }
- 
+
+
+        #region 铏氭嫙鍑哄叆搴�
+        public WebResponseContent GetAvailablePurchaseOrders()
+        {
+            List<Dt_InboundOrder> InOders = _inboundOrderRepository.QueryData().Where(x => x.OrderStatus != InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt()).ToList();
+            List<string> InOderCodes = InOders.Select(x => x.UpperOrderNo).ToList();
+            return WebResponseContent.Instance.OK("鎴愬姛",data: InOderCodes);
+        }
+
+        public WebResponseContent GetAvailablePickingOrders()
+        {
+            List<Dt_OutboundOrder> outOders = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().Where(x => x.OrderStatus != OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt()).ToList();
+
+            List<string> outOderCodes = outOders.Select(x => x.UpperOrderNo).ToList();
+            return WebResponseContent.Instance.OK("鎴愬姛", data: outOderCodes);
+
+        }
+        public WebResponseContent BarcodeValidate(NoStockOutModel noStockOut)
+        {
+            try
+            {
+                Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == noStockOut.inOder && x.OrderStatus != InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt()).Includes(x => x.Details).First();
+                if(inboundOrder == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒伴噰璐崟锛歿noStockOut.inOder}");
+                }
+                var matchedDetail = inboundOrder.Details.FirstOrDefault(detail => detail.Barcode == noStockOut.barCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
+
+                if (matchedDetail == null)
+                {
+                    return WebResponseContent.Instance.Error($"鍦ㄩ噰璐崟 {noStockOut.inOder} 涓湭鎵惧埌鏉$爜涓� {noStockOut.barCode} 鐨勬槑缁嗐��");
+                }
+                matchedDetail.NoStockOutQty = 0;
+
+                Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == noStockOut.outOder && x.OrderStatus != OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt()).Includes(x => x.Details).First();
+                if (outboundOrder == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒板嚭搴撳崟锛歿noStockOut.inOder}");
+                }
+                var matchedCode = outboundOrder.Details.FirstOrDefault(detail => detail.MaterielCode == matchedDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
+
+                if (matchedCode == null)
+                {
+                    return WebResponseContent.Instance.Error($"鍦ㄥ嚭搴撳崟鐨勭墿鏂欑紪鐮佷腑鏈壘鍒颁笌閲囪喘鍗曚腑鐨剓matchedDetail.MaterielCode} 瀵瑰簲鐨勭墿鏂欍��");
+                }
+                matchedCode.NoStockOutQty = 0;
+
+                //鍓╀綑鍏ュ簱鏁伴噺鍗宠櫄鎷熷嚭鍏ュ簱鍓╀綑鍙嚭鏁伴噺
+                decimal outQuantity = matchedDetail.OrderQuantity - matchedDetail.ReceiptQuantity;
+                if(outQuantity == 0)
+                {
+                    return WebResponseContent.Instance.Error($"璇ラ噰璐崟涓殑鏉$爜瀵瑰簲鐨勫彲鍑烘暟閲忎负0");
+                }
+                if (matchedCode.OrderQuantity < outQuantity)
+                {
+                    return WebResponseContent.Instance.Error($"璇ラ噰璐崟涓殑鏉$爜瀵瑰簲鐨勫彲鍑烘暟閲忚秴鍑哄嚭搴撳崟鍑哄簱鏁伴噺{matchedDetail.OrderQuantity - matchedCode.OrderQuantity},涓嶆弧瓒虫暣鍖呭嚭搴�");
+                }
+                //鍗曟嵁鍑哄簱閿佸畾鏁伴噺
+                matchedDetail.NoStockOutQty += outQuantity;
+                matchedCode.NoStockOutQty += outQuantity;
+
+                if ((matchedCode.LockQuantity + matchedCode.NoStockOutQty) > matchedCode.OrderQuantity)
+                {
+                   return WebResponseContent.Instance.Error($"鍑哄簱鍗曟槑缁嗘暟閲忔孩鍑簕matchedCode.LockQuantity - matchedCode.OrderQuantity}");
+                }
+                matchedDetail.OrderDetailStatus = OrderDetailStatusEnum.Inbounding.ObjToInt();
+                matchedCode.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt();
+
+                _unitOfWorkManage.BeginTran();
+                _inboundOrderDetailService.UpdateData(matchedDetail);
+                _outboundOrderDetailService.UpdateData(matchedCode);
+                _unitOfWorkManage.CommitTran();
+                return WebResponseContent.Instance.OK();
+            }
+            catch(Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return WebResponseContent.Instance.Error(ex.Message);
+            }
+        }
+
+
+        public WebResponseContent DeleteBarcode(NoStockOutModel noStockOut)
+        {
+            try
+            {
+                Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == noStockOut.inOder && x.OrderStatus != InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt()).Includes(x => x.Details).First();
+                if (inboundOrder == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒伴噰璐崟锛歿noStockOut.inOder}");
+                }
+                var matchedDetail = inboundOrder.Details.FirstOrDefault(detail => detail.Barcode == noStockOut.barCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
+
+                if (matchedDetail == null)
+                {
+                    return WebResponseContent.Instance.Error($"鍦ㄩ噰璐崟 {noStockOut.inOder} 涓湭鎵惧埌鏉$爜涓� {noStockOut.barCode} 鐨勬槑缁嗐��");
+                }
+                matchedDetail.NoStockOutQty = 0;
+
+                Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == noStockOut.outOder && x.OrderStatus != OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt()).Includes(x => x.Details).First();
+                if (outboundOrder == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒板嚭搴撳崟锛歿noStockOut.inOder}");
+                }
+                var matchedCode = outboundOrder.Details.FirstOrDefault(detail => detail.MaterielCode == matchedDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
+
+                if (matchedCode == null)
+                {
+                    return WebResponseContent.Instance.Error($"鍦ㄥ嚭搴撳崟鐨勭墿鏂欑紪鐮佷腑鏈壘鍒颁笌閲囪喘鍗曚腑鐨剓matchedDetail.MaterielCode} 瀵瑰簲鐨勭墿鏂欍��");
+                }
+                matchedCode.NoStockOutQty = 0;
+                _unitOfWorkManage.BeginTran();
+                _inboundOrderDetailService.UpdateData(matchedDetail);
+                _outboundOrderDetailService.UpdateData(matchedCode);
+                _unitOfWorkManage.CommitTran();
+                return WebResponseContent.Instance.OK();
+
+            }
+            catch(Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return WebResponseContent.Instance.Error(ex.Message);
+            }
+        }
+
+        public WebResponseContent NoStockOutSubmit(NoStockOutSubmit noStockOutSubmit)
+        {
+            try
+            {
+                Dt_InboundOrder inboundOrder = Db.Queryable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == noStockOutSubmit.InOderSubmit && x.OrderStatus != InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt()).Includes(x => x.Details).First();
+                if (inboundOrder == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒伴噰璐崟锛歿noStockOutSubmit.InOderSubmit}");
+                }
+                Dt_OutboundOrder outboundOrder = Db.Queryable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == noStockOutSubmit.OutOderSubmit && x.OrderStatus != OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt()).Includes(x => x.Details).First();
+                if (outboundOrder == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒板嚭搴撳崟锛歿noStockOutSubmit.OutOderSubmit}");
+                }
+                List<Dt_InboundOrderDetail> inboundOrderDetails = new List<Dt_InboundOrderDetail>();
+                List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
+                foreach (var BarCode in noStockOutSubmit.BarCodeSubmit)
+                {
+                   var inboundOrderDetail = inboundOrder.Details.FirstOrDefault(detail => detail.Barcode == BarCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
+
+                    if(inboundOrderDetail == null)
+                    {
+                        return WebResponseContent.Instance.Error($"鍦ㄩ噰璐崟 {noStockOutSubmit.InOderSubmit} 涓湭鎵惧埌鏉$爜涓� {BarCode} 鐨勬槑缁嗐��");
+                    }
+                    var outboundOrderDetail = outboundOrder.Details.FirstOrDefault(detail => detail.MaterielCode == inboundOrderDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt());
+
+                    if (outboundOrderDetail == null)
+                    {
+                        return WebResponseContent.Instance.Error($"鍦ㄥ嚭搴撳崟鐨勭墿鏂欑紪鐮佷腑鏈壘鍒颁笌閲囪喘鍗曚腑鐨剓inboundOrderDetail.MaterielCode} 瀵瑰簲鐨勭墿鏂欍��");
+                    }
+                    inboundOrderDetail.ReceiptQuantity += inboundOrderDetail.NoStockOutQty;
+                    inboundOrderDetail.OverInQuantity = inboundOrderDetail.ReceiptQuantity;
+                    inboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt();
+                    inboundOrderDetails.Add(inboundOrderDetail);
+
+                    outboundOrderDetail.LockQuantity += outboundOrderDetail.NoStockOutQty;
+                    outboundOrderDetail.OverOutQuantity = outboundOrderDetail.LockQuantity;
+                    if(outboundOrderDetail.OrderQuantity == outboundOrderDetail.OverOutQuantity)
+                    {
+                        outboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt();
+                    }
+                    outboundOrderDetails.Add(outboundOrderDetail);
+
+                }
+                //鍒ゆ柇鍏ュ簱鍗曟嵁鏄庣粏鏄惁鍏ㄩ儴鏄畬鎴愮姸鎬�
+                bool inoderOver = inboundOrder.Details.Count() == inboundOrder.Details.Select(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count();
+                if (inoderOver)
+                {
+                    inboundOrder.OrderStatus = InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt();
+                }
+                //鍒ゆ柇鍑哄簱鍗曟嵁鏄庣粏鏄惁鍏ㄩ儴鏄畬鎴愮姸鎬�
+                bool outOderOver = outboundOrder.Details.Count() == outboundOrder.Details.Select(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt()).Count();
+                if (outOderOver)
+                {
+                    outboundOrder.OrderStatus = OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt();
+                }
+                //鏁版嵁澶勭悊
+                _unitOfWorkManage.BeginTran();
+                _inboundOrderDetailService.UpdateData(inboundOrderDetails);
+                _outboundOrderDetailService.UpdateData(outboundOrderDetails);
+                _inboundOrderRepository.UpdateData(inboundOrder);
+                _outboundOrderService.UpdateData(outboundOrder);
+                _unitOfWorkManage.CommitTran();
+
+                return WebResponseContent.Instance.OK();
+            }
+            catch(Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return WebResponseContent.Instance.Error(ex.Message);
+            }
+        }
+        #endregion
+
+
         #endregion
     }
 
+   
+
     #region 鏀寔绫诲畾涔�
 
     public class ValidationResult<T>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj"
index b11d170..3fa27c9 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj"
@@ -8,6 +8,7 @@
 
   <ItemGroup>
     <ProjectReference Include="..\WIDESEA_IBasicService\WIDESEA_IBasicService.csproj" />
+    <ProjectReference Include="..\WIDESEA_IInboundService\WIDESEA_IInboundService.csproj" />
     <ProjectReference Include="..\WIDESEA_IOutboundService\WIDESEA_IOutboundService.csproj" />
     <ProjectReference Include="..\WIDESEA_IRecordService\WIDESEA_IRecordService.csproj" />
     <ProjectReference Include="..\WIDESEA_IStockService\WIDESEA_IStockService.csproj" />
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
index dd51866..53d317b 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
@@ -1,4 +1,5 @@
 锘縰sing Autofac.Core;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using WIDESEA_Core;
@@ -106,5 +107,35 @@
         {
             return await Service.CancelPicking(dto.OrderNo,dto.PalletCode,dto.Barcode);
         }
+
+        [HttpPost,HttpGet, Route("GetAvailablePurchaseOrders"),AllowAnonymous]
+        public WebResponseContent GetAvailablePurchaseOrders()
+        {
+            return  Service.GetAvailablePurchaseOrders();
+        }
+
+        [HttpPost, HttpGet, Route("GetAvailablePickingOrders"),AllowAnonymous]
+        public WebResponseContent GetAvailablePickingOrders()
+        {
+            return Service.GetAvailablePickingOrders();
+        }
+
+        [HttpPost, HttpGet, Route("BarcodeValidate"), AllowAnonymous]
+        public WebResponseContent BarcodeValidate([FromBody] NoStockOutModel noStockOut)
+        {
+            return Service.BarcodeValidate(noStockOut);
+        }
+
+        [HttpPost, HttpGet, Route("DeleteBarcode"), AllowAnonymous]
+        public WebResponseContent DeleteBarcode([FromBody] NoStockOutModel noStockOut)
+        {
+            return Service.DeleteBarcode(noStockOut);
+        }
+
+        [HttpPost, HttpGet, Route("NoStockOutSubmit"), AllowAnonymous]
+        public WebResponseContent NoStockOutSubmit([FromBody] NoStockOutSubmit noStockOutSubmit)
+        {
+            return Service.NoStockOutSubmit(noStockOutSubmit);
+        }
     }
 }

--
Gitblit v1.9.3