mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 10:12:51 +00:00
This commit is contained in:
parent
449aa63f85
commit
de22ffabc1
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
:title="$t('components.folder.addFolder')"
|
||||
:title="title"
|
||||
v-model="dialogVisible"
|
||||
width="720"
|
||||
append-to-body
|
||||
|
|
@ -54,11 +54,19 @@ import { MsgSuccess, MsgAlert } from '@/utils/message'
|
|||
import { t } from '@/locales'
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: t('components.folder.addFolder'),
|
||||
},
|
||||
})
|
||||
|
||||
const FolderFormRef = ref()
|
||||
|
||||
const loading = ref(false)
|
||||
const dialogVisible = ref<boolean>(false)
|
||||
const sourceType = ref<any>('')
|
||||
const isEdit = ref<boolean>(false)
|
||||
|
||||
const folderForm = ref<any>({
|
||||
name: '',
|
||||
|
|
@ -84,23 +92,37 @@ watch(dialogVisible, (bool) => {
|
|||
desc: '',
|
||||
parent_id: '',
|
||||
}
|
||||
isEdit.value = false
|
||||
}
|
||||
})
|
||||
|
||||
const open = (source: string, id: string) => {
|
||||
const open = (source: string, id: string, data?: any) => {
|
||||
sourceType.value = source
|
||||
folderForm.value.parent_id = id
|
||||
if (data) {
|
||||
folderForm.value.name = data.name
|
||||
folderForm.value.desc = data.desc
|
||||
isEdit.value = true
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
const submitHandle = async () => {
|
||||
await FolderFormRef.value.validate((valid: any) => {
|
||||
if (valid) {
|
||||
folderApi.postFolder( sourceType.value, folderForm.value, loading).then((res) => {
|
||||
MsgSuccess(t('common.createSuccess'))
|
||||
emit('refresh')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
if (isEdit.value) {
|
||||
folderApi.putFolder(sourceType.value, folderForm.value, loading).then((res) => {
|
||||
MsgSuccess(t('common.editSuccess'))
|
||||
emit('refresh')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
} else {
|
||||
folderApi.postFolder(sourceType.value, folderForm.value, loading).then((res) => {
|
||||
MsgSuccess(t('common.createSuccess'))
|
||||
emit('refresh')
|
||||
dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="folder-tree">
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
:placeholder="$t('common.search')"
|
||||
|
|
@ -28,19 +28,54 @@
|
|||
node-key="id"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<div class="custom-tree-node flex align-center">
|
||||
<AppIcon iconName="app-folder" style="font-size: 16px"></AppIcon>
|
||||
<span class="ml-8">{{ node.label }}</span>
|
||||
<div class="flex-between w-full" @mouseenter.stop="handleMouseEnter(data)">
|
||||
<div class="flex align-center">
|
||||
<AppIcon iconName="app-folder" style="font-size: 16px"></AppIcon>
|
||||
<span class="ml-8">{{ node.label }}</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
@click.stop
|
||||
v-show="hoverNodeId === data.id"
|
||||
@mouseenter.stop="handleMouseEnter(data)"
|
||||
@mouseleave.stop="handleMouseleave"
|
||||
class="mr-16"
|
||||
>
|
||||
<el-dropdown trigger="click" :teleported="false">
|
||||
<el-button text class="w-full">
|
||||
<el-icon class="rotate-90"><MoreFilled /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click.stop="openCreateFolder(data)">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
{{ '添加子文件夹' }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.stop="openEditFolder(data)">
|
||||
<el-icon><EditPen /></el-icon>
|
||||
{{ $t('common.edit') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided @click.stop="deleteFolder(data)">
|
||||
<el-icon><Delete /></el-icon>
|
||||
{{ $t('common.delete') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
<CreateFolderDialog ref="CreateFolderDialogRef" @refresh="refreshFolder" :title="title" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import type { TreeInstance } from 'element-plus'
|
||||
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
|
||||
import { t } from '@/locales'
|
||||
import folderApi from '@/api/folder'
|
||||
defineOptions({ name: 'FolderTree' })
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
|
@ -51,6 +86,10 @@ const props = defineProps({
|
|||
type: String,
|
||||
default: 'root',
|
||||
},
|
||||
source: {
|
||||
type: String,
|
||||
default: 'APPLICATION',
|
||||
},
|
||||
isShared: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
|
|
@ -68,6 +107,7 @@ interface Tree {
|
|||
name: string
|
||||
children?: Tree[]
|
||||
id?: string
|
||||
show?: boolean
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
|
|
@ -75,15 +115,23 @@ const defaultProps = {
|
|||
label: 'name',
|
||||
}
|
||||
|
||||
const emit = defineEmits(['handleNodeClick'])
|
||||
const emit = defineEmits(['handleNodeClick', 'refreshTree'])
|
||||
|
||||
const treeRef = ref<TreeInstance>()
|
||||
const filterText = ref('')
|
||||
const hoverNodeId = ref<string | undefined>('')
|
||||
const title = ref('')
|
||||
|
||||
watch(filterText, (val) => {
|
||||
treeRef.value!.filter(val)
|
||||
})
|
||||
|
||||
function handleMouseEnter(data: Tree) {
|
||||
hoverNodeId.value = data.id
|
||||
}
|
||||
function handleMouseleave() {
|
||||
hoverNodeId.value = ''
|
||||
}
|
||||
const filterNode = (value: string, data: Tree) => {
|
||||
if (!value) return true
|
||||
return data.name.includes(value)
|
||||
|
|
@ -97,6 +145,26 @@ const handleSharedNodeClick = () => {
|
|||
treeRef.value?.setCurrentKey(undefined)
|
||||
emit('handleNodeClick', { id: 'share', name: t(props.shareTitle) })
|
||||
}
|
||||
|
||||
function deleteFolder(row: Tree) {
|
||||
folderApi.delFolder(row.id as string, props.source).then(() => {
|
||||
emit('refreshTree')
|
||||
})
|
||||
}
|
||||
|
||||
const CreateFolderDialogRef = ref()
|
||||
function openCreateFolder(row: Tree) {
|
||||
title.value = '添加子文件夹'
|
||||
CreateFolderDialogRef.value.open(props.source, row.id)
|
||||
}
|
||||
function openEditFolder(row: Tree) {
|
||||
title.value = '编辑文件夹'
|
||||
CreateFolderDialogRef.value.open(props.source, row.id, row)
|
||||
}
|
||||
|
||||
function refreshFolder() {
|
||||
emit('refreshTree')
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.shared-knowledge {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
export enum DeviceType {
|
||||
Mobile = 'Mobile',
|
||||
Desktop = 'Desktop'
|
||||
Desktop = 'Desktop',
|
||||
}
|
||||
|
||||
export enum ValidType {
|
||||
Application = 'application',
|
||||
Knowledge = 'knowledge',
|
||||
User = 'user'
|
||||
User = 'user',
|
||||
}
|
||||
|
||||
export enum ValidCount {
|
||||
Application = 5,
|
||||
Knowledge = 50,
|
||||
User = 2
|
||||
User = 2,
|
||||
}
|
||||
|
||||
export enum FolderSource {
|
||||
KNOWLEDGE = 'KNOWLEDGE',
|
||||
APPLICATION = 'APPLICATION',
|
||||
TOOL = 'TOOL',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@
|
|||
>
|
||||
<template #default="{ row }">
|
||||
<div class="flex-between">
|
||||
<auto-tooltip :content="row.abstract">
|
||||
<span :title="row.abstract">
|
||||
{{ row.abstract }}
|
||||
</auto-tooltip>
|
||||
</span>
|
||||
<div @click.stop v-show="mouseId === row.id && row.id !== 'new'">
|
||||
<el-dropdown trigger="click" :teleported="false">
|
||||
<el-icon class="rotate-90 mt-4"><MoreFilled /></el-icon>
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
ref="treeRef"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<div class="custom-tree-node flex align-center lighter">
|
||||
<div class="flex align-center lighter">
|
||||
<img
|
||||
src="@/assets/fileType/file-icon.svg"
|
||||
alt=""
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
<template #left>
|
||||
<h4 class="p-16 pb-0">{{ $t('views.knowledge.title') }}</h4>
|
||||
<folder-tree
|
||||
:source="FolderSource.KNOWLEDGE"
|
||||
:data="folderList"
|
||||
:currentNodeKey="currentFolder?.id"
|
||||
@handleNodeClick="folderClickHandel"
|
||||
class="p-8"
|
||||
isShared
|
||||
@refreshTree="refreshFolder"
|
||||
/>
|
||||
</template>
|
||||
<SharedWorkspace v-if="currentFolder.id === 'share'"></SharedWorkspace>
|
||||
|
|
@ -44,8 +46,13 @@
|
|||
</el-select>
|
||||
</div>
|
||||
<el-dropdown trigger="click">
|
||||
<el-button type="primary" class="ml-8"
|
||||
v-hasPermission="[RoleConst.ADMIN.getWorkspaceRole,PermissionConst.KNOWLEDGE_CREATE.getWorkspacePermission]"
|
||||
<el-button
|
||||
type="primary"
|
||||
class="ml-8"
|
||||
v-hasPermission="[
|
||||
RoleConst.ADMIN.getWorkspaceRole,
|
||||
PermissionConst.KNOWLEDGE_CREATE.getWorkspacePermission,
|
||||
]"
|
||||
>
|
||||
{{ $t('common.create') }}
|
||||
<el-icon class="el-icon--right">
|
||||
|
|
@ -217,8 +224,13 @@
|
|||
<template #mouseEnter>
|
||||
<div @click.stop>
|
||||
<el-dropdown trigger="click">
|
||||
<el-button text @click.stop
|
||||
v-hasPermission="[RoleConst.ADMIN.getWorkspaceRole,PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermission]"
|
||||
<el-button
|
||||
text
|
||||
@click.stop
|
||||
v-hasPermission="[
|
||||
RoleConst.ADMIN.getWorkspaceRole,
|
||||
PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermission,
|
||||
]"
|
||||
>
|
||||
<el-icon>
|
||||
<MoreFilled />
|
||||
|
|
@ -297,6 +309,7 @@ import useStore from '@/stores'
|
|||
import { numberFormat } from '@/utils/common'
|
||||
import { t } from '@/locales'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { FolderSource } from '@/enums/common'
|
||||
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||
import { hasPermission } from '@/utils/permission/index'
|
||||
|
||||
|
|
@ -378,7 +391,7 @@ function getList() {
|
|||
|
||||
function getFolder() {
|
||||
const params = {}
|
||||
folder.asyncGetFolder('KNOWLEDGE', params, loading).then((res: any) => {
|
||||
folder.asyncGetFolder(FolderSource.KNOWLEDGE, params, loading).then((res: any) => {
|
||||
folderList.value = res.data
|
||||
currentFolder.value = res.data?.[0] || {}
|
||||
getList()
|
||||
|
|
@ -401,7 +414,7 @@ function clickFolder(item: any) {
|
|||
const CreateFolderDialogRef = ref()
|
||||
|
||||
function openCreateFolder() {
|
||||
CreateFolderDialogRef.value.open('KNOWLEDGE', currentFolder.value.parent_id)
|
||||
CreateFolderDialogRef.value.open(FolderSource.KNOWLEDGE, currentFolder.value.parent_id)
|
||||
}
|
||||
|
||||
const GenerateRelatedDialogRef = ref<InstanceType<typeof GenerateRelatedDialog>>()
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ const searchType = ref('title')
|
|||
|
||||
const handleClick = (e: MouseEvent, ele: any) => {
|
||||
e.preventDefault()
|
||||
document.querySelector(`${ele}`).scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||
document.querySelector(`${ele}`)?.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
ref="treeRef"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<div class="custom-tree-node flex align-center lighter">
|
||||
<div class="flex align-center lighter">
|
||||
<img
|
||||
src="@/assets/fileType/file-icon.svg"
|
||||
alt=""
|
||||
|
|
|
|||
Loading…
Reference in New Issue