From 2f37d51bd79026d64ad493de1eef817eb16aeb5b Mon Sep 17 00:00:00 2001
From: songshankun <songshankun@foxmail.com>
Date: 星期六, 28 十月 2023 16:53:31 +0800
Subject: [PATCH] feat: 通道展开组件/任务卡片组件

---
 tsconfig.app.json                                  |    2 
 package-lock.json                                  |  351 ++++++++++++++++++++++++++
 src/api/task.ts                                    |   84 ++++++
 src/views/dashboard/components/ChannelCollapse.vue |   70 +++++
 src/common/constants/index.ts                      |   17 +
 src/components.d.ts                                |    4 
 src/api/index.ts                                   |   23 +
 src/components/DashboardLayout.vue                 |    1 
 src/auto-imports.d.ts                              |   72 -----
 vite.config.ts                                     |   11 
 src/views/dashboard/components/TaskInfo.vue        |   95 +++++++
 src/views/dashboard/index.vue                      |   29 ++
 package.json                                       |    2 
 src/common/utils/request.ts                        |   17 
 14 files changed, 687 insertions(+), 91 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 349fc86..6e1f76b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,10 +11,12 @@
         "@element-plus/icons-vue": "^2.1.0",
         "@vueuse/core": "^10.5.0",
         "axios": "^1.5.1",
+        "dayjs": "^1.11.10",
         "element-plus": "^2.4.1",
         "lodash-es": "^4.17.21",
         "pinia": "^2.1.7",
         "vue": "^3.3.4",
+        "vue-hooks-plus": "^1.8.5",
         "vue-router": "^4.2.5"
       },
       "devDependencies": {
@@ -951,6 +953,11 @@
       "integrity": "sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==",
       "dev": true
     },
+    "node_modules/@types/js-cookie": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/@types/js-cookie/-/js-cookie-3.0.5.tgz",
+      "integrity": "sha512-dtLshqoiGRDHbHueIT9sjkd2F4tW1qPSX2xKAQK8p1e6pM+Z913GM1shv7dOqqasEMYbC5zEaClJomQe8OtQLA=="
+    },
     "node_modules/@types/json-schema": {
       "version": "7.0.14",
       "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.14.tgz",
@@ -1669,6 +1676,16 @@
         "node": ">=12"
       }
     },
+    "node_modules/call-bind": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.5.tgz",
+      "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
+      "dependencies": {
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.2.1",
+        "set-function-length": "^1.1.1"
+      }
+    },
     "node_modules/callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
@@ -1864,6 +1881,14 @@
         }
       }
     },
+    "node_modules/decode-uri-component": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+      "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
     "node_modules/deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
@@ -1896,6 +1921,19 @@
       },
       "engines": {
         "node": ">=12"
+      }
+    },
+    "node_modules/define-data-property": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.1.tgz",
+      "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
+      "dependencies": {
+        "get-intrinsic": "^1.2.1",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
       }
     },
     "node_modules/define-lazy-prop": {
@@ -2414,6 +2452,14 @@
         "node": ">=8"
       }
     },
+    "node_modules/filter-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/filter-obj/-/filter-obj-1.1.0.tgz",
+      "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/find-up": {
       "version": "5.0.0",
       "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
@@ -2496,8 +2542,18 @@
     "node_modules/function-bind": {
       "version": "1.1.2",
       "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
-      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-      "dev": true
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
+      "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
+      "dependencies": {
+        "function-bind": "^1.1.2",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3",
+        "hasown": "^2.0.0"
+      }
     },
     "node_modules/get-stream": {
       "version": "6.0.1",
@@ -2566,6 +2622,14 @@
         "node": ">=10"
       }
     },
+    "node_modules/gopd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz",
+      "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+      "dependencies": {
+        "get-intrinsic": "^1.1.3"
+      }
+    },
     "node_modules/graphemer": {
       "version": "1.4.0",
       "resolved": "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz",
@@ -2581,11 +2645,34 @@
         "node": ">=8"
       }
     },
+    "node_modules/has-property-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
+      "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
+      "dependencies": {
+        "get-intrinsic": "^1.2.2"
+      }
+    },
+    "node_modules/has-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz",
+      "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/hasown": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.0.tgz",
       "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
