From 4f40a6aeee4a09a663409a6e4fc60350b5fd48a0 Mon Sep 17 00:00:00 2001
From: xiazhengtongxue <133085197+xiazhengtongxue@users.noreply.github.com>
Date: 星期二, 21 四月 2026 13:12:16 +0800
Subject: [PATCH] feat: 添加AGV任务管理和托盘组功能 feat(task): 新增AGV任务页面和路由配置 feat(stock): 添加托盘组管理页面及进站出站操作 feat(task): 在任务历史页面添加操作类型列 refactor: 优化AGV任务查询条件及过滤逻辑

---
 Code/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfo.jsx  |    2 
 Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/agvTask.jsx |   78 +++
 Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js             |   12 
 Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/agvTask.vue     |  236 ++++++++++
 Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js             |    4 
 Code/WMS/WIDESEA_WMSClient/src/views/stock/groupPalle.vue     |  487 ++++++++++++++++++++++
 Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_agv.vue    |  231 ++++++++++
 Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_hty.vue    |    6 
 Code/WMS/WIDESEA_WMSClient/src/extension/taskinfo/agvTask.jsx |   78 +++
 Code/WMS/WIDESEA_WMSClient/src/extension/stock/groupPalle.jsx |  133 ++++++
 10 files changed, 1,265 insertions(+), 2 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/agvTask.jsx b/Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/agvTask.jsx
new file mode 100644
index 0000000..ddca5c7
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/agvTask.jsx
@@ -0,0 +1,78 @@
+//姝s鏂囦欢鏄敤鏉ヨ嚜瀹氫箟鎵╁睍涓氬姟浠g爜锛屽彲浠ユ墿灞曚竴浜涜嚜瀹氫箟椤甸潰鎴栬�呴噸鏂伴厤缃敓鎴愮殑浠g爜
+
+let extension = {
+  components: {
+    //鏌ヨ鐣岄潰鎵╁睍缁勪欢
+    gridHeader: "",
+    gridBody: "",
+    gridFooter: "",
+    //鏂板缓銆佺紪杈戝脊鍑烘鎵╁睍缁勪欢
+    modelHeader: "",
+    modelBody: "",
+    modelFooter: "",
+  },
+  tableAction: "", //鎸囧畾鏌愬紶琛ㄧ殑鏉冮檺(杩欓噷濉啓琛ㄥ悕,榛樿涓嶇敤濉啓)
+  buttons: { view: [], box: [], detail: [] }, //鎵╁睍鐨勬寜閽�
+  methods: {
+    //涓嬮潰杩欎簺鏂规硶鍙互淇濈暀涔熷彲浠ュ垹闄�
+    onInit() {},
+    onInited() {
+      //妗嗘灦鍒濆鍖栭厤缃悗
+      //濡傛灉瑕侀厤缃槑缁嗚〃,鍦ㄦ鏂规硶鎿嶄綔
+      //this.detailOptions.columns.forEach(column=>{ });
+    },
+searchBefore(param) {
+  //鐣岄潰鏌ヨ鍓�,鍙互缁檖aram.wheres娣诲姞鏌ヨ鍙傛暟
+  //杩斿洖false锛屽垯涓嶄細鎵ц鏌ヨ
+  
+  // 绗竴涓繃婊ゆ潯浠�
+  const roadwayFilter1 = {
+    name: "roadway",
+    value: "ZJ1",
+    displayType: "like",
+  };
+  
+  // 绗簩涓繃婊ゆ潯浠�
+  const roadwayFilter2 = {
+    name: "roadway",
+    value: "FJ1",
+    displayType: "like",
+  };
+
+  if (!param.wheres) {
+    param.wheres = [];
+  }
+  
+  // 灏嗕袱涓繃婊ゆ潯浠舵坊鍔犲埌鏌ヨ鍙傛暟涓�
+  param.wheres.push(roadwayFilter1);
+  param.wheres.push(roadwayFilter2);
+  
+  return true;
+},
+    searchAfter(result) {
+      //鏌ヨ鍚庯紝result杩斿洖鐨勬煡璇㈡暟鎹�,鍙互鍦ㄦ樉绀哄埌琛ㄦ牸鍓嶅鐞嗚〃鏍肩殑鍊�
+      return true;
+    },
+    addBefore(formData) {
+      //鏂板缓淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛紝鍙互缁欑粰琛ㄥ崟璁剧疆鍊硷紝鑷繁杈撳嚭鐪媐ormData鐨勫��
+      return true;
+    },
+    updateBefore(formData) {
+      //缂栬緫淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛ㄣ�佸垹闄よ鐨処d
+      return true;
+    },
+    rowClick({ row, column, event }) {
+      //鏌ヨ鐣岄潰鐐瑰嚮琛屼簨浠�
+      this.$refs.table.$refs.table.toggleRowSelection(row); //鍗曞嚮琛屾椂閫変腑褰撳墠琛�;
+    },
+    modelOpenAfter(row) {
+      //鐐瑰嚮缂栬緫銆佹柊寤烘寜閽脊鍑烘鍚庯紝鍙互鍦ㄦ澶勫啓閫昏緫锛屽锛屼粠鍚庡彴鑾峰彇鏁版嵁
+      //(1)鍒ゆ柇鏄紪杈戣繕鏄柊寤烘搷浣滐細 this.currentAction=='Add';
+      //(2)缁欏脊鍑烘璁剧疆榛樿鍊�
+      //(3)this.editFormFields.瀛楁='xxx';
+      //濡傛灉闇�瑕佺粰涓嬫媺妗嗚缃粯璁ゅ�硷紝璇烽亶鍘唗his.editFormOptions鎵惧埌瀛楁閰嶇疆瀵瑰簲data灞炴�х殑key鍊�
+      //鐪嬩笉鎳傚氨鎶婅緭鍑虹湅锛歝onsole.log(this.editFormOptions)
+    },
+  },
+};
+export default extension;
diff --git a/Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js b/Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js
index 9915346..b8b1b7a 100644
--- a/Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js
+++ b/Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js
@@ -77,6 +77,10 @@
     path: '/task',
     name: 'task',
     component: () => import('@/views/taskinfo/task.vue')
