From f53be30287bc8161805509980bb39a3aae6d5145 Mon Sep 17 00:00:00 2001
From: 647556386 <647556386@qq.com>
Date: 星期二, 13 一月 2026 18:42:48 +0800
Subject: [PATCH] Merge branch 'htq20251215' of http://115.159.85.185:8098/r/ZhongRui/ALDbanyunxiangmu into htq20251215

---
 /dev/null                                                                                      |    0 
 项目代码/WIDESEA_WMSClient/src/extension/inbound/Dt_AllocateOrder.js                               |    1 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs                   |   16 
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs |    2 
 项目代码/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js                           |  273 ++++-------------
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IInboundService/IInboundOrderService.cs                 |    2 
 项目代码/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js                                 |   28 +
 项目代码/WMS无仓储版/WIDESEA_WMSServer/BigGreenService/BigGreenService.cs                              |   98 ++---
 项目代码/WIDESEA_WMSClient/src/views/Home.vue                                                      |  437 +++++++++++++++++++----------
 项目代码/WIDESEA_WMSClient/config/buttons.js                                                       |    2 
 项目代码/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js                                   |    2 
 11 files changed, 444 insertions(+), 417 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/config/buttons.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/config/buttons.js"
index b9462f7..0fb06b3 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/config/buttons.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/config/buttons.js"
@@ -319,7 +319,7 @@
     name: "鍏抽棴鍗曟嵁",
     icon: '',
     class: '',
-    value: 'CloseOrder',
+    value: ' ',
     type: 'warning',
     onClick: function () {
     }
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/Dt_AllocateOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/Dt_AllocateOrder.js"
index 5a01af4..42b4c4f 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/Dt_AllocateOrder.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/Dt_AllocateOrder.js"
@@ -404,7 +404,6 @@
 
           param.wheres.push(...wheres);
         return true;
