From c4e1a656954799267cbd61d3de3a040e8dc8e46a Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期二, 11 十一月 2025 08:48:42 +0800
Subject: [PATCH] 提交出库

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-wal      |    0 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Inbound/PalletSumQuantityDTO.cs                                |    6 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutStockLockInfoService.cs                         |  133 +++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs            |   10 
 项目代码/WIDESEA_WMSClient/src/router/index.js                                                                |    2 
 项目代码/WIDESEA_WMSClient/src/router/viewGird.js                                                             |    8 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IBasicService/IInvokeMESService.cs                                 |    3 
 项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue                                   |   20 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs                        |   24 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/ISplitPackageService.cs                           |   20 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundOrderController.cs          |   14 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundLockInfo.cs                       |   19 
 项目代码/WIDESEA_WMSClient/src/views/outbound/SplitPackageModal.vue                                           |  106 ++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutStockLockInfoService.cs                       |    8 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs                                     |  155 +++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ESSController.cs                             |   20 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db     |    0 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-wal |    0 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/Dt_StockInfoDetail.cs                           |    3 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs        |   87 ++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/MaterielToMesService.cs                               |    9 
 项目代码/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue                                              |  354 ++++++++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/OutLockStockStatusEnum.cs                         |   34 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Dt_FeedbackToMes.cs                                   |   59 +
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs                          |  386 +++++++++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderGetDTO.cs                                |   45 +
 项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db          |    0 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundOrderService.cs                          |    2 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs                   |   12 
 项目代码/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js                                              |    5 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs                      |  302 +++++-
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/SplitPackageService.cs                             |  169 ++++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs                                   |  150 ++-
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_PickingRecord.cs                          |   95 ++
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs                            |   18 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs                                   |    3 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs                                   |  103 ++
 37 files changed, 2,214 insertions(+), 170 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js"
index e28f59c..13b07b2 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js"
@@ -72,8 +72,9 @@
 
     try {
       console.log('鍙戣捣鍒嗘壒鍏ュ簱璇锋眰锛屽弬鏁帮細', { inboundOrderNos});
-      const response = await http.post('/api/InboundOrder/BatchInbound', {
-        inboundOrderNos: inboundOrderNos, 
+      const response = await http.post('/api/InboundOrder/BatchOrderFeedbackToMes', {
+        orderNos: inboundOrderNos, 
+        inout:1
       });
 
       const { status, message, data } = response;
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 6091790..decb2fd 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"
@@ -14,13 +14,20 @@
               <span>宸查�変腑 {{ selection.length }} 椤�</span>
             </el-col>
             <el-col :span="8">
-              <el-link
+          <!--     <el-link
                 type="primary"
                 size="small"
                 style="float: right; height: 20px"
                 @click="lockstocks"
-                >閿佸畾搴撳瓨</el-link
-              >
+                >閿佸畾搴撳瓨</el-link> -->
+
+              <el-link
+                type="primary"
+                size="small"
+                style="float: right; height: 20px"
+                @click="handleOpenPicking"
+                >鎷i��</el-link>
+                 
               <el-link
                 type="primary"
                 size="small"
@@ -310,6 +317,13 @@
           });
         });
     },
+    // 鎵撳紑鎷i�夐〉闈�
+   handleOpenPicking() {
+      this.$router.push({
+        path: '/outbound/picking',
+        query: { orderId: this.row.id }
+      })
+    },
     outbound() {
       if (this.selection.length === 0) {
         return this.$message.error("璇烽�夋嫨鍗曟嵁鏄庣粏");
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/index.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/index.js"
index febef0c..a42f273 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/index.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/index.js"
@@ -36,7 +36,7 @@
     meta:{
         anonymous:true
       }
-  },
+  }, 
   {
     path: '/bigdata',
     name: 'bigdata',
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
index 4ee7e1b..a78b685 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
@@ -73,7 +73,13 @@
     path: '/outboundOrderDetail',
     name: 'outboundOrderDetail',
     component: () => import('@/views/outbound/outboundOrderDetail.vue')
-  }, {
+  }, 
+  {
+  path: '/outbound/picking',
+  name: 'PickingConfirm',
+  component: () => import('@/views/outbound/PickingConfirm.vue'),
+  meta: { title: '鎷i�夌‘璁�', keepAlive: false }
+},{
     path: '/stockInfo',
     name: 'stockInfo',
     component: () => import('@/views/stock/stockInfo.vue')
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue"
new file mode 100644
index 0000000..899297b
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue"
@@ -0,0 +1,354 @@
+<template>
+  <div class="picking-confirm">
+    <div class="page-header">
+      <el-page-header @back="goBack">
+        <template #content>
+          <span class="title">鍑哄簱鎷i�夌‘璁� - {{ orderInfo.orderNo }}</span>
+        </template>
+      </el-page-header>
+    </div>
+
+    <el-row :gutter="20" class="main-content">
+      <el-col :span="8">
+        <div class="scan-section">
+          <el-card header="鎵爜鍖哄煙">
+            <el-form label-width="100px" size="small">
+              <el-form-item label="鎵樼洏鏉$爜">
+                <el-input 
+                  v-model="scanForm.palletCode" 
+                  placeholder="鎵弿鎴栬緭鍏ユ墭鐩樻潯鐮�"
+                  @keyup.enter="handlePalletScan"
+                  clearable
+                >
+                  <template #append>
+                    <el-button @click="handlePalletScan">纭</el-button>
+                  </template>
+                </el-input>
+              </el-form-item>
+
+              <el-form-item label="鐗╂枡鏉$爜">
+                <el-input 
+                  v-model="scanForm.barcode" 
+                  placeholder="鎵弿鎴栬緭鍏ョ墿鏂欐潯鐮�"
+                  @keyup.enter="handleBarcodeScan"
+                  :disabled="!currentPallet"
+                  clearable
+                >
+                  <template #append>
+                    <el-button @click="handleBarcodeScan" :disabled="!currentPallet">纭</el-button>
+                  </template>
+                </el-input>
+              </el-form-item>
+
+              <el-form-item label="鎷i�夋暟閲�">
+                <el-input-number 
+                  v-model="scanForm.quantity" 
+                  :min="1" 
+                  :max="maxPickQuantity"
+                  :disabled="!currentLockInfo"
+                />
+              </el-form-item>
+            </el-form>
+
+            <div class="current-info" v-if="currentPallet">
+              <p>褰撳墠鎵樼洏: {{ currentPallet.palletCode }}</p>
+              <p>璐т綅: {{ currentPallet.locationCode }}</p>
+              <p>鐘舵��: {{ currentPallet.statusText }}</p>
+            </div>
+          </el-card>
+
+          <div class="action-buttons">
+            <el-button 
+              type="warning" 
+              @click="handleBackToStock" 
+              :disabled="!currentPallet"
+              style="margin-bottom: 10px;"
+            >
+              鍥炲簱
+            </el-button>
+            <el-button 
+              type="success" 
+              @click="handleDirectOutbound" 
+              :disabled="!currentPallet"
+              style="margin-bottom: 10px;"
+            >
+              鐩存帴鍑哄簱
+            </el-button>
+            <el-button 
+              type="primary" 
+              @click="handleOpenSplit" 
+              :disabled="!currentLockInfo"
+            >
+              鎷嗗寘
+            </el-button>
+          </div>
+        </div>
+      </el-col>
+
+      <el-col :span="16">
+        <el-card header="鎷i�夌粨鏋�">
+          <div class="summary-info">
+            <el-alert
+              :title="`鏈嫞璐�: ${unpickedCount} 鏉�, ${unpickedQuantity} 涓猔"
+              type="warning"
+              :closable="false"
+            />
+          </div>
+
+          <vol-table
+            :data="pickedList"
+            :columns="pickedColumns"
+            :pagination="false"
+            :height="400"
+          >
+            <template #action="{ row }">
+              <el-button type="text" @click="handleCancelPick(row)">鎾ら攢</el-button>
+            </template>
+          </vol-table>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 鎷嗗寘寮圭獥 -->
+    <vol-box
+      v-model="splitVisible"
+      title="鎷嗗寘鎿嶄綔"
+      :width="600"
+      :height="500"
+    >
+      <SplitPackageModal
+        v-if="splitVisible"
+        :lockInfo="currentLockInfo"
+        @success="handleSplitSuccess"
+        @close="splitVisible = false"
+      />
+    </vol-box>
+  </div>
+</template>
+
+<script>
+import SplitPackageModal from './SplitPackageModal.vue'
+
+export default {
+  components: { SplitPackageModal },
+  data() {
+    return {
+      orderInfo: {},
+      scanForm: {
+        palletCode: '',
+        barcode: '',
+        quantity: 1
+      },
+      currentPallet: null,
+      currentLockInfo: null,
+      pickedList: [],
+      pickedColumns: [
+        { field: 'barcode', title: '鐗╂枡鏉$爜', width: 150 },
+        { field: 'materielCode', title: '鐗╂枡缂栫爜', width: 120 },
+        { field: 'materielName', title: '鐗╂枡鍚嶇О', width: 150 },
+        { field: 'pickQuantity', title: '鎷i�夋暟閲�', width: 100 },
+        { field: 'palletCode', title: '鎵樼洏缂栧彿', width: 120 },
+        { field: 'pickTime', title: '鎷i�夋椂闂�', width: 160 },
+        { field: 'operator', title: '鎿嶄綔浜�', width: 100 },
+        { field: 'action', title: '鎿嶄綔', width: 80, slot: true }
+      ],
+      splitVisible: false,
+      maxPickQuantity: 0
+    }
+  },
+  computed: {
+    unpickedCount() {
+      return this.orderInfo.unpickedCount || 0
+    },
+    unpickedQuantity() {
+      return this.orderInfo.unpickedQuantity || 0
+    }
+  },
+  methods: {
+    goBack() {
+      this.$router.back()
+    },
+
+    async loadOrderInfo() {
+      const orderId = this.$route.query.orderId
+      if (!orderId) return
+
+      try {
+        const result = await this.http.post(`api/OutboundOrder/GetById?id=${orderId}`)
+        if (result.status) {
+          this.orderInfo = result.data
+        }
+      } catch (error) {
+        this.$message.error('鍔犺浇鍑哄簱鍗曚俊鎭け璐�')
+      }
+    },
+
+    async handlePalletScan() {
+      if (!this.scanForm.palletCode) {
+        this.$message.warning('璇疯緭鍏ユ墭鐩樻潯鐮�')
+        return
+      }
+
+      try {
+        const result = await this.http.get(
+          `api/OutboundPicking/GetPalletOutboundStatus?palletCode=${this.scanForm.palletCode}`
+        )
+        if (result.status) {
+          this.currentPallet = result.data
+          this.loadPalletLockInfo()
+          this.$message.success(`鎵樼洏 ${this.scanForm.palletCode} 璇嗗埆鎴愬姛`)
+        } else {
+          this.$message.error(result.message)
+        }
+      } catch (error) {
+        this.$message.error('鎵樼洏璇嗗埆澶辫触')
+      }
+    },
+
+    async loadPalletLockInfo() {
+      if (!this.currentPallet) return
+
+      try {
+        const result = await this.http.get(
+          `api/OutboundPicking/GetPalletLockInfos?palletCode=${this.currentPallet.palletCode}`
+        )
+        if (result.status && result.data.length > 0) {
+          this.currentLockInfo = result.data[0]
+          this.maxPickQuantity = this.currentLockInfo.assignQuantity - this.currentLockInfo.pickedQty
+        }
+      } catch (error) {
+        console.error('鍔犺浇閿佸畾淇℃伅澶辫触:', error)
+      }
+    },
+
+    async handleBarcodeScan() {
+      // 瀹炵幇鎵爜纭閫昏緫
+      if (!this.scanForm.barcode) {
+        this.$message.warning('璇疯緭鍏ョ墿鏂欐潯鐮�')
+        return
+      }
+
+      try {
+        const request = {
+          barcode: this.scanForm.barcode,
+          quantity: this.scanForm.quantity,
+          palletCode: this.currentPallet.palletCode,
+          orderId: this.orderInfo.id
+        }
+
+        const result = await this.http.post('api/OutboundPicking/ConfirmPicking', request)
+        if (result.status) {
+          this.$message.success('鎷i�夌‘璁ゆ垚鍔�')
+          this.scanForm.barcode = ''
+          this.scanForm.quantity = 1
+          this.loadPickedHistory()
+          this.loadOrderInfo()
+        } else {
+          this.$message.error(result.message)
+        }
+      } catch (error) {
+        this.$message.error('鎷i�夌‘璁ゅけ璐�')
+      }
+    },
+
+    async handleBackToStock() {
+      if (!this.currentPallet) return
+
+      try {
+        await this.$confirm(`纭畾灏嗘墭鐩� ${this.currentPallet.palletCode} 鍥炲簱鍚楋紵`, '鎻愮ず', {
+          type: 'warning'
+        })
+
+        const result = await this.http.post('api/BackToStock/GenerateBackToStockTask', {
+          palletCode: this.currentPallet.palletCode,
+          currentLocation: '鎷i�変綅'
+        })
+
+        if (result.status) {
+          this.$message.success('鍥炲簱浠诲姟宸茬敓鎴�')
+          this.resetCurrentPallet()
+        }
+      } catch (error) {
+        // 鐢ㄦ埛鍙栨秷
+      }
+    },
+
+    async handleDirectOutbound() {
+      if (!this.currentPallet) return
+
+      try {
+        await this.$confirm(`纭畾灏嗘墭鐩� ${this.currentPallet.palletCode} 鐩存帴鍑哄簱鍚楋紵`, '鎻愮ず', {
+          type: 'warning'
+        })
+
+        const result = await this.http.post('api/OutboundPicking/DirectOutbound', {
+          palletCode: this.currentPallet.palletCode
+        })
+
+        if (result.status) {
+          this.$message.success('鐩存帴鍑哄簱鎴愬姛')
+          this.resetCurrentPallet()
+          this.loadOrderInfo()
+        }
+      } catch (error) {
+        // 鐢ㄦ埛鍙栨秷
+      }
+    },
+
+    handleOpenSplit() {
+      if (!this.currentLockInfo) {
+        this.$message.warning('璇峰厛閫夋嫨閿佸畾淇℃伅')
+        return
+      }
+      this.splitVisible = true
+    },
+
+    handleSplitSuccess() {
+      this.$message.success('鎷嗗寘鎴愬姛')
+      this.loadPalletLockInfo()
+    },
+
+    resetCurrentPallet() {
+      this.currentPallet = null
+      this.currentLockInfo = null
+      this.scanForm.palletCode = ''
+    },
+
+    async loadPickedHistory() {
+      const orderId = this.$route.query.orderId
+      if (!orderId) return
+
+      try {
+        const result = await this.http.get(`api/OutboundPicking/GetPickingHistory?orderId=${orderId}`)
+        if (result.status) {
+          this.pickedList = result.data
+        }
+      } catch (error) {
+        console.error('鍔犺浇鎷i�夊巻鍙插け璐�:', error)
+      }
+    },
+
+    async handleCancelPick(row) {
+      try {
+        await this.$confirm('纭畾鎾ら攢杩欐潯鎷i�夎褰曞悧锛�', '鎻愮ず', { type: 'warning' })
+        
+        const result = await this.http.post('api/OutboundPicking/CancelPicking', {
+          pickingHistoryId: row.id
+        })
+
+        if (result.status) {
+          this.$message.success('鎾ら攢鎴愬姛')
+          this.loadPickedHistory()
+          this.loadOrderInfo()
+        }
+      } catch (error) {
+        // 鐢ㄦ埛鍙栨秷
+      }
+    }
+  },
+  mounted() {
+    this.loadOrderInfo()
+    this.loadPickedHistory()
+  }
+}
+</script>
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/SplitPackageModal.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/SplitPackageModal.vue"
new file mode 100644
index 0000000..4316ca9
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/SplitPackageModal.vue"
@@ -0,0 +1,106 @@
+<template>
+  <div class="split-package-modal">
+    <el-form :model="form" :rules="rules" ref="formRef" label-width="120px">
+      <el-form-item label="鍘熸潯鐮�" prop="originalBarcode">
+        <el-input v-model="form.originalBarcode" readonly />
+      </el-form-item>
+      <el-form-item label="鐗╂枡缂栫爜" prop="materielCode">
+        <el-input v-model="form.materielCode" readonly />
+      </el-form-item>
+      <el-form-item label="鎷嗗寘鏁伴噺" prop="splitQuantity" required>
+        <el-input-number 
+          v-model="form.splitQuantity" 
+          :min="1" 
+          :max="maxSplitQuantity"
+          style="width: 100%"
+        />
+        <div class="tip">鏈�澶у彲鎷嗘暟閲�: {{ maxSplitQuantity }}</div>
+      </el-form-item>
+      <el-form-item label="鎿嶄綔浜�" prop="operator">
+        <el-input v-model="form.operator" />
+      </el-form-item>
+    </el-form>
+
+    <div class="modal-footer">
+      <el-button @click="$emit('close')">鍙栨秷</el-button>
+      <el-button type="primary" @click="handleConfirm" :loading="loading">
+        纭鎷嗗寘
+      </el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    lockInfo: {
+      type: Object,
+      default: null
+    }
+  },
+  data() {
+    return {
+      form: {
+        outStockLockInfoId: 0,
+        originalBarcode: '',
+        materielCode: '',
+        splitQuantity: 1,
+        operator: ''
+      },
+      rules: {
+        splitQuantity: [
+          { required: true, message: '璇疯緭鍏ユ媶鍖呮暟閲�', trigger: 'blur' },
+          { type: 'number', min: 1, message: '鎷嗗寘鏁伴噺蹇呴』澶т簬0', trigger: 'blur' }
+        ]
+      },
+      loading: false
+    }
+  },
+  computed: {
+    maxSplitQuantity() {
+      if (!this.lockInfo) return 0
+      return this.lockInfo.assignQuantity - this.lockInfo.pickedQty
+    }
+  },
+  watch: {
+    lockInfo: {
+      immediate: true,
+      handler(newVal) {
+        if (newVal) {
+          this.form.outStockLockInfoId = newVal.id
+          this.form.originalBarcode = newVal.currentBarcode
+          this.form.materielCode = newVal.materielCode
+          this.form.operator = '褰撳墠鐢ㄦ埛' // 瀹為檯搴斾粠鐢ㄦ埛淇℃伅鑾峰彇
+        }
+      }
+    }
+  },
+  methods: {
+    async handleConfirm() {
+      const valid = await this.$refs.formRef.validate()
+      if (!valid) return
+
+      if (this.form.splitQuantity > this.maxSplitQuantity) {
+        this.$message.warning(`鎷嗗寘鏁伴噺涓嶈兘澶т簬${this.maxSplitQuantity}`)
+        return
+      }
+
+      this.loading = true
+      try {
+        const result = await this.http.post('api/OutboundPicking/SplitPackage', this.form)
+        if (result.status) {
+          this.$message.success('鎷嗗寘鎴愬姛')
+          this.$emit('success', result.data)
+          this.$emit('close')
+        } else {
+          this.$message.error(result.message)
+        }
+      } catch (error) {
+        this.$message.error('鎷嗗寘鎿嶄綔澶辫触')
+      } finally {
+        this.loading = false
+      }
+    }
+  }
+}
+</script>
\ No newline at end of file
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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db" "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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db"
index 41f613e..9338314 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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db"
+++ "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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db"
Binary files differ
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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-wal" "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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-wal"
index ba21f9e..59bbf77 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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-wal"
+++ "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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-wal"
Binary files differ
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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db" "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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db"
index 4e92bf4..f89f26c 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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db"
+++ "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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db"
Binary files differ
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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-wal" "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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-wal"
index d4eea7a..306ad96 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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-wal"
+++ "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/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-wal"
Binary files differ
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_BasicService/InvokeMESService.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_BasicService/InvokeMESService.cs"
index 0b48c40..e41ddf5 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_BasicService/InvokeMESService.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_BasicService/InvokeMESService.cs"
@@ -1,6 +1,7 @@
 锘縰sing Microsoft.Extensions.Logging;
 using Newtonsoft.Json;
 using Org.BouncyCastle.Asn1.Ocsp;