+  },{
+    path: '/agvTask',
+    name: 'agvTask',
+    component: () => import('@/views/taskinfo/agvTask.vue')
   },
   {
     path: '/taskHty',
diff --git a/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/agvTask.vue b/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/agvTask.vue
new file mode 100644
index 0000000..0e23fd9
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/agvTask.vue
@@ -0,0 +1,236 @@
+
+<template>
+  <view-grid
+    ref="grid"
+    :columns="columns"
+    :detail="detail"
+    :editFormFields="editFormFields"
+    :editFormOptions="editFormOptions"
+    :searchFormFields="searchFormFields"
+    :searchFormOptions="searchFormOptions"
+    :table="table"
+    :extend="extend"
+  >
+  </view-grid>
+</template>
+  <script>
+import extend from "@/extension/taskinfo/agvTask.jsx";
+import { ref, defineComponent } from "vue";
+export default defineComponent({
+  setup() {
+    const table = ref({
+      key: "taskId",
+      footer: "Foots",
+      cnName: "浠诲姟淇℃伅",
+      name: "task",
+      url: "/Task/",
+      sortName: "CreateDate",
+    });
+    const editFormFields = ref({});
+    const editFormOptions = ref([]);
+    const searchFormFields = ref({
+      taskNum: "",
+      palletCode: "",
+      roadway: "",
+      sourceAddress: "",
+      targetAddress: "",
+      currentAddress: "",
+      nextAddress: "",
+      creater: "",
+      createDate: "",
+    });
+    const searchFormOptions = ref([
+      [
+        { title: "浠诲姟鍙�", field: "taskNum", type: "int" },
+        { title: "鎵樼洏缂栧彿", field: "palletCode", type: "like" },
+        {
+          title: "浠诲姟绫诲瀷",
+          field: "taskType",
+          type: "selectList",
+          dataKey: "taskType",
+          data: [],
+        },
+        {
+          title: "浠诲姟鐘舵��",
+          field: "taskStatus",
+          type: "selectList",
+          dataKey: "taskState",
+          data: [],
+        },
+      ],
+      [
+        { title: "璧峰鍦板潃", field: "sourceAddress", type: "like" },
+        { title: "鐩爣鍦板潃", field: "targetAddress", type: "like" },
+        { title: "褰撳墠浣嶇疆", field: "currentAddress", type: "like" },
+        { title: "涓嬩竴浣嶇疆", field: "nextAddress", type: "like" },
+      ],
+      [
+        { title: "宸烽亾鍙�", field: "roadway", type: "like" },
+        { title: "鍒涘缓浜�", field: "creater", type: "like" },
+        { title: "鍒涘缓鏃堕棿", field: "createDate", type: "datetime" },
+      ],
+    ]);
+    const columns = ref([
+      {
+        field: "taskId",
+        title: "TaskId",
+        type: "int",
+        width: 90,
+        hidden: true,
+        readonly: true,
+        require: true,
+        align: "left",
+      },
+      {
+        field: "taskNum",
+        title: "浠诲姟鍙�",
+        type: "int",
+        width: 90,
+        align: "left",
+      },
+      {
+        field: "palletCode",
+        title: "鎵樼洏缂栧彿",
+        type: "string",
+        width: 200,
+        align: "left",
+      },
+      {
+        field: "roadway",
+        title: "宸烽亾鍙�",
+        type: "string",
+        width: 90,
+        align: "left",
+      },
+      {
+        field: "taskType",
+        title: "浠诲姟绫诲瀷",
+        type: "int",
+        width: 90,
+        align: "left",
+        bind: { key: "taskType", data: [] },
+      },
+      {
+        field: "taskStatus",
+        title: "浠诲姟鐘舵��",
+        type: "int",
+        width: 150,
+        align: "left",
+        bind: { key: "taskState", data: [] },
+      },
+      {
+        field: "sourceAddress",
+        title: "璧峰鍦板潃",
+        type: "int",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "targetAddress",
+        title: "鐩爣鍦板潃",
+        type: "string",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "currentAddress",
+        title: "褰撳墠浣嶇疆",
+        type: "string",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "nextAddress",
+        title: "涓嬩竴浣嶇疆",
+        type: "string",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "exceptionMessage",
+        title: "寮傚父淇℃伅",
+        type: "string",
+        width: 90,
+        align: "left",
+        hidden: true,
+      },
+      {
+        field: "grade",
+        title: "浼樺厛绾�",
+        type: "int",
+        width: 80,
+        align: "left",
+      },
+      {
+        field: "dispatchertime",
+        title: "浠诲姟涓嬪彂鏃堕棿",
+        type: "datetime",
+        width: 150,
+        align: "left",
+      },
+      {
+        field: "wMSId",
+        title: "WMS浠诲姟涓婚敭",
+        type: "int",
+        width: 120,
+        align: "left",
+        hidden: true,
+      },
+      {
+        field: "creater",
+        title: "鍒涘缓浜�",
+        type: "string",
+        width: 90,
+        align: "left",
+      },
+      {
+        field: "createDate",
+        title: "鍒涘缓鏃堕棿",
+        type: "datetime",
+        width: 150,
+        align: "left",
+      },
+      {
+        field: "modifier",
+        title: "淇敼浜�",
+        type: "string",
+        width: 100,
+        align: "left",
+      },
+      {
+        field: "modifyDate",
+        title: "淇敼鏃堕棿",
+        type: "datetime",
+        width: 160,
+        align: "left",
+      },
+      {
+        field: "remark",
+        title: "澶囨敞",
+        type: "string",
+        width: 100,
+        align: "left",
+        hidden: true,
+      },
+    ]);
+    const detail = ref({
+      cnName: "",
+      table: "",
+      columns: [],
+      sortName: "",
+      key: "",
+    });
+    return {
+      table,
+      extend,
+      editFormFields,
+      editFormOptions,
+      searchFormFields,
+      searchFormOptions,
+      columns,
+      detail,
+    };
+  },
+});
+</script>
+  
\ No newline at end of file
diff --git a/Code/WMS/WIDESEA_WMSClient/src/extension/stock/groupPalle.jsx b/Code/WMS/WIDESEA_WMSClient/src/extension/stock/groupPalle.jsx
new file mode 100644
index 0000000..1f74685
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/extension/stock/groupPalle.jsx
@@ -0,0 +1,133 @@
+//姝s鏂囦欢鏄敤鏉ヨ嚜瀹氫箟鎵╁睍涓氬姟浠g爜锛屽彲浠ユ墿灞曚竴浜涜嚜瀹氫箟椤甸潰鎴栬�呴噸鏂伴厤缃敓鎴愮殑浠g爜
+
+let extension = {
+  components: {
+    //鏌ヨ鐣岄潰鎵╁睍缁勪欢
+    gridHeader: '',
+    gridBody: '',
+    gridFooter: '',
+    //鏂板缓銆佺紪杈戝脊鍑烘鎵╁睍缁勪欢
+    modelHeader: '',
+    modelBody: '',
+    modelFooter: ''
+  },
+  tableAction: '',
+  buttons: { view: [], box: [], detail: [] },
+  methods: {
+    onInit() {
+      // 娣诲姞MES鎿嶄綔鍒�
+      this.columns.push({
+        title: '鎿嶄綔',
+        field: '鎿嶄綔',
+        align: 'center',
+        width: 200,
+        fixed: 'right',
+        render: (h, { row, column, index }) => {
+          return (
+            <div>
+              <el-button
+                type="primary"
+                size="small"
+                onClick={($e) => { this.handleInbound(row); }}
+              >杩涚珯</el-button>
+              <el-button
+                type="success"
+                size="small"
+                style="margin-left: 8px"
+                onClick={($e) => { this.handleOutbound(row); }}
+              >鍑虹珯</el-button>
+            </div>
+          );
+        }
+      });
+    },
+
+    // 鎵樼洏杩涚珯鎿嶄綔
+    async handleInbound(row) {
+      try {
+        await this.$confirm(`纭鎵ц鎵樼洏杩涚珯鎿嶄綔锛焅n鎵樼洏缂栧彿锛�${row.palletCode}`, "杩涚珯纭", {
+          confirmButtonText: "纭",
+          cancelButtonText: "鍙栨秷",
+          type: "warning"
+        });
+
+        const result = await this.http.post("/api/StockInfo/inboundInContainer", {
+          palletCode: row.palletCode,
+          stockId: row.id
+        }, "姝e湪璋冪敤MES鎺ュ彛...");
+
+        if (result.status) {
+          this.$Message.success(result.message || "鎵樼洏杩涚珯鎴愬姛");
+          this.$refs.table.load();
+        } else {
+          this.$error(result.message || "鎵樼洏杩涚珯澶辫触");
+        }
+      } catch (error) {
+        if (error !== "cancel") {
+          this.$error(error.message || "缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+        }
+      }
+    },
+
+    // 鎵樼洏鍑虹珯鎿嶄綔
+    async handleOutbound(row) {
+      try {
+        await this.$confirm(`纭鎵ц鎵樼洏鍑虹珯鎿嶄綔锛焅n鎵樼洏缂栧彿锛�${row.palletCode}`, "鍑虹珯纭", {
+          confirmButtonText: "纭",
+          cancelButtonText: "鍙栨秷",
+          type: "warning"
+        });
+
+        const result = await this.http.post("/api/StockInfo/outboundInContainer", {
+          palletCode: row.palletCode,
+          stockId: row.id
+        }, "姝e湪璋冪敤MES鎺ュ彛...");
+
+        if (result.status) {
+          this.$Message.success(result.message || "鎵樼洏鍑虹珯鎴愬姛");
+          this.$refs.table.load();
+        } else {
+          this.$error(result.message || "鎵樼洏鍑虹珯澶辫触");
+        }
+      } catch (error) {
+        if (error !== "cancel") {
+          this.$error(error.message || "缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+        }
+      }
+    },
+
+    onInited() {
+      // 妗嗘灦鍒濆鍖栭厤缃悗
+    },
+    searchBefore(param) {
+      const locationCodeFilter = {
+        name: "stockStatus",
+        value: "1",
+        displayType: "int"
+      };
+      if (!param.wheres) {
+        param.wheres = [];
+      }
+      // 灏嗚繃婊ゆ潯浠舵坊鍔犲埌鏌ヨ鍙傛暟涓�
+      param.wheres.push(locationCodeFilter);
+      return true;
+    },
+    searchAfter(result) {
+      return true;
+    },
+    addBefore(formData) {
+      return true;
+    },
+    updateBefore(formData) {
+      return true;
+    },
+    rowClick({ row, column, event }) {
+      this.$refs.table.$refs.table.toggleRowSelection(row);
+    },
+    modelOpenAfter(row) {
+      // 鐐瑰嚮缂栬緫銆佹柊寤烘寜閽脊鍑烘鍚�
+    }
+  }
+};
+
+export default extension;
diff --git a/Code/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfo.jsx b/Code/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfo.jsx
index 809dd5f..5e181b8 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfo.jsx
+++ b/Code/WMS/WIDESEA_WMSClient/src/extension/stock/stockInfo.jsx
@@ -103,7 +103,7 @@
       return true;
     },
     searchAfter(result) {
-      return true;
+      return result;
     },
     addBefore(formData) {
       return true;
diff --git a/Code/WMS/WIDESEA_WMSClient/src/extension/taskinfo/agvTask.jsx b/Code/WMS/WIDESEA_WMSClient/src/extension/taskinfo/agvTask.jsx
new file mode 100644
index 0000000..ddca5c7
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/extension/taskinfo/agvTask.jsx
@@ -0,0 +1,78 @@
+//姝s鏂囦欢鏄敤鏉ヨ嚜瀹氫箟鎵╁睍涓氬姟浠g爜锛屽彲浠ユ墿灞曚竴浜涜嚜瀹氫箟椤甸潰鎴栬�呴噸鏂伴厤缃敓鎴愮殑浠g爜
+
+let extension = {
+  components: {
+    //鏌ヨ鐣岄潰鎵╁睍缁勪欢
+    gridHeader: "",
+    gridBody: "",
+    gridFooter: "",
+    //鏂板缓銆佺紪杈戝脊鍑烘鎵╁睍缁勪欢
+    modelHeader: "",
+    modelBody: "",
+    modelFooter: "",
+  },
+  tableAction: "", //鎸囧畾鏌愬紶琛ㄧ殑鏉冮檺(杩欓噷濉啓琛ㄥ悕,榛樿涓嶇敤濉啓)
+  buttons: { view: [], box: [], detail: [] }, //鎵╁睍鐨勬寜閽�
+  methods: {
+    //涓嬮潰杩欎簺鏂规硶鍙互淇濈暀涔熷彲浠ュ垹闄�
+    onInit() {},
+    onInited() {
+      //妗嗘灦鍒濆鍖栭厤缃悗
+      //濡傛灉瑕侀厤缃槑缁嗚〃,鍦ㄦ鏂规硶鎿嶄綔
+      //this.detailOptions.columns.forEach(column=>{ });
+    },
+searchBefore(param) {
+  //鐣岄潰鏌ヨ鍓�,鍙互缁檖aram.wheres娣诲姞鏌ヨ鍙傛暟
+  //杩斿洖false锛屽垯涓嶄細鎵ц鏌ヨ
+  
+  // 绗竴涓繃婊ゆ潯浠�
+  const roadwayFilter1 = {
+    name: "roadway",
+    value: "ZJ1",
+    displayType: "like",
+  };
+  
+  // 绗簩涓繃婊ゆ潯浠�
+  const roadwayFilter2 = {
+    name: "roadway",
+    value: "FJ1",
+    displayType: "like",
+  };
+
+  if (!param.wheres) {
+    param.wheres = [];
+  }
+  
+  // 灏嗕袱涓繃婊ゆ潯浠舵坊鍔犲埌鏌ヨ鍙傛暟涓�
+  param.wheres.push(roadwayFilter1);
+  param.wheres.push(roadwayFilter2);
+  
+  return true;
+},
+    searchAfter(result) {
+      //鏌ヨ鍚庯紝result杩斿洖鐨勬煡璇㈡暟鎹�,鍙互鍦ㄦ樉绀哄埌琛ㄦ牸鍓嶅鐞嗚〃鏍肩殑鍊�
+      return true;
+    },
+    addBefore(formData) {
+      //鏂板缓淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛紝鍙互缁欑粰琛ㄥ崟璁剧疆鍊硷紝鑷繁杈撳嚭鐪媐ormData鐨勫��
+      return true;
+    },
+    updateBefore(formData) {
+      //缂栬緫淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛ㄣ�佸垹闄よ鐨処d
+      return true;
+    },
+    rowClick({ row, column, event }) {
+      //鏌ヨ鐣岄潰鐐瑰嚮琛屼簨浠�
+      this.$refs.table.$refs.table.toggleRowSelection(row); //鍗曞嚮琛屾椂閫変腑褰撳墠琛�;
+    },
+    modelOpenAfter(row) {
+      //鐐瑰嚮缂栬緫銆佹柊寤烘寜閽脊鍑烘鍚庯紝鍙互鍦ㄦ澶勫啓閫昏緫锛屽锛屼粠鍚庡彴鑾峰彇鏁版嵁
+      //(1)鍒ゆ柇鏄紪杈戣繕鏄柊寤烘搷浣滐細 this.currentAction=='Add';
+      //(2)缁欏脊鍑烘璁剧疆榛樿鍊�
+      //(3)this.editFormFields.瀛楁='xxx';
+      //濡傛灉闇�瑕佺粰涓嬫媺妗嗚缃粯璁ゅ�硷紝璇烽亶鍘唗his.editFormOptions鎵惧埌瀛楁閰嶇疆瀵瑰簲data灞炴�х殑key鍊�
+      //鐪嬩笉鎳傚氨鎶婅緭鍑虹湅锛歝onsole.log(this.editFormOptions)
+    },
+  },
+};
+export default extension;
diff --git a/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js b/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
index 92b91b8..257c9b1 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
+++ b/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
@@ -95,7 +95,17 @@
     path: '/task_hty',
     name: 'task_hty',
     component: () => import('@/views/taskinfo/task_hty.vue')
-  }, {
+  },{
+    path: '/task_agv',
+    name: 'task_agv',
+    component: () => import('@/views/taskinfo/task_agv.vue')
+  },
+  {
+    path: '/groupPalle',
+    name: 'groupPalle',
+    component: () => import('@/views/stock/groupPalle.vue')
+  },
+  {
     path: '/stockView',
     name: 'stockView',
     component: () => import('@/views/stock/stockView.vue')
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/stock/groupPalle.vue b/Code/WMS/WIDESEA_WMSClient/src/views/stock/groupPalle.vue
new file mode 100644
index 0000000..0c45982
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/stock/groupPalle.vue
@@ -0,0 +1,487 @@
+<template>
+  <view-grid
+    ref="grid"
+    :columns="columns"
+    :detail="detail"
+    :editFormFields="editFormFields"
+    :editFormOptions="editFormOptions"
+    :searchFormFields="searchFormFields"
+    :searchFormOptions="searchFormOptions"
+    :table="table"
+    :tableExpand="tableExpand"
+    :extend="extend"
+  >
+  </view-grid>
+</template>
+
+<script>
+import extend from "@/extension/stock/groupPalle.jsx";
+import {
+  defineComponent,
+  getCurrentInstance,
+  h,
+  reactive,
+  ref,
+  resolveComponent,
+} from "vue";
+
+const TEXT = {
+  pageName: "搴撳瓨淇℃伅",
+  palletCode: "鎵樼洏缂栧彿",
+  stockStatus: "搴撳瓨鐘舵��",
+  locationCode: "璐т綅缂栧彿",
+  warehouse: "浠撳簱",
+  creator: "鍒涘缓浜�",
+  createDate: "鍒涘缓鏃堕棿",
+  modifier: "淇敼浜�",
+  modifyDate: "淇敼鏃堕棿",
+  detailName: "搴撳瓨鏄庣粏",
+  materielName: "鐗╂枡鍚嶇О",
+  serialNumber: "鐢佃姱鐮�",
+  stockQuantity: "搴撳瓨鏁伴噺",
+  status: "鐘舵��",
+  inboundOrderRowNo: "閫氶亾鍙�",
+  detailLoading: "搴撳瓨鏄庣粏鍔犺浇涓�...",
+  detailLoadFailed: "搴撳瓨鏄庣粏鍔犺浇澶辫触",
+  detailEmpty: "褰撳墠搴撳瓨澶存殏鏃犳槑缁嗘暟鎹�",
+  expandPrefix: "鎵樼洏锛�",
+  expandMiddle: " / ",
+  expandLocation: "璐т綅锛�",
+};
+
+export default defineComponent({
+  setup() {
+    const { proxy } = getCurrentInstance();
+    const ElTable = resolveComponent("el-table");
+    const ElTableColumn = resolveComponent("el-table-column");
+
+    const table = ref({
+      key: "id",
+      footer: "Foots",
+      cnName: TEXT.pageName,
+      name: "stockInfo",
+      url: "/StockInfo/",
+      sortName: "id",
+    });
+
+    const editFormFields = ref({
+      palletCode: "",
+      locationCode: "",
+    });
+
+    const editFormOptions = ref([
+      [
+        { field: "palletCode", title: TEXT.palletCode, type: "string" },
+        { field: "locationCode", title: TEXT.locationCode, type: "string" },
+      ],
+    ]);
+
+    const searchFormFields = ref({
+      palletCode: "",
+      locationCode: "",
+    });
+
+    const searchFormOptions = ref([
+      [
+        { title: TEXT.palletCode, field: "palletCode", type: "like" },
+        { title: TEXT.locationCode, field: "locationCode", type: "like" },
+      ],
+    ]);
+
+    const columns = ref([
+      {
+        field: "id",
+        title: "Id",
+        type: "int",
+        width: 90,
+        hidden: true,
+        readonly: true,
+        require: true,
+        align: "left",
+      },
+      {
+        field: "palletCode",
+        title: TEXT.palletCode,
+        type: "string",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "stockStatus",
+        title: TEXT.stockStatus,
+        type: "int",
+        width: 120,
+        align: "left",
+        bind: { key: "stockStatusEmun", data: [] },
+      },
+    //   {
+    //     field: "locationCode",
+    //     title: TEXT.locationCode,
+    //     type: "string",
+    //     width: 150,
+    //     align: "left",
+    //   },
+      {
+        field: "warehouseId",
+        title: TEXT.warehouse,
+        type: "select",
+        width: 100,
+        align: "left",
+        bind: { key: "warehouseEnum", data: [] },
+      },
+      {
+        field: "creater",
+        title: TEXT.creator,
+        type: "string",
+        width: 90,
+        align: "left",
+      },
+      {
+        field: "createDate",
+        title: TEXT.createDate,
+        type: "datetime",
+        width: 160,
+        align: "left",
+      },
+      {
+        field: "modifier",
+        title: TEXT.modifier,
+        type: "string",
+        width: 100,
+        align: "left",
+        hidden: true,
+      },
+      {
+        field: "modifyDate",
+        title: TEXT.modifyDate,
+        type: "datetime",
+        width: 160,
+        align: "left",
+        hidden: true,
+      },
+    ]);
+
+    const detail = ref({
+      cnName: "#detailCnName",
+      table: "",
+      columns: [],
+      sortName: "",
+    });
+
+    const detailState = reactive({
+      rowsMap: {},
+      loadingMap: {},
+      errorMap: {},
+    });
+
+    const stockStatusOptions = ref([]);
+
+    const detailColumns = [
+      { field: "materielName", title: TEXT.materielName, minWidth: 160 },
+      { field: "serialNumber", title: TEXT.serialNumber, minWidth: 160 },
+      { field: "stockQuantity", title: TEXT.stockQuantity, minWidth: 120 },
+      { field: "status", title: TEXT.status, minWidth: 120 },
+      { field: "inboundOrderRowNo", title: TEXT.inboundOrderRowNo, minWidth: 120 },
+    ];
+
+    const normalizeValue = (value) => {
+      return value === null || value === undefined || value === "" ? "--" : value;
+    };
+
+    const formatStatusText = (value) => {
+      const matched = stockStatusOptions.value.find((item) => `${item.key}` === `${value}`);
+      return matched ? matched.value || matched.label : normalizeValue(value);
+    };
+
+    const getDetailRows = (stockId) => {
+      return detailState.rowsMap[stockId] || [];
+    };
+
+    const loadDetailRows = async (row) => {
+      if (!row || !row.id || detailState.loadingMap[row.id]) {
+        return;
+      }
+      if (detailState.rowsMap[row.id]) {
+        return;
+      }
+
+      detailState.loadingMap[row.id] = true;
+      detailState.errorMap[row.id] = "";
+      try {
+        const result = await proxy.http.post("/api/StockInfoDetail/getPageData", {
+          page: 1,
+          rows: 200,
+          sort: "id",
+          order: "asc",
+          wheres: JSON.stringify([
+            {
+              name: "stockId",
+              value: String(row.id),
+              displayType: "int",
+            },
+          ]),
+        });
+        detailState.rowsMap[row.id] = (result && result.rows) || [];
+      } catch (error) {
+        detailState.rowsMap[row.id] = null;
+        detailState.errorMap[row.id] = error?.message || TEXT.detailLoadFailed;
+      } finally {
+        detailState.loadingMap[row.id] = false;
+      }
+    };
+
+    const loadStockStatusOptions = async () => {
+      try {
+        const result = await proxy.http.post("/api/Sys_Dictionary/GetVueDictionary", ["stockStatusEmun"]);
+        const matched = (result || []).find((item) => item.dicNo === "stockStatusEmun");
+        stockStatusOptions.value = matched ? matched.data || [] : [];
+      } catch (error) {
+        stockStatusOptions.value = [];
+      }
+    };
+
+    loadStockStatusOptions();
+
+    const renderStatus = (row) => {
+      if (detailState.loadingMap[row.id]) {
+        return h("div", { class: "stock-detail-status" }, TEXT.detailLoading);
+      }
+      if (detailState.errorMap[row.id]) {
+        return h(
+          "div",
+          { class: "stock-detail-status stock-detail-status--error" },
+          detailState.errorMap[row.id]
+        );
+      }
+      return null;
+    };
+
+    const renderDetailTable = (row) => {
+      const statusNode = renderStatus(row);
+      if (statusNode) {
+        return statusNode;
+      }
+
+      const rows = getDetailRows(row.id);
+      if (!rows.length) {
+        return h("div", { class: "stock-detail-status" }, TEXT.detailEmpty);
+      }
+
+      return h("div", { class: "stock-detail-table-wrapper" }, [
+        h("div", { class: "stock-detail-toolbar" }, [
+          h("div", { class: "stock-detail-toolbar__left" }, TEXT.detailName),
+          h("div", { class: "stock-detail-toolbar__right" }, [
+            h("span", { class: "stock-detail-count" }, `${rows.length} 鏉),
+          ]),
+        ]),
+        h(
+          ElTable,
+          {
+            data: rows,
+            border: true,
+            stripe: true,
+            size: "small",
+            class: "stock-detail-el-table",
+            maxHeight: 420,
+            emptyText: TEXT.detailEmpty,
+          },
+          () =>
+            detailColumns.map((column) =>
+              h(ElTableColumn, {
+                key: column.field,
+                prop: column.field,
+                label: column.title,
+                minWidth: column.minWidth,
+                showOverflowTooltip: true,
+                formatter: (detailRow) =>
+                  column.field === "status"
+                    ? formatStatusText(detailRow[column.field])
+                    : normalizeValue(detailRow[column.field]),
+              })
+            )
+        ),
+      ]);
+    };
+
+    const tableExpand = ref({
+      width: 55,
+      onChange(row, expandedRows) {
+        const isExpanded = expandedRows.some((item) => item.id === row.id);
+        if (isExpanded) {
+          loadDetailRows(row);
+        }
+      },
+      render(render, { row }) {
+        return render("div", { class: "stock-detail-panel" }, [
+          render("div", { class: "stock-detail-header" }, [
+            render("div", { class: "stock-detail-header__main" }, [
+              render("div", { class: "stock-detail-title" }, TEXT.detailName),
+              render(
+                "div",
+                { class: "stock-detail-subtitle" },
+                `${TEXT.expandPrefix}${normalizeValue(row.palletCode)}${TEXT.expandMiddle}${TEXT.expandLocation}${normalizeValue(row.locationCode)}`
+              ),
+            ]),
+            // render("div", { class: "stock-detail-tags" }, [
+            //   render("span", { class: "stock-detail-tag" }, normalizeValue(row.palletCode)),
+            //   render(
+            //     "span",
+            //     { class: "stock-detail-tag stock-detail-tag--muted" },
+            //     normalizeValue(row.locationCode)
+            //   ),
+            // ]),
+          ]),
+          renderDetailTable(row),
+        ]);
+      },
+    });
+
+    return {
+      table,
+      extend,
+      editFormFields,
+      editFormOptions,
+      searchFormFields,
+      searchFormOptions,
+      columns,
+      detail,
+      tableExpand,
+    };
+  },
+});
+</script>
+
+<style scoped>
+.stock-detail-panel {
+  margin: 4px 8px 12px;
+  padding: 14px 16px 16px;
+  background: linear-gradient(180deg, #ffffff 0%, #fafbfc 100%);
+  border: 1px solid #e8edf3;
+  border-radius: 10px;
+  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
+}
+
+.stock-detail-header {
+  display: flex;
+  align-items: flex-start;
+  justify-content: space-between;
+  gap: 12px;
+  margin-bottom: 12px;
+  padding-bottom: 12px;
+  border-bottom: 1px solid #edf1f5;
+}
+
+.stock-detail-header__main {
+  min-width: 0;
+}
+
+.stock-detail-title {
+  margin-bottom: 4px;
+  font-size: 15px;
+  font-weight: 700;
+  color: #303133;
+}
+
+.stock-detail-subtitle {
+  font-size: 13px;
+  color: #606266;
+  line-height: 1.6;
+}
+
+.stock-detail-tags {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: flex-end;
+  gap: 8px;
+}
+
+.stock-detail-tag {
+  display: inline-flex;
+  align-items: center;
+  height: 28px;
+  padding: 0 10px;
+  color: #1f5eff;
+  background: #edf4ff;
+  border: 1px solid #d8e6ff;
+  border-radius: 999px;
+  font-size: 12px;
+  font-weight: 600;
+}
+
+.stock-detail-tag--muted {
+  color: #4e5969;
+  background: #f4f6f8;
+  border-color: #e5e9ef;
+}
+
+.stock-detail-status {
+  padding: 14px 12px;
+  color: #606266;
+  background: #f8fafc;
+  border: 1px dashed #d9e2ec;
+  border-radius: 8px;
+}
+
+.stock-detail-status--error {
+  color: #f56c6c;
+  background: #fef0f0;
+  border-color: #fde2e2;
+}
+
+.stock-detail-table-wrapper {
+  overflow-x: auto;
+  border: 1px solid #ebeef5;
+  border-radius: 8px;
+  background: #fff;
+}
+
+.stock-detail-toolbar {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 12px;
+  padding: 12px 14px;
+  background: #f8fafc;
+  border-bottom: 1px solid #edf1f5;
+}
+
+.stock-detail-toolbar__left {
+  font-size: 13px;
+  font-weight: 600;
+  color: #303133;
+}
+
+.stock-detail-count {
+  display: inline-flex;
+  align-items: center;
+  height: 24px;
+  padding: 0 10px;
+  color: #606266;
+  background: #fff;
+  border: 1px solid #e5e9ef;
+  border-radius: 999px;
+  font-size: 12px;
+}
+
+:deep(.stock-detail-el-table) {
+  border-top: none;
+}
+
+:deep(.stock-detail-el-table .el-table__inner-wrapper::before) {
+  display: none;
+}
+
+:deep(.stock-detail-el-table th.el-table__cell) {
+  background: #f5f7fa;
+  color: #303133;
+  font-weight: 600;
+}
+
+:deep(.stock-detail-el-table td.el-table__cell) {
+  color: #606266;
+}
+
+:deep(.stock-detail-el-table .el-table__body tr:hover > td.el-table__cell) {
+  background: #f0f7ff;
+}
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_agv.vue b/Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_agv.vue
new file mode 100644
index 0000000..8beaf41
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_agv.vue
@@ -0,0 +1,231 @@
+
+<template>
+  <view-grid
+    ref="grid"
+    :columns="columns"
+    :detail="detail"
+    :editFormFields="editFormFields"
+    :editFormOptions="editFormOptions"
+    :searchFormFields="searchFormFields"
+    :searchFormOptions="searchFormOptions"
+    :table="table"
+    :extend="extend"
+  >
+  </view-grid>
+</template>
+    <script>
+import extend from "@/extension/taskinfo/agvTask.jsx";
+import { ref, defineComponent } from "vue";
+export default defineComponent({
+  setup() {
+    const table = ref({
+      key: "taskId",
+      footer: "Foots",
+      cnName: "浠诲姟淇℃伅",
+      name: "task",
+      url: "/Task/",
+      sortName: "CreateDate",
+    });
+    const editFormFields = ref({});
+    const editFormOptions = ref([]);
+    const searchFormFields = ref({
+      taskNum: "",
+      palletCode: "",
+      roadway: "",
+      taskStatus: "",
+      taskType: "",
+      sourceAddress: "",
+      targetAddress: "",
+      currentAddress: "",
+      nextAddress: "",
+      creater: "",
+      createDate: "",
+    });
+    const searchFormOptions = ref([
+      [
+        { title: "浠诲姟鍙�", field: "taskNum", type: "int" },
+        { title: "鎵樼洏缂栧彿", field: "palletCode", type: "like" },
+        { title: "鍒涘缓浜�", field: "creater", type: "like" },
+      ],
+      [
+        { title: "浠诲姟绫诲瀷",field: "taskType",type: "selectList",dataKey: "taskTypeEnum",data: [],},
+        { title: "浠诲姟鐘舵��",field: "taskStatus",type: "selectList",dataKey: "taskStatusEnum",data: [],},
+        { title: "宸烽亾鍙�", field: "roadway", type: "like" },
+      ],
+      [
+        { title: "璧峰鍦板潃", field: "sourceAddress", type: "like" },
+        { title: "鐩爣鍦板潃", field: "targetAddress", type: "like" },
+        { title: "鍒涘缓鏃堕棿", field: "createDate", type: "datetime" },
+      ],
+    ]);
+    const columns = ref([
+      {
+        field: "taskId",
+        title: "taskId",
+        type: "int",
+        width: 90,
+        hidden: true,
+        readonly: true,
+        require: true,
+        align: "left",
+      },
+      {
+        field: "taskNum",
+        title: "浠诲姟鍙�",
+        type: "int",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "palletCode",
+        title: "鎵樼洏缂栧彿",
+        type: "string",
+        width: 160,
+        align: "left",
+      },
+      {
+        field: "roadway",
+        title: "宸烽亾鍙�",
+        type: "string",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "taskType",
+        title: "浠诲姟绫诲瀷",
+        type: "int",
+        width: 120,
+        align: "left",
+        bind: { key: "taskTypeEnum", data: [] },
+      },
+      {
+        field: "taskStatus",
+        title: "浠诲姟鐘舵��",
+        type: "int",
+        width: 150,
+        align: "left",
+        bind: { key: "taskStatusEnum", data: [] },
+      },
+      {
+        field: "sourceAddress",
+        title: "璧峰鍦板潃",
+        type: "int",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "targetAddress",
+        title: "鐩爣鍦板潃",
+        type: "string",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "currentAddress",
+        title: "褰撳墠浣嶇疆",
+        type: "string",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "nextAddress",
+        title: "涓嬩竴浣嶇疆",
+        type: "string",
+        width: 120,
+        align: "left",
+      },
+      {
+        field: "exceptionMessage",
+        title: "寮傚父淇℃伅",
+        type: "string",
+        width: 90,
+        align: "left",
+      },
+      // {
+      //   field: "grade",
+      //   title: "浼樺厛绾�",
+      //   type: "int",
+      //   width: 80,
+      //   align: "left",
+      // },
+      {
+        field: "depth",
+        title: "娣卞害",
+        type: "int",
+        width: 80,
+        align: "left",
+        bind: { key: "locationDepth", data: [] },
+      },
+      {
+        field: "dispatchertime",
+        title: "浠诲姟涓嬪彂鏃堕棿",
+        type: "datetime",
+        width: 160,
+        align: "left",
+        // hidden:true,
+      },
+      {
+        field: "wMSId",
+        title: "WMS浠诲姟涓婚敭",
+        type: "int",
+        width: 120,
+        align: "left",
+        hidden: true,
+      },
+      {
+        field: "creater",
+        title: "鍒涘缓浜�",
+        type: "string",
+        width: 90,
+        align: "left",
+      },
+      {
+        field: "createDate",
+        title: "鍒涘缓鏃堕棿",
+        type: "datetime",
+        width: 160,
+        align: "left",
+      },
+      {
+        field: "modifier",
+        title: "淇敼浜�",
+        type: "string",
+        width: 100,
+        align: "left",
+      },
+      {
+        field: "modifyDate",
+        title: "淇敼鏃堕棿",
+        type: "datetime",
+        width: 160,
+        align: "left",
+      },
+      {
+        field: "remark",
+        title: "澶囨敞",
+        type: "string",
+        width: 100,
+        align: "left",
+        hidden: true,
+      },
+    ]);
+    const detail = ref({
+      cnName: "#detailCnName",
+      table: "",
+      columns: [],
+      sortName: "",
+    });
+    return {
+      table,
+      extend,
+      editFormFields,
+      editFormOptions,
+      searchFormFields,
+      searchFormOptions,
+      columns,
+      detail,
+    };
+  },
+});
+</script>
+    
\ No newline at end of file
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_hty.vue b/Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_hty.vue
index 3621bf7..ba60513 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_hty.vue
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/taskinfo/task_hty.vue
@@ -89,6 +89,12 @@
         type: "string",
         width: 120,
         align: "left",
+      },{
+        field: "operateType",
+        title: "鎿嶄綔绫诲瀷",
+        type: "string",
+        width: 120,
+        align: "left"
       },
       {
         field: "taskType",

--
Gitblit v1.9.3