-        return true;
       },
       searchAfter(result) {
         //鏌ヨ鍚庯紝result杩斿洖鐨勬煡璇㈡暟鎹�,鍙互鍦ㄦ樉绀哄埌琛ㄦ牸鍓嶅鐞嗚〃鏍肩殑鍊�
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js"
index 3a6458b..2e7a4ed 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js"
@@ -5,12 +5,13 @@
 import { ElDialog , ElForm, ElFormItem, ElInput, ElButton, ElMessage ,ElSelect ,ElOption } from 'element-plus'; // 寮曞叆ElMessage锛岃В鍐虫彁绀烘棤鍙嶅簲
 import gridBody from '../inbound/extend/Pallet.vue'
 import gridHeader from './extend/EmptyTrayInbound.vue'
+import gridFooter from "./extend/UndoPalletGroup.vue";
 let extension = {
     components: {
       //鏌ヨ鐣岄潰鎵╁睍缁勪欢
       gridHeader: gridHeader,
       gridBody: gridBody,
-      gridFooter: '',
+      gridFooter: gridFooter,
       //鏂板缓銆佺紪杈戝脊鍑烘鎵╁睍缁勪欢
       modelHeader: '',
       modelBody: '',
@@ -44,207 +45,8 @@
       //     this.$emit('openPalletDialog', targetRow.orderNo);
       //   }
       // },
-      {
-                name: '鎾ら攢缁勭洏',
-                type: 'primary',
-                value: '鎾ら攢缁勭洏',
-                onClick: function () {
-                    console.log('鎾ら攢缁勭洏鎸夐挳琚偣鍑�');
-                    const mountNode = document.createElement('div');
-                    document.body.appendChild(mountNode);
-
-                    // 鍝嶅簲寮忚〃鍗曟暟鎹細鎵樼洏鍙凤紙蹇呭~锛�
-                    const formData = reactive({
-                        palletCode: '', // 鎵樼洏鍙疯緭鍏ユ
-                        barcode:''
-                    });
-
-                    // 鎻愪氦琛ㄥ崟鐨勭粺涓�閫昏緫
-                    const submitForm = async () => {
-                        const formRef = vnode.component.refs.cancelPalletForm;
-                        try {
-                            // 鎵ц琛ㄥ崟鏍¢獙锛堟墭鐩樺彿蹇呭~锛�
-                            await formRef.validate();
-                        } catch (err) {
-                            ElMessage.warning('璇疯緭鍏ユ湁鏁堢殑鎵樼洏鍙�');
-                            return;
-                        }
-
-                        // 鍙戣捣鎾ら攢缁勭洏璇锋眰
-                        try {
-                            //console.log('鍙戣捣鎾ら攢缁勭洏璇锋眰锛屾墭鐩樺彿锛�', formData.palletCode.trim());
-                            const response = await http.post('/api/InboundOrder/UndoPalletGroup?palletCode='+formData.palletCode.trim()+'&barcode='+formData.barcode.trim());
-                              
-
-                            const { status, message, data } = response;
-                            if (status) {
-                                ElMessage.success(`鎾ら攢缁勭洏鎴愬姛锛屾墭鐩樺彿锛�${formData.palletCode.trim()}`);
-                                this.refresh(); // 鎴愬姛鍚庡埛鏂板垪琛�
-                                // 鍏抽棴瀵硅瘽妗�
-                                render(null, mountNode);
-                                document.body.removeChild(mountNode);
-                            } else {
-                                console.log('鎾ら攢缁勭洏澶辫触锛屽悗绔彁绀猴細', message);
-                                ElMessage.error(message || data?.message || '鎾ら攢缁勭洏澶辫触');
-                                selectPalletCodeInput(); // 閫変腑杈撳叆妗嗘柟渚块噸鏂拌緭鍏�
-                            }
-                        } catch (error) {
-                            console.error('鎾ら攢缁勭洏璇锋眰寮傚父锛�', error);
-                            ElMessage.error('缃戠粶寮傚父鎴栨帴鍙i敊璇紝璇风◢鍚庨噸璇�');
-                            selectPalletCodeInput();
-                        }
-                    };
-
-                    // 閫変腑杈撳叆妗嗘枃鏈紙鏂逛究閲嶆柊杈撳叆锛�
-                    const selectPalletCodeInput = () => {
-                        setTimeout(() => {
-                            const inputRef = vnode.component.refs.palletCodeInput;
-                            if (inputRef) {
-                                const targetInput = inputRef.$el?.querySelector('input') || inputRef;
-                                targetInput?.focus();
-                                targetInput?.select();
-                            }
-                        }, 100);
-                    };
-
-                    // 鍒涘缓瀵硅瘽妗哣Node
-                    const vnode = createVNode(ElDialog, {
-                        title: '鎾ら攢缁勭洏',
-                        width: '400px',
-                        modelValue: true,
-                        appendToBody: true,
-                        onOpened: () => {
-                            // 瀵硅瘽妗嗘墦寮�鍚庤嚜鍔ㄨ仛鐒﹁緭鍏ユ
-                            setTimeout(() => {
-                                const inputRef = vnode.component.refs.palletCodeInput;
-                                inputRef?.focus();
-                            }, 100);
-                        },
-                        'onUpdate:modelValue': (isVisible) => {
-                            if (!isVisible) {
-                                render(null, mountNode);
-                                document.body.removeChild(mountNode);
-                            }
-                        }
-                    }, {
-                        default: () => h(ElForm, {
-                            model: formData,
-                            rules: {
-                                palletCode: [
-                                    { required: true, message: '璇疯緭鍏ユ墭鐩樺彿', trigger: ['blur', 'enter'] },
-                                    { min: 1, max: 50, message: '鎵樼洏鍙烽暱搴︿笉鑳借秴杩�50涓瓧绗�', trigger: ['blur', 'input'] }
-                                ]
-                            },
-                            ref: 'cancelPalletForm'
-                        }, [
-                            // 鎵樼洏鍙疯緭鍏ラ」
-                            h(ElFormItem, { label: '鎵樼洏鍙�', prop: 'palletCode', required: true }, [
-                                h(ElInput, {
-                                    type: 'text',
-                                    modelValue: formData.palletCode,
-                                    'onUpdate:modelValue': (val) => {
-                                        formData.palletCode = val;
-                                    },
-                                    ref: 'palletCodeInput',
-                                    placeholder: '鎵爜杈撳叆鎴栨墜鍔ㄨ緭鍏ユ墭鐩樺彿',
-                                    maxLength: 50,
-                                    // 鐩戝惉鍥炶溅浜嬩欢锛堟壂鐮佹灙榛樿浼氬彂閫佸洖杞︼級
-                                    onKeydown: (e) => {
-                                        if (e.key === 'Enter') {
-                                            e.preventDefault();
-                                            submitForm();
-                                        }
-                                    }
-                                })
-                            ]),
-                            h(ElFormItem,{label: '鏉$爜', prop: 'barcode'},[
-                              h(ElInput, {
-                                type: 'text',
-                                modelValue: formData.barcode,
-                                'onUpdate:modelValue': (val) => {
-                                    formData.barcode = val;
-                                },
-                                placeholder: '鍙�夛紝鎵爜杈撳叆鎴栨墜鍔ㄨ緭鍏ユ潯鐮�',
-                                maxLength: 50,
-                                onKeydown: (e) => {
-                                    if (e.key === 'Enter') {
-                                        e.preventDefault();
-                                        submitForm();
-                                    }
-                                  }
-                              })
-                            ]),
-                            // 搴曢儴鎸夐挳鍖�
-                            h('div', { style: { textAlign: 'right', marginTop: '16px' } }, [
-                                h(ElButton, {
-                                    type: 'text',
-                                    onClick: () => {
-                                        render(null, mountNode);
-                                        document.body.removeChild(mountNode);
-                                        ElMessage.info('鍙栨秷鎾ら攢缁勭洏');
-                                    }
-                                }, '鍙栨秷'),
-                                h(ElButton, {
-                                    type: 'primary',
-                                    onClick: submitForm.bind(this) // 缁戝畾this涓婁笅鏂�
-                                }, '纭鎾ら攢')
-                            ])
-                        ])
-                    });
-
-                    vnode.appContext = this.$.appContext;
-                    render(vnode, mountNode);
-                }
-            },
-      {
-  name: '鍒嗘壒鍏ュ簱',
-  type: 'primary',
-  value: '鍒嗘壒鍏ュ簱',
-  onClick: async function () { 
-    console.log('鍒嗘壒鍏ュ簱鎸夐挳琚偣鍑伙紝寮�濮嬫牎楠�');
-    const selectedRows = this.$refs.table.getSelected();
-
-    // 鏍¢獙1锛氭槸鍚﹂�変腑琛岋紙鑷冲皯閫夋嫨涓�鏉★級
-    if (selectedRows.length === 0) {
-      console.log('鏍¢獙涓嶉�氳繃锛氭湭閫変腑浠讳綍鍗曟嵁');
-      ElMessage.warning('璇烽�夋嫨鑷冲皯涓�鏉″崟鎹�');
-      return;
-    }
-
-    // 鏀堕泦鎵�鏈夐�変腑鍗曟嵁鐨勭紪鍙凤紙杩囨护鏃犲崟鎹彿鐨勫紓甯歌锛�
-    const inboundOrderNos = selectedRows
-      .filter(row => row.orderNo)
-      .map(row => row.orderNo);
-
-    // 鏍¢獙2锛氭槸鍚︽湁鏈夋晥鍗曟嵁鍙�
-    if (inboundOrderNos.length === 0) {
-      console.log('鏍¢獙涓嶉�氳繃锛氶�変腑鍗曟嵁鏃犳湁鏁堢紪鍙�');
-      ElMessage.warning('閫変腑鐨勫崟鎹腑鏃犳湁鏁堢紪鍙凤紝璇烽噸鏂伴�夋嫨');
-      return;
-    }
-
-    try {
-      console.log('鍙戣捣鍒嗘壒鍏ュ簱璇锋眰锛屽弬鏁帮細', { inboundOrderNos});
-      const response = await http.post('/api/InboundOrder/BatchOrderFeedbackToMes', {
-        orderNos: inboundOrderNos, 
-        inout:1
-      });
-
-      const { status, message, data } = response;
-      if (status) {
-        console.log('鍒嗘壒鍏ュ簱鎴愬姛锛屽悗绔繑鍥烇細', data);
-        ElMessage.success(`鍒嗘壒鍏ュ簱鎴愬姛锛佸叡澶勭悊${inboundOrderNos.length}鏉″崟鎹甡);
-        this.refresh(); // 鍏ュ簱鎴愬姛鍚庡埛鏂板垪琛紙澶嶇敤鍘熸湁閫昏緫锛�
-      } else {
-        console.log('鍒嗘壒鍏ュ簱澶辫触锛屽悗绔彁绀猴細', message);
-        ElMessage.error(message || data?.message || '鍒嗘壒鍏ュ簱澶辫触');
-      }
-    } catch (error) {
-      console.error('鍒嗘壒鍏ュ簱璇锋眰寮傚父锛�', error);
-      ElMessage.error('缃戠粶寮傚父鎴栨帴鍙i敊璇紝璇风◢鍚庨噸璇�');
-    }
-  }
-},], box: [], detail: [] }, 
+      
+], box: [], detail: [] }, 
     methods: {
        //涓嬮潰杩欎簺鏂规硶鍙互淇濈暀涔熷彲浠ュ垹闄�
       onInit() {  
@@ -260,6 +62,73 @@
                this.$refs.gridHeader.open();
             }
         }
+
+        var UndoPalletGroupBtn = this.buttons.find(
+        (x) => x.value == "UndoPalletGroup"
+      );
+      if (UndoPalletGroupBtn != null) {
+        UndoPalletGroupBtn.onClick = () => {
+          this.$refs.gridFooter.open();
+        };
+      }
+
+      var BatchInOrderFeedbackToMesBtn = this.buttons.find(
+        (x) => x.value == "BatchInOrderFeedbackToMes"
+      );
+      if (BatchInOrderFeedbackToMesBtn != null) {
+        BatchInOrderFeedbackToMesBtn.onClick = () => {
+          var rows = this.$refs.table.getSelected();
+          // 鏍¢獙鏄惁鏈夐�変腑鏁版嵁
+          if (!rows || rows.length === 0) {
+            return this.$Message.error("璇峰厛閫夋嫨闇�瑕佸鐞嗙殑鍗曟嵁");
+          }
+          if (rows.length > 1) {
+            return this.$Message.error("璇烽�夋嫨涓�鏉℃暟鎹�");
+          }
+          this.http.post(`api/Inbound/BatchInOrderFeedbackToMes?id=${rows[0].id}`, {}, "鏁版嵁澶勭悊涓�...")
+            .then((x) => {
+              if (x.status) {
+                this.$Message.success(x.message);
+                this.refresh();
+              } else {
+                return this.$Message.error(x.message);
+              }
+            })
+            .catch((error) => {
+              // 澧炲姞寮傚父鎹曡幏锛屽鐞嗙綉缁滈敊璇瓑鎯呭喌
+              //_this.$Message.error('璇锋眰澶辫触锛�' + (error.message || '鏈煡閿欒'));
+            });
+        };
+      }
+
+      var CloseOrderBtn = this.buttons.find(
+        (x) => x.value == "CloseOrder"
+      );
+      if (CloseOrderBtn != null) {
+        CloseOrderBtn.onClick = () => {
+          var rows = this.$refs.table.getSelected();
+          // 鏍¢獙鏄惁鏈夐�変腑鏁版嵁
+          if (!rows || rows.length === 0) {
+            return this.$Message.error("璇峰厛閫夋嫨闇�瑕佸叧闂殑鍗曟嵁");
+          }
+          if (rows.length > 1) {
+            return this.$Message.error("璇烽�夋嫨涓�鏉″崟鎹�");
+          }
+          this.http.post(`api/InboundOrder/HandCloseOrder?orderIds=${rows[0].orderNo}`, {}, "鏁版嵁澶勭悊涓�...")
+            .then((x) => {
+              if (x.status) {
+                this.$Message.success(x.message);
+                this.refresh();
+              } else {
+                return this.$Message.error(x.message);
+              }
+            })
+            .catch((error) => {
+              // 澧炲姞寮傚父鎹曡幏锛屽鐞嗙綉缁滈敊璇瓑鎯呭喌
+              //_this.$Message.error('璇锋眰澶辫触锛�' + (error.message || '鏈煡閿欒'));
+            });
+        };
+      }
       },
       onInited() {
         
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 9c780c9..9176f78 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"
@@ -82,7 +82,7 @@
           if (rows.length > 1) {
             return this.$Message.error("璇烽�夋嫨涓�鏉″崟鎹�");
           }
-          this.http.post(`api/InboundOrder/HandCloseOrder?orderIds=${rows[0].id}`, {}, "鏁版嵁澶勭悊涓�...")
+          this.http.post(`api/InboundOrder/HandCloseOrder?orderIds=${rows[0].inboundOrderNo}`, {}, "鏁版嵁澶勭悊涓�...")
             .then((x) => {
               if (x.status) {
                 this.$Message.success(x.message);
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
index 638df8b..1ff6c97 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
@@ -556,6 +556,34 @@
       //妗嗘灦鍒濆鍖栭厤缃悗
       //濡傛灉瑕侀厤缃槑缁嗚〃,鍦ㄦ鏂规硶鎿嶄綔
       //this.detailOptions.columns.forEach(column=>{ });
+      var CloseOrderBtn = this.buttons.find(
+              (x) => x.value == "CloseOrder"
+            );
+            if (CloseOrderBtn != null) {
+              CloseOrderBtn.onClick = () => {
+                var rows = this.$refs.table.getSelected();
+                // 鏍¢獙鏄惁鏈夐�変腑鏁版嵁
+                if (!rows || rows.length === 0) {
+                  return this.$Message.error("璇峰厛閫夋嫨闇�瑕佸叧闂殑鍗曟嵁");
+                }
+                if (rows.length > 1) {
+                  return this.$Message.error("璇烽�夋嫨涓�鏉″崟鎹�");
+                }
+                this.http.post(`api/InboundOrder/HandCloseOrder?orderIds=${rows[0].orderNo}`, {}, "鏁版嵁澶勭悊涓�...")
+                  .then((x) => {
+                    if (x.status) {
+                      this.$Message.success(x.message);
+                      this.refresh();
+                    } else {
+                      return this.$Message.error(x.message);
+                    }
+                  })
+                  .catch((error) => {
+                    // 澧炲姞寮傚父鎹曡幏锛屽鐞嗙綉缁滈敊璇瓑鎯呭喌
+                    //_this.$Message.error('璇锋眰澶辫触锛�' + (error.message || '鏈煡閿欒'));
+                  });
+              };
+            }
     },
     searchBefore(param) {
 
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/Home.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/Home.vue"
index 1afb2bd..c86c83d 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/Home.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/Home.vue"
@@ -2,85 +2,120 @@
   <div class="wms-dashboard">
     <!-- 缁熻鍗$墖鍖哄煙 - 缁戝畾鍝嶅簲寮忔暟鎹� -->
     <el-row :gutter="20" class="stats-card-row">
-  <el-col :span="4">
-    <div class="stats-card">
-      <div class="metric-icon">
-        <el-icon :size="32">
-          <Box />
-        </el-icon>
-      </div>
-      <div class="card-title">鎬诲簱瀛�</div>
-      <div class="card-value">{{ formatNumber(bigscreendata.totalStockQuantity) }}</div>
-    </div>
-  </el-col>
-  <el-col :span="4">
-    <div class="stats-card">
-      <div class="metric-icon">
-        <el-icon :size="32">
-          <Document />
-        </el-icon>
-      </div>
-      <div class="card-title">寰呭嚭搴撹鍗�</div>
-      <div class="card-value">{{ bigscreendata.unOutBoundOrderCount }}</div>
-    </div>
-  </el-col>
-  <el-col :span="4">
-    <div class="stats-card">
-      <div class="metric-icon">
-        <el-icon :size="32">
-          <Download />
-        </el-icon>
-      </div>
-      <div class="card-title">浠婃棩鍏ュ簱瀹屾垚鏁�</div>
-      <div class="card-value">{{ bigscreendata.inboundCount }}</div>
-    </div>
-  </el-col>
-  <el-col :span="4">
-    <div class="stats-card">
-      <div class="metric-icon">
-        <el-icon :size="32">
-          <Upload />
-        </el-icon>
-      </div>
-      <div class="card-title">浠婃棩鍑哄簱瀹屾垚鏁�</div>
-      <div class="card-value">{{ bigscreendata.outboundCount }}</div>
-    </div>
-  </el-col>
-  <el-col :span="4">
-    <div class="stats-card">
-      <div class="metric-icon">
-        <el-icon :size="32">
-          <Box />
-        </el-icon>
-      </div>
-      <div class="card-title">鏈夎揣鏂欑</div>
-      <div class="card-value">{{ formatNumber(bigscreendata.inStockPallet) }}</div>
-    </div>
-  </el-col>
-  <el-col :span="4">
-    <div class="stats-card">
-      <div class="metric-icon">
-        <el-icon :size="32">
-          <Box />
-        </el-icon>
-      </div>
-      <div class="card-title">绌虹鏁伴噺</div>
-      <div class="card-value">{{ formatNumber(bigscreendata.freeStockPallet) }}</div>
-    </div>
-  </el-col>
-</el-row>
-
+      <el-col :span="4">
+        <div class="stats-card">
+          <div class="metric-icon">
+            <el-icon :size="32">
+              <Box />
+            </el-icon>
+          </div>
+          <div class="card-title">鎬诲簱瀛�</div>
+          <div class="card-value">{{ formatNumber(bigscreendata.totalStockQuantity) }}</div>
+        </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="stats-card">
+          <div class="metric-icon">
+            <el-icon :size="32">
+              <Document />
+            </el-icon>
+          </div>
+          <div class="card-title">寰呭嚭搴撹鍗�</div>
+          <div class="card-value">{{ bigscreendata.unOutBoundOrderCount }}</div>
+        </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="stats-card">
+          <div class="metric-icon">
+            <el-icon :size="32">
+              <Download />
+            </el-icon>
+          </div>
+          <div class="card-title">浠婃棩鍏ュ簱瀹屾垚鏁�</div>
+          <div class="card-value">{{ bigscreendata.inboundCount }}</div>
+        </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="stats-card">
+          <div class="metric-icon">
+            <el-icon :size="32">
+              <Upload />
+            </el-icon>
+          </div>
+          <div class="card-title">浠婃棩鍑哄簱瀹屾垚鏁�</div>
+          <div class="card-value">{{ bigscreendata.outboundCount }}</div>
+        </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="stats-card">
+          <div class="metric-icon">
+            <el-icon :size="32">
+              <Box />
+            </el-icon>
+          </div>
+          <div class="card-title">鏈夎揣鏂欑</div>
+          <div class="card-value">{{ formatNumber(bigscreendata.inStockPallet) }}</div>
+        </div>
+      </el-col>
+      <el-col :span="4">
+        <div class="stats-card">
+          <div class="metric-icon">
+            <el-icon :size="32">
+              <Box />
+            </el-icon>
+          </div>
+          <div class="card-title">绌虹鏁伴噺</div>
+          <div class="card-value">{{ formatNumber(bigscreendata.freeStockPallet) }}</div>
+        </div>
+      </el-col>
+    </el-row>
 
     <!-- 鍥捐〃鍖哄煙锛堢涓�琛岋級 -->
     <el-row :gutter="20" class="chart-row">
-      <el-col :span="12">
-        <!-- 鏇挎崲el-card涓篸iv锛屼繚鐣檆hart-card绫诲悕 -->
+      <el-col :span="8">
         <div class="chart-card">
           <div class="chart-title">搴撲綅鍒╃敤鐜�</div>
           <div ref="locationRateRef" class="chart-container"></div>
         </div>
       </el-col>
-      <el-col :span="12">
+      <!-- 涓存湡淇℃伅鏀逛负琛ㄦ牸 -->
+      <el-col :span="8">
+        <div class="chart-card">
+          <div class="chart-title">鐗╂枡涓存湡淇℃伅</div>
+          <!-- 涓存湡鐗╂枡琛ㄦ牸 -->
+          <div class="expiration-table-container">
+            <el-table 
+              :data="expirationTableData" 
+              border 
+              stripe 
+              style="width: 100%;"
+              :empty-text="emptyText"
+            >
+              <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" align="center" />
+              <el-table-column prop="materielName" label="鐗╂枡鍚嶇О" align="center" show-overflow-tooltip />
+              <el-table-column prop="batchNo" label="鎵规鍙�" align="center" />
+              <el-table-column prop="validDate" label="鏈夋晥鏈�" align="center" />
+              <el-table-column label="涓存湡绛夌骇" align="center">
+                <template #default="{ row }">
+                  <span :class="getExpireLevelClass(row.expireLevel)">{{ row.expireLevel }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column prop="daysToExpiration" label="涓存湡澶╂暟" align="center">
+                <template #default="{ row }">
+                  <span :class="row.daysToExpiration < 0 ? 'text-red' : ''">
+                    {{ row.daysToExpiration < 0 ? '宸茶繃鏈�' : `${row.daysToExpiration}澶ー }}
+                  </span>
+                </template>
+              </el-table-column>
+              <!-- <el-table-column prop="barcode" label="鏉$爜" align="center" /> -->
+              <el-table-column prop="stockQuantity" label="搴撳瓨鏁伴噺" align="center" />
+              <el-table-column prop="locationCode" label="搴撲綅" align="center" />
+              <el-table-column prop="palletCode" label="鎵樼洏缂栧彿" align="center" />
+            </el-table>
+          </div>
+        </div>
+      </el-col>
+      <el-col :span="8">
         <div class="chart-card">
           <div class="chart-title">杩�7鏃ュ嚭鍏ュ簱瓒嬪娍锛堝浘鍍忓寲璧板娍锛�</div>
           <div ref="stockTrendRef" class="chart-container"></div>
@@ -95,7 +130,6 @@
     <!-- 琛ㄦ牸鍖哄煙 - 缁戝畾鍚庣浣滀笟鏁版嵁 -->
     <el-row :gutter="20" class="table-row" width="100%">
       <el-col :span="24">
-        <!-- 鏇挎崲el-card涓篸iv锛屼繚鐣檛able-card绫诲悕 -->
         <div class="table-card">
           <div class="table-title">瀹炴椂浣滀笟鐩戞帶</div>
           <el-table :data="showTaskList" border style="width: 100%;">
@@ -125,9 +159,13 @@
 </template>
 
 <script setup>
-import { ref, onMounted, onUnmounted, nextTick } from 'vue';
+import { ref, onMounted, onUnmounted, nextTick, computed } from 'vue';
 import * as echarts from 'echarts';
 import http from "@/api/http.js";
+// 琛ュ厖缂哄け鐨勫浘鏍囧鍏�
+import { Box, Document, Download, Upload } from '@element-plus/icons-vue';
+// 琛ュ厖ElMessage瀵煎叆
+import { ElMessage } from 'element-plus';
 
 // 鍝嶅簲寮忔暟鎹�
 const month = ref('month');
@@ -146,9 +184,86 @@
   taskList: [],
   inboundCount: 0,
   outboundCount: 0,
-  inventoryLocationDist: [], // 搴撳瓨搴撲綅鍒嗗竷鏁版嵁
-  exceptionTypeTrend: []     // 寮傚父绫诲瀷瓒嬪娍鏁版嵁
+  inventoryLocationDist: [], 
+  exceptionTypeTrend: [],    
+  nearExpirationList: []      // 鏀逛负鏁扮粍绫诲瀷锛屽尮閰嶆柊鏁版嵁缁撴瀯
 });
+
+// 涓存湡琛ㄦ牸鏁版嵁锛堣绠楀睘鎬э細閫傞厤鏂扮殑鏁扮粍鏁版嵁缁撴瀯锛�
+const expirationTableData = computed(() => {
+  // 鏂版暟鎹粨鏋勬槸鏁扮粍锛岀洿鎺ュ彇鏁扮粍骞跺鐞嗙┖鍊�
+  const expirationList = bigscreendata.value.nearExpirationList || [];
+
+  // 绗竴姝ワ細鍘婚噸 - 鎸� 鐗╂枡缂栫爜+鎵规鍙�+鎵樼洏缂栧彿+鏈夋晥鏈� 鍞竴鏍囪瘑鍘婚噸
+  const uniqueMap = new Map();
+  expirationList.forEach(item => {
+    // 鎷兼帴鍞竴鏍囪瘑锛堝鐞嗙┖鍊硷紝閬垮厤鍥犵┖鍊煎鑷撮噸澶嶅垽鏂敊璇級
+    const uniqueKey = [
+      item.materielCode || '鏈煡缂栫爜',
+      item.batchNo || '鏈煡鎵规',
+      item.palletCode || '鏈煡鎵樼洏',
+    ].join('|'); // 鐢ㄧ壒娈婂瓧绗﹀垎闅旓紝閬垮厤瀛楁鍊兼嫾鎺ュ悗娣锋穯
+
+    // 鍙繚鐣欑涓�娆″嚭鐜扮殑璁板綍
+    if (!uniqueMap.has(uniqueKey)) {
+      uniqueMap.set(uniqueKey, item);
+    }
+  });
+
+  // 鎻愬彇鍘婚噸鍚庣殑鏁扮粍
+  const uniqueExpirationList = Array.from(uniqueMap.values());
+
+  // 绗簩姝ワ細閬嶅巻鍘婚噸鍚庣殑鏁版嵁锛岃ˉ鍏呬复鏈熺瓑绾у拰榛樿鍊�
+  return uniqueExpirationList.map(item => {
+    // 鎻愬彇褰撳墠鐗╂枡鐨勪复鏈熷ぉ鏁帮紙鏍稿績瀛楁锛�
+    const daysToExpiration = item.daysToExpiration || 0;
+    // 璁$畻涓存湡绛夌骇
+    let expireLevel = '';
+    if (daysToExpiration < 0) {
+      expireLevel = '宸茶繃鏈�';
+    } else if (daysToExpiration <= 7) {
+      expireLevel = '7澶╁唴涓存湡';
+    } else if (daysToExpiration <= 15) {
+      expireLevel = '15澶╁唴涓存湡';
+    } else if (daysToExpiration <= 30) {
+      expireLevel = '30澶╁唴涓存湡';
+    } else {
+      expireLevel = '30澶╀互涓�';
+    }
+
+    return {
+      materielCode: item.materielCode || '鏈煡缂栫爜',
+      materielName: item.materielName || '鏈煡鍚嶇О',
+      batchNo: item.batchNo || '鏈煡鎵规',
+      validDate: item.validDate || '鏈煡鏈夋晥鏈�',
+      daysToExpiration: daysToExpiration,
+      expireLevel: expireLevel,
+      stockQuantity: item.stockQuantity || 0,
+      locationCode: item.locationCode || '鏈煡搴撲綅',
+      palletCode: item.palletCode || '鏈煡鎵樼洏',
+      unit: item.unit || 'PCS'
+    };
+  });
+});
+
+// 绌烘暟鎹彁绀烘枃鏈紙淇鍒ゆ柇閫昏緫锛�
+const emptyText = computed(() => {
+  const expirationList = bigscreendata.value.nearExpirationList || [];
+  // 鏁扮粍闀垮害涓�0鏃舵樉绀虹┖鎻愮ず锛屽惁鍒欎笉鏄剧ず锛堝師閫昏緫鍐欏弽浜嗭級
+  return expirationList.length === 0 ? '鏆傛棤涓存湡鐗╂枡鏁版嵁' : '';
+});
+
+// 鑾峰彇涓存湡绛夌骇鏍峰紡绫�
+const getExpireLevelClass = (level) => {
+  switch(level) {
+    case '宸茶繃鏈�': return 'expire-level expired';
+    case '7澶╁唴涓存湡': return 'expire-level urgent';
+    case '15澶╁唴涓存湡': return 'expire-level warning';
+    case '30澶╁唴涓存湡': return 'expire-level normal';
+    case '30澶╀互涓�': return 'expire-level low';
+    default: return 'expire-level default';
+  }
+};
 
 const taskStatusMap = {
   100: "鏂板缓",
@@ -171,57 +286,54 @@
   990: "浠诲姟寮傚父",
   110: "鎻愬崌鏈烘墽琛屼腑"
 };
+
+// 鑾峰彇浠诲姟鐘舵�佹枃鏈�
 const getTaskStatusText = (statusNum) => {
-  // 澶勭悊绌哄�笺�佹棤鏁堝�硷紝鍏滃簳鏄剧ず鈥滄湭鐭ョ姸鎬佲��
   if (statusNum === undefined || statusNum === null || isNaN(statusNum)) {
     return "鏈煡鐘舵��";
   }
-  // 绮惧噯鍖归厤鏄犲皠鍊硷紝鏃犲尮閰嶅垯杩斿洖鈥滄湭鐭ョ姸鎬佲��
   return taskStatusMap[statusNum] || "鏈煡鐘舵��";
 };
-const showTaskList = ref([]); // 琛ㄦ牸鏄剧ず鐨�5鏉′换鍔★紙杞挱鐢級
-const currentTaskIndex = ref(5); // 涓嬩竴涓鏄剧ず鐨勪换鍔$储寮曪紙鍒濆浠庣6鏉″紑濮嬶紝鍓�5鏉¢粯璁ゆ樉绀猴級
-let taskCarouselTimer = null; // 杞挱瀹氭椂鍣�
+
+// 琛ㄦ牸鏄剧ず鐨勪换鍔″垪琛紙杞挱鐢級
+const showTaskList = ref([]);
+const currentTaskIndex = ref(5);
+let taskCarouselTimer = null;
+
 // 鏁板瓧鏍煎紡鍖栵紙鍗冨垎浣嶅垎闅旓級
 const formatNumber = (num) => {
   if (!num) return '0';
   return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
 };
 
+// 浠诲姟鍒楄〃杞挱閫昏緫
 const startTaskCarousel = () => {
-  // 娓呴櫎鏃у畾鏃跺櫒锛岄槻姝㈤噸澶嶅惎鍔�
   if (taskCarouselTimer) clearInterval(taskCarouselTimer);
 
   const totalTask = bigscreendata.value.taskList.length;
-  // 浠诲姟鏁�<=5鏃讹紝涓嶈疆鎾紙娌℃湁鏇村浠诲姟鍙崲锛�
   if (totalTask <= 5) {
     showTaskList.value = [...bigscreendata.value.taskList];
     return;
   }
 
-  // 鍚姩5绉掑畾鏃跺櫒
   taskCarouselTimer = setInterval(() => {
-    // 1. 鏂板涓�1鏉′换鍔″埌鏄剧ず鍒楄〃鏈熬
     showTaskList.value.push(bigscreendata.value.taskList[currentTaskIndex.value]);
-    // 2. 鍒犻櫎鍒楄〃鏈�鍓嶉潰1鏉℃棫浠诲姟锛堝缁堜繚鎸�5鏉★級
     showTaskList.value.shift();
-    // 3. 鏇存柊涓嬩竴涓换鍔$储寮曪紝瓒呭嚭鎬绘暟鍒欓噸缃紙寰幆杞挱锛�
     currentTaskIndex.value++;
     if (currentTaskIndex.value >= totalTask) {
-      currentTaskIndex.value = 0; // 閲嶇疆涓�0锛屽惊鐜挱鏀�
+      currentTaskIndex.value = 0;
     }
-  }, 5000); // 5绉掗棿闅�
+  }, 5000);
 };
 
+// 鑾峰彇浠诲姟绫诲瀷鏂囨湰
 const getTaskTypeText = (taskTypeNum) => {
-  // 澶勭悊绌哄��/鏃犳晥鍊�
   if (!taskTypeNum || isNaN(taskTypeNum)) return "鏈煡绫诲瀷";
   
-  // 瀵瑰簲鍚庣TaskEnumHelper鐨勫垎缁勮鍒�
   if (taskTypeNum >= 500 && taskTypeNum < 900) return "鍏ュ簱";
   if (taskTypeNum >= 100 && taskTypeNum < 500) return "鍑哄簱";
   if (taskTypeNum >= 900 && taskTypeNum < 1000) return "绉诲簱";
-  return "鍏朵粬浣滀笟"; // 鍏滃簳
+  return "鍏朵粬浣滀笟";
 };
 
 // 鑾峰彇浠诲姟鐘舵�佹牱寮忕被
@@ -230,15 +342,14 @@
     return "status-unknown";
   }
   
-  // 鏍规嵁鐘舵�佽寖鍥磋繑鍥炰笉鍚屾牱寮�
-  if (statusNum >= 900) return "status-completed"; // 瀹屾垚
-  if (statusNum >= 400) return "status-processing"; // 杈撻�佺嚎鎵ц涓�
-  if (statusNum >= 300) return "status-processing"; // AGV鎵ц涓�
-  if (statusNum >= 200) return "status-processing"; // 鍫嗗灈鏈烘墽琛屼腑
-  if (statusNum >= 100) return "status-pending"; // 鏂板缓銆佸凡鍙戦��
-  if (statusNum === 970) return "status-suspended"; // 鎸傝捣
-  if (statusNum === 980) return "status-canceled"; // 鍙栨秷
-  if (statusNum === 990) return "status-error"; // 寮傚父
+  if (statusNum >= 900) return "status-completed";
+  if (statusNum >= 400) return "status-processing";
+  if (statusNum >= 300) return "status-processing";
+  if (statusNum >= 200) return "status-processing";
+  if (statusNum >= 100) return "status-pending";
+  if (statusNum === 970) return "status-suspended";
+  if (statusNum === 980) return "status-canceled";
+  if (statusNum === 990) return "status-error";
   
   return "status-unknown";
 };