+using SqlSugar;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -9,10 +10,13 @@
 using System.Security.Policy;
 using System.Text;
 using System.Threading.Tasks;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseRepository;
 using WIDESEA_DTO.Basic;
 using WIDESEA_DTO.Inbound;
 using WIDESEA_DTO.Outbound;
 using WIDESEA_IBasicService;
+using WIDESEA_Model.Models;
 
 namespace WIDESEA_BasicService
 {
@@ -22,13 +26,22 @@
         private readonly ILogger<InvokeMESService> _logger;
         private string UserName = "12312";
         private string Password = "1";
-        public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger)
+
+        private readonly IRepository<Dt_FeedbackToMes> _feedbacktomesRepository;
+        private readonly IRepository<Dt_StockInfoDetail> _stockInfoDetailRepository;
+        private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
+        private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
+        public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger, IRepository<Dt_FeedbackToMes> feedbacktomesRepository, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrder> inboundOrderRepository)
         {
             _httpClientFactory = httpClientFactory;
             _logger = logger;
+            _feedbacktomesRepository = feedbacktomesRepository;
+            _stockInfoDetailRepository = stockInfoDetailRepository;
+            _stockInfoRepository = stockInfoRepository;
+            _inboundOrderRepository = inboundOrderRepository;
         }
 
-        public async Task<ResponseModel> FeedbackInbound(  FeedbackInboundRequestModel model)
+        public async Task<ResponseModel> FeedbackInbound(FeedbackInboundRequestModel model)
         {
             string json = JsonConvert.SerializeObject(model);
             var content = new StringContent(json, Encoding.UTF8, "application/json");
@@ -45,10 +58,10 @@
                 throw new HttpRequestException(body);
             }
 
-           return JsonConvert.DeserializeObject<ResponseModel>(body);
+            return JsonConvert.DeserializeObject<ResponseModel>(body);
         }
 
-        public async Task FeedbackOutbound(  FeedbackOutboundRequestModel model)
+        public async Task FeedbackOutbound(FeedbackOutboundRequestModel model)
         {
             string json = JsonConvert.SerializeObject(model);
             var content = new StringContent(json, Encoding.UTF8, "application/json");
@@ -81,7 +94,7 @@
 
             var client = _httpClientFactory.CreateClient("MESUrl");
             // 鎷兼帴 URL 鍙傛暟
-           // string url = $"{client.BaseAddress}UserTicket={userTicket}&API={api}&UserData={userDataEncoded}";
+            // string url = $"{client.BaseAddress}UserTicket={userTicket}&API={api}&UserData={userDataEncoded}";
 
 
             client.DefaultRequestHeaders.Clear();
@@ -141,6 +154,84 @@
             }
         }
 
-    }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="orderNos"></param>
+        /// <param name="inout">鍏ュ簱浼�1  鍑哄簱浼�2</param>
+        /// <returns></returns>
+        public async Task<WebResponseContent> BatchOrderFeedbackToMes(List<string> orderNos, int inout)
+        {
+            if (inout == 1)
+            {
+                foreach (var orderNo in orderNos)
+                {
+                    try
+                    {
+                        var stockinfos = _stockInfoRepository.Db.Queryable<Dt_StockInfo>("info").Where(info => info.StockStatus == 6)
+                                        .Where(it => SqlFunc.Subqueryable<Dt_StockInfoDetail>().Where(s => s.StockId == it.Id && s.OrderNo == orderNo).Any())
+                                        .ToList();
+                        var feeds = _feedbacktomesRepository.Db.Queryable<Dt_FeedbackToMes>().Where(x => x.OrderNo == orderNo && x.ReportStatus == 1).Select(o => o.PalletCode).ToList();
+                        var unreports = stockinfos.Where(x => !feeds.Contains(x.PalletCode)).ToList();
+                        if (unreports!=null && !unreports.Any()) {
+                            return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖浼犵殑鏁版嵁");
+                        }
+                        foreach (var item in unreports)
+                        {
+                            var lists = _stockInfoDetailRepository.Db.Queryable<Dt_StockInfoDetail>().Where(x => x.StockId == item.Id).ToList();
+                            if (lists.Any())
+                            {
+                                var inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().First(x => x.InboundOrderNo == lists.FirstOrDefault().OrderNo);
+                                if (inboundOrder != null)
+                                {
+                                    var feedmodel = new FeedbackInboundRequestModel
+                                    {
+                                        reqCode = Guid.NewGuid().ToString(),
+                                        reqTime = DateTime.Now.ToString(),
+                                        business_type = inboundOrder.BusinessType,
+                                        factoryArea = inboundOrder.FactoryArea,
+                                        operationType = 1,
+                                        orderNo = inboundOrder.UpperOrderNo,
+                                        status = inboundOrder.OrderStatus,
+                                        details = new List<FeedbackInboundDetailsModel>()
 
+                                    };
+                                    
+                                    var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.SupplyCode, item.BatchNo, item.InboundOrderRowNo, item.Unit, item.WarehouseCode })
+                                       .Select(group => new FeedbackInboundDetailsModel
+                                       {
+                                           materialCode = group.Key.MaterielCode,
+                                           supplyCode = group.Key.SupplyCode,
+                                           batchNo = group.Key.BatchNo,
+                                           lineNo = group.Key.InboundOrderRowNo,
+                                           // warehouseCode = group.Key.WarehouseCode=="0"?"1072": group.Key.WarehouseCode,
+                                           warehouseCode = "1072",
+                                           unit = group.Key.Unit,
+                                           barcodes = group.Select(row => new FeedbackBarcodesModel
+                                           {
+                                               barcode = row.Barcode,
+                                               qty = row.StockQuantity
+                                           }).ToList()
+                                       }).ToList();
+                                    feedmodel.details = groupedData;
+                                    var result = await FeedbackInbound(feedmodel);
+                                    if (result != null && result.code == 200)
+                                    {
+                                        _feedbacktomesRepository.Db.Insertable(new Dt_FeedbackToMes { OrderNo = orderNo, PalletCode = item.PalletCode, ReportStatus = 1 }).ExecuteCommand();
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        _logger.LogInformation("InvokeMESService  BatchOrderFeedbackToMes 鍥炲啓MES澶辫触:  " + ex.Message);
+                        return WebResponseContent.Instance.Error(ex.Message);
+                    }
+
+                }
+            }
+            return WebResponseContent.Instance.OK();
+        }
+    }
 }
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_BasicService/MaterielToMesService.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_BasicService/MaterielToMesService.cs"
index ecd6300..9b291b1 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_BasicService/MaterielToMesService.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_BasicService/MaterielToMesService.cs"
@@ -16,9 +16,9 @@
 namespace WIDESEA_BasicService
 {
     internal class MaterielToMesService : ServiceBase<Dt_MaterielToMes, IRepository<Dt_MaterielToMes>>, IMaterielToMesService
-    { 
-
-        public MaterielToMesService(IRepository<Dt_MaterielToMes> BaseDal) : base(BaseDal)
+    {
+     
+        public MaterielToMesService(IRepository<Dt_MaterielToMes> BaseDal ) : base(BaseDal)
         {
             
         }
@@ -48,5 +48,8 @@
 
             
         }
+
+
+       
     }
 }
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_Common/StockEnum/OutLockStockStatusEnum.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_Common/StockEnum/OutLockStockStatusEnum.cs"
index 01dbf7c..7507b14 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_Common/StockEnum/OutLockStockStatusEnum.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_Common/StockEnum/OutLockStockStatusEnum.cs"
@@ -7,6 +7,21 @@
 
 namespace WIDESEA_Common.StockEnum
 {
+
+    //public enum OutLockStockStatusEnum
+    //{
+    //    宸插垎閰� = 1,
+    //    鍑哄簱涓� = 2,
+    //    宸叉嫞閫� = 3,
+    //    宸插嚭搴� = 4,
+    //    宸插洖搴� = 5
+    //}
+    public enum SplitPackageStatusEnum
+    {
+        宸叉媶鍖� = 1,
+        宸叉嫞閫� = 2,
+        宸插洖搴� = 3
+    }
     public enum OutLockStockStatusEnum
     {
         [Description("宸插垎閰�")]
@@ -15,11 +30,26 @@
         [Description("鍑哄簱涓�")]
         鍑哄簱涓� = 1,
 
+        [Description("閮ㄥ垎鎷i��")]
+        閮ㄥ垎鎷i�� = 2,
+
+        [Description("宸叉嫞閫�")]
+        宸叉嫞閫� =3,
+
+        [Description("宸插嚭搴�")]
+        宸插嚭搴� = 4,
+
         [Description("鍑哄簱瀹屾垚")]
-        鍑哄簱瀹屾垚 = 2,
+        鍑哄簱瀹屾垚 = 5,
 
         [Description("鎷i�夊畬鎴�")]
-        鎷i�夊畬鎴� = 3,
+        鎷i�夊畬鎴� =6,
+
+        [Description("鍥炲簱涓�")]
+        鍥炲簱涓� = 7,
+
+        [Description("宸插洖搴�")]
+        宸插洖搴� =8,
 
         [Description("鎾ら攢")]
         鎾ら攢 = 99
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_DTO/Inbound/PalletSumQuantityDTO.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_DTO/Inbound/PalletSumQuantityDTO.cs"
index 9cd59d3..062fc8d 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_DTO/Inbound/PalletSumQuantityDTO.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_DTO/Inbound/PalletSumQuantityDTO.cs"
@@ -14,4 +14,10 @@
 
         public string UniqueUnit { get; set; }
     }
+
+    public class BatchOrderFeedbackToMesDto
+    {
+       public List<string> orderNos { get; set; }
+        public int inout { 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_DTO/Outbound/OutboundOrderGetDTO.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_DTO/Outbound/OutboundOrderGetDTO.cs"
index e029706..5eeecc4 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_DTO/Outbound/OutboundOrderGetDTO.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_DTO/Outbound/OutboundOrderGetDTO.cs"
@@ -12,4 +12,49 @@
         public int pageNo { get; set; }
 
     }
+
+    // 鎷嗗寘璇锋眰
+    public class SplitPackageRequest
+    {
+        public int OutStockLockInfoId { get; set; }
+        public string MaterielCode { get; set; }
+        public decimal SplitQuantity { get; set; }
+        public string Operator { get; set; }
+    }
+
+ 
+    public class PickingConfirmRequest
+    {
+        public int OrderDetailId { get; set; }
+        public string Barcode { get; set; }
+        public string MaterielCode { get; set; }
+        public decimal PickQuantity { get; set; }
+        public string LocationCode { get; set; }
+        public string PalletCode { get; set; }
+    }     
+
+    public class DirectOutboundRequest
+    {
+        public string PalletCode { get; set; }
+    }
+
+    public class CancelPickingRequest
+    {
+        public int PickingHistoryId { get; set; }
+    }
+
+    public class BackToStockRequest
+    {
+        public string PalletCode { get; set; }
+        public string CurrentLocation { get; set; }
+        public string TargetLocation { get; set; }
+        public string Operator { get; set; }
+    }
+
+    public class BackToStockCompleteRequest
+    {
+        public string TaskNum { get; set; }
+        public string TargetLocation { get; set; }
+        public DateTime CompleteTime { 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_IBasicService/IInvokeMESService.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_IBasicService/IInvokeMESService.cs"
index b4be4dd..f6be106 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_IBasicService/IInvokeMESService.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_IBasicService/IInvokeMESService.cs"
@@ -19,5 +19,8 @@
         Task<string> GetToken(String username, string password);
 
         Task<ResponseModel> NewMaterielToMes(MaterielToMesDTO model);
+
+
+        Task<WebResponseContent> BatchOrderFeedbackToMes(List<string> orderNos, int inout);
     }
 }
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/IOutStockLockInfoService.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/IOutStockLockInfoService.cs"
index 6d7bef1..67f3519 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/IOutStockLockInfoService.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/IOutStockLockInfoService.cs"
@@ -18,8 +18,12 @@
         /// 
         /// </summary>
         IRepository<Dt_OutStockLockInfo> Repository { get; }
-
+ 
+        Task<List<Dt_OutStockLockInfo>> GetByOrderDetailId(int orderDetailId);
+        Task<List<Dt_OutStockLockInfo>> GetByPalletCode(string palletCode, int? status = null);
         Dt_OutStockLockInfo GetOutStockLockInfo(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, Dt_StockInfo outStock, decimal assignQuantity, int? taskNum = null);
-
+        Dt_OutStockLockInfo GetOutStockLockInfo(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, Dt_StockInfo outStock, decimal assignQuantity, string barcode = null, int? taskNum = null);
+        Task<List<Dt_OutStockLockInfo>> GetPalletLockInfos(string palletCode);
+        Task<WebResponseContent> UpdateLockInfoBarcode(int lockInfoId, string newBarcode);
     }
 }
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/IOutboundOrderService.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/IOutboundOrderService.cs"
index b8c2661..0f47b1c 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/IOutboundOrderService.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/IOutboundOrderService.cs"
@@ -17,5 +17,7 @@
         IRepository<Dt_OutboundOrder> Repository { get; }
 
         WebResponseContent ReceiveOutboundOrder(Dt_OutboundOrder model, int operateType);
