mirror of
https://gitee.com/hhyykk/ipms-sjy-ui.git
synced 2025-06-20 15:22:00 +08:00
211 lines
5.1 KiB
Vue
211 lines
5.1 KiB
Vue
<template>
|
||
<div className="folder-header" v-if="folderList && folderList.length > 0">
|
||
<el-input v-model="folderName" class="!w-340px" clearable placeholder="请输入文件夹名称">
|
||
<template #prefix>
|
||
<Icon icon="ep:search" />
|
||
</template>
|
||
</el-input>
|
||
<el-space>
|
||
<el-button type="danger" plain @click="toggleExpandAll">
|
||
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
|
||
</el-button>
|
||
</el-space>
|
||
</div>
|
||
<div>
|
||
<el-tree
|
||
ref="treeRef"
|
||
v-if="refreshTable"
|
||
:load="folderLoading"
|
||
:data="folderList"
|
||
:expand-on-click-node="false"
|
||
:filter-node-method="filterNode"
|
||
:props="defaultProps"
|
||
:default-expand-all="isExpandAll"
|
||
highlight-current
|
||
node-key="id"
|
||
@node-click="handleNodeClick"
|
||
>
|
||
<template #default="{ node, data }">
|
||
<span class="custom-tree-node">
|
||
<span>{{ node.label }}</span>
|
||
<span class="btns" :class="{ show: data.id === curCategoryId }">
|
||
<el-button type="primary" size="small" plain @click="appendFolder(data.id)"
|
||
>新增</el-button
|
||
>
|
||
<el-button
|
||
style="margin-left: 8px"
|
||
type="warning"
|
||
size="small"
|
||
plain
|
||
@click="updateFolder(data.id)"
|
||
>修改</el-button
|
||
>
|
||
<el-button
|
||
:class="{ hidden: data.children !== undefined }"
|
||
style="margin-left: 8px"
|
||
type="danger"
|
||
size="small"
|
||
plain
|
||
@click="deleteFolder(data.id)"
|
||
>删除</el-button
|
||
>
|
||
</span>
|
||
</span>
|
||
</template>
|
||
<template #empty>
|
||
<el-button type="primary" plain @click="appendFolder(0)">新增文件夹</el-button>
|
||
</template>
|
||
</el-tree>
|
||
</div>
|
||
|
||
<!-- 表单弹窗:添加/修改 -->
|
||
<CategoryForm ref="formRef" @success="getFolderList" />
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ElTree } from 'element-plus'
|
||
import { defaultProps, handleTree } from '@/utils/tree'
|
||
import { CategoryApi, CategoryVO } from '@/api/infra/category'
|
||
import CategoryForm from './CategoryForm.vue'
|
||
import download from '@/utils/download'
|
||
|
||
defineOptions({ name: 'CategoryFolderTree' })
|
||
const emits = defineEmits(['node-click'])
|
||
|
||
const { t } = useI18n() // 国际化
|
||
const message = useMessage() // 消息弹窗
|
||
|
||
const folderLoading = ref(false)
|
||
const folderName = ref('')
|
||
const folderList = ref<Tree[]>([])
|
||
const refreshTable = ref(true) // 重新渲染表格状态
|
||
const exportLoading = ref(false) // 导出的加载中
|
||
const isExpandAll = ref(true) // 是否展开,默认全部展开
|
||
const curCategoryId = ref<number>()
|
||
|
||
const treeRef = ref<InstanceType<typeof ElTree>>()
|
||
const formRef = ref()
|
||
|
||
/** 查询文件夹列表 */
|
||
const getFolderList = async () => {
|
||
folderLoading.value = true
|
||
try {
|
||
const data = await CategoryApi.getCategoryList()
|
||
folderList.value = handleTree(data, 'id', 'parentId')
|
||
// 重载树
|
||
refreshTable.value = false
|
||
await nextTick()
|
||
refreshTable.value = true
|
||
} finally {
|
||
folderLoading.value = false
|
||
}
|
||
}
|
||
|
||
/** 处理部门被点击 */
|
||
const handleNodeClick = async (row: { [key: string]: any }) => {
|
||
curCategoryId.value = row.id
|
||
emits('node-click', row)
|
||
}
|
||
|
||
/** 基于名字过滤 */
|
||
const filterNode = (name: string, data: Tree) => {
|
||
if (!name) return true
|
||
return data.name.includes(name)
|
||
}
|
||
|
||
/** 监听过滤项 */
|
||
watch(folderName, (val) => {
|
||
treeRef.value!.filter(val)
|
||
})
|
||
|
||
/** 新增文件夹 */
|
||
const appendFolder = (id: number) => {
|
||
formRef.value.open('create', id)
|
||
}
|
||
|
||
/** 修改文件夹 */
|
||
const updateFolder = (id: number) => {
|
||
formRef.value.open('update', id)
|
||
}
|
||
|
||
/** 删除文件夹 */
|
||
const deleteFolder = async (id: number) => {
|
||
try {
|
||
// 删除的二次确认
|
||
await message.delConfirm()
|
||
// 发起删除
|
||
await CategoryApi.deleteCategory(id)
|
||
message.success(t('common.delSuccess'))
|
||
// 刷新列表
|
||
getFolderList()
|
||
} catch {}
|
||
}
|
||
|
||
/** 导出按钮操作 */
|
||
const handleExport = async () => {
|
||
try {
|
||
// 导出的二次确认
|
||
await message.exportConfirm()
|
||
// 发起导出
|
||
exportLoading.value = true
|
||
const data = await CategoryApi.exportCategory()
|
||
download.excel(data, '文件目录.xls')
|
||
} catch {
|
||
} finally {
|
||
exportLoading.value = false
|
||
}
|
||
}
|
||
|
||
/** 展开/折叠操作 */
|
||
const toggleExpandAll = async () => {
|
||
refreshTable.value = false
|
||
isExpandAll.value = !isExpandAll.value
|
||
await nextTick()
|
||
refreshTable.value = true
|
||
}
|
||
|
||
// invoke
|
||
getFolderList()
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.folder-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.custom-tree-node {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
font-size: 14px;
|
||
padding-right: 8px;
|
||
}
|
||
|
||
.hidden {
|
||
visibility: hidden;
|
||
}
|
||
|
||
.show {
|
||
visibility: visible !important;
|
||
}
|
||
|
||
:deep(.el-tree-node__children) {
|
||
margin-top: 7px;
|
||
}
|
||
|
||
:deep(.el-tree-node__content) {
|
||
.btns {
|
||
visibility: hidden;
|
||
}
|
||
|
||
&:hover {
|
||
.btns {
|
||
visibility: visible;
|
||
}
|
||
}
|
||
}
|
||
</style>
|