@@ -247,34 +358,32 @@
 const getTypeClass = (taskTypeNum) => {
   if (!taskTypeNum || isNaN(taskTypeNum)) return "type-unknown";
   
-  // 瀵瑰簲鍚庣TaskEnumHelper鐨勫垎缁勮鍒�
-  if (taskTypeNum >= 500 && taskTypeNum < 900) return "type-inbound"; // 鍏ュ簱
-  if (taskTypeNum >= 100 && taskTypeNum < 500) return "type-outbound"; // 鍑哄簱
-  if (taskTypeNum >= 900 && taskTypeNum < 1000) return "type-transfer"; // 绉诲簱
+  if (taskTypeNum >= 500 && taskTypeNum < 900) return "type-inbound";
+  if (taskTypeNum >= 100 && taskTypeNum < 500) return "type-outbound";
+  if (taskTypeNum >= 900 && taskTypeNum < 1000) return "type-transfer";
   
-  return "type-other"; // 鍏朵粬浣滀笟
+  return "type-other";
 };
 
 // 鑾峰彇鍚庣澶у睆鏁版嵁
 const fetchBigGreenData = async () => {
   try {
-    debugger
     const res = await http.get('/api/BigScreen/GetBigGreenData');
     console.log('澶у睆鏁版嵁', res);
     
     bigscreendata.value = res.data || res;
-    // 鏁版嵁鏇存柊鍚庡埛鏂板浘琛�
+    // 鏁版嵁鏇存柊鍚庡埛鏂板浘琛ㄥ拰琛ㄦ牸
     nextTick(() => {
       const total = bigscreendata.value.taskList.length;
-      // 鍒濆鍖栨樉绀哄墠5鏉★紙涓嶈冻5鏉″垯鏄剧ず鍏ㄩ儴锛�
       showTaskList.value = total >=5 
         ? [...bigscreendata.value.taskList.slice(0,5)] 
         : [...bigscreendata.value.taskList];
-      startTaskCarousel(); // 鍚姩浠诲姟杞挱
+      startTaskCarousel();
       refreshCharts();
     });
   } catch (error) {
     ElMessage.error('鏁版嵁鑾峰彇澶辫触锛岃妫�鏌ュ悗绔帴鍙f槸鍚︽甯�');
+    console.error('鏁版嵁鑾峰彇澶辫触锛�', error);
   }
 };
 
