From 0796eebe3520fafb0ac5d36ee584af81506d7e9c Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期六, 20 九月 2025 14:05:52 +0800
Subject: [PATCH] 2025.9.20 数据产品(待完成)

---
 src/components/SideList.vue |  288 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 227 insertions(+), 61 deletions(-)

diff --git a/src/components/SideList.vue b/src/components/SideList.vue
index 104fde9..a3a795c 100644
--- a/src/components/SideList.vue
+++ b/src/components/SideList.vue
@@ -1,50 +1,153 @@
 <template>
-  <el-tree
-    class="el-tree"
-    v-loading="isLoading"
-    :data="dataList"
-    :props="defaultProps"
-    @node-click="handleNodeClick"
-    default-expand-all
-    highlight-current
-    check-on-click-node
-    empty-text="鏆傛棤璁板綍"
-  >
-    <template #default="{ node, data }">
-      <slot :node="node" :data="data">
-        <div
-          :class="
-            data.selected
-              ? 'selected-tree-node custom-tree-node'
-              : 'custom-tree-node'
-          "
-        >
-          <el-icon v-if="data.type == 0" color="var(--el-color-info)">
-            <SuccessFilled/>
-          </el-icon>
-          <el-icon v-else-if="data.type == 1" color="var(--el-color-danger)">
-            <QuestionFilled />
-          </el-icon>
-          <el-icon v-else-if="data.type == 2" color="var(--el-color-warning)">
-            <QuestionFilled />
-          </el-icon>
-          <el-icon v-else-if="data.type == 3" color="var(--el-color-danger)">
-            <WarnTriangleFilled />
-          </el-icon>
-          <el-icon v-else-if="data.type == 4" color="var(--el-color-danger)">
-            <WarningFilled/>
-          </el-icon>
-          <el-icon v-else-if="data.type == 5" color="var(--el-color-warning)">
-            <WarningFilled/>
-          </el-icon>
-          <el-icon v-else-if="data.type == 6" color="var(--el-color-success)">
-            <SuccessFilled/>
-          </el-icon>
-          <div>{{ node.label }}</div>
-        </div>
-      </slot>
-    </template>
-  </el-tree>
+  <div style="padding-right: 10px;">
+    <div v-if="legend" class="state-label">
+      <el-input
+        v-model="filterText"
+        icon="Search"
+        style="width: 180px"
+        placeholder="鍏抽敭瀛楃瓫閫�"
+        clearable
+      />
+      <el-tooltip placement="bottom-start" effect="dark">
+        <template #content>
+          <el-space>
+            <el-space
+              v-for="(item, index) in stateLabels"
+              :key="index"
+              :size="1"
+            >
+              <el-icon :color="item.color">
+                <component :is="item.icon"></component>
+              </el-icon>
+              {{ item.name }}
+              <!-- <el-text size="small">{{ item.name }}</el-text> -->
+            </el-space>
+          </el-space>
+          <br />
+          <el-space>
+            <el-space :size="1">
+              <el-icon :size="16" color="var(--el-color-success)">
+                <Avatar />
+              </el-icon>
+              姝e湪鎵ц宸℃煡
+            </el-space>
+            <el-space :size="1">
+              <el-icon :size="16" color="var(--el-color-info)">
+                <Avatar />
+              </el-icon>
+              鏈墽琛�
+            </el-space>
+          </el-space>
+        </template>
+        <el-space>
+          <el-icon class="cursor-p" :size="16" color="var(--el-color-primary)"
+            ><QuestionFilled
+          /></el-icon>
+          <el-text size="small" class="cursor-p">瀹℃牳鐘舵�佸浘渚�</el-text>
+        </el-space>
+      </el-tooltip>
+    </div>
+    <el-tree
+      ref="treeRef"
+      class="el-tree"
+      v-loading="isLoading"
+      :data="dataList"
+      :props="defaultProps"
+      @node-click="handleNodeClick"
+      :filter-node-method="filterNode"
+      default-expand-all
+      highlight-current
+      check-on-click-node
+      empty-text="鏆傛棤璁板綍"
+    >
+      <template #default="{ node, data }">
+        <slot :node="node" :data="data">
+          <div
+            :class="
+              data.selected
+                ? 'selected-tree-node custom-tree-node'
+                : 'custom-tree-node'
+            "
+          >
+            <el-icon
+              v-if="data.status == '姝e湪鎵ц'"
+              :size="16"
+              color="var(--el-color-success)"
+              style="margin-left: -16px"
+            >
+              <Avatar />
+            </el-icon>
+            <el-icon
+              v-if="data.status == '鏈墽琛�'"
+              :size="16"
+              color="var(--el-color-info)"
+              style="margin-left: -16px"
+            >
+              <Avatar />
+            </el-icon>
+            <!-- <el-icon :color="stateLabels[data.type].color">
+            <component :is="stateLabels[data.type].icon"></component>
+          </el-icon> -->
+            <el-icon
+              v-if="data.type == 0"
+              :size="16"
+              color="var(--el-color-info)"
+            >
+              <SuccessFilled />
+            </el-icon>
+            <el-icon
+              v-else-if="data.type == 1"
+              :size="16"
+              color="var(--el-color-danger)"
+            >
+              <QuestionFilled />
+            </el-icon>
+            <el-icon
+              v-else-if="data.type == 2"
+              :size="16"
+              color="var(--el-color-warning)"
+            >
+              <QuestionFilled />
+            </el-icon>
+            <el-icon
+              v-else-if="data.type == 3"
+              :size="16"
+              color="var(--el-color-danger)"
+            >
+              <WarnTriangleFilled />
+            </el-icon>
+            <el-icon
+              v-else-if="data.type == 4"
+              :size="16"
+              color="var(--el-color-danger)"
+            >
+              <WarningFilled />
+            </el-icon>
+            <el-icon
+              v-else-if="data.type == 5"
+              :size="16"
+              color="var(--el-color-warning)"
+            >
+              <WarningFilled />
+            </el-icon>
+            <el-icon
+              v-else-if="data.type == 6"
+              :size="16"
+              color="var(--el-color-success)"
+            >
+              <SuccessFilled />
+            </el-icon>
+            <!-- <el-text>{{ node.label }}</el-text> -->
+            {{ node.label }}
+            <span v-if="data.count">
+              {{ '_(' + data.count + ')' }}
+              <!-- <el-text size="small">鐐规</el-text>) -->
+            </span>
+          </div>
+        </slot>
+      </template>
+    </el-tree>
+  </div>
 </template>
 
 <script>
