Pārlūkot izejas kodu

feat: 增加部门的树的搜索

louhangfei 11 mēneši atpakaļ
vecāks
revīzija
4dd138a8d1
3 mainītis faili ar 79 papildinājumiem un 39 dzēšanām
  1. 14 14
      src/types/dept/type.ts
  2. 34 0
      src/utils/tree.ts
  3. 31 25
      src/views/auth/dept/dept.vue

+ 14 - 14
src/types/dept/type.ts

@@ -1,20 +1,20 @@
 /* V4: 部门树结构 */
 export interface DeptTreeItem {
-  id: number | null,
-  deptName: string, // 部门名称
-  parentId: number | null, // 上级部门 id
-  orderNum: number | undefined, // 排序
-  createdBy: number, // 创建人
-  updatedBy: number, // 更新人
-  createdAt: string, // 创建时间
-  updatedAt: string, // 更新时间
-  isDeleted: number, // 0-未删除。 大于 0-已删除
-  tenantId: number, // 租户 ID
-  userCount: number, // 组织下的用户数量
+  id: number | null;
+  deptName: string; // 部门名称
+  parentId: number | null; // 上级部门 id
+  orderNum: number | undefined; // 排序
+  createdBy: number; // 创建人
+  updatedBy: number; // 更新人
+  createdAt: string; // 创建时间
+  updatedAt: string; // 更新时间
+  isDeleted: number; // 0-未删除。 大于 0-已删除
+  tenantId: number; // 租户 ID
+  userCount: number; // 组织下的用户数量
 }
 
-export type DeptTree = DeptTreeItem & { children: DeptTreeItem[] }
+export type DeptTree = DeptTreeItem & { children: DeptTree[] };
 
-export type addDeptProps = Pick<DeptTreeItem, 'parentId' | 'deptName' | 'orderNum'>
+export type addDeptProps = Pick<DeptTreeItem, 'parentId' | 'deptName' | 'orderNum'>;
 
-export type editDeptProps = addDeptProps & {id?: DeptTreeItem['id']}
+export type editDeptProps = addDeptProps & { id?: DeptTreeItem['id'] };

+ 34 - 0
src/utils/tree.ts

@@ -0,0 +1,34 @@
+interface TreeItem {
+  children: TreeItem[];
+}
+
+interface FilterTreeProps<T> {
+  /** 数节点 */
+  nodes: T[];
+  /** 搜索关键字 */
+  value: string;
+  /** 要匹配的字段名 */
+  key: string;
+}
+
+/**
+ * 过滤树状结构,返回值仍然是一棵树
+ */
+export const filterTree = <T extends TreeItem>(data: FilterTreeProps<T>): T[] => {
+  const { nodes, value, key } = data;
+  if (!value) {
+    return nodes;
+  }
+  return nodes.reduce((acc, node) => {
+    const nodeMatches = node[key].includes(value);
+    const filteredChildren = node.children ? filterTree({ nodes: node.children, value, key }) : [];
+
+    if (nodeMatches || filteredChildren.length > 0) {
+      acc.push({
+        ...node,
+        children: filteredChildren.length > 0 ? filteredChildren : nodeMatches ? node.children : [],
+      });
+    }
+    return acc;
+  }, [] as T[]);
+};

+ 31 - 25
src/views/auth/dept/dept.vue

@@ -1,21 +1,16 @@
 <template>
   <PageWrapper>
-    <el-card :bordered="false" class="proCard">
-      <el-table :data="tableData" row-key="id" :tree-props="treeProps" default-expand-all>
-        <el-table-column label="组织名称">
-          <template #default="{ row }">
-            {{ `${row.deptName} (${row.userCount})` }}
-          </template>
-        </el-table-column>
-      </el-table>
-    </el-card>
-    <CreateDrawer_shangfei
-      ref="createDrawerRef"
-      :title="drawerTitle"
-      :deptList="tableData"
-      @change="reloadTable"
-      v-if="disableDepartmentEdit"
-    />
+    <div class="search"
+      ><span class="searchLabel"> 搜索:</span><el-input v-model="searchKey" placeholder="请输入关键字进行搜索" />
+    </div>
+    <el-table :data="filterData" row-key="id" :tree-props="treeProps" default-expand-all>
+      <el-table-column label="组织名称">
+        <template #default="{ row }">
+          {{ `${row.deptName} (${row.userCount})` }}
+        </template>
+      </el-table-column>
+    </el-table>
+
     <CreateDrawer
       ref="createDrawerRef"
       :title="drawerTitle"
@@ -23,28 +18,24 @@
       :data-source="currentDept"
       :width="450"
       @change="reloadTable"
-      v-else
     />
   </PageWrapper>
 </template>
 
 <script lang="ts" setup>
-  import { onMounted, reactive, ref } from 'vue';
+  import { computed, onMounted, reactive, ref } from 'vue';
   import { PageWrapper } from '@/components/Page';
   import { getAllDepartments } from '@/api/auth/dept';
   import CreateDrawer from './CreateDrawer.vue';
-  import CreateDrawer_shangfei from './CreateDrawer-shangfei.vue';
-  import { useGlobSetting } from '@/hooks/setting';
-  import type { DeptTreeItem } from '@/types/dept/type';
-
-  const globSetting = useGlobSetting();
-  const disableDepartmentEdit = globSetting.disableDepartmentEdit;
+  import type { DeptTree, DeptTreeItem } from '@/types/dept/type';
+  import { filterTree } from '@/utils/tree';
 
-  const tableData = ref<any[]>([]);
+  const tableData = ref<DeptTree[]>([]);
   const treeProps = reactive({
     checkStrictly: false,
   });
   const createDrawerRef = ref();
+  const searchKey = ref('');
   const drawerTitle = ref('添加部门');
   const currentDept = ref<DeptTreeItem>({
     id: null,
@@ -65,6 +56,13 @@
     tableData.value = result;
   };
 
+  const filterData = computed(() => {
+    if (!searchKey.value) {
+      return tableData.value;
+    }
+    return filterTree({ nodes: tableData.value, value: searchKey.value, key: 'deptName' });
+  });
+
   function reloadTable() {
     loadDataTable();
   }
@@ -96,4 +94,12 @@
   .el-space__item:hover {
     cursor: pointer;
   }
+  .search {
+    margin: 20px;
+    width: 300px;
+    display: flex;
+    .searchLabel {
+      width: 65px;
+    }
+  }
 </style>