@@ -292,23 +401,21 @@
 const locationRateRef = ref(null);
 const exceptionTrendRef = ref(null);
 
-// 鍥捐〃瀹炰緥锛堝叏灞�绠$悊锛岀敤浜庨攢姣佸拰resize锛�
+// 鍥捐〃瀹炰緥锛堝叏灞�绠$悊锛�
 let inventoryPieChart = null;
 let stockTrendChart = null;
 let locationRateChart = null;
 let exceptionTrendChart = null;
 
-// 鍒濆鍖栧簱瀛樺簱浣嶅垎甯冮ゼ鍥撅紙鍏宠仈鍚庣鏁版嵁锛�
+// 鍒濆鍖栧簱瀛樺簱浣嶅垎甯冮ゼ鍥�
 const initInventoryPie= () => {
   if (!inventoryPieRef.value) return;
 
-  // 閿�姣佹棫瀹炰緥锛岄槻姝㈠唴瀛樻硠婕�
   if (inventoryPieChart) {
     inventoryPieChart.dispose();
   }
 
   inventoryPieChart = echarts.init(inventoryPieRef.value);
-  // 浼樺厛浣跨敤鍚庣鏁版嵁锛屾棤鏁版嵁鍒欑敤榛樿鍊�
   const locationData = bigscreendata.value.inventoryLocationDist.length 
     ? bigscreendata.value.inventoryLocationDist
     : [
@@ -361,7 +468,7 @@
   return inventoryPieChart;
 };
 
-// 鍒濆鍖栬繎7鏃ュ嚭鍏ュ簱瓒嬪娍鍥撅紙鍏宠仈鍚庣鏁版嵁锛�
+// 鍒濆鍖栬繎7鏃ュ嚭鍏ュ簱瓒嬪娍鍥�
 const initStockTrend = () => {
   if (!stockTrendRef.value) return;
 
@@ -370,15 +477,11 @@
   }
 
   stockTrendChart = echarts.init(stockTrendRef.value);
-  // 浼樺厛浣跨敤鍚庣鏁版嵁
   const trendData = bigscreendata.value.dailyInOutBoundList;
-  console.log('鍑哄叆搴撹秼鍔挎暟鎹�', trendData);
 
-  // 璁$畻鏁版嵁涓殑鏈�澶у�硷紝鐢ㄤ簬璁剧疆Y杞磋寖鍥�
-  const maxInbound = Math.max(...trendData.map(item => item.dailyInboundQuantity || 0));
-  const maxOutbound = Math.max(...trendData.map(item => item.dailyOutboundQuantity || 0));
+  const maxInbound = trendData.length ? Math.max(...trendData.map(item => item.dailyInboundQuantity || 0)) : 0;
+  const maxOutbound = trendData.length ? Math.max(...trendData.map(item => item.dailyOutboundQuantity || 0)) : 0;
   const maxValue = Math.max(maxInbound, maxOutbound);
-  console.log('鏈�澶у�艰绠楃粨鏋�:', { maxInbound, maxOutbound, maxValue });
 
   const option = {
     tooltip: {
@@ -407,7 +510,6 @@
       type: 'value',
       name: '鏁伴噺',
       min: 0,
-      // 鏍规嵁鏁版嵁鍔ㄦ�佽缃渶澶у�硷紝鐣欏嚭涓�浜涚┖闂�
       max: maxValue > 0 ? Math.ceil(maxValue * 1.2) : 10
     },
     series: [
@@ -438,18 +540,15 @@
   return stockTrendChart;
 };
 
-// 鍒濆鍖栧簱浣嶅埄鐢ㄧ巼鐜舰鍥撅紙淇锛氱粺涓�瀹炰緥绠$悊锛屽叧鑱斿悗绔暟鎹級
+// 鍒濆鍖栧簱浣嶅埄鐢ㄧ巼鐜舰鍥�
 const initLocationRate = () => {
   if (!locationRateRef.value) return;
 
-  // 閿�姣佹棫瀹炰緥
   if (locationRateChart) {
     locationRateChart.dispose();
   }
 
   locationRateChart = echarts.init(locationRateRef.value);
-  // 浼樺厛浣跨敤鍚庣鏁版嵁锛屾棤鏁版嵁鍒欑敤榛樿鍊�
-  console.log('搴撲綅鍒╃敤鐜囨暟鎹�', bigscreendata.value.locationUtilizationRate);
   const utilizationRate = bigscreendata.value.locationUtilizationRate || 0;
   const freeRate = 100 - utilizationRate;
 
@@ -507,7 +606,7 @@
   return locationRateChart;
 };
 
-// 鍒濆鍖栧紓甯哥被鍨嬬粺璁¤秼鍔垮浘锛堝叧鑱斿悗绔暟鎹級
+// 鍒濆鍖栧紓甯哥被鍨嬬粺璁¤秼鍔垮浘
 const initExceptionTrend = () => {
   if (!exceptionTrendRef.value) return;
 
@@ -516,7 +615,6 @@
   }
 
   exceptionTrendChart = echarts.init(exceptionTrendRef.value);
-  // 浼樺厛浣跨敤鍚庣鏁版嵁
   const exceptionData = bigscreendata.value.exceptionTypeTrend.length
     ? bigscreendata.value.exceptionTypeTrend
     : {
@@ -602,11 +700,11 @@
   return exceptionTrendChart;
 };
 
-// 鍒锋柊鎵�鏈夊浘琛紙绉婚櫎鏃犳晥闆疯揪鍥鹃�昏緫锛�
+// 鍒锋柊鎵�鏈夊浘琛�
 const refreshCharts = () => {
   const charts = [
     initStockTrend,
-    initLocationRate,
+    initLocationRate
   ];
 
   charts.forEach(initFunc => {
@@ -633,7 +731,7 @@
   });
 };
 
-// 缁勪欢鎸傝浇鏃讹細鍏堣姹傛暟鎹紝鍐嶅垵濮嬪寲鍥捐〃
+// 缁勪欢鎸傝浇鏃�
 onMounted(() => {
   // 鍏堣幏鍙栧悗绔暟鎹�
   fetchBigGreenData();
@@ -647,7 +745,7 @@
   });
 });
 
