From 80dbe95a364ec753195ab9087c1eca1f5a6fa27c Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期四, 13 十一月 2025 09:36:06 +0800
Subject: [PATCH] 提交

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-shm      |    0 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-shm |    0 
 项目代码/WIDESEA_WMSClient/src/views/outbound/Picking.vue                                                     |  312 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 312 insertions(+), 0 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/Picking.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/Picking.vue"
new file mode 100644
index 0000000..3deb16d
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/Picking.vue"
@@ -0,0 +1,312 @@
+<template>
+  <div class="picking-container">
+    <!-- 鍑哄簱鍗曞垪琛� -->
+    <div class="card mb-4" v-for="order in pickingOrders" :key="order.outStockOrderId">
+      <div class="card-header bg-light d-flex justify-content-between align-items-center">
+        <div>
+          <h5 class="mb-0">鍑哄簱鍗�: {{ order.orderNumber }}</h5>
+          <small class="text-muted">
+            闇�姹�: {{ order.totalRequiredQuantity }} | 
+            宸查攣瀹�: {{ order.totalLockedQuantity }}
+          </small>
+        </div>
+        <button @click="confirmOrder(order)" class="btn btn-primary btn-sm"
+                :disabled="!canConfirmOrder(order)">
+          <i class="fas fa-check"></i> 纭鏁村崟鍑哄簱
+        </button>
+      </div>
+      
+      <div class="card-body p-0">
+        <div class="table-responsive">
+          <table class="table table-hover mb-0">
+            <thead>
+              <tr>
+                <th width="5%">#</th>
+                <th>浜у搧鍚嶇О</th>
+                <th>鎵瑰彿/鏉$爜</th>
+                <th>鍑哄簱鏁伴噺</th>
+                <th>搴撳瓨鏁伴噺</th>
+                <th>搴撲綅</th>
+                <th width="20%">鎿嶄綔</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr v-for="(item, index) in order.pickingItems" :key="item.outStockLockId"
+                  :class="{
+                    'table-success': item.status === 'Confirmed',
+                    'table-warning': needsSplit(item)
+                  }">
+                <td>{{ index + 1 }}</td>
+                <td>{{ item.productName }}</td>
+                <td>
+                  <div>
+                    <strong>{{ item.batchNumber }}</strong>
+                    <br>
+                    <small class="text-muted">{{ item.barCode }}</small>
+                  </div>
+                </td>
+                <td>
+                  <span class="font-weight-bold text-primary">
+                    {{ item.outStockQuantity }}
+                  </span>
+                  <small class="text-muted ml-1">{{ item.packageUnit }}</small>
+                </td>
+                <td>
+                  <span :class="{
+                    'text-success': item.isWholePackage,
+                    'text-warning': needsSplit(item)
+                  }">
+                    {{ item.stockQuantity }} {{ item.packageUnit }}
+                  </span>
+                </td>
+                <td>{{ item.location }}</td>
+                <td>
+                  <!-- 鏁村寘鐩存帴纭 -->
+                  <button v-if="item.isWholePackage && item.status === 'Pending'"
+                          @click="confirmWholePicking(item)"
+                          class="btn btn-success btn-sm"
+                          :disabled="loading">
+                    <i class="fas fa-check"></i> 纭
+                  </button>
+                  
+                  <!-- 闇�瑕佹媶鍖呯殑鎯呭喌 -->
+                  <div v-else-if="needsSplit(item) && item.status === 'Pending'">
+                    <button @click="showSplitModal(item)"
+                            class="btn btn-warning btn-sm mb-1"
+                            :disabled="loading">
+                      <i class="fas fa-cube"></i> 鎷嗗寘
+                    </button>
+                    <div class="small text-muted">
+                      闇�鎷嗗寘: {{ item.outStockQuantity }}/{{ item.stockQuantity }}
+                    </div>
+                  </div>
+                  
+                  <!-- 宸茬‘璁ょ姸鎬� -->
+                  <span v-else-if="item.status === 'Confirmed'" class="text-success">
+                    <i class="fas fa-check-circle"></i> 宸茬‘璁�
+                  </span>
+                </td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+      </div>
+    </div>
+
+    <!-- 鎷嗗寘妯℃�佹 -->
+    <div class="modal fade" id="splitModal" tabindex="-1">
+      <div class="modal-dialog">
+        <div class="modal-content">
+          <div class="modal-header">
+            <h5 class="modal-title">鎷嗗寘鎿嶄綔</h5>
+            <button type="button" class="close" data-dismiss="modal">
+              <span>&times;</span>
+            </button>
+          </div>
+          <div class="modal-body">
+            <div v-if="currentSplitItem">
+              <div class="form-group">
+                <label>浜у搧鍚嶇О</label>
+                <input type="text" class="form-control" :value="currentSplitItem.productName" readonly>
+              </div>
+              <div class="form-group">
+                <label>鍘熸潯鐮�</label>
+                <input type="text" class="form-control" :value="currentSplitItem.barCode" readonly>
+              </div>
+              <div class="row">
+                <div class="col-6">
+                  <div class="form-group">
+                    <label>鍘熷簱瀛樻暟閲�</label>
+                    <input type="text" class="form-control" :value="currentSplitItem.stockQuantity" readonly>
+                  </div>
+                </div>
+                <div class="col-6">
+                  <div class="form-group">
+                    <label>鍑哄簱鏁伴噺</label>
+                    <input type="text" class="form-control" :value="currentSplitItem.outStockQuantity" readonly>
+                  </div>
+                </div>
+              </div>
+              <div class="form-group">
+                <label>鎷嗗寘鏁伴噺</label>
+                <input type="number" class="form-control" v-model="splitQuantity"
+                       :max="currentSplitItem.stockQuantity - 0.01" step="0.01" min="0.01">
+                <small class="form-text text-muted">
+                  鎷嗗嚭鏁伴噺: {{ splitQuantity }} | 
+                  鍓╀綑鏁伴噺: {{ (currentSplitItem.stockQuantity - splitQuantity).toFixed(2) }}
+                </small>
+              </div>
+            </div>
+          </div>
+          <div class="modal-footer">
+            <button type="button" class="btn btn-secondary" data-dismiss="modal">鍙栨秷</button>
+            <button type="button" class="btn btn-warning" @click="confirmSplit" 
+                    :disabled="!splitQuantity || splitQuantity <= 0">
+              <i class="fas fa-cube"></i> 纭鎷嗗寘
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 鎿嶄綔鎻愮ず -->
+    <div v-if="message" :class="['alert', messageType === 'success' ? 'alert-success' : 'alert-danger', 'mt-3']">
+      {{ message }}
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      pickingOrders: [],
+      loading: false,
+      message: '',
+      messageType: 'success',
+      currentSplitItem: null,
+      splitQuantity: 0
+    }
+  },
+  mounted() {
+    this.loadPickingList();
+    // 鍒濆鍖栨ā鎬佹
+    $('#splitModal').on('hidden.bs.modal', () => {
+      this.currentSplitItem = null;
+      this.splitQuantity = 0;
+    });
+  },
+  methods: {
+    async loadPickingList() {
+      try {
+        this.loading = true;
+        const response = await this.$http.get('/Picking/PickingList');
+        this.pickingOrders = response.data;
+      } catch (error) {
+        this.showMessage('鍔犺浇鎷i�夊垪琛ㄥけ璐�', 'error');
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 鍒ゆ柇鏄惁闇�瑕佹媶鍖�
+    needsSplit(item) {
+      return !item.isWholePackage && item.outStockQuantity <= item.stockQuantity;
+    },
+
+    // 鏁村寘纭
+    async confirmWholePicking(item) {
+      try {
+        this.loading = true;
+        const response = await this.$http.post('/Picking/ConfirmWholePicking', {
+          outStockLockId: item.outStockLockId
+        });
+        
+        if (response.data.success) {
+          this.showMessage(response.data.message, 'success');
+          this.loadPickingList();
+        } else {
+          this.showMessage(response.data.message, 'error');
+        }
+      } catch (error) {
+        this.showMessage('鎿嶄綔澶辫触', 'error');
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 鏄剧ず鎷嗗寘妯℃�佹
+    showSplitModal(item) {
+      this.currentSplitItem = item;
+      this.splitQuantity = item.outStockQuantity; // 榛樿鎷嗗嚭鏁伴噺涓哄嚭搴撴暟閲�
+      $('#splitModal').modal('show');
+    },
+
+    // 纭鎷嗗寘
+    async confirmSplit() {
+      if (!this.splitQuantity || this.splitQuantity <= 0) {
+        this.showMessage('璇疯緭鍏ユ湁鏁堢殑鎷嗗寘鏁伴噺', 'error');
+        return;
+      }
+
+      try {
+        this.loading = true;
+        const response = await this.$http.post('/Picking/SplitPackage', {
+          outStockLockId: this.currentSplitItem.outStockLockId,
+          splitQuantity: this.splitQuantity
+        });
+        
+        if (response.data.success) {
+          this.showMessage(`鎷嗗寘鎴愬姛锛佹柊鏉$爜: ${response.data.data.newBarCode}`, 'success');
+          $('#splitModal').modal('hide');
+          this.loadPickingList();
+        } else {
+          this.showMessage(response.data.message, 'error');
+        }
+      } catch (error) {
+        this.showMessage('鎷嗗寘澶辫触', 'error');
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 纭鏁村崟鍑哄簱
+    async confirmOrder(order) {
+      if (!confirm(`纭畾瑕佺‘璁ゆ暣涓嚭搴撳崟 ${order.orderNumber} 鍚楋紵`)) return;
+      
+      try {
+        this.loading = true;
+        const response = await this.$http.post('/Picking/ConfirmOutStockOrder', {
+          outStockOrderId: order.outStockOrderId
+        });
+        
+        if (response.data.success) {
+          this.showMessage(response.data.message, 'success');
+          this.loadPickingList();
+        } else {
+          this.showMessage(response.data.message, 'error');
+        }
+      } catch (error) {
+        this.showMessage('鎿嶄綔澶辫触', 'error');
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 妫�鏌ユ槸鍚﹀彲浠ョ‘璁ゆ暣鍗�
+    canConfirmOrder(order) {
+      return order.pickingItems.every(item => 
+        item.status === 'Pending' && 
+        (item.isWholePackage || this.needsSplit(item))
+      );
+    },
+
+    showMessage(msg, type) {
+      this.message = msg;
+      this.messageType = type;
+      setTimeout(() => {
+        this.message = '';
+      }, 3000);
+    }
+  }
+}
+</script>
+
+<style scoped>
+.picking-container {
+  max-width: 1400px;
+  margin: 0 auto;
+}
+
+.table td {
+  vertical-align: middle;
+}
+
+.btn-sm {
+  min-width: 80px;
+}
+
+.badge {
+  font-family: monospace;
+}
+</style>
\ 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-shm" "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-shm"
index 3153eb6..ce475c3 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-shm"
+++ "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-shm"
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-shm" "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-shm"
index 0d91de9..a0b5b32 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-shm"
+++ "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-shm"
Binary files differ

--
Gitblit v1.9.3