update 优化 封装TreePanel树组件 简化页面代码
This commit is contained in:
@@ -0,0 +1,228 @@
|
|||||||
|
<template>
|
||||||
|
<el-col
|
||||||
|
:lg="modelCollapsed ? 1 : expandedSpan"
|
||||||
|
:xs="24"
|
||||||
|
class="tree-panel-col"
|
||||||
|
:class="{ 'is-collapsed': modelCollapsed }"
|
||||||
|
>
|
||||||
|
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': modelCollapsed }">
|
||||||
|
<template #header>
|
||||||
|
<div
|
||||||
|
class="panel-heading search-panel-toggle tree-panel-header"
|
||||||
|
:class="{ 'is-collapsed': modelCollapsed }"
|
||||||
|
@click.stop="toggleCollapsed"
|
||||||
|
>
|
||||||
|
<div v-show="!modelCollapsed">
|
||||||
|
<h3>{{ title }}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="!modelCollapsed">
|
||||||
|
<el-input v-model="filterText" :placeholder="placeholder" prefix-icon="Search" clearable />
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
class="mt-2 dept-tree"
|
||||||
|
:node-key="nodeKey"
|
||||||
|
:data="data"
|
||||||
|
:props="(treeProps as any)"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
:filter-node-method="internalFilterNode"
|
||||||
|
highlight-current
|
||||||
|
default-expand-all
|
||||||
|
@node-click="onNodeClick"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
/** 面板标题 */
|
||||||
|
title: string;
|
||||||
|
/** 搜索输入框占位文字 */
|
||||||
|
placeholder?: string;
|
||||||
|
/** 树数据 */
|
||||||
|
data: any[];
|
||||||
|
/** el-tree node-key */
|
||||||
|
nodeKey?: string;
|
||||||
|
/** el-tree props 配置 */
|
||||||
|
treeProps?: Record<string, string>;
|
||||||
|
/** 展开时占的栅格列数 (lg) */
|
||||||
|
expandedSpan?: number;
|
||||||
|
/** 默认过滤字段名 (用于内置 filterNode) */
|
||||||
|
filterField?: string;
|
||||||
|
/** 自定义过滤方法,传入则覆盖默认 filterField 逻辑 */
|
||||||
|
filterNodeMethod?: (value: string, data: any) => boolean;
|
||||||
|
/** 折叠状态 (v-model:collapsed) */
|
||||||
|
collapsed?: boolean;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
placeholder: '请输入名称',
|
||||||
|
nodeKey: 'id',
|
||||||
|
treeProps: () => ({ label: 'label', children: 'children' }),
|
||||||
|
expandedSpan: 5,
|
||||||
|
filterField: 'label',
|
||||||
|
collapsed: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:collapsed': [value: boolean];
|
||||||
|
'node-click': [data: any, node: any, component: any];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const modelCollapsed = computed({
|
||||||
|
get: () => props.collapsed,
|
||||||
|
set: (val: boolean) => emit('update:collapsed', val)
|
||||||
|
});
|
||||||
|
|
||||||
|
const filterText = ref('');
|
||||||
|
const treeRef = ref<ElTreeInstance>();
|
||||||
|
|
||||||
|
const toggleCollapsed = () => {
|
||||||
|
modelCollapsed.value = !modelCollapsed.value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const internalFilterNode = (value: string, data: any) => {
|
||||||
|
if (props.filterNodeMethod) {
|
||||||
|
return props.filterNodeMethod(value, data);
|
||||||
|
}
|
||||||
|
if (!value) return true;
|
||||||
|
return data[props.filterField]?.indexOf(value) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
watchEffect(
|
||||||
|
() => {
|
||||||
|
treeRef.value?.filter(filterText.value);
|
||||||
|
},
|
||||||
|
{ flush: 'post' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const onNodeClick = (data: any, node: any, component: any) => {
|
||||||
|
emit('node-click', data, node, component);
|
||||||
|
};
|
||||||
|
|
||||||
|
const contentSpan = computed(() => (modelCollapsed.value ? 23 : 24 - props.expandedSpan));
|
||||||
|
|
||||||
|
const setCurrentKey = (key: any) => treeRef.value?.setCurrentKey(key);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
treeRef,
|
||||||
|
contentSpan,
|
||||||
|
setCurrentKey
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
$mobile-breakpoint: 900px;
|
||||||
|
|
||||||
|
.tree-panel-col {
|
||||||
|
min-width: 0;
|
||||||
|
transition:
|
||||||
|
max-width 0.24s ease,
|
||||||
|
flex-basis 0.24s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-col.is-collapsed {
|
||||||
|
max-width: 56px;
|
||||||
|
flex: 0 0 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-shell,
|
||||||
|
.side-panel {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-shell {
|
||||||
|
--tree-panel-max-height: 620px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-shell :deep(.el-card__header) {
|
||||||
|
display: block;
|
||||||
|
padding: 12px 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-shell :deep(.el-card__body) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: var(--tree-panel-max-height);
|
||||||
|
min-height: 0;
|
||||||
|
max-height: var(--tree-panel-max-height);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-header {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-header::after {
|
||||||
|
display: block;
|
||||||
|
width: 9px;
|
||||||
|
min-width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
margin-left: auto;
|
||||||
|
flex-shrink: 0;
|
||||||
|
transform-origin: center;
|
||||||
|
transform: rotate(135deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-header.is-collapsed {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-panel.is-collapsed :deep(.el-card__body) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-shell.is-collapsed :deep(.el-card__header) {
|
||||||
|
padding: 12px 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-shell.is-collapsed .tree-panel-header::after {
|
||||||
|
margin-left: 0;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-tree {
|
||||||
|
padding-top: 6px;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 180px;
|
||||||
|
max-height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
padding-right: 4px;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-tree::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-tree::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 999px;
|
||||||
|
background: var(--app-text-muted);
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-tree::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $mobile-breakpoint) {
|
||||||
|
.tree-panel-col {
|
||||||
|
max-width: 100%;
|
||||||
|
flex: 0 0 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-panel-shell {
|
||||||
|
--tree-panel-max-height: 420px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.side-panel.is-collapsed {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,36 +2,15 @@
|
|||||||
<div class="p-2 app-container system-post-page">
|
<div class="p-2 app-container system-post-page">
|
||||||
<el-row :gutter="20" class="content-grid">
|
<el-row :gutter="20" class="content-grid">
|
||||||
<!-- 部门树 -->
|
<!-- 部门树 -->
|
||||||
<el-col :lg="treeCollapsed ? 1 : 5" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
|
<tree-panel
|
||||||
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
|
ref="treePanelRef"
|
||||||
<template #header>
|
v-model:collapsed="treeCollapsed"
|
||||||
<div
|
title="部门结构"
|
||||||
class="panel-heading search-panel-toggle tree-panel-header"
|
placeholder="请输入部门名称"
|
||||||
:class="{ 'is-collapsed': treeCollapsed }"
|
:data="deptOptions"
|
||||||
@click.stop="treeCollapsed = !treeCollapsed"
|
:expanded-span="5"
|
||||||
>
|
@node-click="handleNodeClick"
|
||||||
<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>
|
|
||||||
<el-col
|
<el-col
|
||||||
:lg="treeCollapsed ? 23 : 19"
|
:lg="treeCollapsed ? 23 : 19"
|
||||||
:xs="24"
|
:xs="24"
|
||||||
@@ -252,6 +231,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="Post" lang="ts">
|
<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 { listPost, addPost, delPost, getPost, updatePost, deptTreeSelect } from '@/api/system/post';
|
||||||
import { PostForm, PostQuery, PostVO } from '@/api/system/post/types';
|
import { PostForm, PostQuery, PostVO } from '@/api/system/post/types';
|
||||||
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
|
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
|
||||||
@@ -266,10 +246,9 @@ const ids = ref<Array<number | string>>([]);
|
|||||||
const single = ref(true);
|
const single = ref(true);
|
||||||
const multiple = ref(true);
|
const multiple = ref(true);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const deptName = ref('');
|
|
||||||
const treeCollapsed = ref(false);
|
const treeCollapsed = ref(false);
|
||||||
const deptOptions = ref<DeptTreeVO[]>([]);
|
const deptOptions = ref<DeptTreeVO[]>([]);
|
||||||
const deptTreeRef = ref<ElTreeInstance>();
|
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
|
||||||
const postFormRef = ref<ElFormInstance>();
|
const postFormRef = ref<ElFormInstance>();
|
||||||
const queryFormRef = 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 { 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 getTreeSelect = async () => {
|
||||||
const res = await deptTreeSelect();
|
const res = await deptTreeSelect();
|
||||||
@@ -375,7 +338,7 @@ const resetQuery = () => {
|
|||||||
queryFormRef.value?.resetFields();
|
queryFormRef.value?.resetFields();
|
||||||
queryParams.value.pageNum = 1;
|
queryParams.value.pageNum = 1;
|
||||||
queryParams.value.deptId = undefined;
|
queryParams.value.deptId = undefined;
|
||||||
deptTreeRef.value?.setCurrentKey(undefined);
|
treePanelRef.value?.setCurrentKey(undefined);
|
||||||
/** 清空左边部门树选中值 */
|
/** 清空左边部门树选中值 */
|
||||||
queryParams.value.belongDeptId = undefined;
|
queryParams.value.belongDeptId = undefined;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
|
|||||||
@@ -2,36 +2,15 @@
|
|||||||
<div class="p-2 system-user-page">
|
<div class="p-2 system-user-page">
|
||||||
<el-row :gutter="20" class="content-grid">
|
<el-row :gutter="20" class="content-grid">
|
||||||
<!-- 部门树 -->
|
<!-- 部门树 -->
|
||||||
<el-col :lg="treeCollapsed ? 1 : 5" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
|
<tree-panel
|
||||||
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
|
ref="treePanelRef"
|
||||||
<template #header>
|
v-model:collapsed="treeCollapsed"
|
||||||
<div
|
title="部门结构"
|
||||||
class="panel-heading search-panel-toggle tree-panel-header"
|
placeholder="请输入部门名称"
|
||||||
:class="{ 'is-collapsed': treeCollapsed }"
|
:data="deptOptions"
|
||||||
@click.stop="treeCollapsed = !treeCollapsed"
|
:expanded-span="5"
|
||||||
>
|
@node-click="handleNodeClick"
|
||||||
<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>
|
|
||||||
<el-col
|
<el-col
|
||||||
:lg="treeCollapsed ? 23 : 19"
|
:lg="treeCollapsed ? 23 : 19"
|
||||||
:xs="24"
|
:xs="24"
|
||||||
@@ -472,6 +451,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="User" lang="ts">
|
<script setup name="User" lang="ts">
|
||||||
|
import TreePanel from '@/components/TreePanel/index.vue';
|
||||||
import api from '@/api/system/user';
|
import api from '@/api/system/user';
|
||||||
import { UserForm, UserQuery, UserVO } from '@/api/system/user/types';
|
import { UserForm, UserQuery, UserVO } from '@/api/system/user/types';
|
||||||
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
|
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
|
||||||
@@ -495,7 +475,6 @@ const single = ref(true);
|
|||||||
const multiple = ref(true);
|
const multiple = ref(true);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
|
const dateRange = ref<[DateModelType, DateModelType]>(['', '']);
|
||||||
const deptName = ref('');
|
|
||||||
const treeCollapsed = ref(false);
|
const treeCollapsed = ref(false);
|
||||||
const deptOptions = ref<DeptTreeVO[]>([]);
|
const deptOptions = ref<DeptTreeVO[]>([]);
|
||||||
const enabledDeptOptions = ref<DeptTreeVO[]>([]);
|
const enabledDeptOptions = ref<DeptTreeVO[]>([]);
|
||||||
@@ -528,7 +507,7 @@ const columns = ref<FieldOption[]>([
|
|||||||
{ key: 6, label: `创建时间`, visible: true, children: [] }
|
{ key: 6, label: `创建时间`, visible: true, children: [] }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const deptTreeRef = ref<ElTreeInstance>();
|
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
|
||||||
const queryFormRef = ref<ElFormInstance>();
|
const queryFormRef = ref<ElFormInstance>();
|
||||||
const userFormRef = ref<ElFormInstance>();
|
const userFormRef = ref<ElFormInstance>();
|
||||||
const uploadRef = ref<ElUploadInstance>();
|
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 { 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 () => {
|
const getList = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
@@ -669,7 +633,7 @@ const resetQuery = () => {
|
|||||||
queryFormRef.value?.resetFields();
|
queryFormRef.value?.resetFields();
|
||||||
queryParams.value.pageNum = 1;
|
queryParams.value.pageNum = 1;
|
||||||
queryParams.value.deptId = undefined;
|
queryParams.value.deptId = undefined;
|
||||||
deptTreeRef.value?.setCurrentKey(undefined);
|
treePanelRef.value?.setCurrentKey(undefined);
|
||||||
handleQuery();
|
handleQuery();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,36 +2,16 @@
|
|||||||
<div class="p-2 app-container workflow-process-definition-page">
|
<div class="p-2 app-container workflow-process-definition-page">
|
||||||
<el-row :gutter="20" class="content-grid">
|
<el-row :gutter="20" class="content-grid">
|
||||||
<!-- 流程分类树 -->
|
<!-- 流程分类树 -->
|
||||||
<el-col :lg="treeCollapsed ? 1 : 4" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
|
<tree-panel
|
||||||
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
|
ref="treePanelRef"
|
||||||
<template #header>
|
v-model:collapsed="treeCollapsed"
|
||||||
<div
|
title="流程分类"
|
||||||
class="panel-heading search-panel-toggle tree-panel-header"
|
placeholder="请输入流程分类名"
|
||||||
:class="{ 'is-collapsed': treeCollapsed }"
|
:data="categoryOptions"
|
||||||
@click.stop="treeCollapsed = !treeCollapsed"
|
:expanded-span="4"
|
||||||
>
|
filter-field="categoryName"
|
||||||
<div v-show="!treeCollapsed" class="table-heading">
|
@node-click="handleNodeClick"
|
||||||
<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>
|
|
||||||
<el-col
|
<el-col
|
||||||
:lg="treeCollapsed ? 23 : 20"
|
:lg="treeCollapsed ? 23 : 20"
|
||||||
:xs="24"
|
:xs="24"
|
||||||
@@ -344,6 +324,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="processDefinition" lang="ts">
|
<script setup name="processDefinition" lang="ts">
|
||||||
|
import TreePanel from '@/components/TreePanel/index.vue';
|
||||||
import {
|
import {
|
||||||
listDefinition,
|
listDefinition,
|
||||||
deleteDefinition,
|
deleteDefinition,
|
||||||
@@ -364,7 +345,7 @@ import type { ElMessageBoxOptions, TabsPaneContext, UploadRequestOptions } from
|
|||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
const queryFormRef = ref<ElFormInstance>();
|
const queryFormRef = ref<ElFormInstance>();
|
||||||
const categoryTreeRef = ref<ElTreeInstance>();
|
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
|
||||||
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const ids = ref<Array<any>>([]);
|
const ids = ref<Array<any>>([]);
|
||||||
@@ -376,7 +357,6 @@ const total = ref(0);
|
|||||||
const uploadDialogLoading = ref(false);
|
const uploadDialogLoading = ref(false);
|
||||||
const processDefinitionList = ref<FlowDefinitionVo[]>([]);
|
const processDefinitionList = ref<FlowDefinitionVo[]>([]);
|
||||||
const categoryOptions = ref<CategoryTreeVO[]>([]);
|
const categoryOptions = ref<CategoryTreeVO[]>([]);
|
||||||
const categoryName = ref('');
|
|
||||||
const treeCollapsed = ref(false);
|
const treeCollapsed = ref(false);
|
||||||
const autoPass = ref(false);
|
const autoPass = ref(false);
|
||||||
/** 部署文件分类选择 */
|
/** 部署文件分类选择 */
|
||||||
@@ -442,21 +422,6 @@ const handleNodeClick = (data: CategoryTreeVO) => {
|
|||||||
}
|
}
|
||||||
handleQuery();
|
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 getTreeselect = async () => {
|
||||||
const res = await categoryTree();
|
const res = await categoryTree();
|
||||||
|
|||||||
@@ -2,36 +2,16 @@
|
|||||||
<div class="p-2 app-container workflow-process-instance-page">
|
<div class="p-2 app-container workflow-process-instance-page">
|
||||||
<el-row :gutter="20" class="content-grid">
|
<el-row :gutter="20" class="content-grid">
|
||||||
<!-- 流程分类树 -->
|
<!-- 流程分类树 -->
|
||||||
<el-col :lg="treeCollapsed ? 1 : 4" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
|
<tree-panel
|
||||||
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
|
ref="treePanelRef"
|
||||||
<template #header>
|
v-model:collapsed="treeCollapsed"
|
||||||
<div
|
title="流程分类"
|
||||||
class="panel-heading search-panel-toggle tree-panel-header"
|
placeholder="请输入流程分类名"
|
||||||
:class="{ 'is-collapsed': treeCollapsed }"
|
:data="categoryOptions"
|
||||||
@click.stop="treeCollapsed = !treeCollapsed"
|
:expanded-span="4"
|
||||||
>
|
filter-field="categoryName"
|
||||||
<div v-show="!treeCollapsed" class="table-heading">
|
@node-click="handleNodeClick"
|
||||||
<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>
|
|
||||||
<el-col
|
<el-col
|
||||||
:lg="treeCollapsed ? 23 : 20"
|
:lg="treeCollapsed ? 23 : 20"
|
||||||
:xs="24"
|
:xs="24"
|
||||||
@@ -315,6 +295,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import TreePanel from '@/components/TreePanel/index.vue';
|
||||||
import {
|
import {
|
||||||
pageByRunning,
|
pageByRunning,
|
||||||
pageByFinish,
|
pageByFinish,
|
||||||
@@ -337,7 +318,7 @@ import { ElForm, FormInstance } from 'element-plus';
|
|||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
||||||
const queryFormRef = ref<ElFormInstance>();
|
const queryFormRef = ref<ElFormInstance>();
|
||||||
const categoryTreeRef = ref<ElTreeInstance>();
|
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { UserVO } from '@/api/system/user/types';
|
import { UserVO } from '@/api/system/user/types';
|
||||||
const form = ref<Record<string, any>>({
|
const form = ref<Record<string, any>>({
|
||||||
@@ -374,7 +355,6 @@ const processDefinitionName = ref();
|
|||||||
const processInstanceList = ref<FlowInstanceVO[]>([]);
|
const processInstanceList = ref<FlowInstanceVO[]>([]);
|
||||||
const processDefinitionHistoryList = ref<Array<any>>([]);
|
const processDefinitionHistoryList = ref<Array<any>>([]);
|
||||||
const categoryOptions = ref<CategoryOption[]>([]);
|
const categoryOptions = ref<CategoryOption[]>([]);
|
||||||
const categoryName = ref('');
|
|
||||||
const treeCollapsed = ref(false);
|
const treeCollapsed = ref(false);
|
||||||
|
|
||||||
const processDefinitionDialog = reactive<DialogOption>({
|
const processDefinitionDialog = reactive<DialogOption>({
|
||||||
@@ -415,21 +395,6 @@ const handleNodeClick = (data: CategoryTreeVO) => {
|
|||||||
}
|
}
|
||||||
handleQuery();
|
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 getTreeselect = async () => {
|
||||||
const res = await categoryTree();
|
const res = await categoryTree();
|
||||||
|
|||||||
@@ -2,36 +2,16 @@
|
|||||||
<div class="p-2 app-container workflow-my-document-page">
|
<div class="p-2 app-container workflow-my-document-page">
|
||||||
<el-row :gutter="20" class="content-grid">
|
<el-row :gutter="20" class="content-grid">
|
||||||
<!-- 流程分类树 -->
|
<!-- 流程分类树 -->
|
||||||
<el-col :lg="treeCollapsed ? 1 : 4" :xs="24" class="tree-panel-col" :class="{ 'is-collapsed': treeCollapsed }">
|
<tree-panel
|
||||||
<el-card shadow="hover" class="side-panel tree-panel-shell" :class="{ 'is-collapsed': treeCollapsed }">
|
ref="treePanelRef"
|
||||||
<template #header>
|
v-model:collapsed="treeCollapsed"
|
||||||
<div
|
title="流程分类"
|
||||||
class="panel-heading search-panel-toggle tree-panel-header"
|
placeholder="请输入流程分类名"
|
||||||
:class="{ 'is-collapsed': treeCollapsed }"
|
:data="categoryOptions"
|
||||||
@click.stop="treeCollapsed = !treeCollapsed"
|
:expanded-span="4"
|
||||||
>
|
filter-field="categoryName"
|
||||||
<div v-show="!treeCollapsed" class="table-heading">
|
@node-click="handleNodeClick"
|
||||||
<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>
|
|
||||||
<el-col
|
<el-col
|
||||||
:lg="treeCollapsed ? 23 : 20"
|
:lg="treeCollapsed ? 23 : 20"
|
||||||
:xs="24"
|
:xs="24"
|
||||||
@@ -169,6 +149,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import TreePanel from '@/components/TreePanel/index.vue';
|
||||||
import { pageByCurrent, deleteByInstanceIds, cancelProcessApply } from '@/api/workflow/instance';
|
import { pageByCurrent, deleteByInstanceIds, cancelProcessApply } from '@/api/workflow/instance';
|
||||||
import { categoryTree } from '@/api/workflow/category';
|
import { categoryTree } from '@/api/workflow/category';
|
||||||
import { CategoryTreeVO } from '@/api/workflow/category/types';
|
import { CategoryTreeVO } from '@/api/workflow/category/types';
|
||||||
@@ -178,7 +159,7 @@ import { RouterJumpVo } from '@/api/workflow/workflowCommon/types';
|
|||||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
||||||
const queryFormRef = ref<ElFormInstance>();
|
const queryFormRef = ref<ElFormInstance>();
|
||||||
const categoryTreeRef = ref<ElTreeInstance>();
|
const treePanelRef = ref<InstanceType<typeof TreePanel>>();
|
||||||
|
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
@@ -197,7 +178,6 @@ const total = ref(0);
|
|||||||
const processInstanceList = ref<FlowInstanceVO[]>([]);
|
const processInstanceList = ref<FlowInstanceVO[]>([]);
|
||||||
|
|
||||||
const categoryOptions = ref<CategoryTreeVO[]>([]);
|
const categoryOptions = ref<CategoryTreeVO[]>([]);
|
||||||
const categoryName = ref('');
|
|
||||||
const treeCollapsed = ref(false);
|
const treeCollapsed = ref(false);
|
||||||
|
|
||||||
const tab = ref('running');
|
const tab = ref('running');
|
||||||
@@ -222,21 +202,6 @@ const handleNodeClick = (data: CategoryTreeVO) => {
|
|||||||
}
|
}
|
||||||
handleQuery();
|
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 getTreeselect = async () => {
|
||||||
const res = await categoryTree();
|
const res = await categoryTree();
|
||||||
|
|||||||
Reference in New Issue
Block a user