-// 缁勪欢鍗歌浇鏃讹細閿�姣佸浘琛ㄥ疄渚嬶紝绉婚櫎浜嬩欢鐩戝惉
+// 缁勪欢鍗歌浇鏃�
 onUnmounted(() => {
   const charts = [
     inventoryPieChart,
@@ -661,7 +759,7 @@
       chart.dispose();
     }
   });
-  clearInterval(taskCarouselTimer); // 娓呴櫎杞挱瀹氭椂鍣�
+  clearInterval(taskCarouselTimer);
   window.removeEventListener('resize', handleResize);
 });
 </script>
@@ -692,7 +790,7 @@
   margin-bottom: 20px;
 }
 
-/* 鏍稿績淇敼锛氳ˉ鍏卍iv鐗坈ard鐨勫熀纭�鏍峰紡锛屾ā鎷焑l-card鐨勮瑙夋晥鏋� */
+/* 鏍稿績鏍峰紡锛氬崱鐗囧熀纭�鏍峰紡 */
 .stats-card, .chart-card, .table-card {
   background: #fff;
   border-radius: 8px;
@@ -712,7 +810,6 @@
   overflow: hidden;
   background: linear-gradient(145deg, #ffffff 0%, #f9fafc 100%);
 }
-
 
 .stats-card:hover {
   transform: translateY(-6px) scale(1.02);
@@ -735,7 +832,6 @@
   transition: all 0.3s ease;
 }
 
-
 .card-title {
   font-size: 15px;
   color: #606266;
@@ -745,23 +841,16 @@
 }
 
 .card-value {
-  font-size: 26px;
-  font-weight: 600;
-  margin: 4px 0;
-  background: linear-gradient(to right, #409eff, #36cfc9);
-  -webkit-background-clip: text;
-  -webkit-text-fill-color: transparent;
-  background-clip: text;
-}
-
-
-.card-value {
   font-size: 32px;
   font-weight: 700;
   margin: 8px 0 4px;
   color: #2c3e50;
   text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
   line-height: 1.2;
+  background: linear-gradient(to right, #409eff, #36cfc9);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
 }
 
 .card-change {
@@ -799,6 +888,58 @@
   box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.03);
 }
 
+/* 涓存湡鐗╂枡琛ㄦ牸瀹瑰櫒鏍峰紡 */
+.expiration-table-container {
+  width: 100%;
+  height: 100%;
+  min-height: 300px;
+  flex: 1;
+  overflow-y: auto;
+}
+
+/* 涓存湡绛夌骇鏍囩鏍峰紡 */
+.expire-level {
+  padding: 2px 8px;
+  border-radius: 4px;
+  font-size: 12px;
+  font-weight: 500;
+}
+.expire-level.expired {
+  background-color: #fff2f0;
+  color: #ff4d4f;
+  border: 1px solid #ffccc7;
+}
+.expire-level.urgent {
+  background-color: #fff7e6;
+  color: #fa8c16;
+  border: 1px solid #ffd591;
+}
+.expire-level.warning {
+  background-color: #f6ffed;
+  color: #52c41a;
+  border: 1px solid #b7eb8f;
+}
+.expire-level.normal {
+  background-color: #e6f7ff;
+  color: #1890ff;
+  border: 1px solid #91d5ff;
+}
+.expire-level.low {
+  background-color: #f0f2f5;
+  color: #666666;
+  border: 1px solid #d9d9d9;
+}
+.expire-level.default {
+  background-color: #fafafa;
+  color: #8c8c8c;
+  border: 1px solid #e8e8e8;
+}
+
+/* 宸茶繃鏈熸枃瀛楃孩鑹� */
+.text-red {
+  color: #ff4d4f;
+  font-weight: 500;
+}
 
 .chart-title,
 .table-title {
@@ -814,7 +955,6 @@
   position: relative;
   letter-spacing: 0.5px;
 }
-
 
 .view-btn {
   font-size: 12px;
@@ -1090,10 +1230,7 @@
   animation: pulse 2.8s infinite;
 }
 
-
 .btn-group {
   margin-left: 10px;
 }
-
-/* 绉婚櫎鍘熸湁鐨別l-card__body鏍峰紡绌块�忥紝鍥犱负宸茬粡鏇挎崲涓虹函div */
 </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/BigGreenService/BigGreenService.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/BigGreenService/BigGreenService.cs"
index 2c3797e..f533a7f 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/BigGreenService/BigGreenService.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/BigGreenService/BigGreenService.cs"
@@ -58,7 +58,7 @@
 
             //璁$畻搴撲綅鍒╃敤鐜�
             var freeLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.Free).Count();
-            var inStockLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.InStock || x.LocationStatus == (int)LocationStatusEnum.Pallet).Count();
+            var inStockLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus != (int)LocationStatusEnum.Free).Count();
             int totalLocation = freeLocation + inStockLocation;
             decimal locationUtilizationRate = totalLocation == 0
                 ? 0
