Merge pull request '😝优化报表分组,风格与机构分组一致' (#368) from KaneLeung/Admin.NET.Pro:v2 into v2

Reviewed-on: https://code.adminnet.top/Admin.NET/Admin.NET.Pro/pulls/368
This commit is contained in:
zuohuaijun 2025-07-07 16:53:46 +08:00
commit 57db9373ae

View File

@ -1,47 +1,70 @@
<template> <template>
<div class="group-panel" v-loading="state.isLoading"> <el-card class="box-card" shadow="hover" body-style="height:100%;overflow:auto;padding:5px;width:100%;" v-loading="state.isLoading">
<el-button-group class="group-panel-buttonGroup"> <template #header>
<el-button icon="ele-CirclePlus" size="small" @click="createFormShow">{{ $t('新增分组') }}</el-button> <div class="card-header">
<el-dropdown split-button @command="handleCommand" size="small" :icon="Delete" @click="editFormShow"> <div class="tree-h-flex">
{{ $t('编辑分组') }} <div class="tree-h-left">
<template v-slot:dropdown> <el-input :prefix-icon="Search" v-model.lazy="filterText" clearable :placeholder="$t('查询')" />
<el-dropdown-menu> </div>
<el-dropdown-item command="del" :icon="Delete">{{ $t('删除分组') }}</el-dropdown-item> <div class="tree-h-right">
<el-dropdown-item command="refresh" :icon="RefreshRight">{{ $t('刷新分组') }}</el-dropdown-item> <el-dropdown @command="handleCommand">
</el-dropdown-menu> <el-button style="margin-left: 8px; width: 34px">
</template> <el-icon class="el-icon--center">
</el-dropdown> <more-filled />
</el-button-group> </el-icon>
<el-card :loading="true" class="group-panel-tree" shadow="never"> </el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="expandAll">{{ $t('message.list.allExpand') }}</el-dropdown-item>
<el-dropdown-item command="collapseAll">{{ $t('message.list.allFold') }}</el-dropdown-item>
<el-dropdown-item command="create">{{ $t('新增分组') }}</el-dropdown-item>
<el-dropdown-item command="edit">{{ $t('编辑分组') }}</el-dropdown-item>
<el-dropdown-item command="delete">{{ $t('删除分组') }}</el-dropdown-item>
<el-dropdown-item command="refresh">{{ $t('message.list.refresh') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</div>
</template>
<div style="margin-bottom: 45px" v-loading="state.loading">
<el-scrollbar> <el-scrollbar>
<div v-if="state.groupTree"> <el-tree
<el-tree v-if="state.treeData"
ref="groupTree" ref="treeRef"
:data="state.groupTree" class="filter-tree"
:props="state.defaultProps" :data="state.treeData"
:default-expand-all="true" node-key="id"
:expand-on-click-node="false" :props="{ children: 'children', label: 'label' }"
:highlight-current="true" :filter-node-method="filterNode"
@node-click="(group: SysReportGroup) => emit('nodeClick', group)" @node-click="(group: SysReportGroup) => emit('nodeClick', group)"
/> :default-expanded-keys="state.treeData[0] && [state.treeData[0].id]"
</div> highlight-current
<div v-else> >
<el-empty /> <template #default="{ node }">
</div> <el-icon v-if="node.level == 1" size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-School /></el-icon>
<el-icon v-else-if="node.level == 2" size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-Refrigerator /></el-icon>
<el-icon v-else size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-CollectionTag /></el-icon>
<highLightKeyword v-if="filterText" :text="node.label" :keyword="filterText" />
<span v-else>{{ node.label }}</span>
</template>
</el-tree>
<el-empty v-else :image-size="100" />
</el-scrollbar> </el-scrollbar>
</el-card> </div>
</el-card>
<EditReportGroup ref="editReportGroup" :title="state.title" @handleQuery="handleQuery"></EditReportGroup> <EditReportGroup ref="editReportGroup" :title="state.title" @handleQuery="fetchTreeData"></EditReportGroup>
</div>
</template> </template>
<script setup lang="ts" name="sysReportGroup"> <script setup lang="ts" name="sysReportGroup">
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive, ref, watch } from 'vue';
import { ElMessage, ElMessageBox, ElTree } from 'element-plus'; import { ElMessage, ElMessageBox, ElTree } from 'element-plus';
import { Delete, RefreshRight } from '@element-plus/icons-vue'; import { Search, Delete, RefreshRight, MoreFilled } from '@element-plus/icons-vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import EditReportGroup from './editReportGroup.vue'; import EditReportGroup from './editReportGroup.vue';
import highLightKeyword from '/@/components/highLightKeyword/index.vue';
import { getAPI } from '/@/utils/axios-utils'; import { getAPI } from '/@/utils/axios-utils';
import { SysReportGroup, SysReportGroupApi } from '/@/api-services'; import { SysReportGroup, SysReportGroupApi } from '/@/api-services';
@ -51,25 +74,23 @@ const { t } = useI18n();
// / // /
const emit = defineEmits(['nodeClick']); const emit = defineEmits(['nodeClick']);
const groupTree = ref<InstanceType<typeof ElTree>>(); const treeRef = ref<InstanceType<typeof ElTree>>();
const editReportGroup = ref<InstanceType<typeof EditReportGroup>>(); const editReportGroup = ref<InstanceType<typeof EditReportGroup>>();
const filterText = ref('');
const state = reactive({ const state = reactive({
/** 是否加载中 */ isLoading: false, //
isLoading: false,
title: '', title: '',
groupTree: [], treeData: [],
defaultProps: {
children: 'children',
label: 'label',
},
}); });
//
onMounted(() => { onMounted(() => {
getGroupTree(); fetchTreeData();
}); });
const getGroupTree = () => { //
const fetchTreeData = () => {
state.isLoading = true; state.isLoading = true;
getAPI(SysReportGroupApi) getAPI(SysReportGroupApi)
.apiSysReportGroupListGet() .apiSysReportGroupListGet()
@ -77,13 +98,14 @@ const getGroupTree = () => {
getTree(res.data.result ?? []); getTree(res.data.result ?? []);
let rootGroup = [{ id: 0, label: t('全部'), value: 0, children: [] }]; let rootGroup = [{ id: 0, label: t('全部'), value: 0, children: [] }];
rootGroup[0].children = res.data.result as []; rootGroup[0].children = res.data.result as [];
state.groupTree = rootGroup as []; state.treeData = rootGroup as [];
}) })
.finally(() => { .finally(() => {
state.isLoading = false; state.isLoading = false;
}); });
}; };
//
const getTree = (tree: SysReportGroup[]): [] => { const getTree = (tree: SysReportGroup[]): [] => {
tree.forEach((r: any) => { tree.forEach((r: any) => {
r.label = `${r.number}[${r.name}]`; r.label = `${r.number}[${r.name}]`;
@ -92,85 +114,90 @@ const getTree = (tree: SysReportGroup[]): [] => {
return []; return [];
}; };
const handleCommand = (cmd: string) => { //
switch (cmd) { watch(filterText, (val) => {
// treeRef.value!.filter(val);
case 'refresh': });
getGroupTree();
break; //
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.label.includes(value);
};
//
const handleCommand = async (command: string | number | object) => {
if ('expandAll' == command) {
//
for (let i = 0; i < treeRef.value!.store._getAllNodes().length; i++) {
treeRef.value!.store._getAllNodes()[i].expanded = true;
}
} else if ('collapseAll' == command) {
//
for (let i = 0; i < treeRef.value!.store._getAllNodes().length; i++) {
treeRef.value!.store._getAllNodes()[i].expanded = false;
}
} else if ('create' == command) {
//
state.title = t('新增分组');
editReportGroup.value?.openDialog({});
} else if ('edit' == command) {
//
const currData = treeRef.value!.getCurrentNode();
if (!currData) {
ElMessage.error(t('请选择分组后编辑'));
return;
}
if (currData.id == 0) {
ElMessage.error(t('请选择有效的分组节点'));
return;
}
state.title = t('编辑分组');
editReportGroup.value?.openDialog(currData);
} else if ('delete' == command) {
// //
case 'del': const currData = treeRef.value!.getCurrentNode();
const currData = groupTree.value!.getCurrentNode(); if (currData.id == 0) {
if (currData) { ElMessage.error(t('请选择有效的分组节点'));
reportGroupDelete(currData.id, currData.label); return;
} }
break; ElMessageBox.confirm(t('确认删除?', { label: currData.label }), t('提示'), {
confirmButtonText: t('确定'),
cancelButtonText: t('取消'),
type: 'warning',
}).then(() => {
getAPI(SysReportGroupApi)
.apiSysReportGroupDeletePost({ id: recordId })
.then((res) => {
ElMessage.success(t('删除成功'));
fetchTreeData();
});
});
} else if ('refresh' == command) {
//
fetchTreeData();
} }
}; };
const createFormShow = () => {
state.title = t('新增分组');
editReportGroup.value?.openDialog({});
};
const editFormShow = () => {
const currData = groupTree.value!.getCurrentNode();
if (!currData) {
ElMessage.error(t('请选择分组后编辑'));
return;
}
if (currData.id == 0) {
ElMessage.error(t('请选择有效的分组节点'));
return;
}
state.title = t('编辑分组');
editReportGroup.value?.openDialog(currData);
};
const reportGroupDelete = (recordId: number, label: string) => {
if (recordId == 0) {
ElMessage.error(t('请选择有效的分组节点'));
return;
}
ElMessageBox.confirm(t('确认删除?', { label: label }), t('提示'), {
confirmButtonText: t('确定'),
cancelButtonText: t('取消'),
type: 'warning',
}).then(() => {
getAPI(SysReportGroupApi)
.apiSysReportGroupDeletePost({ id: recordId })
.then((res) => {
ElMessage.success(t('删除成功'));
getGroupTree();
});
});
};
const handleQuery = () => {
getGroupTree();
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.group-panel { .box-card {
background-color: var(--el-fill-color-blank); flex: 1;
display: flex; > :deep(.el-card__header) {
flex-direction: column; padding: 5px;
height: 100%;
.group-panel-buttonGroup {
width: 100%;
padding: 5px 0 10px 0;
}
.group-panel-tree {
flex: 1;
:deep(.el-card__body) {
padding: 0px;
height: 100%;
}
} }
} }
.tree-h-flex {
display: flex;
}
.tree-h-left {
flex: 1;
width: 100%;
}
.tree-h-right {
width: 42px;
min-width: 42px;
}
</style> </style>