-      "dev": true,
       "dependencies": {
         "function-bind": "^1.1.2"
       },
@@ -2828,6 +2915,14 @@
       "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
       "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
+    },
+    "node_modules/js-cookie": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz",
+      "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+      "engines": {
+        "node": ">=14"
+      }
     },
     "node_modules/js-tokens": {
       "version": "4.0.0",
@@ -3364,6 +3459,11 @@
         "boolbase": "^1.0.0"
       }
     },
+    "node_modules/object-inspect": {
+      "version": "1.13.1",
+      "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.1.tgz",
+      "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ=="
+    },
     "node_modules/once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
@@ -3680,6 +3780,31 @@
         "node": ">=6"
       }
     },
+    "node_modules/qs": {
+      "version": "6.11.2",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.2.tgz",
+      "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
+      "dependencies": {
+        "side-channel": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/query-string": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.3.tgz",
+      "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
+      "dependencies": {
+        "decode-uri-component": "^0.2.2",
+        "filter-obj": "^1.1.0",
+        "split-on-first": "^1.0.0",
+        "strict-uri-encode": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -3941,6 +4066,14 @@
         "node": ">=14.0.0"
       }
     },
+    "node_modules/screenfull": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz",
+      "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/scule": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/scule/-/scule-1.0.0.tgz",
@@ -3974,6 +4107,20 @@
         "node": ">=10"
       }
     },
+    "node_modules/set-function-length": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.1.1.tgz",
+      "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
+      "dependencies": {
+        "define-data-property": "^1.1.1",
+        "get-intrinsic": "^1.2.1",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -4000,6 +4147,16 @@
       "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.1.tgz",
       "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
       "dev": true
+    },
+    "node_modules/side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      }
     },
     "node_modules/signal-exit": {
       "version": "3.0.7",
@@ -4077,6 +4234,22 @@
       "resolved": "https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
       "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
       "dev": true
+    },
+    "node_modules/split-on-first": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-1.1.0.tgz",
+      "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/strict-uri-encode": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+      "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
+      "engines": {
+        "node": ">=4"
+      }
     },
     "node_modules/string-argv": {
       "version": "0.3.2",
@@ -4604,6 +4777,23 @@
       },
       "peerDependencies": {
         "eslint": ">=6.0.0"
+      }
+    },
+    "node_modules/vue-hooks-plus": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmmirror.com/vue-hooks-plus/-/vue-hooks-plus-1.8.5.tgz",
+      "integrity": "sha512-cIatTWz6QQcoSCDn7jadQ3zMr799FmNiHyb59yUvR7Ws5KDJ/KdIMHHx/b0XDKzbGhQ61kcJ78zJKAKhOV0pWw==",
+      "dependencies": {
+        "@types/js-cookie": "^3.0.1",
+        "@vue/devtools-api": "^6.5.0",
+        "js-cookie": "^3.0.1",
+        "lodash": "^4.17.21",
+        "qs": "^6.11.0",
+        "query-string": "^7.1.1",
+        "screenfull": "^5.0.0"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.25"
       }
     },
     "node_modules/vue-router": {
@@ -5358,6 +5548,11 @@
       "integrity": "sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==",
       "dev": true
     },
+    "@types/js-cookie": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/@types/js-cookie/-/js-cookie-3.0.5.tgz",
+      "integrity": "sha512-dtLshqoiGRDHbHueIT9sjkd2F4tW1qPSX2xKAQK8p1e6pM+Z913GM1shv7dOqqasEMYbC5zEaClJomQe8OtQLA=="
+    },
     "@types/json-schema": {
       "version": "7.0.14",
       "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.14.tgz",
@@ -5917,6 +6112,16 @@
         "run-applescript": "^5.0.0"
       }
     },
+    "call-bind": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.5.tgz",
+      "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
+      "requires": {
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.2.1",
+        "set-function-length": "^1.1.1"
+      }
+    },
     "callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
@@ -6068,6 +6273,11 @@
         "ms": "2.1.2"
       }
     },
+    "decode-uri-component": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+      "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="
+    },
     "deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