@@ -75,7 +75,7 @@
             // 4. 鑾峰彇杩�7鏃ユ瘡鏃ュ嚭鍏ュ簱鏄庣粏锛堟牳蹇冧慨鏀癸細璋冪敤涓婇潰鐨勬柟娉曪級
             var dailyInOutBoundList = Get7DaysDailyInOutBound();
 
-            var nearExpirationList = GetMaterialsNearExpiration();
+            List<StockInfoDetailExtDTO> nearExpirationList = GetMaterialsNearExpiration();
             //鑾峰彇浣滀笟缁熻
             var completeTask = SimpleStatistics();
             //浠诲姟
@@ -239,7 +239,7 @@
 
             public List<SimpleStatisticsDTO> CompleteTask { get; set; }
 
-            public NearExpirationDTO NearExpirationList { get; set; }
+            public List<StockInfoDetailExtDTO> NearExpirationList { get; set; }
         }
 
         /// <summary>
@@ -270,82 +270,70 @@
             public int Count { get; set; }
         }
 
-        public class NearExpirationDTO
+        
+        public class StockInfoDetailExtDTO : Dt_StockInfoDetail
         {
-            public int DaysToExpiration { get; set; }
-
-            public List<Dt_StockInfoDetail> Details { get; set; }
-
             public string LocationCode { get; set; }
-
             public string PalletCode { get; set; }
+            public int DaysToExpiration { get; set; }
         }
 
         ///<summary>
         ///鑾峰彇杩�30澶╄杩囨湡鐨勭墿鏂�
         /// </summary>