+
+        Task<WebResponseContent> GetById(int id);
     }
 }
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"
new file mode 100644
index 0000000..a0c4c6f
--- /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_IOutboundService/IOutboundPickingService.cs"
@@ -0,0 +1,24 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseRepository;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_DTO.Outbound;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_IOutboundService
+{
+    public interface IOutboundPickingService : IService<Dt_PickingRecord>
+    {
+        IRepository<Dt_PickingRecord> Repository { get; }
+
+        Task<WebResponseContent> CancelPicking(CancelPickingRequest request);
+        Task<WebResponseContent> ConfirmPicking(PickingConfirmRequest request);
+        Task<List<Dt_PickingRecord>> GetPickingHistory(int orderId);
+
+        Task<WebResponseContent> GetPalletOutboundStatus(string palletCode);
+    }
+}
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/ISplitPackageService.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/ISplitPackageService.cs"
new file mode 100644
index 0000000..aeeb77d
--- /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_IOutboundService/ISplitPackageService.cs"
@@ -0,0 +1,20 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseRepository;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_DTO.Outbound;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_IOutboundService
+{
+    public interface ISplitPackageService : IService<Dt_SplitPackageRecord>
+    {
+        IRepository<Dt_SplitPackageRecord> Repository { get; }
+
+        Task<WebResponseContent> SplitPackage(SplitPackageRequest request);
+    }
+}
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_ITaskInfoService/ITaskService.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_ITaskInfoService/ITaskService.cs"
index b66106d..34b8861 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_ITaskInfoService/ITaskService.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_ITaskInfoService/ITaskService.cs"
@@ -43,5 +43,8 @@
         Task<WebResponseContent> PalletOutboundTask(string endStation, string palletCode = "");
 
         Task<WebResponseContent> TaskCompleted(string taskNum);
+
+
+        WebResponseContent GenerateOutboundTasks(int[] keys);
     }
 }
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/Dt_FeedbackToMes.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/Dt_FeedbackToMes.cs"
new file mode 100644
index 0000000..36c9614
--- /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/Dt_FeedbackToMes.cs"
@@ -0,0 +1,59 @@
+锘縰sing SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Core.DB.Models;
+
+namespace WIDESEA_Model.Models
+{
+   
+    // <summary>
+    /// 
+    ///</summary>
+    [SugarTable("Dt_FeedbackToMes")]
+    public class Dt_FeedbackToMes : BaseEntity
+    {
+
+
+        /// <summary>
+        /// 澶�  娉�:
+        /// 榛樿鍊�:
+        ///</summary>
+        [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "涓婚敭")]
+        public int Id { get; set; }
+
+        /// <summary>
+        /// 澶�  娉�:
+        /// 榛樿鍊�:
+        ///</summary>
+        [SugarColumn(ColumnName = "OrderNo")]
+        public string OrderNo { get; set; } = null!;
+
+        /// <summary>
+        /// 澶�  娉�:
+        /// 榛樿鍊�:
+        ///</summary>
+        [SugarColumn(ColumnName = "PalletCode")]
+        public string PalletCode { get; set; } = null!;
+
+        /// <summary>
+        /// 澶�  娉�:
+        /// 榛樿鍊�:
+        ///</summary>
+        [SugarColumn(ColumnName = "ReportStatus")]
+        public int ReportStatus { get; set; }
+
+        /// <summary>
+        /// 澶�  娉�:
+        /// 榛樿鍊�:
+        ///</summary>
+        [SugarColumn(ColumnName = "Remark")]
+        public string Remark { get; set; } = null!;
+
+  
+
+
+    }
+}
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_OutboundLockInfo.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_OutboundLockInfo.cs"
index 9c9e499..f85fe7a 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_OutboundLockInfo.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_OutboundLockInfo.cs"
@@ -82,6 +82,11 @@
         public decimal AssignQuantity {  get; set; }
 
         /// <summary>
+        /// 宸叉嫞閫夋暟閲� 
+        /// </summary>
+        [SugarColumn(IsNullable = false, ColumnDescription = "宸叉嫞閫夋暟閲�")]
+        public decimal PickedQty { get; set; } // 
+        /// <summary>
         /// 璐т綅缂栧彿
         /// </summary>
         [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "璐т綅缂栧彿")]
@@ -104,9 +109,21 @@
         public int? TaskNum { get; set; }
 
         /// <summary>
-        /// 鐘舵��
+        /// 鐘舵�� 鐘舵�侊細0-宸插垎閰� 1-閮ㄥ垎鎷i�� 2-宸叉嫞閫� 3-宸插畬鎴�
         /// </summary>
         [SugarColumn(IsNullable = false, ColumnDescription = "鐘舵��")]
         public int Status { get; set; }
+
+        [SugarColumn(Length = 100)]
+        public string CurrentBarcode { get; set; } // 褰撳墠鏉$爜锛堟媶鍖呭悗鍙兘鍙樺寲锛�
+
+        public decimal OriginalLockQuantity { get; set; } // 鍘熷閿佸畾鏁伴噺
+        public int IsSplitted { get; set; } // 鏄惁宸叉媶鍖� 0-鍚� 1-鏄�
+
+        public int? ParentLockId { get; set; }
+
+        [Navigate(NavigateType.OneToOne, nameof(StockInfo))]//涓�瀵逛竴 SchoolId鏄疭tudentA绫婚噷闈㈢殑
+        public Dt_StockInfo StockInfo { get; set; } //涓嶈兘璧嬪�煎彧鑳芥槸null
+
     }
 }
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_PickingRecord.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_PickingRecord.cs"
new file mode 100644
index 0000000..8700510
--- /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/Dt_PickingRecord.cs"
@@ -0,0 +1,95 @@
+锘縰sing SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Core.DB.Models;
+
+namespace WIDESEA_Model.Models
+{
+    
+    /// <summary>
+    /// 鎷i�夎褰曡〃
+    /// </summary>
+ 
+    [SugarTable(nameof(Dt_PickingRecord), "鎷i�夎褰曡〃")]
+
+    public class Dt_PickingRecord : BaseEntity
+    {
+        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+        public int Id { get; set; }
+
+        public int OrderDetailId { get; set; }
+
+        [SugarColumn(Length = 100)]
+        public string Barcode { get; set; }
+
+        public decimal PickQuantity { get; set; }
+
+        public DateTime PickTime { get; set; } = DateTime.Now;
+
+        [SugarColumn(Length = 50)]
+        public string Operator { get; set; }
+
+        [SugarColumn(Length = 50)]
+        public string LocationCode { get; set; }
+
+        public int StockId { get; set; }
+    }
+ 
+
+    /// <summary>
+    /// 鍥炲簱璁板綍琛�
+    /// </summary>
+    [SugarTable("Dt_ReturnStockRecord")]
+    public class Dt_ReturnStockRecord : BaseEntity
+    {
+        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+        public long Id { get; set; }
+
+        public string TaskNo { get; set; }
+        public string PalletId { get; set; }
+        public string LocationId { get; set; }
+        public string NewLocationId { get; set; }
+
+        /// <summary>
+        /// 鍥炲簱鏁伴噺
+        /// </summary>
+        public decimal ReturnQty { get; set; }
+    
+        public DateTime ReturnTime { get; set; }
+        /// <summary>
+        /// 0-寰呭洖搴� 1-宸插洖搴�
+        /// </summary>
+        public int Status { get; set; }
+    }
+
+    /// <summary>
+    /// 鎷嗗寘璁板綍琛�
+    /// </summary>
+    [SugarTable("Dt_SplitPackageRecord")]
+    public class Dt_SplitPackageRecord: BaseEntity
+    {
+        [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+        public int Id { get; set; }
+
+        public int OutStockLockInfoId { get; set; } // 鍏宠仈鐨勫嚭搴撻攣瀹氫俊鎭�
+        public string OriginalBarcode { get; set; } // 鍘熸潯鐮�
+        public string NewBarcode { get; set; } // 鏂版潯鐮�
+ 
+        /// <summary>
+        /// 鎷嗗垎鏁伴噺锛堟柊鏉$爜鏁伴噺锛�
+        /// </summary>
+        public decimal SplitQty { get; set; }
+ 
+
+ 
+        public string MaterielCode { get; set; } // 鐗╂枡缂栫爜
+        public DateTime SplitTime { get; set; } = DateTime.Now;
+        public string Operator { get; set; } // 鎿嶄綔浜�
+        public int Status { get; set; } // 鐘舵�侊細1-宸叉媶鍖� 2-宸叉嫞閫� 3-宸插洖搴�
+    }
+
+    
+}
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/Stock/Dt_StockInfoDetail.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/Stock/Dt_StockInfoDetail.cs"
index 0786329..a69b904 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/Stock/Dt_StockInfoDetail.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/Stock/Dt_StockInfoDetail.cs"
@@ -131,5 +131,8 @@
         /// </summary>
         [SugarColumn(IsNullable = true, ColumnDescription = "澶囨敞")]
         public string Remark { get; set; }
+
+        [SugarColumn(IsIgnore = true)]
+        public Dt_StockInfo StockInfo { 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/OutStockLockInfoService.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/OutStockLockInfoService.cs"
index a48a488..ca2bf8b 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/OutStockLockInfoService.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/OutStockLockInfoService.cs"
@@ -46,6 +46,7 @@
                 OrderDetailId = outboundOrderDetail.Id,
                 OrderNo = outboundOrder.OrderNo,
                 OrderType = outboundOrder.OrderType,
+
                 OriginalQuantity = outStock.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode).Sum(x => x.StockQuantity),
                 Status = taskNum == null ? OutLockStockStatusEnum.宸插垎閰�.ObjToInt() : OutLockStockStatusEnum.鍑哄簱涓�.ObjToInt(),
                 StockId = outStock.Id,
@@ -58,5 +59,137 @@
 
             return outStockLockInfo;
         }