@@ -61,16 +164,59 @@
         }
       ]
     },
-    loading: Boolean
+    loading: Boolean,
+    // 鏄惁灞曠ず鍥句緥
+    legend: {
+      type: Boolean,
+      default: false
+    }
   },
   emits: ['itemClick'],
   data() {
     return {
+      filterText: '',
       defaultProps: {
         children: 'children',
         label: 'title'
       },
-      isLoading: this.loading
+      isLoading: this.loading,
+      stateLabels: [
+        {
+          color: 'var(--el-color-info)',
+          name: '鏃犻棶棰�',
+          icon: 'SuccessFilled'
+        },
+        {
+          color: 'var(--el-color-danger)',
+          name: '闂鏈鏍�',
+          icon: 'QuestionFilled'
+        },
+        {
+          color: 'var(--el-color-warning)',
+          name: '闂閮ㄥ垎瀹℃牳',
+          icon: 'QuestionFilled'
+        },
+        {
+          color: 'var(--el-color-danger)',
+          name: '鏈暣鏀�',
+          icon: 'WarnTriangleFilled'
+        },
+        {
+          color: 'var(--el-color-danger)',
+          name: '鏁存敼鏈鏍�',
+          icon: 'WarningFilled'
+        },
+        {
+          color: 'var(--el-color-warning)',
+          name: '鏁存敼閮ㄥ垎瀹℃牳',
+          icon: 'WarningFilled'
+        },
+        {
+          color: 'var(--el-color-success)',
+          name: '瀹℃牳瀹屾垚',
+          icon: 'SuccessFilled'
+        }
+      ]
     };
   },
   computed: {
@@ -89,6 +235,7 @@
       for (const [key, value] of itemMap) {
         const i = {
           title: key,
+          count: value.length,
           children: []
         };
         value.forEach((v) => {
@@ -109,6 +256,9 @@
     }
   },
   watch: {
+    filterText(val) {
+      this.$refs.treeRef.filter(val);
+    },
     loading(nValue) {
       this.isLoading = nValue;
     },
@@ -116,17 +266,17 @@
     dataList(nValue) {
       if (this.isLoading) {
         if (nValue.length > 0) {
-          this.dataList.forEach((d) => {
-            d.children.forEach((c) => {
-              c.selected = false;
-            });
-          });
+          // this.dataList.forEach((d) => {
+          //   d.children.forEach((c) => {
+          //     c.selected = false;
+          //   });
+          // });
           if (nValue[0].children.length > 0) {
             const c = nValue[0].children[0];
-            c.selected = true;
+            // c.selected = true;
             this.$emit('itemClick', c);
           } else {
-            nValue[0].selected = true;
+            // nValue[0].selected = true;
           }
         }
         this.isLoading = false;
@@ -135,16 +285,21 @@
   },
   methods: {
     handleNodeClick(data) {
-      this.dataList.forEach((d) => {
-        d.children.forEach((c) => {
-          c.selected = false;
-        });
-      });
-      data.selected = true;
+      // this.dataList.forEach((d) => {
+      //   d.children.forEach((c) => {
+      //     c.selected = false;
+      //   });
+      // });
+      // data.selected = true;
       //鐖惰妭鐐圭殑鐐瑰嚮浜嬩欢涓嶅仛浼犻��
       if (data.children == undefined) {
         this.$emit('itemClick', data);
       }
+    },
+
+    filterNode(value, data) {
+      if (!value) return true;
+      return data.title.includes(value);
     }
   }
 };
@@ -163,4 +318,15 @@
 .selected-tree-node {
   color: var(--el-color-primary);
 }
+
+.state-label {
+  position: sticky;
+  z-index: 1;
+  top: 0;
+  background-color: white;
+  // box-shadow: var(--el-box-shadow-light);
+  border-bottom: var(--el-border);
+  display: flex;
+  padding-bottom: 4px;
+}
 </style>

--
Gitblit v1.9.3