-        public NearExpirationDTO GetMaterialsNearExpiration()
+        public List<StockInfoDetailExtDTO> GetMaterialsNearExpiration()
         {
-            // 鍒濆鍖栬繑鍥濪TO
-            var resultDTO = new NearExpirationDTO
-            {
-                Details = new List<Dt_StockInfoDetail>(),
-                LocationCode = string.Empty,
-                PalletCode = string.Empty,
-                DaysToExpiration = 0 // 鍒濆鍖栧ぉ鏁�
-            };
+            List<StockInfoDetailExtDTO> resultDTO = new List<StockInfoDetailExtDTO>();
 
-            DateTime currentTime = DateTime.Now;
-            DateTime thirtyDaysLater = currentTime.AddDays(30);
-
-            // 绛涢��30澶╁唴杩囨湡鐨勫簱瀛樻槑缁�
-            var nearExpirationList = _stockInfoDetailRepository.Db.Queryable<Dt_StockInfoDetail>()
-                .Where(x => (x.ValidDate.Value - x.CreateDate).TotalDays <= 30)
+            var nearExpirationList = _stockInfoDetailRepository.QueryData()
+                .Join(
+                    _stockInfoRepository.QueryData(),
+                    detail => detail.StockId,
+                    stock => stock.Id,
+                    (detail, stock) => new
+                    {
+                        Detail = detail,
+                        LocationCode = stock.LocationCode,
+                        PalletCode = stock.PalletCode
+                    }
+                )
+                .Where(x => x.Detail.ValidDate.HasValue
+                        && (x.Detail.ValidDate.Value - x.Detail.CreateDate).TotalDays <= 30)
                 .ToList();
 
-            // 鏃犵鍚堟潯浠剁殑鏄庣粏锛岀洿鎺ヨ繑鍥�
+           
             if (!nearExpirationList.Any())
             {
                 return resultDTO;
             }
 
             
-            var firstStockId = nearExpirationList.First().StockId;
-           
-            var stock = _stockInfoRepository.Db.Queryable<Dt_StockInfo>()
-                .First(x => x.Id == firstStockId);
-
-            
-            if (stock == null)
+            foreach (var item in nearExpirationList)
             {
-                return resultDTO;
-            }
+                int daysToExpire = item.Detail.ValidDate.HasValue
+                    ? Math.Max(0, (item.Detail.ValidDate.Value - item.Detail.CreateDate).Days)
+                    : 0;
 
-            
-            resultDTO.LocationCode = stock.LocationCode;
-            resultDTO.PalletCode = stock.PalletCode;
-
-           
-            int minDaysToExpiration = int.MaxValue; 
-            foreach (var detail in nearExpirationList)
-            {
-                
-                TimeSpan totalDaysToExpiration = detail.ValidDate.Value - detail.CreateDate;
-                double remainingDays = totalDaysToExpiration.TotalDays;
-                int daysToExpiration = (int)Math.Ceiling(Math.Max(0, remainingDays));
+                var extDetail = new StockInfoDetailExtDTO
+                {
+                    MaterielCode = item.Detail.MaterielCode,
+                    MaterielName = item.Detail.MaterielName,
+                    BatchNo = item.Detail.BatchNo,
+                    SupplyCode = item.Detail.SupplyCode,
+                    StockQuantity = item.Detail.StockQuantity,
+                    CreateDate = item.Detail.CreateDate,
+                    ValidDate = item.Detail.ValidDate,
+                    LocationCode = item.LocationCode,
+                    PalletCode = item.PalletCode,
+                    Barcode = item.Detail.Barcode,
+                    DaysToExpiration = daysToExpire
+                };
 
                
-                if (daysToExpiration < minDaysToExpiration)
-                {
-                    minDaysToExpiration = daysToExpiration;
-                }
-
-                
-                resultDTO.Details.Add(detail);
+                resultDTO.Add(extDetail);
             }
 
-           
-            resultDTO.DaysToExpiration = minDaysToExpiration;
+            resultDTO = resultDTO.OrderBy(d => d.DaysToExpiration).ToList();
 
             return resultDTO;
         }
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_IInboundService/IInboundOrderService.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_IInboundService/IInboundOrderService.cs"
index 2b061e8..70bacb2 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_IInboundService/IInboundOrderService.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_IInboundService/IInboundOrderService.cs"
@@ -28,6 +28,6 @@
 
         WebResponseContent UnPalletGroupBarcode(string orderNo);
 