+
+        /// <summary>
+        /// 鍒涘缓鍑哄簱閿佸畾淇℃伅
+        /// </summary>
+        public Dt_OutStockLockInfo GetOutStockLockInfo(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, Dt_StockInfo outStock, decimal assignQuantity, string barcode = null, int? taskNum = null)
+        {
+            // 鑾峰彇搴撳瓨鏄庣粏涓殑鏉$爜淇℃伅锛堝鏋滄湭鎸囧畾鏉$爜锛屼娇鐢ㄧ涓�涓彲鐢ㄦ潯鐮侊級
+            var stockDetails = outStock.Details.Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode && x.StockQuantity > x.OutboundQuantity)
+                .OrderBy(x => x.ProductionDate).ToList();
+
+            if (!stockDetails.Any())
+            {
+                throw new Exception($"鏈壘鍒扮墿鏂橻{outboundOrderDetail.MaterielCode}]鐨勫彲鐢ㄥ簱瀛樻槑缁�");
+            }
+
+            // 纭畾鏉$爜锛堝鏋滄湭鎸囧畾锛屼娇鐢ㄦ渶鏃╁叆搴撶殑鏉$爜锛�
+            var targetBarcode = barcode;
+            if (string.IsNullOrEmpty(targetBarcode))
+            {
+                targetBarcode = stockDetails.First().Barcode;
+            }
+            // 鑾峰彇璇ユ潯鐮佺殑鍙敤鏁伴噺
+            var barcodeDetail = stockDetails.FirstOrDefault(x => x.Barcode == targetBarcode);
+            if (barcodeDetail == null)
+            {
+                throw new Exception($"鏉$爜[{targetBarcode}]鍦ㄥ簱瀛樹腑涓嶅瓨鍦�");
+            }
+
+            return new Dt_OutStockLockInfo()
+            {
+                PalletCode = outStock.PalletCode,
+                AssignQuantity = assignQuantity,
+                MaterielCode = outboundOrderDetail.MaterielCode,
+                BatchNo = outboundOrderDetail.BatchNo ?? outStock.Details.FirstOrDefault()?.BatchNo,
+                LocationCode = outStock.LocationCode,
+                MaterielName = outboundOrderDetail.MaterielName,
+                OrderDetailId = outboundOrderDetail.Id,
+                OrderNo = outboundOrder.OrderNo,
+                OrderQuantity = outboundOrderDetail.OrderQuantity,
+                OriginalQuantity = outStock.Details
+                    .Where(x => x.MaterielCode == outboundOrderDetail.MaterielCode)
+                    .Sum(x => x.StockQuantity),
+                Status = taskNum == null ? (int)OutLockStockStatusEnum.宸插垎閰� : (int)OutLockStockStatusEnum.鍑哄簱涓�,
+                StockId = outStock.Id,
+                TaskNum = taskNum,
+                Unit = outboundOrderDetail.Unit,
+
+
+                // 鏂板瀛楁璧嬪��
+                CurrentBarcode = targetBarcode, // 褰撳墠鍒嗛厤鐨勬潯鐮�
+                OriginalLockQuantity = assignQuantity, // 鍘熷閿佸畾鏁伴噺
+                IsSplitted = 0 // 鍒濆鏈媶鍖�
+            };
+        }
+
+        /// <summary>
+        /// 鏍规嵁璁㈠崟鏄庣粏ID鑾峰彇鍑哄簱閿佸畾淇℃伅
+        /// </summary>
+        public async Task<List<Dt_OutStockLockInfo>> GetByOrderDetailId(int orderDetailId)
+        {
+            return await Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(x => x.OrderDetailId == orderDetailId)
+                .OrderBy(x => x.Id)
+                .ToListAsync();
+        }
+
+        /// <summary>
+        /// 鏍规嵁鎵樼洏缂栧彿鑾峰彇鍑哄簱閿佸畾淇℃伅
+        /// </summary>
+        public async Task<List<Dt_OutStockLockInfo>> GetByPalletCode(string palletCode, int? status = null)
+        {
+            var query = Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(x => x.PalletCode == palletCode);
+
+            if (status.HasValue)
+            {
+                query = query.Where(x => x.Status == status.Value);
+            }
+
+            return await query.OrderBy(x => x.Id).ToListAsync();
+        }
+
+        /// <summary>
+        /// 鑾峰彇鎵樼洏鐨勯攣瀹氫俊鎭�
+        /// </summary>
+        public async Task<List<Dt_OutStockLockInfo>> GetPalletLockInfos(string palletCode)
+        {
+            return await Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(x => x.PalletCode == palletCode && x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+                .ToListAsync();
+        }
+
+        /// <summary>
+        /// 鏇存柊鍑哄簱閿佸畾淇℃伅鐨勬潯鐮侊紙鐢ㄤ簬鎷嗗寘鎿嶄綔锛�
+        /// </summary>
+        public async Task<WebResponseContent> UpdateLockInfoBarcode(int lockInfoId, string newBarcode)
+        {
+            try
+            {
+                var lockInfo = await Db.Queryable<Dt_OutStockLockInfo>()
+                    .Where(x => x.Id == lockInfoId)
+                    .FirstAsync();
+
+                if (lockInfo == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒板嚭搴撻攣瀹氫俊鎭�");
+
+                // 楠岃瘉鏂版潯鐮佹槸鍚﹀瓨鍦�
+                var stockDetail = await Db.Queryable<Dt_StockInfoDetail>()
+                    .Where(x => x.Barcode == newBarcode &&
+                               x.StockId == lockInfo.StockId &&
+                               x.MaterielCode == lockInfo.MaterielCode)
+                    .FirstAsync();
+
+                if (stockDetail == null)
+                    return WebResponseContent.Instance.Error("鏂版潯鐮佸湪搴撳瓨涓笉瀛樺湪");
+
+                // 鏇存柊鏉$爜鍜屾媶鍖呯姸鎬�
+                lockInfo.CurrentBarcode = newBarcode;
+                lockInfo.IsSplitted = 1;
+
+                await Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+                return WebResponseContent.Instance.OK("鏇存柊鏉$爜鎴愬姛");
+            }
+            catch (Exception ex)
+            {
+                return WebResponseContent.Instance.Error($"鏇存柊鏉$爜澶辫触: {ex.Message}");
+            }
+        }
+
+
+
     }
 }
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/OutboundOrderDetailService.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/OutboundOrderDetailService.cs"
index 3e6904c..fdf2e9c 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/OutboundOrderDetailService.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/OutboundOrderDetailService.cs"
@@ -1,4 +1,5 @@
 锘縰sing WIDESEA_Common.LocationEnum;
+using WIDESEA_Common.StockEnum;
 using WIDESEA_Core;
 using WIDESEA_Core.BaseRepository;
 using WIDESEA_Core.BaseServices;
@@ -21,9 +22,10 @@
         private readonly ILocationInfoService _locationInfoService;
         private readonly IBasicService _basicService;
         private readonly IRecordService _recordService;
+        private readonly IOutboundOrderService _outboundOrderService;
         private readonly ILocationStatusChangeRecordService _locationStatusChangeRecordService;
 
-        public OutboundOrderDetailService(IRepository<Dt_OutboundOrderDetail> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockService stockService, IOutStockLockInfoService outStockLockInfoService, IBasicService basicService, IRecordService recordService, ILocationInfoService locationInfoService, ILocationStatusChangeRecordService locationStatusChangeRecordService) : base(BaseDal)
+        public OutboundOrderDetailService(IRepository<Dt_OutboundOrderDetail> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockService stockService, IOutStockLockInfoService outStockLockInfoService, IBasicService basicService, IRecordService recordService, ILocationInfoService locationInfoService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IOutboundOrderService outboundOrderService) : base(BaseDal)
         {
             _unitOfWorkManage = unitOfWorkManage;
             _stockService = stockService;
@@ -32,90 +34,259 @@
             _recordService = recordService;
             _locationInfoService = locationInfoService;
             _locationStatusChangeRecordService = locationStatusChangeRecordService;
+            _outboundOrderService = outboundOrderService;
         }
 
+
         /// <summary>
-        /// 
+        /// 鍒嗛厤鍑哄簱搴撳瓨  鎸夊厛杩涘厛鍑哄師鍒欏垎閰�
         /// </summary>