@@ -6094,6 +6304,16 @@
       "requires": {
         "bplist-parser": "^0.2.0",
         "untildify": "^4.0.0"
+      }
+    },
+    "define-data-property": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.1.tgz",
+      "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
+      "requires": {
+        "get-intrinsic": "^1.2.1",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.0"
       }
     },
     "define-lazy-prop": {
@@ -6494,6 +6714,11 @@
         "to-regex-range": "^5.0.1"
       }
     },
+    "filter-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/filter-obj/-/filter-obj-1.1.0.tgz",
+      "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="
+    },
     "find-up": {
       "version": "5.0.0",
       "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
@@ -6552,8 +6777,18 @@
     "function-bind": {
       "version": "1.1.2",
       "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
-      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-      "dev": true
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
+    },
+    "get-intrinsic": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
+      "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
+      "requires": {
+        "function-bind": "^1.1.2",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3",
+        "hasown": "^2.0.0"
+      }
     },
     "get-stream": {
       "version": "6.0.1",
@@ -6607,6 +6842,14 @@
         "slash": "^3.0.0"
       }
     },
+    "gopd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz",
+      "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+      "requires": {
+        "get-intrinsic": "^1.1.3"
+      }
+    },
     "graphemer": {
       "version": "1.4.0",
       "resolved": "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz",
@@ -6619,11 +6862,28 @@
       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
       "dev": true
     },
+    "has-property-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
+      "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
+      "requires": {
+        "get-intrinsic": "^1.2.2"
+      }
+    },
+    "has-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz",
+      "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
+    },
+    "has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+    },
     "hasown": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.0.tgz",
       "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
-      "dev": true,
       "requires": {
         "function-bind": "^1.1.2"
       }
@@ -6799,6 +7059,11 @@
       "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
       "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
+    },
+    "js-cookie": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz",
+      "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw=="
     },
     "js-tokens": {
       "version": "4.0.0",
@@ -7224,6 +7489,11 @@
         "boolbase": "^1.0.0"
       }
     },
+    "object-inspect": {
+      "version": "1.13.1",
+      "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.1.tgz",
+      "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ=="
+    },
     "once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
@@ -7449,6 +7719,25 @@
       "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
       "dev": true
     },
+    "qs": {
+      "version": "6.11.2",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.2.tgz",
+      "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
+      "requires": {
+        "side-channel": "^1.0.4"
+      }
+    },
+    "query-string": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.3.tgz",
+      "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
+      "requires": {
+        "decode-uri-component": "^0.2.2",
+        "filter-obj": "^1.1.0",
+        "split-on-first": "^1.0.0",
+        "strict-uri-encode": "^2.0.0"
+      }
+    },
     "queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -7648,6 +7937,11 @@
         "source-map-js": ">=0.6.2 <2.0.0"
       }
     },
+    "screenfull": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz",
+      "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA=="
+    },
     "scule": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/scule/-/scule-1.0.0.tgz",
@@ -7674,6 +7968,17 @@
         }
       }
     },
+    "set-function-length": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.1.1.tgz",
+      "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
+      "requires": {
+        "define-data-property": "^1.1.1",
+        "get-intrinsic": "^1.2.1",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.0"
+      }
+    },
     "shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -7694,6 +7999,16 @@
       "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.1.tgz",
       "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
       "dev": true
+    },
+    "side-channel": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
+      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+      "requires": {
+        "call-bind": "^1.0.0",
+        "get-intrinsic": "^1.0.2",
+        "object-inspect": "^1.9.0"
+      }
     },
     "signal-exit": {
       "version": "3.0.7",
@@ -7761,6 +8076,16 @@
       "resolved": "https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
       "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
       "dev": true
+    },
+    "split-on-first": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-1.1.0.tgz",
+      "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
+    },
+    "strict-uri-encode": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+      "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="
     },
     "string-argv": {
       "version": "0.3.2",
@@ -8122,6 +8447,20 @@
         "semver": "^7.3.6"
       }
     },
