update 优化 封装TreePanel树组件 简化页面代码

This commit is contained in:
疯狂的狮子Li
2026-04-09 13:58:30 +08:00
parent 02b5ca7c48
commit 4f713d66db
6 changed files with 288 additions and 238 deletions
+12 -49
View File
@@ -2,36 +2,15 @@
<div class="p-2 app-container system-post-page">
<el-row :gutter="20" class="content-grid">
<!-- 部门树 -->
<el-col :lg="treeCollapsed ? 1 : 5" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
<template #header>
<div
class="panel-heading search-panel-toggle tree-panel-header"
:class="{ 'is-collapsed': treeCollapsed }"
@click.stop="treeCollapsed = !treeCollapsed"
>
<div v-show="!treeCollapsed">
<h3>部门结构</h3>
</div>
</div>
</template>
<template v-if="!treeCollapsed">
<el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
<el-tree
ref="deptTreeRef"
class="mt-2 dept-tree"
node-key="id"
:data="deptOptions"
:props="{ label: 'label', children: 'children' } as any"
:expand-on-click-node="false"
:filter-node-method="filterNode"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</template>
</el-card>
</el-col>
<tree-panel
ref="treePanelRef"
v-model:collapsed="treeCollapsed"
title="部门结构"
placeholder="请输入部门名称"
:data="deptOptions"
:expanded-span="5"
@node-click="handleNodeClick"
/>
<el-col
:lg="treeCollapsed ? 23 : 19"
:xs="24"
@@ -252,6 +231,7 @@
</template>
<script setup name="Post" lang="ts">
import TreePanel from '@/components/TreePanel/index.vue';
import { listPost, addPost, delPost, getPost, updatePost, deptTreeSelect } from '@/api/system/post';
import { PostForm, PostQuery, PostVO } from '@/api/system/post/types';
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
@@ -266,10 +246,9 @@ const ids = ref<Array<number | string>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const deptName = ref('');
const treeCollapsed = ref(false);
const deptOptions = ref<DeptTreeVO[]>([]);
const deptTreeRef = ref<ElTreeInstance>();
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
const postFormRef = ref<ElFormInstance>();
const queryFormRef = ref<ElFormInstance>();
@@ -311,22 +290,6 @@ const data = reactive<PageData<PostForm, PostQuery>>({
const { queryParams, form, rules } = toRefs<PageData<PostForm, PostQuery>>(data);
/** 通过条件过滤节点 */
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.label.indexOf(value) !== -1;
};
/** 根据名称筛选部门树 */
watchEffect(
() => {
deptTreeRef.value?.filter(deptName.value);
},
{
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
}
);
/** 查询部门下拉树结构 */
const getTreeSelect = async () => {
const res = await deptTreeSelect();
@@ -375,7 +338,7 @@ const resetQuery = () => {
queryFormRef.value?.resetFields();
queryParams.value.pageNum = 1;
queryParams.value.deptId = undefined;
deptTreeRef.value?.setCurrentKey(undefined);
treePanelRef.value?.setCurrentKey(undefined);
/** 清空左边部门树选中值 */
queryParams.value.belongDeptId = undefined;
handleQuery();
+12 -48
View File
@@ -2,36 +2,15 @@
<div class="p-2 system-user-page">
<el-row :gutter="20" class="content-grid">
<!-- 部门树 -->
<el-col :lg="treeCollapsed ? 1 : 5" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
<template #header>
<div
class="panel-heading search-panel-toggle tree-panel-header"
:class="{ 'is-collapsed': treeCollapsed }"
@click.stop="treeCollapsed = !treeCollapsed"
>
<div v-show="!treeCollapsed">
<h3>部门结构</h3>
</div>
</div>
</template>
<template v-if="!treeCollapsed">
<el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
<el-tree
ref="deptTreeRef"
class="mt-2 dept-tree"
node-key="id"
:data="deptOptions"
:props="{ label: 'label', children: 'children' } as any"
:expand-on-click-node="false"
:filter-node-method="filterNode"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</template>
</el-card>
</el-col>
<tree-panel
ref="treePanelRef"
v-model:collapsed="treeCollapsed"
title="部门结构"
placeholder="请输入部门名称"
:data="deptOptions"
:expanded-span="5"
@node-click="handleNodeClick"
/>
<el-col
:lg="treeCollapsed ? 23 : 19"
:xs="24"
@@ -472,6 +451,7 @@
</template>
<script setup name="User" lang="ts">
import TreePanel from '@/components/TreePanel/index.vue';
import api from '@/api/system/user';
import { UserForm, UserQuery, UserVO } from '@/api/system/user/types';
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
@@ -495,7 +475,6 @@ const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
const deptName = ref('');
const treeCollapsed = ref(false);
const deptOptions = ref<DeptTreeVO[]>([]);
const enabledDeptOptions = ref<DeptTreeVO[]>([]);
@@ -528,7 +507,7 @@ const columns = ref<FieldOption[]>([
{ key: 6, label: `创建时间`, visible: true, children: [] }
]);
const deptTreeRef = ref<ElTreeInstance>();
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
const queryFormRef = ref<ElFormInstance>();
const userFormRef = ref<ElFormInstance>();
const uploadRef = ref<ElUploadInstance>();
@@ -608,21 +587,6 @@ const data = reactive<PageData<UserForm, UserQuery>>(initData);
const { queryParams, form, rules } = toRefs<PageData<UserForm, UserQuery>>(data);
/** 通过条件过滤节点 */
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.label.indexOf(value) !== -1;
};
/** 根据名称筛选部门树 */
watchEffect(
() => {
deptTreeRef.value?.filter(deptName.value);
},
{
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
}
);
/** 查询用户列表 */
const getList = async () => {
loading.value = true;
@@ -669,7 +633,7 @@ const resetQuery = () => {
queryFormRef.value?.resetFields();
queryParams.value.pageNum = 1;
queryParams.value.deptId = undefined;
deptTreeRef.value?.setCurrentKey(undefined);
treePanelRef.value?.setCurrentKey(undefined);
handleQuery();
};
+12 -47
View File
@@ -2,36 +2,16 @@
<div class="p-2 app-container workflow-process-definition-page">
<el-row :gutter="20" class="content-grid">
<!-- 流程分类树 -->
<el-col :lg="treeCollapsed ? 1 : 4" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
<template #header>
<div
class="panel-heading search-panel-toggle tree-panel-header"
:class="{ 'is-collapsed': treeCollapsed }"
@click.stop="treeCollapsed = !treeCollapsed"
>
<div v-show="!treeCollapsed" class="table-heading">
<h3>流程分类</h3>
</div>
</div>
</template>
<template v-if="!treeCollapsed">
<el-input v-model="categoryName" placeholder="请输入流程分类名" prefix-icon="Search" clearable />
<el-tree
ref="categoryTreeRef"
class="mt-2 dept-tree"
node-key="id"
:data="categoryOptions"
:props="{ label: 'label', children: 'children' } as any"
:expand-on-click-node="false"
:filter-node-method="filterNode"
highlight-current
default-expand-all
@node-click="handleNodeClick"
></el-tree>
</template>
</el-card>
</el-col>
<tree-panel
ref="treePanelRef"
v-model:collapsed="treeCollapsed"
title="流程分类"
placeholder="请输入流程分类名"
:data="categoryOptions"
:expanded-span="4"
filter-field="categoryName"
@node-click="handleNodeClick"
/>
<el-col
:lg="treeCollapsed ? 23 : 20"
:xs="24"
@@ -344,6 +324,7 @@
</template>
<script setup name="processDefinition" lang="ts">
import TreePanel from '@/components/TreePanel/index.vue';
import {
listDefinition,
deleteDefinition,
@@ -364,7 +345,7 @@ import type { ElMessageBoxOptions, TabsPaneContext, UploadRequestOptions } from
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const queryFormRef = ref<ElFormInstance>();
const categoryTreeRef = ref<ElTreeInstance>();
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
const loading = ref(true);
const ids = ref<Array<any>>([]);
@@ -376,7 +357,6 @@ const total = ref(0);
const uploadDialogLoading = ref(false);
const processDefinitionList = ref<FlowDefinitionVo[]>([]);
const categoryOptions = ref<CategoryTreeVO[]>([]);
const categoryName = ref('');
const treeCollapsed = ref(false);
const autoPass = ref(false);
/** 部署文件分类选择 */
@@ -442,21 +422,6 @@ const handleNodeClick = (data: CategoryTreeVO) => {
}
handleQuery();
};
/** 通过条件过滤节点 */
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.categoryName.indexOf(value) !== -1;
};
/** 根据名称筛选部门树 */
watchEffect(
() => {
categoryTreeRef.value?.filter(categoryName.value);
},
{
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
}
);
/** 查询流程分类下拉树结构 */
const getTreeselect = async () => {
const res = await categoryTree();
+12 -47
View File
@@ -2,36 +2,16 @@
<div class="p-2 app-container workflow-process-instance-page">
<el-row :gutter="20" class="content-grid">
<!-- 流程分类树 -->
<el-col :lg="treeCollapsed ? 1 : 4" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
<template #header>
<div
class="panel-heading search-panel-toggle tree-panel-header"
:class="{ 'is-collapsed': treeCollapsed }"
@click.stop="treeCollapsed = !treeCollapsed"
>
<div v-show="!treeCollapsed" class="table-heading">
<h3>流程分类</h3>
</div>
</div>
</template>
<template v-if="!treeCollapsed">
<el-input v-model="categoryName" placeholder="请输入流程分类名" prefix-icon="Search" clearable />
<el-tree
ref="categoryTreeRef"
class="mt-2 dept-tree"
node-key="id"
:data="categoryOptions"
:props="{ label: 'label', children: 'children' } as any"
:expand-on-click-node="false"
:filter-node-method="filterNode"
highlight-current
default-expand-all
@node-click="handleNodeClick"
></el-tree>
</template>
</el-card>
</el-col>
<tree-panel
ref="treePanelRef"
v-model:collapsed="treeCollapsed"
title="流程分类"
placeholder="请输入流程分类名"
:data="categoryOptions"
:expanded-span="4"
filter-field="categoryName"
@node-click="handleNodeClick"
/>
<el-col
:lg="treeCollapsed ? 23 : 20"
:xs="24"
@@ -315,6 +295,7 @@
</template>
<script setup lang="ts">
import TreePanel from '@/components/TreePanel/index.vue';
import {
pageByRunning,
pageByFinish,
@@ -337,7 +318,7 @@ import { ElForm, FormInstance } from 'element-plus';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
const queryFormRef = ref<ElFormInstance>();
const categoryTreeRef = ref<ElTreeInstance>();
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
import { ref } from 'vue';
import { UserVO } from '@/api/system/user/types';
const form = ref<Record<string, any>>({
@@ -374,7 +355,6 @@ const processDefinitionName = ref();
const processInstanceList = ref<FlowInstanceVO[]>([]);
const processDefinitionHistoryList = ref<Array<any>>([]);
const categoryOptions = ref<CategoryOption[]>([]);
const categoryName = ref('');
const treeCollapsed = ref(false);
const processDefinitionDialog = reactive<DialogOption>({
@@ -415,21 +395,6 @@ const handleNodeClick = (data: CategoryTreeVO) => {
}
handleQuery();
};
/** 通过条件过滤节点 */
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.categoryName.indexOf(value) !== -1;
};
/** 根据名称筛选部门树 */
watchEffect(
() => {
categoryTreeRef.value?.filter(categoryName.value);
},
{
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
}
);
/** 查询流程分类下拉树结构 */
const getTreeselect = async () => {
const res = await categoryTree();
+12 -47
View File
@@ -2,36 +2,16 @@
<div class="p-2 app-container workflow-my-document-page">
<el-row :gutter="20" class="content-grid">
<!-- 流程分类树 -->
<el-col :lg="treeCollapsed ? 1 : 4" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
<template #header>
<div
class="panel-heading search-panel-toggle tree-panel-header"
:class="{ 'is-collapsed': treeCollapsed }"
@click.stop="treeCollapsed = !treeCollapsed"
>
<div v-show="!treeCollapsed" class="table-heading">
<h3>流程分类</h3>
</div>
</div>
</template>
<template v-if="!treeCollapsed">
<el-input v-model="categoryName" placeholder="请输入流程分类名" prefix-icon="Search" clearable />
<el-tree
ref="categoryTreeRef"
class="mt-2 dept-tree"
node-key="id"
:data="categoryOptions"
:props="{ label: 'label', children: 'children' } as any"
:expand-on-click-node="false"
:filter-node-method="filterNode"
highlight-current
default-expand-all
@node-click="handleNodeClick"
></el-tree>
</template>
</el-card>
</el-col>
<tree-panel
ref="treePanelRef"
v-model:collapsed="treeCollapsed"
title="流程分类"
placeholder="请输入流程分类名"
:data="categoryOptions"
:expanded-span="4"
filter-field="categoryName"
@node-click="handleNodeClick"
/>
<el-col
:lg="treeCollapsed ? 23 : 20"
:xs="24"
@@ -169,6 +149,7 @@
</template>
<script setup lang="ts">
import TreePanel from '@/components/TreePanel/index.vue';
import { pageByCurrent, deleteByInstanceIds, cancelProcessApply } from '@/api/workflow/instance';
import { categoryTree } from '@/api/workflow/category';
import { CategoryTreeVO } from '@/api/workflow/category/types';
@@ -178,7 +159,7 @@ import { RouterJumpVo } from '@/api/workflow/workflowCommon/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
const queryFormRef = ref<ElFormInstance>();
const categoryTreeRef = ref<ElTreeInstance>();
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
// 遮罩层
const loading = ref(true);
@@ -197,7 +178,6 @@ const total = ref(0);
const processInstanceList = ref<FlowInstanceVO[]>([]);
const categoryOptions = ref<CategoryTreeVO[]>([]);
const categoryName = ref('');
const treeCollapsed = ref(false);
const tab = ref('running');
@@ -222,21 +202,6 @@ const handleNodeClick = (data: CategoryTreeVO) => {
}
handleQuery();
};
/** 通过条件过滤节点 */
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.categoryName.indexOf(value) !== -1;
};
/** 根据名称筛选部门树 */
watchEffect(
() => {
categoryTreeRef.value?.filter(categoryName.value);
},
{
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
}
);
/** 查询流程分类下拉树结构 */
const getTreeselect = async () => {
const res = await categoryTree();