-        /// <param name="outboundOrderDetails"></param>
-        /// <returns></returns>
         public (List<Dt_StockInfo>, List<Dt_OutboundOrderDetail>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) AssignStockOutbound(List<Dt_OutboundOrderDetail> outboundOrderDetails)
         {
             if (!outboundOrderDetails.Any())
             {
-                throw new Exception($"鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
+                throw new Exception("鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
             }
 
             if (outboundOrderDetails.GroupBy(x => x.OrderId).Count() > 1)
             {
-                throw new Exception($"璇峰嬁鍚屾椂鎿嶄綔澶氫釜鍗曟嵁鏄庣粏");
+                throw new Exception("璇峰嬁鍚屾椂鎿嶄綔澶氫釜鍗曟嵁鏄庣粏");
             }
-            Dt_OutboundOrder outboundOrder = Repository.Db.Queryable<Dt_OutboundOrder>().Where(x => x.Id == outboundOrderDetails.FirstOrDefault().OrderId).First();
-            List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>();
-            List<Dt_OutboundOrderDetail> groupDetails = outboundOrderDetails.GroupBy(x => new { x.MaterielCode, x.BatchNo }).Select(x => new Dt_OutboundOrderDetail { OrderQuantity = x.Sum(v => v.OrderQuantity) - x.Sum(v => v.LockQuantity), MaterielCode = x.Key.MaterielCode, BatchNo = x.Key.BatchNo }).ToList();
 
+            var outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+                .First(x => x.Id == outboundOrderDetails.First().OrderId);
+
+            List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>();
             List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>();
             List<Dt_LocationInfo> locationInfos = new List<Dt_LocationInfo>();
+
+            // 鎸夌墿鏂欏拰鎵规鍒嗙粍澶勭悊
+            var groupDetails = outboundOrderDetails
+                .GroupBy(x => new { x.MaterielCode, x.BatchNo })
+                .Select(x => new
+                {
+                    MaterielCode = x.Key.MaterielCode,
+                    BatchNo = x.Key.BatchNo,
+                    Details = x.ToList(),
+                    TotalNeedQuantity = x.Sum(v => v.OrderQuantity - v.OverOutQuantity - v.LockQuantity)
+                })
+                .Where(x => x.TotalNeedQuantity > 0)
+                .ToList();
+
             foreach (var item in groupDetails)
             {
-                var originalNeedQuantity = item.OrderQuantity;
+                var needQuantity = item.TotalNeedQuantity;
 
-                var needQuantity = originalNeedQuantity;
-
+                // 鑾峰彇鍙敤搴撳瓨锛堟寜鍏堣繘鍏堝嚭鎺掑簭锛�
                 List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo);
                 if (!stockInfos.Any())
                 {
-                    throw new Exception($"鏈壘鍒板彲鍒嗛厤搴撳瓨");
+                    throw new Exception($"鐗╂枡[{item.MaterielCode}]鎵规[{item.BatchNo}]鏈壘鍒板彲鍒嗛厤搴撳瓨");
                 }
-                List<Dt_StockInfo> autoAssignStocks = _stockService.StockInfoService.GetOutboundStocks(stockInfos, item.MaterielCode, needQuantity, out decimal residueQuantity);
 
-                item.LockQuantity += needQuantity - residueQuantity;
-                outStocks.AddRange(autoAssignStocks);
-                var assignQuantity = needQuantity - residueQuantity;
+                // 鍒嗛厤搴撳瓨锛堟寜鍏堣繘鍏堝嚭锛�
+                List<Dt_StockInfo> autoAssignStocks = _stockService.StockInfoService.GetOutboundStocks(
+                    stockInfos, item.MaterielCode, needQuantity, out decimal residueQuantity);
 
-                List<Dt_OutboundOrderDetail> details = outboundOrderDetails.Where(x => !string.IsNullOrEmpty(x.BatchNo) ? x.BatchNo == item.BatchNo : true && x.MaterielCode == item.MaterielCode).ToList();
-
-                for (int i = 0; i < details.Count; i++)
+                if (residueQuantity > 0)
                 {
-                    var orderQuantity = details[i].OrderQuantity;
-                    for (int j = 0; j < autoAssignStocks.Count; j++)
-                    {
-                        var detailAssignQuantity = outStockLockInfos.Where(x => !string.IsNullOrEmpty(x.BatchNo) ? x.BatchNo == item.BatchNo : true && x.MaterielCode == item.MaterielCode && x.OrderDetailId == details[i].Id).Sum(x => x.AssignQuantity);//鍑哄簱璁㈠崟鏄庣粏宸插垎閰嶆暟閲�
-
-                        var palletAssignQuantity = outStockLockInfos.Where(x => x.BatchNo == item.BatchNo && x.MaterielCode == item.MaterielCode && x.PalletCode == autoAssignStocks[j].PalletCode).Sum(x => x.AssignQuantity);//鍑哄簱璇︽儏宸插垎閰嶆暟閲�
-                        if (string.IsNullOrEmpty(item.BatchNo))
-                        {
-                            palletAssignQuantity = outStockLockInfos.Where(x => x.MaterielCode == item.MaterielCode && x.PalletCode == autoAssignStocks[j].PalletCode).Sum(x => x.AssignQuantity);//鍑哄簱璇︽儏宸插垎閰嶆暟閲�
-                        }
-                        var palletOutboundQuantity = autoAssignStocks[j].Details.Sum(x => x.OutboundQuantity);
-                        if (palletAssignQuantity < palletOutboundQuantity)//濡傛灉鍑哄簱璇︽儏宸插垎閰嶆暟閲忓皬浜庢墭鐩樺凡鍒嗛厤鏁伴噺锛屽垯鍙互缁х画娣诲姞璇ユ墭鐩樺嚭搴撲俊鎭�
-                        {
-                            var orderDetailNeedQuantity = details[i].OrderQuantity - detailAssignQuantity;
-                            if (orderDetailNeedQuantity > autoAssignStocks[j].Details.Sum(x => x.OutboundQuantity) - palletAssignQuantity)
-                            {
-                                details[i].LockQuantity += autoAssignStocks[j].Details.Sum(x => x.OutboundQuantity) - palletAssignQuantity;
-                                Dt_OutStockLockInfo outStockLockInfo = _outStockLockInfoService.GetOutStockLockInfo(outboundOrder, details[i], autoAssignStocks[j], autoAssignStocks[j].Details.Sum(x => x.OutboundQuantity) - palletAssignQuantity);
-                                outStockLockInfos.Add(outStockLockInfo);
-                            }
-                            else
-                            {
-                                Dt_OutStockLockInfo outStockLockInfo = _outStockLockInfoService.GetOutStockLockInfo(outboundOrder, details[i], autoAssignStocks[j], details[i].OrderQuantity - details[i].LockQuantity);
-                                outStockLockInfos.Add(outStockLockInfo);
-                                details[i].LockQuantity = details[i].OrderQuantity;
-                                break;
-                            }
-
-                        }
-                    }
+                    throw new Exception($"鐗╂枡[{item.MaterielCode}]搴撳瓨涓嶈冻锛岄渶瑕亄needQuantity}锛屽彲鐢▄needQuantity - residueQuantity}");
                 }
 
+                outStocks.AddRange(autoAssignStocks);
 
-                locationInfos.AddRange(_locationInfoService.GetLocationInfos(outStocks.Select(x => x.LocationCode).ToList()));
+                // 鎸夊厛杩涘厛鍑哄師鍒欏垎閰嶉攣瀹氭暟閲忓埌鍚勪釜鏄庣粏
+                DistributeLockQuantityByFIFO(item.Details, autoAssignStocks, outStockLockInfos, outboundOrder);
             }
+
+            locationInfos.AddRange(_locationInfoService.GetLocationInfos(outStocks.Select(x => x.LocationCode).Distinct().ToList()));
 
             return (outStocks, outboundOrderDetails, outStockLockInfos, locationInfos);
         }
 
+        /// <summary>
+        /// 鎸夊厛杩涘厛鍑哄師鍒欏垎閰嶉攣瀹氭暟閲忓埌鍚勪釜鏄庣粏
+        /// </summary>
+        private void DistributeLockQuantityByFIFO(
+            List<Dt_OutboundOrderDetail> details,
+            List<Dt_StockInfo> assignStocks,
+            List<Dt_OutStockLockInfo> outStockLockInfos,
+            Dt_OutboundOrder outboundOrder)
+        {
+            // 鎸夊厛杩涘厛鍑烘帓搴忓嚭搴撳崟鏄庣粏锛堝亣璁惧厛鍒涘缓鐨勬槑缁嗛渶瑕佷紭鍏堟弧瓒筹級
+            var sortedDetails = details
+                .OrderBy(x => x.Id) // 鎸塈D鎺掑簭锛屽亣璁惧厛鍒涘缓鐨処D灏�
+                .ToList();
+
+            // 鎸夊厛杩涘厛鍑烘帓搴忓簱瀛橈紙鐢熶骇鏃ユ湡鏈�鏃╃殑浼樺厛锛�
+            var sortedStockDetails = assignStocks
+                .SelectMany(x => x.Details)
+                .Where(x => details.Any(d => d.MaterielCode == x.MaterielCode))
+                .OrderBy(x => x.ProductionDate)
+                .ToList();
+
+            // 涓烘瘡涓簱瀛樻槑缁嗗垱寤哄垎閰嶈褰�
+            foreach (var stockDetail in sortedStockDetails)
+            {
+                var stockInfo = assignStocks.First(x => x.Id == stockDetail.StockId);
+                var allocatedQuantity = stockDetail.OutboundQuantity; // 杩欎釜搴撳瓨鏄庣粏鍒嗛厤鐨勬暟閲�
+
+                if (allocatedQuantity <= 0) continue;
+
+                // 鎸夐『搴忓垎閰嶇粰鍚勪釜鍑哄簱鍗曟槑缁�
+                decimal remainingAllocate = allocatedQuantity;
+
+                foreach (var detail in sortedDetails)
+                {
+                    if (remainingAllocate <= 0) break;
+
+                    // 璁$畻杩欎釜鏄庣粏杩橀渶瑕佸垎閰嶇殑鏁伴噺
+                    var alreadyAssigned = outStockLockInfos
+                        .Where(x => x.OrderDetailId == detail.Id && x.StockId == stockInfo.Id)
+                        .Sum(x => x.AssignQuantity);
+
+                    var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity - alreadyAssigned;
+
+                    if (detailNeed <= 0) continue;
+
+                    // 鍒嗛厤鏁伴噺
+                    var assignQuantity = Math.Min(remainingAllocate, detailNeed);
+
+                    // 鍒涘缓鍑哄簱閿佸畾淇℃伅
+                    var lockInfo = _outStockLockInfoService.GetOutStockLockInfo(
+                        outboundOrder, detail, stockInfo, assignQuantity, stockDetail.Barcode);
+                    outStockLockInfos.Add(lockInfo);
+
+                    // 鏇存柊鏄庣粏鐨勯攣瀹氭暟閲�
+                    detail.LockQuantity += assignQuantity;
+                    remainingAllocate -= assignQuantity;
+                }
+
+                // 濡傛灉杩樻湁鍓╀綑鍒嗛厤鏁伴噺锛岃鏄庨�昏緫鏈夎
+                if (remainingAllocate > 0)
+                {
+                    throw new Exception($"搴撳瓨鍒嗛厤閫昏緫閿欒锛屽墿浣欐湭鍒嗛厤鏁伴噺锛歿remainingAllocate}");
+                }
+            }
+        }
+
+ 
+/// <summary>
+    /// 鍒涘缓鍑哄簱閿佸畾淇℃伅
+    /// </summary>
+    private void CreateOutStockLockInfos(Dt_OutboundOrder outboundOrder,List<Dt_OutboundOrderDetail> details,
+        List<Dt_StockInfo> assignStocks,List<Dt_OutStockLockInfo> outStockLockInfos)
+        {
+            foreach (var stock in assignStocks)
+            {
+                // 鑾峰彇璇ュ簱瀛樹腑鐩稿叧鐗╂枡鐨勫彲鐢ㄦ潯鐮佷俊鎭�
+                var stockDetails = stock.Details
+                    .Where(x => details.Any(d => d.MaterielCode == x.MaterielCode) &&
+                               x.StockQuantity > x.OutboundQuantity)
+                    .OrderBy(x => x.ProductionDate) // 鍏堣繘鍏堝嚭
+                    .ToList();
+                if (!stockDetails.Any()) continue;
+
+                var stockAssignQuantity = stockDetails.Sum(x => x.OutboundQuantity);
+
+
+                // 鏌ユ壘杩欎釜搴撳瓨宸茬粡鍒嗛厤鐨勬暟閲�
+                var existingAssign = outStockLockInfos
+                    .Where(x => x.StockId == stock.Id &&
+                               details.Any(d => d.Id == x.OrderDetailId))
+                    .Sum(x => x.AssignQuantity);
+
+                var availableAssign = stockAssignQuantity - existingAssign;
+
+                if (availableAssign <= 0) continue;
+
+                // 鎸夊厛杩涘厛鍑哄師鍒欏垎閰嶆潯鐮�
+                var barcodeAllocation = AllocateBarcodes(stockDetails, availableAssign);
+
+
+                // 鍒嗛厤缁欏悇涓槑缁�
+                foreach (var detail in details.Where(d => d.LockQuantity > 0))
+                {
+                    var alreadyAssigned = outStockLockInfos
+                        .Where(x => x.OrderDetailId == detail.Id && x.StockId == stock.Id)
+                        .Sum(x => x.AssignQuantity);
+
+                    var canAssign = Math.Min(detail.LockQuantity - alreadyAssigned, availableAssign);
+
+                    if (canAssign > 0)
+                    {
+                        // 涓鸿繖涓垎閰嶇‘瀹氭潯鐮�
+                        var (barcode, barcodeQuantity) = GetBarcodeForAllocation(barcodeAllocation, canAssign);
+
+                        var lockInfo = _outStockLockInfoService.GetOutStockLockInfo(
+                            outboundOrder, detail, stock, canAssign, barcode,null);
+                        outStockLockInfos.Add(lockInfo);
+
+                        availableAssign -= canAssign;
+
+                        // 鏇存柊鏉$爜鍒嗛厤璁板綍
+                        UpdateBarcodeAllocation(barcodeAllocation, barcode, barcodeQuantity);
+                    }
+
+                    if (availableAssign <= 0) break;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 鎸夊厛杩涘厛鍑哄師鍒欏垎閰嶆潯鐮�
+        /// </summary>
+        private Dictionary<string, decimal> AllocateBarcodes(List<Dt_StockInfoDetail> stockDetails, decimal totalQuantity)
+        {
+            var allocation = new Dictionary<string, decimal>();
+            decimal remainingQuantity = totalQuantity;
+
+            foreach (var detail in stockDetails.OrderBy(x => x.ProductionDate))
+            {
+                if (remainingQuantity <= 0) break;
+
+                decimal available = detail.StockQuantity - detail.OutboundQuantity;
+                decimal allocate = Math.Min(available, remainingQuantity);
+
+                allocation[detail.Barcode] = allocate;
+                remainingQuantity -= allocate;
+            }
+
+            return allocation;
+        }
+
+        /// <summary>
+        /// 涓哄垎閰嶈幏鍙栧悎閫傜殑鏉$爜
+        /// </summary>
+        private (string barcode, decimal quantity) GetBarcodeForAllocation(Dictionary<string, decimal> barcodeAllocation, decimal requiredQuantity)
+        {
+            foreach (var (barcode, quantity) in barcodeAllocation)
+            {
+                if (quantity >= requiredQuantity)
+                {
+                    return (barcode, requiredQuantity);
+                }
+            }
+
+            // 濡傛灉鍗曚釜鏉$爜鏁伴噺涓嶈冻锛屼娇鐢ㄧ涓�涓潯鐮�
+            var first = barcodeAllocation.First();
+            return (first.Key, Math.Min(first.Value, requiredQuantity));
+        }
+
+        /// <summary>
+        /// 鏇存柊鏉$爜鍒嗛厤璁板綍
+        /// </summary>
+        private void UpdateBarcodeAllocation(Dictionary<string, decimal> barcodeAllocation, string barcode, decimal usedQuantity)
+        {
+            if (barcodeAllocation.ContainsKey(barcode))
+            {
+                barcodeAllocation[barcode] -= usedQuantity;
+                if (barcodeAllocation[barcode] <= 0)
+                {
+                    barcodeAllocation.Remove(barcode);
+                }
+            }
+        }
         /// <summary>
         /// 鍑哄簱搴撳瓨鍒嗛厤鍚庯紝鏇存柊鏁版嵁搴撴暟鎹�
         /// </summary>
@@ -126,30 +297,19 @@
         /// <param name="locationStatus"></param>
         /// <param name="tasks"></param>
         /// <returns></returns>
-        public WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutboundOrderDetail> outboundOrderDetails, List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos, LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List<Dt_Task>? tasks = null)
+        public WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutboundOrderDetail> outboundOrderDetails, 
+            List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos, 
+            LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List<Dt_Task>? tasks = null)
         {
             try
             {
+                // 鏇存柊搴撳瓨鐘舵��
+                stockInfos.ForEach(x => x.StockStatus = (int)StockStatusEmun.鍑哄簱閿佸畾);
                 _stockService.StockInfoService.Repository.UpdateData(stockInfos);
-                List<Dt_StockInfoDetail> stockInfoDetails = new List<Dt_StockInfoDetail>();
-                foreach (var item in stockInfos)
-                {
-                    foreach (var detail in item.Details)
-                    {
-                        // 杩涜瀹夊叏杞崲
-                        if (detail.OutboundQuantity != null && decimal.TryParse(detail.OutboundQuantity.ToString(), out decimal outboundDecimal))
-                        {
-                            decimal outboundDecimal1 = Convert.ToDecimal(detail.OutboundQuantity);
-                        }
-                        else
-                        {
-                            detail.OutboundQuantity = 0; // 榛樿鍊兼垨璁板綍閿欒
-                        }
-                    }
-                    stockInfoDetails.AddRange(item.Details);
-
-                }
-                _stockService.StockInfoDetailService.Repository.UpdateData(stockInfoDetails);
+ 
+                // 鏇存柊搴撳瓨鏄庣粏
+                var stockDetails = stockInfos.SelectMany(x => x.Details).ToList();
+                _stockService.StockInfoDetailService.Repository.UpdateData(stockDetails);
                 BaseDal.UpdateData(outboundOrderDetails);
 
                 List<Dt_OutStockLockInfo> addOutStockLockInfos = outStockLockInfos.Where(x => x.Id == 0).ToList();
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/OutboundOrderService.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/OutboundOrderService.cs"
index 6a0d029..9b0c138 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/OutboundOrderService.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/OutboundOrderService.cs"
@@ -1,4 +1,6 @@
-锘縰sing AutoMapper;
+锘縰sing Autofac.Core;
+using AutoMapper;
+using Microsoft.AspNetCore.Mvc;
 using SqlSugar;
 using WIDESEA_Core;
 using WIDESEA_Core.BaseRepository;
@@ -179,6 +181,20 @@
             }
         }
 
+        /// <summary>
+        /// 鏍规嵁ID鑾峰彇鍑哄簱鍗�
+        /// </summary>
+        public async Task<WebResponseContent> GetById(int id)
+        {
+            var order = await Db.Queryable<Dt_OutboundOrder>().FirstAsync(o=>o.Id==id);
+            if (order == null)
+            {
+                return WebResponseContent.Instance.Error("鏈壘鍒板嚭搴撳崟淇℃伅");
+            }
+            return WebResponseContent.Instance.OK(null, order);
+        }
+
+
         static object lock_code = new object();
         public string CreateCodeByRule(string ruleCode)
         {
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"
new file mode 100644
index 0000000..a47f4b8
--- /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_OutboundService/OutboundPickingService.cs"
@@ -0,0 +1,386 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Common.LocationEnum;
+using WIDESEA_Common.OrderEnum;
+using WIDESEA_Common.StockEnum;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseRepository;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_DTO.Outbound;
+using WIDESEA_IBasicService;
+using WIDESEA_IOutboundService;
+using WIDESEA_IStockService;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_OutboundService
+{
+    /// <summary>
+    ///   
+    /// </summary>
+    public class OutboundPickingService : ServiceBase<Dt_PickingRecord, IRepository<Dt_PickingRecord>>, IOutboundPickingService
+    {
+        private readonly IUnitOfWorkManage _unitOfWorkManage;
+        public IRepository<Dt_PickingRecord> Repository => BaseDal;
+
+        private readonly IStockInfoService _stockInfoService;
+        private readonly IStockService _stockService;
+        private readonly IOutStockLockInfoService _outStockLockInfoService;
+        private readonly IStockInfoDetailService _stockInfoDetailService;
+        private readonly ILocationInfoService _locationInfoService;
+        private readonly IOutboundOrderDetailService _outboundOrderDetailService;
+        private readonly ISplitPackageService _splitPackageService;
+ 
+
+        public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService, IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService, IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService) : base(BaseDal)
+        {
+            _unitOfWorkManage = unitOfWorkManage;
+            _stockInfoService = stockInfoService;
+            _stockService = stockService;
+            _outStockLockInfoService = outStockLockInfoService;
+            _stockInfoDetailService = stockInfoDetailService;
+            _locationInfoService = locationInfoService;
+            _outboundOrderDetailService = outboundOrderDetailService;
+            _splitPackageService = splitPackageService;
+        }
+
+        /// <summary>
+        /// 鎵爜鎷i�夌‘璁� - 绠�鍖栫増鏈�
+        /// 鍙鐞嗗疄闄呮嫞閫夌殑搴撳瓨鎵e噺
+        /// </summary>
+        public async Task<WebResponseContent> ConfirmPicking(PickingConfirmRequest request)
+        {
+            try
+            {
+                _unitOfWorkManage.BeginTran();
+
+                // 1. 楠岃瘉鏉$爜鏈夋晥鎬�
+                var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                    .Where(x => x.Barcode == request.Barcode && x.MaterielCode == request.MaterielCode)
+                    .FirstAsync();
+
+                if (stockDetail == null)
+                    return WebResponseContent.Instance.Error("鏃犳晥鐨勬潯鐮佹垨鐗╂枡缂栫爜");
+
+                // 2. 妫�鏌ュ簱瀛樺彲鐢ㄦ暟閲�
+                decimal availableQuantity = stockDetail.StockQuantity - stockDetail.OutboundQuantity;
+                if (request.PickQuantity > availableQuantity)
+                    return WebResponseContent.Instance.Error($"鎷i�夋暟閲忚秴杩囧彲鐢ㄥ簱瀛橈紝鍙敤鏁伴噺锛歿availableQuantity}");
+
+                // 3. 鏌ユ壘鐩稿叧鐨勫嚭搴撻攣瀹氫俊鎭紙鏀寔鎷嗗寘鍚庣殑鏂版潯鐮侊級
+                var lockInfo = await FindLockInfoByBarcode(request.OrderDetailId, request.Barcode, request.MaterielCode);
+
+                if (lockInfo == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒扮浉鍏崇殑鍑哄簱閿佸畾淇℃伅");
+
+                // 4. 妫�鏌ラ攣瀹氭暟閲�
+                decimal remainingLockQuantity = lockInfo.AssignQuantity - lockInfo.PickedQty;
+                if (request.PickQuantity > remainingLockQuantity)
+                    return WebResponseContent.Instance.Error($"鎷i�夋暟閲忚秴杩囬攣瀹氭暟閲忥紝鍓╀綑鍙嫞閫夛細{remainingLockQuantity}");
+
+                // 5. 鏇存柊閿佸畾淇℃伅鐨勫凡鎷i�夋暟閲�
+                lockInfo.PickedQty += request.PickQuantity;
+                await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+                // 6. 鏇存柊搴撳瓨鍑哄簱鏁伴噺 - 瀹為檯鍑忓皯搴撳瓨
+                stockDetail.OutboundQuantity += request.PickQuantity;
+                await _stockInfoService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+                // 7. 鏇存柊鍑哄簱鍗曟槑缁�
+                var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+                    .Where(x => x.Id == request.OrderDetailId)
+                    .FirstAsync();
+
+                orderDetail.OverOutQuantity += request.PickQuantity;
+                orderDetail.LockQuantity -= request.PickQuantity;
+
+                // 妫�鏌ユ槸鍚﹀畬鎴愬嚭搴�
+                if (Math.Abs(orderDetail.OverOutQuantity - orderDetail.OrderQuantity) < 0.001m)
+                {
+                    orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
+                    orderDetail.LockQuantity = 0;
+
+                    // 鏇存柊鐩稿叧鐨勯攣瀹氫俊鎭姸鎬佷负宸插嚭搴�
+                    var relatedLockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                        .Where(x => x.OrderDetailId == request.OrderDetailId &&
+                                   x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+                        .ToListAsync();
+
+                    foreach (var relatedLock in relatedLockInfos)
+                    {
+                        relatedLock.Status = (int)OutLockStockStatusEnum.宸插嚭搴�;
+                    }
+                    await _outStockLockInfoService.Db.Updateable(relatedLockInfos).ExecuteCommandAsync();
+                }
+
+                await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+
+                // 8. 璁板綍鎷i�夊巻鍙�
+                var pickHistory = new Dt_PickingRecord
+                {
+                    OrderDetailId = request.OrderDetailId,
+                    Barcode = request.Barcode,
+                    PickQuantity = request.PickQuantity,
+                    PickTime = DateTime.Now,
+
+                    LocationCode = request.LocationCode,
+                    StockId = stockDetail.StockId
+                };
+                await Db.Insertable(pickHistory).ExecuteCommandAsync();
+
+                _unitOfWorkManage.CommitTran();
+
+                return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�");
+            }
+            catch (Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return WebResponseContent.Instance.Error($"鎷i�夌‘璁ゅけ璐�: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁鏉$爜鏌ユ壘閿佸畾淇℃伅
+        /// </summary>
+        private async Task<Dt_OutStockLockInfo> FindLockInfoByBarcode(int orderDetailId, string barcode, string materielCode)
+        {
+            return await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(x => x.OrderDetailId == orderDetailId &&
+                           x.MaterielCode == materielCode &&
+                           x.CurrentBarcode == barcode &&
+                           x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
+                           x.AssignQuantity > x.PickedQty)
+                .FirstAsync();
+        }
+
+        /// <summary>
+        /// 鑾峰彇鎷i�夊巻鍙�
+        /// </summary>
+        public async Task<List<Dt_PickingRecord>> GetPickingHistory(int orderId)
+        {
+            // 閫氳繃鍑哄簱鍗旾D鏌ヨ鐩稿叧鐨勬嫞閫夊巻鍙�
+            // 娉ㄦ剰锛欴t_PickingRecord 涓病鏈夌洿鎺ュ瓨鍌∣rderId锛岄渶瑕侀�氳繃鍑哄簱鍗曟槑缁嗗叧鑱�
+            var detailIds = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+                .Where(d => d.OrderId == orderId)
+                .Select(d => d.Id)
+                .ToListAsync();
+
+            return await Db.Queryable<Dt_PickingRecord>()
+                .Where(p => detailIds.Contains(p.OrderDetailId))
+                .OrderByDescending(p => p.PickTime)
+                .ToListAsync();
+        }
+
+        /// <summary>
+        /// 鎾ら攢鎷i��
+        /// </summary>
+        public async Task<WebResponseContent> CancelPicking(CancelPickingRequest request)
+        {
+            // 瀹炵幇鎾ら攢鎷i�夌殑閫昏緫锛岄渶瑕侊細
+            // 1. 鎭㈠搴撳瓨鍑哄簱鏁伴噺
+            // 2. 鎭㈠閿佸畾淇℃伅鐨勫凡鎷i�夋暟閲�
+            // 3. 鎭㈠鍑哄簱鍗曟槑缁嗙殑宸插嚭鏁伴噺鍜岄攣瀹氭暟閲�
+            // 4. 鍒犻櫎鎴栨爣璁版嫞閫夊巻鍙茶褰�
+            // 娉ㄦ剰锛氳繖閲岄渶瑕佷簨鍔″鐞�
+            try
+            {
+                _unitOfWorkManage.BeginTran();
+
+                var pickHistory = await Db.Queryable<Dt_PickingRecord>()
+                    .Where(x => x.Id == request.PickingHistoryId)
+                    .FirstAsync();
+
+                if (pickHistory == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒版嫞閫夎褰�");
+
+                // 鎭㈠搴撳瓨
+                var stockDetail = await _stockInfoService.Db.Queryable<Dt_StockInfoDetail>()
+                    .Where(x => x.Barcode == pickHistory.Barcode && x.StockId == pickHistory.StockId)
+                    .FirstAsync();
+                if (stockDetail != null)
+                {
+                    stockDetail.OutboundQuantity -= pickHistory.PickQuantity;
+                    await _stockInfoService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+                }
+                // 鎭㈠閿佸畾淇℃伅
+                var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                    .Where(x => x.OrderDetailId == pickHistory.OrderDetailId && x.StockId == pickHistory.StockId)
+                    .FirstAsync();
+                lockInfo.PickedQty -= pickHistory.PickQuantity;
+                await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+                // 鎭㈠鍑哄簱鍗曟槑缁�
+                var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+                    .Where(x => x.Id == pickHistory.OrderDetailId)
+                    .FirstAsync();
+                orderDetail.OverOutQuantity -= pickHistory.PickQuantity;
+                orderDetail.LockQuantity += pickHistory.PickQuantity;
+                if (orderDetail.OverOutQuantity < orderDetail.OrderQuantity)
+                {
+                    orderDetail.OrderDetailStatus = orderDetail.LockQuantity > 0 ?
+                        (int)OrderDetailStatusEnum.Outbound : (int)OrderDetailStatusEnum.AssignOverPartial;
+                }
+                await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+
+                // 鍒犻櫎鎷i�夊巻鍙茶褰�
+                await Db.Deleteable<Dt_PickingRecord>().Where(x => x.Id == request.PickingHistoryId).ExecuteCommandAsync();
+
+                _unitOfWorkManage.CommitTran();
+                return WebResponseContent.Instance.OK("鎾ら攢鎴愬姛");
+            }
+            catch (Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return WebResponseContent.Instance.Error($"鎾ら攢澶辫触: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇鎵樼洏鐨勫嚭搴撶姸鎬佷俊鎭�
+        /// </summary>
+        public async Task<WebResponseContent> GetPalletOutboundStatus(string palletCode)
+        {
+            // 鑾峰彇鎵樼洏鐨勯攣瀹氫俊鎭�
+            var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Where(x => x.PalletCode == palletCode)
+                .ToListAsync();
+
+            // 鑾峰彇鎵樼洏搴撳瓨淇℃伅
+            var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+                .Includes(x => x.Details)
+                .Where(x => x.PalletCode == palletCode)
+                .FirstAsync();
+
+            if (stockInfo == null)
+                return WebResponseContent.Instance.Error("鏈壘鍒版墭鐩樹俊鎭�");
+
+            // 璁$畻鍚勭鏁伴噺
+            var totalStockQuantity = stockInfo.Details.Sum(x => x.StockQuantity);
+            var totalOutboundQuantity = stockInfo.Details.Sum(x => x.OutboundQuantity);
+            var totalLockedQuantity = lockInfos.Where(x => x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+                .Sum(x => x.AssignQuantity - x.PickedQty);
+            var totalPickedQuantity = lockInfos.Sum(x => x.PickedQty);
+
+            var result = new
+            {
+                PalletCode = palletCode,
+                LocationCode = stockInfo.LocationCode,
+                StockStatus = stockInfo.StockStatus,
+                TotalStockQuantity = totalStockQuantity,
+                TotalOutboundQuantity = totalOutboundQuantity,
+                TotalLockedQuantity = totalLockedQuantity,
+                TotalPickedQuantity = totalPickedQuantity,
+                AvailableQuantity = totalStockQuantity - totalOutboundQuantity,
+                LockInfos = lockInfos.Select(x => new
+                {
+                    x.Id,
+                    x.MaterielCode,
+                    x.OrderDetailId,
+                    x.AssignQuantity,
+                    x.PickedQty,
+                    x.Status,
+                    x.CurrentBarcode,
+                    x.IsSplitted
+                }).ToList(),
+                StockDetails = stockInfo.Details.Select(x => new
+                {
+                    x.Barcode,
+                    x.MaterielCode,
+                    StockQuantity = x.StockQuantity,
+                    OutboundQuantity = x.OutboundQuantity,
+                    AvailableQuantity = x.StockQuantity - x.OutboundQuantity
+                }).ToList()
+            };
+
+            return WebResponseContent.Instance.OK(null, result);
+        }
+
+        /// <summary>
+        /// 鐩存帴鍑哄簱 - 鏁翠釜鎵樼洏鍑哄簱锛屾竻绌哄簱瀛�
+        /// </summary>
+        public async Task<WebResponseContent> DirectOutbound(DirectOutboundRequest request)
+        {
+            try
+            {
+                _unitOfWorkManage.BeginTran();
+
+                // 1. 鑾峰彇鎵樼洏搴撳瓨淇℃伅
+                var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+                    .Includes(x => x.Details)
+                    .Where(x => x.PalletCode == request.PalletCode)
+                    .FirstAsync();
+
+                if (stockInfo == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒版墭鐩樺簱瀛樹俊鎭�");
+
+                // 2. 鑾峰彇鐩稿叧鐨勫嚭搴撻攣瀹氫俊鎭�
+                var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                    .Where(x => x.PalletCode == request.PalletCode &&
+                               x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+                    .ToListAsync();
+
+                // 3. 鏁翠釜鎵樼洏鍑哄簱 - 璁剧疆鍑哄簱鏁伴噺绛変簬搴撳瓨鏁伴噺
+                foreach (var detail in stockInfo.Details)
+                {
+                    decimal outboundQuantity = detail.StockQuantity - detail.OutboundQuantity;
+                    detail.OutboundQuantity = detail.StockQuantity; // 鍏ㄩ儴鍑哄簱
+                    await _stockInfoDetailService.Db.Updateable(detail).ExecuteCommandAsync();
+                }
+
+                // 4. 鏇存柊鍑哄簱閿佸畾淇℃伅
+                foreach (var lockInfo in lockInfos)
+                {
+                    decimal unpicked = lockInfo.AssignQuantity - lockInfo.PickedQty;
+                    lockInfo.PickedQty += unpicked; // 鏍囪涓哄叏閮ㄦ嫞閫�
+                    lockInfo.Status = (int)OutLockStockStatusEnum.宸插嚭搴�;
+                    await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+                    // 鏇存柊鍑哄簱鍗曟槑缁�
+                    var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+                        .Where(x => x.Id == lockInfo.OrderDetailId)
+                        .FirstAsync();
+                    orderDetail.OverOutQuantity += unpicked;
+                    orderDetail.LockQuantity -= unpicked;
+                    orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.Over;
+                    orderDetail.LockQuantity = 0;
+
+                    await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+                }
+
+                // 5. 鏇存柊鎷嗗寘璁板綍鐘舵��
+                var lockInfoIds = lockInfos.Select(x => x.Id).ToList();
+                var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+                    .Where(x => lockInfoIds.Contains(x.OutStockLockInfoId) &&
+                               x.Status == (int)SplitPackageStatusEnum.宸叉媶鍖�)
+                    .ToListAsync();
+
+                foreach (var record in splitRecords)
+                {
+                    record.Status = (int)SplitPackageStatusEnum.宸叉嫞閫�;
+                    await _splitPackageService.Db.Updateable(record).ExecuteCommandAsync();
+                }
+
+                // 6. 娓呯┖璐т綅
+                var location = await _locationInfoService.Db.Queryable<Dt_LocationInfo>()
+                    .Where(x => x.LocationCode == stockInfo.LocationCode)
+                    .FirstAsync();
+                if (location != null)
+                {
+                    location.LocationStatus = (int)LocationStatusEnum.Free;
+                    await _locationInfoService.Db.Updateable(location).ExecuteCommandAsync();
+                }
+
+                _unitOfWorkManage.CommitTran();
+                return WebResponseContent.Instance.OK("鐩存帴鍑哄簱鎴愬姛");
+            }
+            catch (Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return WebResponseContent.Instance.Error($"鐩存帴鍑哄簱澶辫触: {ex.Message}");
+            }
+        }
+    }
+
+}
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/SplitPackageService.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/SplitPackageService.cs"
new file mode 100644
index 0000000..ddc6e54
--- /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_OutboundService/SplitPackageService.cs"
@@ -0,0 +1,169 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Common.StockEnum;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseRepository;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_DTO.Outbound;
+using WIDESEA_IOutboundService;
+using WIDESEA_IStockService;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_OutboundService
+{
+    internal class SplitPackageService : ServiceBase<Dt_SplitPackageRecord, IRepository<Dt_SplitPackageRecord>>, ISplitPackageService
+    {
+        private readonly IUnitOfWorkManage _unitOfWorkManage;
+        public IRepository<Dt_SplitPackageRecord> Repository => BaseDal;
+
+        private readonly IStockInfoService _stockInfoService;
+        private readonly IStockInfoDetailService _stockInfoDetailService;
+        private readonly IOutStockLockInfoService _outStockLockInfoService;
+
+        public SplitPackageService(IRepository<Dt_SplitPackageRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService) : base(BaseDal)
+        {
+            _unitOfWorkManage = unitOfWorkManage;
+            _stockInfoService = stockInfoService;
+            _outStockLockInfoService = outStockLockInfoService;
+            _stockInfoDetailService = stockInfoDetailService;
+        }
+
+        /// <summary>
+        /// 鎷嗗寘鎷嗙鎿嶄綔
+        /// </summary>
+        public async Task<WebResponseContent> SplitPackage(SplitPackageRequest request)
+        {
+            try
+            {
+                _unitOfWorkManage.BeginTran();
+
+                // 1. 楠岃瘉鍑哄簱閿佸畾淇℃伅
+                var lockInfo = await Db.Queryable<Dt_OutStockLockInfo>()
+                    .Where(x => x.Id == request.OutStockLockInfoId &&
+                               x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+                    .FirstAsync();
+
+                if (lockInfo == null)
+                    return WebResponseContent.Instance.Error("鏈壘鍒版湁鏁堢殑鍑哄簱閿佸畾淇℃伅");
+
+                //// 2. 楠岃瘉褰撳墠鏉$爜鐨勫彲鐢ㄦ暟閲�
+                //var currentStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                //    .Where(x => x.Barcode == lockInfo.CurrentBarcode &&
+                //               x.MaterielCode == request.MaterielCode &&
+                //               x.StockId == lockInfo.StockId)
+                //    .FirstAsync();
+
+                //if (currentStockDetail == null)
+                //    return WebResponseContent.Instance.Error("褰撳墠鏉$爜鍦ㄥ簱瀛樹腑涓嶅瓨鍦�");
+
+                //// 3. 妫�鏌ュ彲鐢ㄦ暟閲�
+                //decimal availableQuantity = currentStockDetail.StockQuantity - currentStockDetail.OutboundQuantity;
+                //if (request.SplitQuantity > availableQuantity)
+                //    return WebResponseContent.Instance.Error($"鎷嗗寘鏁伴噺涓嶈兘澶т簬鍙敤鏁伴噺锛屽彲鐢ㄦ暟閲忥細{availableQuantity}");
+
+                // 2. 妫�鏌ュ墿浣欓攣瀹氭暟閲�
+                decimal remainingLockQuantity = lockInfo.AssignQuantity - lockInfo.PickedQty;
+                if (request.SplitQuantity > remainingLockQuantity)
+                    return WebResponseContent.Instance.Error($"鎷嗗寘鏁伴噺涓嶈兘澶т簬鍓╀綑閿佸畾鏁伴噺锛屽墿浣欙細{remainingLockQuantity}");
+
+                // 3. 鐢熸垚鏂版潯鐮�
+                string newBarcode = "";
+
+                // 4. 鍒涘缓鏂扮殑鍑哄簱閿佸畾淇℃伅锛堟柊鏉$爜锛�
+                var newLockInfo = new Dt_OutStockLockInfo
+                {
+                    OrderNo = lockInfo.OrderNo,
+                    OrderDetailId = lockInfo.OrderDetailId,
+                    BatchNo = lockInfo.BatchNo,
+                    MaterielCode = lockInfo.MaterielCode,
+                    MaterielName = lockInfo.MaterielName,
+                    StockId = lockInfo.StockId,
+                    OrderQuantity = lockInfo.OrderQuantity,
+                    OriginalQuantity = lockInfo.OriginalQuantity,
+                    AssignQuantity = request.SplitQuantity, // 鏂版潯鐮佸垎閰嶆暟閲�
+                    PickedQty = 0, // 鏂版潯鐮佹湭鎷i��
+                    LocationCode = lockInfo.LocationCode,
+                    PalletCode = lockInfo.PalletCode,
+                    TaskNum = lockInfo.TaskNum,
+                    Status = (int)OutLockStockStatusEnum.鍑哄簱涓�,
+                    Unit = lockInfo.Unit,
+                
+                    CurrentBarcode = newBarcode, // 鏂版潯鐮�
+                    OriginalLockQuantity = request.SplitQuantity,
+                    IsSplitted = 1,
+                    ParentLockId = lockInfo.Id // 璁板綍鐖剁骇閿佸畾ID
+                };
+                await Db.Insertable(newLockInfo).ExecuteCommandAsync();
+
+                // 5. 鏇存柊鍘熼攣瀹氫俊鎭殑鍒嗛厤鏁伴噺锛堝噺灏戞媶鍖呮暟閲忥級
+                lockInfo.AssignQuantity -= request.SplitQuantity;
+                await Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+                // 6. 璁板綍鎷嗗寘鍘嗗彶锛堢敤浜庤拷韪級
+                var splitHistory = new Dt_SplitPackageRecord
+                {
+                    OutStockLockInfoId = lockInfo.Id,
+                    OriginalBarcode = lockInfo.CurrentBarcode,
+                    NewBarcode = newBarcode,
+                    SplitQty = request.SplitQuantity,
+                    MaterielCode = request.MaterielCode,
+                    SplitTime = DateTime.Now,
+                    Operator = request.Operator,
+                    Status = (int)SplitPackageStatusEnum.宸叉媶鍖�
+                };
+                await Db.Insertable(splitHistory).ExecuteCommandAsync();
+
+                Db.Ado.CommitTran();
+
+                // 7. 鍥炰紶鏂版潯鐮佺粰MES
+               // await SendBarcodeToMES(newBarcode, request.MaterielCode, request.SplitQuantity);
+
+                return WebResponseContent.Instance.OK("鎷嗗寘鎴愬姛", new
+                {
+                    NewBarcode = newBarcode,
+                    NewLockInfoId = newLockInfo.Id
+                });
+            }
+            catch (Exception ex)
+            {
+                Db.Ado.RollbackTran();
+                return WebResponseContent.Instance.Error($"鎷嗗寘澶辫触: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇鍙媶鍖呯殑鍑哄簱閿佸畾淇℃伅
+        /// </summary>
+        public async Task<WebResponseContent> GetSplitableLockInfos(int orderDetailId)
+        {
+            var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                .Includes(x => x.StockInfo)
+                .Where(x => x.OrderDetailId == orderDetailId &&
+                           x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� &&
+                           x.AssignQuantity > x.PickedQty) // 杩樻湁鏈嫞閫夋暟閲�
+                .Select(x => new
+                {
+                    x.Id,
+                    x.PalletCode,
+                    x.LocationCode,
+                    x.MaterielCode,
+                    LockQuantity = x.AssignQuantity - x.PickedQty,
+                    x.CurrentBarcode,
+                    x.IsSplitted,
+                    StockDetails = x.StockInfo.Details.Where(d => d.MaterielCode == x.MaterielCode)
+                        .Select(d => new
+                        {
+                            d.Barcode,
+                            AvailableQuantity = d.StockQuantity - d.OutboundQuantity
+                        })
+                        .ToList()
+                })
+                .ToListAsync();
+
+            return WebResponseContent.Instance.OK(null, lockInfos);
+        }
+    }
+}
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_StockService/StockInfoService.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_StockService/StockInfoService.cs"
index c047a3e..90cfa42 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_StockService/StockInfoService.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_StockService/StockInfoService.cs"
@@ -1,7 +1,10 @@
 锘縰sing AutoMapper;
+using SqlSugar;
+using WIDESEA_Common.LocationEnum;
 using WIDESEA_Common.StockEnum;
 using WIDESEA_Core.BaseRepository;
 using WIDESEA_Core.BaseServices;
+using WIDESEA_Core.Helper;
 using WIDESEA_IBasicService;
 using WIDESEA_IRecordService;
 using WIDESEA_IStockService;
@@ -87,81 +90,98 @@
         public List<Dt_StockInfo> GetOutboundStocks(List<Dt_StockInfo> stockInfos, string materielCode, decimal needQuantity, out decimal residueQuantity)
         {
             List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>();
-            var stockTotalQuantity = stockInfos.Select(x => x.Details.Sum(v => v.StockQuantity - v.OutboundQuantity)).Sum(x => x);
-            //stockInfos = stockInfos.OrderBy(x => x.Id).ToList();
-            if (stockTotalQuantity >= needQuantity)//搴撳瓨澶�
+            // 鎸夊厛杩涘厛鍑烘帓搴忥紙鎸夋潯鐮佺殑鐢熶骇鏃ユ湡锛�
+            var sortedStockDetails = stockInfos
+                .SelectMany(x => x.Details)
+                .Where(x => x.MaterielCode == materielCode && x.StockQuantity > x.OutboundQuantity)
+                .OrderBy(x => x.ProductionDate).ThenBy(x => x.StockId)
+                .ToList();
+
+            // 璁$畻鎬诲彲鐢ㄥ簱瀛�
+            var stockTotalQuantity = sortedStockDetails.Sum(x => x.StockQuantity - x.OutboundQuantity);
+
+            if (stockTotalQuantity < needQuantity)
             {
-                int index = 0;
-                while (needQuantity > 0)
-                {
-                    Dt_StockInfo stockInfo = stockInfos[index];
-                    // 璁$畻鍙敤搴撳瓨鏃惰浆鎹负decimal
-                    decimal useableStockQuantity = stockInfo.Details
-                        .Where(x => x.MaterielCode == materielCode)
-                        .Sum(x => (decimal)x.StockQuantity - (decimal)x.OutboundQuantity);
-
-                    // 灏唍eedQuantity杞崲涓篸ecimal杩涜姣旇緝
-                    if (useableStockQuantity < (decimal)needQuantity && useableStockQuantity > 0)
-                    {
-                        stockInfo.Details.ForEach(x =>
-                            x.OutboundQuantity = x.StockQuantity);
-
-                        // 浣跨敤decimal杩涜璁$畻鍚庡啀杞洖float
-                        needQuantity =   needQuantity - useableStockQuantity;
-                    }
-                    else
-                    {
-                        stockInfo.Details.ForEach(x =>
-                        {
-                            if (x.StockQuantity > x.OutboundQuantity && x.MaterielCode == materielCode)
-                            {
-                                // 灏嗙浉鍏冲�艰浆鎹负decimal杩涜绮剧‘璁$畻
-                                decimal currentStock = (decimal)x.StockQuantity;
-                                decimal currentOutbound = (decimal)x.OutboundQuantity;
-                                decimal currentNeed = (decimal)needQuantity;
-                                decimal available = currentStock - currentOutbound;
-
-                                if (available >= currentNeed)
-                                {
-                                    x.OutboundQuantity = currentOutbound + currentNeed;
-                                    needQuantity = 0;
-                                }
-                                else
-                                {
-                                    needQuantity =currentNeed - available;
-                                    x.OutboundQuantity = x.StockQuantity;
-                                }
-                            }
-                        });
-                    }
-                    outStocks.Add(stockInfo);
-                    index++;
-                }
-
+                residueQuantity = needQuantity - stockTotalQuantity;
             }
             else
             {
-                throw new Exception("搴撳瓨涓嶈冻");
+                residueQuantity = 0;
             }
-            residueQuantity = needQuantity;
+
+            decimal remainingNeed = needQuantity;
+
+            // 鎸夋潯鐮佸垎閰嶅簱瀛�
+            foreach (var detail in sortedStockDetails)
+            {
+                if (remainingNeed <= 0) break;
+
+                decimal availableQuantity = detail.StockQuantity - detail.OutboundQuantity;
+                decimal allocateQuantity = Math.Min(availableQuantity, remainingNeed);
+
+                // 鏇存柊鍑哄簱鏁伴噺
+                detail.OutboundQuantity += allocateQuantity;
+                remainingNeed -= allocateQuantity;
+
+                // 濡傛灉杩欎釜搴撳瓨杩樻病娣诲姞鍒板嚭搴撳垪琛ㄤ腑锛屽氨娣诲姞
+                var stockInfo = stockInfos.First(x => x.Id == detail.StockId);
+                if (!outStocks.Contains(stockInfo))
+                {
+                    outStocks.Add(stockInfo);
+                }
+            }
+
+            residueQuantity = remainingNeed;
             return outStocks;
         }
+        /// <summary>
+        /// 鏍规嵁鏉$爜鑾峰彇搴撳瓨淇℃伅
+        /// </summary>
+        public async Task<Dt_StockInfoDetail> GetStockDetailByBarcode(string barcode, string materielCode)
+        {
+            return await Db.Queryable<Dt_StockInfoDetail>()
+                .Includes(x => x.StockInfo)
+                .Where(x => x.Barcode == barcode && x.MaterielCode == materielCode)
+                .FirstAsync();
+        }
 
+        /// <summary>
+        /// 鑾峰彇鐗╂枡鐨勬墍鏈夋潯鐮佷俊鎭�
+        /// </summary>
+        public async Task<List<Dt_StockInfoDetail>> GetMaterialBarcodes(string materielCode, string batchNo = null)
+        {
+            var query = Db.Queryable<Dt_StockInfoDetail>()
+                .Includes(x => x.StockInfo)
+                .Where(x => x.MaterielCode == materielCode && x.StockQuantity > x.OutboundQuantity);
+
+            if (!string.IsNullOrEmpty(batchNo))
+            {
+                query = query.Where(x => x.BatchNo == batchNo);
+            }
+
+            return await query.OrderBy(x => x.ProductionDate).ToListAsync();
+        }
         public List<Dt_StockInfo> GetStockInfos(string materielCode, string lotNo, List<string> locationCodes)
         {
-            List<Dt_StockInfo> stockInfos = null;
-            if (!string.IsNullOrEmpty(lotNo))
+            var query = Db.Queryable<Dt_StockInfo>()
+             .Where(x => locationCodes.Contains(x.LocationCode)
+             //  && x.StockStatus == (int)StockStatusEmun.姝e父)
+             ).Includes(x => x.Details);
+
+            if (!string.IsNullOrEmpty(materielCode))
             {
-                var stockSort = Db.Queryable<Dt_StockInfo>().Where(x => locationCodes.Contains(x.LocationCode)).Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode && v.BatchNo == lotNo)).ToList();
-                stockInfos = stockSort.OrderBy(x => x.Details.FirstOrDefault()?.EffectiveDate).ThenBy(x => x.Details.Sum(v => v.StockQuantity)).ToList();
-            }
-            else
-            {
-                var stockSort = Db.Queryable<Dt_StockInfo>().Where(x => locationCodes.Contains(x.LocationCode)).Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode)).ToList();
-                stockInfos = stockSort.OrderBy(x => x.Details.FirstOrDefault()?.EffectiveDate).ThenBy(x => x.Details.Sum(v => v.StockQuantity)).ToList();
+                query = query.Where(x => x.Details.Any(d => d.MaterielCode == materielCode));
             }
 
-            return stockInfos;
+            if (!string.IsNullOrEmpty(lotNo))
+            {
+                query = query.Where(x => x.Details.Any(d => d.BatchNo == lotNo));
+            }
+
+            var stocks = query.ToList();
+
+            return stocks.OrderBy(x => x.Details.Where(d => d.MaterielCode == materielCode &&
+                           (string.IsNullOrEmpty(lotNo) || d.BatchNo == lotNo)).Min(d => d.ProductionDate)).ToList();  
             //ISugarQueryable<Dt_LocationInfo> sugarQueryable = Db.Queryable<Dt_LocationInfo>().Where(x => locationCodes.Contains(x.LocationCode));
             //ISugarQueryable<Dt_StockInfo> sugarQueryable1 = Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode));
             //return sugarQueryable.InnerJoin(sugarQueryable1, (a, b) => a.LocationCode == b.LocationCode).Select((a, b) => b).OrderBy(a => a.CreateDate).Includes(a => a.Details).ToList();
@@ -173,5 +193,11 @@
 
             return GetStockInfos(materielCode, batchNo, locationCodes);
         }
+
+        public Dt_StockInfo GetPalletStockInfo(int locationType)
+        {
+
+            return Db.Queryable<Dt_StockInfo>().Where(x => x.StockStatus == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() && SqlFunc.Subqueryable<Dt_LocationInfo>().Where(v => v.LocationCode == x.LocationCode && v.LocationType == locationType && v.LocationStatus == LocationStatusEnum.Pallet.ObjToInt() && (v.EnableStatus == EnableStatusEnum.OnlyOut.ObjToInt() || EnableStatusEnum.Normal.ObjToInt() == v.EnableStatus)).Any()).OrderBy(x => x.ModifyDate).First();
+        }
     }
 }
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_TaskInfoService/TaskService.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_TaskInfoService/TaskService.cs"
index 225e7f6..027ba4e 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_TaskInfoService/TaskService.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_TaskInfoService/TaskService.cs"
@@ -63,7 +63,7 @@
 
         private readonly IOutboundOrderService _outboundOrderService;
         private readonly IOutboundOrderDetailService _outboundOrderDetailService;
-
+        private readonly IOutStockLockInfoService _outStockLockInfoService;
         private readonly ILocationStatusChangeRecordService _locationStatusChangeRecordService;
         private readonly IESSApiService _eSSApiService;
         private readonly IStockService _stockService;
@@ -89,7 +89,7 @@
 
         public List<int> TaskOutboundTypes => typeof(TaskTypeEnum).GetEnumIndexList();
 
-        public TaskService(IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockRepository, ILocationInfoService locationInfoService, IInboundOrderService inboundOrderService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IESSApiService eSSApiService, ILogger<TaskService> logger, IStockService stockService, IRecordService recordService, IInboundOrderDetailService inboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IInvokeMESService invokeMESService) : base(BaseDal)
+        public TaskService(IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockRepository, ILocationInfoService locationInfoService, IInboundOrderService inboundOrderService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IESSApiService eSSApiService, ILogger<TaskService> logger, IStockService stockService, IRecordService recordService, IInboundOrderDetailService inboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IInvokeMESService invokeMESService, IOutStockLockInfoService outStockLockInfoService) : base(BaseDal)
         {
             _mapper = mapper;
             _unitOfWorkManage = unitOfWorkManage;
@@ -105,6 +105,7 @@
             _outboundOrderService = outboundOrderService;
             _outboundOrderDetailService = outboundOrderDetailService;
             _invokeMESService = invokeMESService;
+            _outStockLockInfoService = outStockLockInfoService;
         }
 
         /// <summary>
@@ -264,8 +265,9 @@
                                supplyCode = group.Key.SupplyCode,
                                batchNo = group.Key.BatchNo,
                                lineNo = group.Key.lineNo,
-                               warehouseCode = group.Key.WarehouseCode=="0"?"1072": group.Key.WarehouseCode,
-                               unit= group.Key.BarcodeUnit,
+                               // warehouseCode = group.Key.WarehouseCode=="0"?"1072": group.Key.WarehouseCode,
+                               warehouseCode= "1072",
+                               unit = group.Key.BarcodeUnit,
                                barcodes = group.Select(row => new FeedbackBarcodesModel
                                {
                                    barcode = row.Barcode,
@@ -383,5 +385,150 @@
             }
         }
 
+
+
+      
+        /// <summary>
+        /// 鍥炲簱瀹屾垚鍥炶皟 - AGV灏嗘墭鐩樻斁鍥炶揣浣嶅悗璋冪敤
+        /// </summary>
+        public async Task<WebResponseContent> BackToStockComplete(Dt_Task task)
+        {
+            try
+            {
+                _unitOfWorkManage.BeginTran();
+
+                // 鑾峰彇鐩稿叧鐨勫嚭搴撻攣瀹氫俊鎭�
+                var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+                    .Where(x => x.TaskNum == task.TaskNum &&
+                               x.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�)
+                    .ToListAsync();
+
+                if (!lockInfos.Any())
+                    return WebResponseContent.Instance.Error("鏈壘鍒板洖搴撲腑鐨勯攣瀹氫俊鎭�");
+
+                //  鎭㈠搴撳瓨鍑哄簱鏁伴噺锛堝洖搴撶殑閮ㄥ垎锛�
+                await RestoreStockOutboundQuantity(lockInfos);
+
+                //  鏇存柊鍑哄簱鍗曟槑缁嗙殑閿佸畾鏁伴噺
+                var orderDetailGroups = lockInfos.GroupBy(x => x.OrderDetailId);
+
+                foreach (var group in orderDetailGroups)
+                {
+                    var orderDetailId = group.Key;
+                    var totalUnpicked = group.Sum(x => x.AssignQuantity - x.PickedQty);
+
+                    if (totalUnpicked > 0)
+                    {
+                        var orderDetail = await _outboundOrderService.Db.Queryable<Dt_OutboundOrderDetail>()
+                            .Where(x => x.Id == orderDetailId)
+                            .FirstAsync();
+                        orderDetail.LockQuantity -= totalUnpicked;
+
+                        // 鎭㈠鐘舵��
+                        if (orderDetail.LockQuantity <= 0 && orderDetail.OverOutQuantity <= 0)
+                        {
+                            orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.New;
+                        }
+                        else if (orderDetail.OverOutQuantity > 0)
+                        {
+                            orderDetail.OrderDetailStatus = (int)OrderDetailStatusEnum.AssignOverPartial;
+                        }
+
+                        await _outboundOrderService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+                    }
+                }
+
+                //  鏇存柊閿佸畾淇℃伅鐘舵�佷负宸插洖搴�
+                foreach (var lockInfo in lockInfos)
+                {
+                    lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
+                }
+                await _outStockLockInfoService.Db.Updateable(lockInfos).ExecuteCommandAsync();
+
+                // 6. 鏇存柊搴撳瓨鐘舵��
+                var stockIds = lockInfos.Select(x => x.StockId).Distinct().ToList();
+                var stocks = await _stockService.StockInfoService.Db.Queryable<Dt_StockInfo>()
+                    .Where(x => stockIds.Contains(x.Id))
+                    .ToListAsync();
+
+                foreach (var stock in stocks)
+                {
+                    stock.StockStatus = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
+                    stock.LocationCode = task.TargetAddress; // 鏇存柊璐т綅
+                }
+                await _stockService.StockInfoService.Db.Updateable(stocks).ExecuteCommandAsync();
+
+                // 7. 鏇存柊璐т綅鐘舵��
+                var location = await _locationInfoService.Db.Queryable<Dt_LocationInfo>()
+                    .Where(x => x.LocationCode == task.TargetAddress)
+                    .FirstAsync();
+                if (location != null)
+                {
+                    location.LocationStatus = (int)LocationStatusEnum.InStock;
+                    await _locationInfoService.Db.Updateable(location).ExecuteCommandAsync();
+                }
+
+                //  鏇存柊浠诲姟鐘舵�佷负宸插畬鎴�
+                task.TaskStatus = (int)TaskStatusEnum.Finish;
+             
+                await Db.Updateable(task).ExecuteCommandAsync();
+
+                _unitOfWorkManage.CommitTran();
+
+                return WebResponseContent.Instance.OK("鍥炲簱瀹屾垚", new
+                {
+                    TaskNum = task.TaskNum,
+                    PalletCode = task.PalletCode,
+                    RestoredQuantity = lockInfos.Sum(x => x.AssignQuantity - x.PickedQty)
+                });
+            }
+            catch (Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                return WebResponseContent.Instance.Error($"鍥炲簱瀹屾垚澶勭悊澶辫触: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 鎭㈠搴撳瓨鍑哄簱鏁伴噺锛堝洖搴撶殑閮ㄥ垎锛�
+        /// </summary>
+        private async Task RestoreStockOutboundQuantity(List<Dt_OutStockLockInfo> lockInfos)
+        {
+            // 鎸夊簱瀛業D鍜岀墿鏂欏垎缁�
+            var stockGroups = lockInfos.GroupBy(x => new { x.StockId, x.MaterielCode });
+
+            foreach (var group in stockGroups)
+            {
+                var stockId = group.Key.StockId;
+                var materielCode = group.Key.MaterielCode;
+                var totalUnpicked = group.Sum(x => x.AssignQuantity - x.PickedQty);
+
+                if (totalUnpicked <= 0) continue;
+
+                // 鑾峰彇璇ョ墿鏂欏湪搴撳瓨涓殑鎵�鏈夋潯鐮�
+                var stockDetails = await _stockService.StockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+                    .Where(x => x.StockId == stockId && x.MaterielCode == materielCode)
+                    .ToListAsync();
+
+                if (!stockDetails.Any()) continue;
+
+                // 鎸夊嚭搴撴暟閲忕殑姣斾緥鍒嗛厤鎭㈠鏁伴噺
+                var totalOutbound = stockDetails.Sum(x => x.OutboundQuantity);
+
+                if (totalOutbound <= 0) continue;
+
+                foreach (var detail in stockDetails)
+                {
+                    if (detail.OutboundQuantity <= 0) continue;
+
+                    decimal ratio = detail.OutboundQuantity / totalOutbound;
+                    decimal restoreAmount = Math.Min(detail.OutboundQuantity, totalUnpicked * ratio);
+
+                    detail.OutboundQuantity -= restoreAmount;
+                    await _stockService.StockInfoDetailService.Db.Updateable(detail).ExecuteCommandAsync();
+                }
+            }
+        }
+
     }
 }
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/ESSController.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/ESSController.cs"
index 5077d26..baa5a47 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/ESSController.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/ESSController.cs"
@@ -43,7 +43,7 @@
         public async Task<IActionResult> ContainerArrivalReport([FromBody] ContainerArrivalRequest request)
         {
             //杩欓噷瑕佸垽鏂嚭搴撶殑鏃跺�欙紝鏂欑浼氬埌鎵爜澶勩�備篃浼氳姹傝繖涓帴鍙c��
-
+            _logger.LogInformation(" ESSController  ContainerArrivalReport : CallId={CallId},ContainerCode={ContainerCode},SlotCode={SlotCode}", request.CallId, request.ContainerCode, request.SlotCode);
             var response = new ApiResponse<ContainerArrivalResponseData>
             {
                 Code = 0,
@@ -64,13 +64,13 @@
                 response.Code = 1;
                 response.Msg = "error";
                 response.Data.direction = "0";
-                return Ok(response); 
+                return Ok(response);
             }
 
-           
+
             await _semaphore.WaitAsync();
             try
-            {               
+            {
                 if (_memoryCache.TryGetValue(requestKey, out bool _))
                 {
                     _logger.LogWarning("鍙岄噸妫�鏌ユ娴嬪埌閲嶅璇锋眰锛屽凡蹇界暐: CallId={CallId}", request.CallId);
@@ -79,12 +79,12 @@
                     response.Data.direction = "0";
                     return Ok(response);
                 }
-             
+
                 var result = await _taskService.RequestInboundTask(request.ContainerCode, request.SlotCode);
-                
+
                 var cacheOptions = new MemoryCacheEntryOptions
                 {
-                    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1) 
+                    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1)
                 };
                 _memoryCache.Set(requestKey, true, cacheOptions);
                 if (result.Status)
@@ -95,7 +95,7 @@
                         Msg = "",
                         Data = new ContainerArrivalResponseData
                         {
-                            direction = "100" 
+                            direction = "100"
                         }
                     };
                     return Ok(response);
@@ -105,8 +105,10 @@
                     response.Code = 1;
                     response.Msg = "error";
                     response.Data.direction = "0";
+                    _logger.LogError(" ESSController  ContainerArrivalReport  Error: Message={Message}", result.Message);
+
                     return Ok(response);
-                }                                 
+                }
             }
             catch (Exception ex)
             {
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/Inbound/InboundOrderController.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/Inbound/InboundOrderController.cs"
index 7a055e8..f854191 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/Inbound/InboundOrderController.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/Inbound/InboundOrderController.cs"
@@ -30,7 +30,7 @@
         private readonly WIDESEA_IBasicService.IErpApiService erpApiService;
 
         private readonly WIDESEA_IBasicService.IInvokeMESService _invokeMESService;
-
+ 
         private readonly IESSApiService _eSSApiService;
         private readonly ILocationInfoService _locationInfoService;
         private readonly IDailySequenceService _dailySequenceService;
@@ -79,7 +79,7 @@
             //await _eSSApiService.MoveContainerAsync(new WIDESEA_DTO.Basic.MoveContainerRequest
             //{
             //    slotCode = "3-5",
-            //    containerCode = "A000008002"
+            //    containerCode = "A000008009"
             //});
 
             //await erpApiService.GetSuppliersAsync();
@@ -200,5 +200,11 @@
             return Service.UnPalletQuantity(orderNo);
         }
 
+        [HttpPost, Route("BatchOrderFeedbackToMes"), AllowAnonymous]
+        public async Task<WebResponseContent> BatchOrderFeedbackToMes([FromBody]  BatchOrderFeedbackToMesDto request)
+        {
+           return await _invokeMESService.BatchOrderFeedbackToMes(request.orderNos, request.inout);
+        }
+
     }
 }
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/OutboundOrderController.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/OutboundOrderController.cs"
index 989a8e4..366a6a4 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/OutboundOrderController.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/OutboundOrderController.cs"
@@ -58,5 +58,19 @@
             if (content.Status) return WebResponseContent.Instance.OK(200);
             else return WebResponseContent.Instance.Error(content.Message);
         }
+
+        /// <summary>
+        /// 鏍规嵁ID鑾峰彇鍑哄簱鍗�
+        /// </summary>ss
+        [HttpPost, Route("GetById"), AllowAnonymous, MethodParamsValidate]
+        public async Task<WebResponseContent> GetById(int id)
+        {
+            var order = await Service.GetById(id);
+            if (order == null)
+            {
+                return WebResponseContent.Instance.Error("鏈壘鍒板嚭搴撳崟淇℃伅");
+            }
+            return WebResponseContent.Instance.OK(null, order);
+        }
     }
 }
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"
new file mode 100644
index 0000000..5b1725d
--- /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_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
@@ -0,0 +1,87 @@
+锘縰sing Microsoft.AspNetCore.Mvc;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseController;
+using WIDESEA_DTO.Outbound;
+using WIDESEA_IOutboundService;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_WMSServer.Controllers.Outbound
+{
+ 
+    [Route("api/OutboundPicking")]
+    [ApiController]
+    public class OutboundPickingController : ApiBaseController<IOutboundPickingService, Dt_PickingRecord>
+    {
+        private readonly ISplitPackageService _splitPackageService;
+        private readonly IOutStockLockInfoService _outStockLockInfoService;
+        public OutboundPickingController(IOutboundPickingService service, ISplitPackageService splitPackageService, IOutStockLockInfoService outStockLockInfoService) : base(service)
+        {
+            _splitPackageService = splitPackageService;
+            _outStockLockInfoService = outStockLockInfoService;
+        }
+        /// <summary>
+        /// 鑾峰彇鎵樼洏鐨勫嚭搴撶姸鎬�
+        /// </summary>
+        [HttpGet("GetPalletOutboundStatus")]
+        public async Task<WebResponseContent> GetPalletOutboundStatus(string palletCode)
+        {
+            return await Service.GetPalletOutboundStatus(palletCode);
+        }
+
+        /// <summary>
+        /// 鑾峰彇鎵樼洏鐨勯攣瀹氫俊鎭�
+        /// </summary>
+        [HttpGet("GetPalletLockInfos")]
+        public async Task<WebResponseContent> GetPalletLockInfos(string palletCode)
+        {
+            var lockInfos = await _outStockLockInfoService.GetPalletLockInfos(palletCode);
+            return WebResponseContent.Instance.OK(null, lockInfos);
+        }
+
+        /// <summary>
+        /// 鎷i�夌‘璁�
+        /// </summary>
+        [HttpPost("ConfirmPicking")]
+        public async Task<WebResponseContent> ConfirmPicking([FromBody] PickingConfirmRequest request)
+        {
+            return await Service.ConfirmPicking(request);
+        }
+
+        /// <summary>
+        /// 鎷嗗寘鎿嶄綔
+        /// </summary>
+        [HttpPost("SplitPackage")]
+        public async Task<WebResponseContent> SplitPackage([FromBody] SplitPackageRequest request)
+        {
+            return await _splitPackageService.SplitPackage(request);
+        }
+
+        ///// <summary>
+        ///// 鐩存帴鍑哄簱
+        ///// </summary>
+        //[HttpPost("DirectOutbound")]
+        //public async Task<WebResponseContent> DirectOutbound([FromBody] DirectOutboundRequest request)
+        //{
+        //    return await Service.DirectOutbound(request);
+        //}
+
+        /// <summary>
+        /// 鑾峰彇鎷i�夊巻鍙�
+        /// </summary>
+        [HttpGet("GetPickingHistory")]
+        public async Task<WebResponseContent> GetPickingHistory(int orderId)
+        {
+            var history = await Service.GetPickingHistory(orderId);
+            return WebResponseContent.Instance.OK(null, history);
+        }
+
+        /// <summary>
+        /// 鎾ら攢鎷i��
+        /// </summary>
+        [HttpPost("CancelPicking")]
+        public async Task<WebResponseContent> CancelPicking([FromBody] CancelPickingRequest request)
+        {
+            return await Service.CancelPicking(request);
+        }
+    }
+}
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/TaskInfo/TaskController.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/TaskInfo/TaskController.cs"
index ede1591..4d0c35f 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/TaskInfo/TaskController.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/TaskInfo/TaskController.cs"
@@ -33,5 +33,17 @@
             return result;
         }
 
+
+        /// <summary>
+        /// 鐢熸垚鍑哄簱浠诲姟
+        /// </summary>
+        /// <param name="keys"></param>
+        /// <returns></returns>
+        [HttpPost, HttpGet, Route("GenerateOutboundTasks"), AllowAnonymous]
+        public WebResponseContent GenerateOutboundTasks([FromBody] int[] keys)
+        {
+            return Service.GenerateOutboundTasks(keys);
+        }
+
     }
 }

--
Gitblit v1.9.3