+    "vue-hooks-plus": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmmirror.com/vue-hooks-plus/-/vue-hooks-plus-1.8.5.tgz",
+      "integrity": "sha512-cIatTWz6QQcoSCDn7jadQ3zMr799FmNiHyb59yUvR7Ws5KDJ/KdIMHHx/b0XDKzbGhQ61kcJ78zJKAKhOV0pWw==",
+      "requires": {
+        "@types/js-cookie": "^3.0.1",
+        "@vue/devtools-api": "^6.5.0",
+        "js-cookie": "^3.0.1",
+        "lodash": "^4.17.21",
+        "qs": "^6.11.0",
+        "query-string": "^7.1.1",
+        "screenfull": "^5.0.0"
+      }
+    },
     "vue-router": {
       "version": "4.2.5",
       "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.2.5.tgz",
diff --git a/package.json b/package.json
index 1362d31..e5cd1da 100644
--- a/package.json
+++ b/package.json
@@ -16,10 +16,12 @@
     "@element-plus/icons-vue": "^2.1.0",
     "@vueuse/core": "^10.5.0",
     "axios": "^1.5.1",
+    "dayjs": "^1.11.10",
     "element-plus": "^2.4.1",
     "lodash-es": "^4.17.21",
     "pinia": "^2.1.7",
     "vue": "^3.3.4",
+    "vue-hooks-plus": "^1.8.5",
     "vue-router": "^4.2.5"
   },
   "devDependencies": {
diff --git a/src/api/index.ts b/src/api/index.ts
index 336ce12..1c5ab52 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -1 +1,22 @@
-export {}
+import { request } from '@/common/utils'
+import type { TasksResponse } from './task'
+
+export interface BaseResponse<T = any> {
+  code: number
+  data: T
+  msg: string
+}
+
+/**
+ * 鑾峰彇浠诲姟鍒楄〃
+ * @param taskMode 1: 寰呯敓浜х殑浠诲姟 2: 鐪嬫澘鍚勯�氶亾褰撳墠灞曠ず鐨勪换鍔�
+ */
+export function getTaskList(taskMode: 1 | 2) {
+  return request<BaseResponse<TasksResponse>>({
+    url: '/v1/task/get',
+    method: 'get',
+    params: {
+      taskMode
+    }
+  })
+}
diff --git a/src/api/task.ts b/src/api/task.ts
new file mode 100644
index 0000000..a939691
--- /dev/null
+++ b/src/api/task.ts
@@ -0,0 +1,84 @@
+export interface Order {
+  ID: number
+  CreatedAt: string
+  UpdatedAt: string
+  DeletedAt: string
+  workOrderId: string
+  orderId: string
+  productId: string
+  productName: string
+  parameter: string
+  customer: string
+  deliverDate: string
+  orderAttr: string
+  amount: string
+  unit: string
+  startTime: number
+  endTime: number
+  Status: number
+}
+
+export interface Procedure {
+  ID: number
+  CreatedAt: string
+  UpdatedAt: string
+  DeletedAt: string
+  deviceId: string
+  procedureId: string
+  channel: number
+  processModelNumber: string
+  startTime: number
+  endTime: number
+  realStartTime: number
+  realEndTime: number
+  /** 1 鏈敓浜� 2鐢熶骇涓� 3鐢熶骇瀹屾垚*/
+  Status: 1 | 2 | 3
+  procedure: ProcedureProcedure
+}
+
+export interface ProcedureProcedure {
+  procedureId: string
+  procedureName: string
+  nextProcedureId: string
+  nextProcedureName: string
+  deviceId: string
+  deviceName: string
+  startTime: number
+  endTime: number
+  workHours: string
+  inputMaterials: string
+  outputMaterials: string
+  workers: Workers[]
+  allProcedureNames: string[]
+  channel: number
+}
+
+export interface Task {
+  Order: Order
+  Procedure: Procedure
+  Channel: number
+  AllProcedures: string[]
+  CurrentProcedureIndex: number
+  CanStarted: boolean
+}
+
+export interface Workers {
+  workerId: string
+  workerName: string
+  phoneNum: string
+  startTime: number
+  endTime: number
+}
+
+export interface Prompt {
+  plcNotConnected: string
+  safeProduce: string
+}
+
+export interface TasksResponse {
+  Tasks: Task[]
+  TaskCount: number
+  workers: Workers[]
+  Prompt: Prompt
+  ChannelAmount: number
+}
diff --git a/src/auto-imports.d.ts b/src/auto-imports.d.ts
index 73df040..fb10b91 100644
--- a/src/auto-imports.d.ts
+++ b/src/auto-imports.d.ts
@@ -4,74 +4,4 @@
 // noinspection JSUnusedGlobalSymbols
 // Generated by unplugin-auto-import
 export {}
-declare global {
-  const EffectScope: (typeof import('vue'))['EffectScope']
-  const computed: (typeof import('vue'))['computed']
-  const createApp: (typeof import('vue'))['createApp']
-  const customRef: (typeof import('vue'))['customRef']
-  const defineAsyncComponent: (typeof import('vue'))['defineAsyncComponent']
-  const defineComponent: (typeof import('vue'))['defineComponent']
-  const effectScope: (typeof import('vue'))['effectScope']
-  const getCurrentInstance: (typeof import('vue'))['getCurrentInstance']
-  const getCurrentScope: (typeof import('vue'))['getCurrentScope']
-  const h: (typeof import('vue'))['h']
-  const inject: (typeof import('vue'))['inject']
-  const isProxy: (typeof import('vue'))['isProxy']
-  const isReactive: (typeof import('vue'))['isReactive']
-  const isReadonly: (typeof import('vue'))['isReadonly']
-  const isRef: (typeof import('vue'))['isRef']
-  const markRaw: (typeof import('vue'))['markRaw']
-  const nextTick: (typeof import('vue'))['nextTick']
-  const onActivated: (typeof import('vue'))['onActivated']
-  const onBeforeMount: (typeof import('vue'))['onBeforeMount']
-  const onBeforeUnmount: (typeof import('vue'))['onBeforeUnmount']
-  const onBeforeUpdate: (typeof import('vue'))['onBeforeUpdate']
-  const onDeactivated: (typeof import('vue'))['onDeactivated']
-  const onErrorCaptured: (typeof import('vue'))['onErrorCaptured']
-  const onMounted: (typeof import('vue'))['onMounted']
-  const onRenderTracked: (typeof import('vue'))['onRenderTracked']
-  const onRenderTriggered: (typeof import('vue'))['onRenderTriggered']
-  const onScopeDispose: (typeof import('vue'))['onScopeDispose']
-  const onServerPrefetch: (typeof import('vue'))['onServerPrefetch']
-  const onUnmounted: (typeof import('vue'))['onUnmounted']
-  const onUpdated: (typeof import('vue'))['onUpdated']
-  const provide: (typeof import('vue'))['provide']
-  const reactive: (typeof import('vue'))['reactive']
-  const readonly: (typeof import('vue'))['readonly']
-  const ref: (typeof import('vue'))['ref']
-  const resolveComponent: (typeof import('vue'))['resolveComponent']
-  const shallowReactive: (typeof import('vue'))['shallowReactive']
-  const shallowReadonly: (typeof import('vue'))['shallowReadonly']
-  const shallowRef: (typeof import('vue'))['shallowRef']
-  const toRaw: (typeof import('vue'))['toRaw']
-  const toRef: (typeof import('vue'))['toRef']
-  const toRefs: (typeof import('vue'))['toRefs']
-  const toValue: (typeof import('vue'))['toValue']
-  const triggerRef: (typeof import('vue'))['triggerRef']
-  const unref: (typeof import('vue'))['unref']
-  const useAttrs: (typeof import('vue'))['useAttrs']
-  const useCssModule: (typeof import('vue'))['useCssModule']
-  const useCssVars: (typeof import('vue'))['useCssVars']
-  const useSlots: (typeof import('vue'))['useSlots']
-  const watch: (typeof import('vue'))['watch']
-  const watchEffect: (typeof import('vue'))['watchEffect']
-  const watchPostEffect: (typeof import('vue'))['watchPostEffect']
-  const watchSyncEffect: (typeof import('vue'))['watchSyncEffect']
-}
-// for type re-export
-declare global {
-  // @ts-ignore
-  export type {
-    Component,
-    ComponentPublicInstance,
-    ComputedRef,
-    ExtractDefaultPropTypes,
-    ExtractPropTypes,
-    ExtractPublicPropTypes,
-    InjectionKey,
-    PropType,
-    Ref,
-    VNode,
-    WritableComputedRef
-  } from 'vue'
-}
+declare global {}
diff --git a/src/common/constants/index.ts b/src/common/constants/index.ts
index 898de77..217acf4 100644
--- a/src/common/constants/index.ts
+++ b/src/common/constants/index.ts
@@ -1,3 +1,18 @@
 // 鏈枃浠舵斁缃叕鍏卞父閲忓畾涔�/鍏叡閰嶇疆绛�
 
-export {}
+export const TASK_STATUS_MAP = {
+  1: '鏈敓浜�',
+  2: '鐢熶骇涓�',
+  3: '鐢熶骇瀹屾垚'
+}
+
+export const CHANNEL_NAME_MAP: { [channel: number]: string } = {
+  0: '0',
+  1: 'A',
+  2: 'B',
+  3: 'C',
+  4: 'D',
+  5: 'E',
+  6: 'F',
+  7: 'G'
+}
diff --git a/src/common/utils/request.ts b/src/common/utils/request.ts
index 0522895..48a8aed 100644
--- a/src/common/utils/request.ts
+++ b/src/common/utils/request.ts
@@ -1,8 +1,9 @@
-import axios from 'axios'
+import axiosClient from 'axios'
+import type { AxiosRequestConfig } from 'axios'
 import { ElMessage } from 'element-plus'
 import { getToken } from '@/common/utils/index'
 
-const Axios = axios.create({
+const instance = axiosClient.create({
   responseType: 'json',
   withCredentials: true // 鍏佽鎼哄甫 cookie
 })
@@ -10,7 +11,7 @@
 /**
  * 璇锋眰鎷︽埅鍣�
  */
-Axios.interceptors.request.use(
+instance.interceptors.request.use(
   (config) => {
     // 鑻ユ槸鏈夊仛閴存潈token , 灏辩粰澶撮儴甯︿笂token
     const token = getToken()
@@ -28,17 +29,17 @@
 /**
  * 鍝嶅簲鎷︽埅鍣�
  */
-Axios.interceptors.response.use(
+instance.interceptors.response.use(
   (res) => {
     if (res.data.code == 200) {
-      return res.data ?? {}
+      return res.data
     } else {
       ElMessage({
         message: res.data.msg,
         type: 'error',
         duration: 3 * 1000
       })
-      return res.data ?? {}
+      return Promise.reject(res?.data)
     }
   },
   (error) => {
@@ -59,4 +60,6 @@
   }
 )
 
-export default Axios
+const axios = <T>(cfg: AxiosRequestConfig) => instance.request<any, T>(cfg)
+
+export default axios
diff --git a/src/components.d.ts b/src/components.d.ts
index c76e0d4..12b900c 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -8,8 +8,8 @@
 declare module 'vue' {
   export interface GlobalComponents {
     DashboardLayout: (typeof import('./components/DashboardLayout.vue'))['default']
-    ElButton: (typeof import('element-plus/es'))['ElButton']
-    ElIcon: (typeof import('element-plus/es'))['ElIcon']
+    ElCollapse: (typeof import('element-plus/es'))['ElCollapse']
+    ElCollapseItem: (typeof import('element-plus/es'))['ElCollapseItem']
     ElScrollbar: (typeof import('element-plus/es'))['ElScrollbar']
     RouterLink: (typeof import('vue-router'))['RouterLink']
     RouterView: (typeof import('vue-router'))['RouterView']
diff --git a/src/components/DashboardLayout.vue b/src/components/DashboardLayout.vue
index a88908e..692c86f 100644
--- a/src/components/DashboardLayout.vue
+++ b/src/components/DashboardLayout.vue
@@ -121,5 +121,6 @@
   height: 100%;
   background-color: #153e94;
   border-radius: 6px;
+  padding: 10px 16px;
 }
 </style>
diff --git a/src/views/dashboard/components/ChannelCollapse.vue b/src/views/dashboard/components/ChannelCollapse.vue
new file mode 100644
index 0000000..dcedc3d
--- /dev/null
+++ b/src/views/dashboard/components/ChannelCollapse.vue
@@ -0,0 +1,70 @@
+<template>
+  <div class="channel-collapse">
+    <el-collapse v-model="activeChannel">
+      <el-collapse-item
+        v-for="(tasks, channelNumber) in channels"
+        :key="channelNumber"
+        :title="channelNumber + ' 閫氶亾'"
+        :name="String(channelNumber)"
+      >
+        <template #title>{{ CHANNEL_NAME_MAP[channelNumber] + ' 閫氶亾' }}</template>
+        <TaskInfo v-for="task in tasks" :key="task.Procedure.ID" :task="task"></TaskInfo>
+      </el-collapse-item>
+    </el-collapse>
+  </div>
+</template>
+<script setup lang="ts">
+import { ref, watchEffect } from 'vue'
+import type { Task } from '@/api/task'
+import TaskInfo from './TaskInfo.vue'
+import { CHANNEL_NAME_MAP } from '@/common/constants'
+
+export interface Channel {
+  [channelNumber: number]: Task[]
+}
+
+export interface ChannelCollapseProps {
+  channels: Channel
+}
+
+const props = defineProps<ChannelCollapseProps>()
+const activeChannel = ref<string[]>([])
+
+watchEffect(() => {
+  const channelNumbers = Object.keys(props.channels).sort((a, b) => +a - +b)
+  activeChannel.value = [...channelNumbers]
+})
+</script>
+
+<style scoped lang="scss">
+.channel-collapse {
+  color: #fff;
+  background-color: transparent;
+}
+:deep(.el-collapse) {
+  border: none;
+}
+:deep(.el-collapse-item) {
+  border: none;
+}
+:deep(.el-collapse-item__header) {
+  color: #fff;
+  background-color: transparent;
+  font-size: 19px;
+  font-weight: 600;
+  border: none;
+}
+:deep(.el-collapse-item__wrap) {
+  color: #fff;
+  background-color: transparent;
+  font-size: 16px;
+  border: none;
+  font-weight: 600;
+}
+:deep(.el-collapse-item__content) {
+  color: #fff;
+  background-color: transparent;
+  font-size: 16px;
+  font-weight: 600;
+}
+</style>
diff --git a/src/views/dashboard/components/TaskInfo.vue b/src/views/dashboard/components/TaskInfo.vue
new file mode 100644
index 0000000..9f151d4
--- /dev/null
+++ b/src/views/dashboard/components/TaskInfo.vue
@@ -0,0 +1,95 @@
+<template>
+  <div class="task-info" :class="{ selected }">
+    <div
+      class="task-info-title"
+      :class="{
+        'status-ready': task.Procedure.Status === 1,
+        'status-running': task.Procedure.Status === 2,
+        'status-done': task.Procedure.Status === 3
+      }"
+    >
+      {{ TASK_STATUS_MAP[task.Procedure.Status] }}
+    </div>
+    <div class="task-info-content">
+      <div class="row">
+        <div class="col">宸ュ崟鍙�: {{ task.Order.workOrderId }}</div>
+        <div class="col">鐢熶骇鏁伴噺锛歿{ task.Order.amount || 0 }}{{ task.Order.unit }}</div>
+      </div>
+      <div class="row">
+        <div class="col">褰撳墠浠诲姟: {{ task.Procedure.procedure.procedureName || '' }}</div>
+        <div class="col">浜у搧鍚嶇О锛歿{ task.Order.productName || '' }}</div>
+      </div>
+      <div class="row">璁″垝鏃堕棿: {{ planTimeText }}</div>
+    </div>
+  </div>
+</template>
+<script setup lang="ts">
+import type { Task } from '@/api/task'
+import { computed, toRefs } from 'vue'
+import { TASK_STATUS_MAP } from '@/common/constants'
+import { useDateFormat } from '@vueuse/core'
+
+export interface TaskInfoProps {
+  task: Task
+  selected?: boolean
+}
+
+const props = withDefaults(defineProps<TaskInfoProps>(), {
+  selected: false
+})
+const { task, selected } = toRefs(props)
+
+const planTimeText = computed(() => {
+  const format = (date: number) => {
+    return useDateFormat(date, 'YYYY-MM-DD', { locales: 'zh-cn' })
+  }
+
+  const startTime = task.value.Procedure?.startTime
+  const endTime = task.value.Procedure?.endTime
+  return `${startTime ? format(startTime * 1000).value : '--'} - ${startTime ? format(endTime * 1000).value : '--'}`
+})
+</script>
+
+<style scoped lang="scss">
+$status-default: #13235a;
+$status-running: #ffcc00;
+$status-ready: #13235a;
+$status-done: #13235a;
+.task-info {
+  background-color: #6b83ff;
+  border-radius: 4px;
+}
+.task-info-title {
+  height: 34px;
+  border-radius: 4px;
+  background-color: $status-default;
+  display: flex;
+  align-items: center;
+  padding-left: 20px;
+  font-size: 14px;
+}
+.status-running {
+  color: var(--vt-v-blue);
+  background-color: $status-running;
+}
+.status-ready {
+  background-color: $status-ready;
+}
+.status-done {
+  background-color: $status-done;
+}
+.task-info-content {
+  font-size: 13px;
+  padding: 10px 20px;
+  .row {
+    width: 100%;
+    height: 24px;
+    display: flex;
+    align-items: center;
+  }
+  .col {
+    width: 50%;
+    flex: 1;
+  }
+}
+</style>
diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue
index 6a0fc85..bba3bcc 100644
--- a/src/views/dashboard/index.vue
+++ b/src/views/dashboard/index.vue
@@ -2,7 +2,7 @@
   <DashboardLayout>
     <template #leftBlock1>浠诲姟绛涢�塼abs</template>
     <template #leftBlock2>
-      <div style="height: 1500px">閫氶亾浠诲姟</div>
+      <ChannelCollapse :channels="channels"></ChannelCollapse>
     </template>
     <template #middleBlock1>鏍囬</template>
     <template #middleBlock2>涓荤湅鏉�</template>
@@ -14,9 +14,36 @@
   </DashboardLayout>
 </template>
 <script setup lang="ts">
+import { getTaskList } from '@/api'
+import { computed, ref } from 'vue'
+import ChannelCollapse from '@/views/dashboard/components/ChannelCollapse.vue'
+import type { Task } from '@/api/task'
+import { chain } from 'lodash-es'
+
 defineOptions({
   name: 'DashboardView'
 })
+
+const taskList = ref<Task[]>()
+
+function getChannels() {
+  getTaskList(2)
+    .then((res) => {
+      taskList.value = res.data.Tasks
+    })
+    .catch((err) => {
+      console.error(err)
+      taskList.value = []
+    })
+}
+
+const channels = computed(() => {
+  return chain<Task>(taskList.value)
+    .groupBy((ele) => ele.Channel)
+    .value()
+})
+
+getChannels()
 </script>
 
 <style scoped></style>
diff --git a/tsconfig.app.json b/tsconfig.app.json
index a4378fa..ceee83b 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -1,6 +1,6 @@
 {
   "extends": "@vue/tsconfig/tsconfig.dom.json",
-  "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "global.d.ts"],
+  "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "global.d.ts", "src/**/*.ts"],
   "exclude": ["src/**/__tests__/*"],
   "compilerOptions": {
     "composite": true,
diff --git a/vite.config.ts b/vite.config.ts
index 03be1f2..692b8dc 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -11,6 +11,15 @@
 
 // https://vitejs.dev/config/
 export default defineConfig({
+  server: {
+    proxy: {
+      '/v1/': {
+        target: 'http://192.168.20.4:8003',
+        ws: true,
+        changeOrigin: true
+      }
+    }
+  },
   resolve: {
     alias: {
       '@': pathSrc
@@ -21,7 +30,7 @@
     // element plus 鑷姩瀵煎叆
     AutoImport({
       // 鑷姩瀵煎叆 Vue 鐩稿叧鍑芥暟锛屽锛歳ef, reactive, toRef 绛�
-      imports: ['vue'],
+      // imports: ['vue'],
       // 鑷姩瀵煎叆 Element Plus 鐩稿叧鍑芥暟锛屽锛欵lMessage, ElMessageBox... (甯︽牱寮�)
       resolvers: [
         ElementPlusResolver(),

--
Gitblit v1.8.0