211 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>