-        WebResponseContent HandCloseOrder(List<int> orderIds);
+        WebResponseContent HandCloseOrder(List<string> orderIds);
     }
 }
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_InboundService/InboundOrderService.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_InboundService/InboundOrderService.cs"
index babba31..3dd6e37 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_InboundService/InboundOrderService.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_InboundService/InboundOrderService.cs"
@@ -47,9 +47,10 @@
         private readonly IRepository<Dt_StockInfo> _stockRepository;
         private readonly IRepository<Dt_LocationInfo> _locationInfoRepository;
         private readonly IBasicService _basicService;
+        private readonly IRepository<Dt_AllocateOrder> _allocateOrderRepository;
         public IRepository<Dt_InboundOrder> Repository => BaseDal;
 
-        public InboundOrderService(IRepository<Dt_InboundOrder> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_Task> taskRepository, IStockService stockService, IInboundOrderDetailService inboundOrderDetailService, IMaterialUnitService materialUnitService, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IRepository<Dt_StockInfo> stockRepository, IRepository<Dt_LocationType> locationTypeRepository, IMaterielInfoService materielInfoService, IBasicService basicService, IRepository<Dt_LocationInfo> locationInfoRepository) : base(BaseDal)
+        public InboundOrderService(IRepository<Dt_InboundOrder> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_Task> taskRepository, IStockService stockService, IInboundOrderDetailService inboundOrderDetailService, IMaterialUnitService materialUnitService, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IRepository<Dt_StockInfo> stockRepository, IRepository<Dt_LocationType> locationTypeRepository, IMaterielInfoService materielInfoService, IBasicService basicService, IRepository<Dt_LocationInfo> locationInfoRepository, IRepository<Dt_AllocateOrder> allocateOrderRepository) : base(BaseDal)
         {
             _mapper = mapper;
             _unitOfWorkManage = unitOfWorkManage;
@@ -66,6 +67,7 @@
             _materielInfoService = materielInfoService;
             _basicService = basicService;
             _locationInfoRepository = locationInfoRepository;
+            _allocateOrderRepository = allocateOrderRepository;
         }
 
         public async Task<WebResponseContent> ReceiveInboundOrder(List<Dt_InboundOrder> models, int operateType)
@@ -968,14 +970,18 @@
             return content.OK(data: details);
         }
 
-        public WebResponseContent HandCloseOrder(List<int> orderIds)
+        public WebResponseContent HandCloseOrder(List<string> orderNos)
         {
             try
             {
-                foreach (int id in orderIds)
+                foreach (var orderNo in orderNos)
                 {
-                    var inbound = _inboundOrderRepository.QueryFirst(x => x.Id == id);
-                    if(inbound.OrderStatus !=(int)InOrderStatusEnum.鏈紑濮� && inbound.OrderStatus != (int)InOrderStatusEnum.鍏ュ簱涓�)
+                    var inbound = _inboundOrderRepository.QueryFirst(x => x.InboundOrderNo == orderNo);
+                    if(inbound == null)
+                    {
+                        return WebResponseContent.Instance.Error($"璇ュ崟鎹笉瀛樺湪锛屾棤娉曡繘琛屽叧闂�");
+                    }
+                    if (inbound.OrderStatus != (int)InOrderStatusEnum.鏈紑濮� && inbound.OrderStatus != (int)InOrderStatusEnum.鍏ュ簱涓�)
                     {
                         return WebResponseContent.Instance.Error($"璇ュ崟鎹姸鎬佷笉鍙互鍏抽棴");
                     }
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 f1189fa..aeffcc5 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"
@@ -260,7 +260,7 @@
 
 
         [HttpPost, Route("HandCloseOrder"), AllowAnonymous, MethodParamsValidate]
-        public WebResponseContent HandCloseOrder(List<int> orderIds)
+        public WebResponseContent HandCloseOrder(List<string> orderIds)
         {
             return Service.HandCloseOrder(orderIds);
         }
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\346\216\245\345\217\243\346\226\207\346\241\243/~$es\346\216\245\345\217\243\346\226\207\346\241\243.docx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\346\216\245\345\217\243\346\226\207\346\241\243/~$es\346\216\245\345\217\243\346\226\207\346\241\243.docx"
deleted file mode 100644
index fcd42e3..0000000
--- "a/\351\241\271\347\233\256\350\265\204\346\226\231/\346\216\245\345\217\243\346\226\207\346\241\243/~$es\346\216\245\345\217\243\346\226\207\346\241\243.docx"
+++ /dev/null
Binary files differ

--
Gitblit v1.9.3