5 changed files with 396 additions and 7 deletions
@ -0,0 +1,344 @@ |
|||||
|
<!-- |
||||
|
@ 作者: han2015 |
||||
|
@ 时间: 2025-05-12 15:39:13 |
||||
|
@ 备注: 文档管理组件 |
||||
|
--> |
||||
|
<script lang="ts" setup> |
||||
|
import { useUserStore } from "@/store/modules/user"; |
||||
|
import { getMatterList,getMySpaces} from "@/api/doc/index" |
||||
|
import { matterPage,matterInfo,matterTree,matterPermit} from "@/api/doc/type" |
||||
|
import Space from "./space.vue"; |
||||
|
import {ElSelect,ElOption, ElText,ElInput,ElTree,TreeNode,ElDropdown,ElDropdownItem} from "element-plus"; |
||||
|
import { doAccessManage,getSpaceMatterList,doCreateSpaceDir,doDelSpaceMatter, |
||||
|
doAiTraining,doAiDocDels,spaceMatterRename} from "@/api/doc/space" |
||||
|
|
||||
|
//定义事件 |
||||
|
defineProps({ |
||||
|
modelValue: String // 接收父组件的值 |
||||
|
}) |
||||
|
const emit = defineEmits(['update:modelValue']) |
||||
|
|
||||
|
const userStore = useUserStore(); |
||||
|
const uid=btoa("p0"+userStore.userInfoCont.userId); |
||||
|
const rawUid="p0"+userStore.userInfoCont.userId |
||||
|
|
||||
|
const matterList = ref<matterInfo[]>([]) |
||||
|
const treeData=ref<matterTree[]>([])//{name:'个人空间',uuid:'root',children:[]} |
||||
|
const currentNode=ref<matterTree>({}) //打开的路径层次 |
||||
|
const paginInfo = ref({ page: 0, total: 0 }) |
||||
|
|
||||
|
const SpaceID= ref<{name:string,uuid:string,userUuid:string,manager:boolean,permits:matterPermit}>({}) //当前space的id |
||||
|
const spaceEleRef = ref() //space组件的引用,它与spaceTreeRef没有父子关系,反而是为了处理spaceTree的操作而创建的该变量 |
||||
|
const spaceTreeRef = ref(); //space的树组件的引用 |
||||
|
let spaceNodeUid="" //用来判断树组件的展开和关闭,如何只是展开和关闭的点击事件不在刷新,通currentNode的作用 |
||||
|
let isNewSpaceNode=true //用来减少父组件树的重置 |
||||
|
const spaceCutLevelPermit=ref(0) |
||||
|
|
||||
|
const Departs = computed(() => { |
||||
|
return `${'p0'+userStore.userInfoCont.userId},${userStore.userInfoCont.company},${userStore.userInfoCont.department},${userStore.userInfoCont.organization}` |
||||
|
}) |
||||
|
|
||||
|
enum PERMITS { |
||||
|
FORBID, //0 |
||||
|
VIEW, //1 |
||||
|
DOWNLOAD, //2 |
||||
|
UPLOAD, //3 |
||||
|
UPANDDOWNLOAD, //4 |
||||
|
EDIT, //5 |
||||
|
MANAGER, //6 |
||||
|
} |
||||
|
|
||||
|
//加载目录文件列表 |
||||
|
function onLoadMatterList(){ |
||||
|
emit('update:modelValue', currentNode.value.uuid) |
||||
|
let _page: matterPage = { |
||||
|
page: paginInfo.value.page, |
||||
|
pageSize: 50, |
||||
|
orderCreateTime: "DESC", |
||||
|
orderDir: "DESC", |
||||
|
dir:"true", |
||||
|
puuid:currentNode.value.uuid, |
||||
|
deleted:false |
||||
|
}; |
||||
|
|
||||
|
getMatterList(uid,_page).then((resp)=>{ |
||||
|
//page+1 是由于分页的起始index是1,而后端api的分页index起始是0 |
||||
|
paginInfo.value={total:resp.data.totalPages,page:resp.data.page} |
||||
|
matterList.value=resp.data.data |
||||
|
}) |
||||
|
} |
||||
|
//树节点展开 |
||||
|
function onNodeExpand(node: TreeNode, resolve: (data: matterTree[]) => void, reject: () => void) { |
||||
|
let cuuid ="root" |
||||
|
if ((node.data as matterTree).uuid) { |
||||
|
cuuid= (node.data as matterTree).uuid |
||||
|
currentNode.value = node.data |
||||
|
} |
||||
|
|
||||
|
let _page: matterPage = { |
||||
|
page: 0, |
||||
|
pageSize: 50, |
||||
|
orderCreateTime: "DESC", |
||||
|
orderDir: "DESC", |
||||
|
dir:"true", |
||||
|
puuid: cuuid, |
||||
|
deleted: false |
||||
|
}; |
||||
|
|
||||
|
getMatterList(uid, _page).then((resp) => { |
||||
|
let node_data = resp.data.data.filter((item) => { |
||||
|
return item.dir |
||||
|
}).map((val) => { |
||||
|
const copy = structuredClone(val) |
||||
|
copy.dir = !copy.dir |
||||
|
return copy |
||||
|
}) |
||||
|
|
||||
|
resolve(node_data) |
||||
|
}).catch(() => reject()) |
||||
|
emit('update:modelValue', currentNode.value.uuid) |
||||
|
} |
||||
|
//树节点单击 |
||||
|
function onNodeClick(data:matterTree,node:TreeNode,self:any,env:any){ |
||||
|
if (data){ |
||||
|
if (currentNode.value.uuid === data.uuid) return; |
||||
|
currentNode.value = data |
||||
|
}else{ |
||||
|
currentNode.value={uuid:"root",name:"个人空间"} |
||||
|
} |
||||
|
onLoadMatterList() |
||||
|
} |
||||
|
|
||||
|
//-------------------space feature--------------------- |
||||
|
function onSpaceNodeClick(data:matterTree,node:TreeNode,self:any,env:any){ |
||||
|
//如果在单个组件上重复点击,不在刷新请求 |
||||
|
if(spaceNodeUid==data.uuid) return; |
||||
|
spaceNodeUid=data.uuid |
||||
|
|
||||
|
if(data.uuid.startsWith("s0") && data.uuid!=SpaceID.value.uuid){ //切换空间 |
||||
|
currentNode.value={uuid:"root",name:data.name}//切换空间就要重置currentNode |
||||
|
SpaceID.value={ |
||||
|
name: data.name ?? "", |
||||
|
uuid: data.uuid ?? "", |
||||
|
userUuid: data.userUuid ?? "", |
||||
|
manager: data.manager ?? false, |
||||
|
permits:data.permits ?? { id: 0, MatterUuid: '', data: '{}' } |
||||
|
}; |
||||
|
onSpaceMatterList() |
||||
|
}else{ |
||||
|
let matter= { |
||||
|
uuid:data.uuid==SpaceID.value.uuid?"root":data.uuid, |
||||
|
puuid: data.puuid, |
||||
|
name:data.name, |
||||
|
agent:data.agent, |
||||
|
dir:true, |
||||
|
permits:data.permits, |
||||
|
path:data.path, |
||||
|
permitVal:data.permitVal |
||||
|
} |
||||
|
//打开具体的节点 |
||||
|
handleSpaceDoubleClick(matter) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function flushSpaceTree(uuid:string,data:matterTree[]){ |
||||
|
if(uuid==="root") uuid=SpaceID.value.uuid |
||||
|
spaceTreeRef.value.updateKeyChildren(uuid,data) |
||||
|
} |
||||
|
|
||||
|
function handleSpaceDoubleClick(row:matterInfo,ind?:number){ |
||||
|
if(row.dir){ |
||||
|
//设置当前文件夹的权限等级 |
||||
|
if(row.permitVal){ |
||||
|
spaceCutLevelPermit.value=row.permitVal |
||||
|
}else{ |
||||
|
if (SpaceID.value.manager) { |
||||
|
spaceCutLevelPermit.value=9 |
||||
|
}else{ |
||||
|
let _pert: Record<string, number> |
||||
|
_pert = JSON.parse(row.permits!.data) |
||||
|
let val=_pert[rawUid.replace("p0","")] |
||||
|
if(val){ |
||||
|
spaceCutLevelPermit.value = val |
||||
|
}else{ |
||||
|
spaceCutLevelPermit.value = PERMITS.FORBID //没有权限!! |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
isNewSpaceNode=true |
||||
|
//1:如果是当前目录的父组件没必要更新目录树 |
||||
|
//2: 如果当前目录是当前空间根目录,没必要更新目录树 |
||||
|
if(currentNode.value.puuid==row.uuid || row.uuid=="root") isNewSpaceNode=false |
||||
|
currentNode.value=row |
||||
|
onSpaceMatterList() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//加载目录文件列表 |
||||
|
function onSpaceMatterList(){ |
||||
|
emit('update:modelValue', currentNode.value.uuid) |
||||
|
let _page: matterPage= { |
||||
|
page: paginInfo.value.page, |
||||
|
pageSize: 50, |
||||
|
orderCreateTime: "DESC", |
||||
|
orderDir: "DESC", |
||||
|
puuid:currentNode.value.uuid, |
||||
|
dir:"true", |
||||
|
deleted:false, |
||||
|
space:SpaceID.value.uuid, |
||||
|
}; |
||||
|
|
||||
|
getSpaceMatterList(uid,_page).then((resp)=>{ |
||||
|
if (SpaceID.value.manager) { |
||||
|
resp.data.data.forEach(item => { |
||||
|
item.permitVal=PERMITS.MANAGER |
||||
|
}) |
||||
|
matterList.value=resp.data.data |
||||
|
}else{ |
||||
|
matterList.value=resp.data.data.filter(item=>{ //具体的权限验证和过滤 |
||||
|
|
||||
|
if(item.permits.ID==0){ |
||||
|
item.permitVal=spaceCutLevelPermit.value |
||||
|
}else{ |
||||
|
//如果该文档有设定权限,解析该文档的具体权限 |
||||
|
let _pert: Record<string, number> |
||||
|
_pert = JSON.parse(item.permits!.data) |
||||
|
let val=_pert[rawUid.replace("p0","")] |
||||
|
if(val){ |
||||
|
item.permitVal = val |
||||
|
}else{ |
||||
|
item.permitVal = PERMITS.FORBID //没有权限!! |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if(item.permitVal>0){ |
||||
|
return true |
||||
|
} |
||||
|
|
||||
|
return false |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//展开的时候暂时不做目录更新,看以后的使用情况 |
||||
|
let node_data = matterList.value.filter(item=> { |
||||
|
return item.dir |
||||
|
}).map(val => { |
||||
|
const copy = structuredClone(toRaw(val)) |
||||
|
copy.dir = !copy.dir |
||||
|
copy.manager=SpaceID.value.manager |
||||
|
return copy |
||||
|
}) |
||||
|
|
||||
|
if(isNewSpaceNode) { |
||||
|
//由于支持目录树的原因,所有的空间根目录uuid都是root,这样树组件就有问题,所以用了spaceid作为其uuid |
||||
|
//但是云盘的根目录是root,所以当uuid是spaceid时,自动替换为root |
||||
|
if(currentNode.value.uuid=="root") flushSpaceTree(SpaceID.value.uuid,node_data); |
||||
|
else flushSpaceTree(currentNode.value.uuid,node_data); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
/////////////////////////////////////////////////////// |
||||
|
|
||||
|
|
||||
|
//渲染完页面再执行 |
||||
|
onMounted(async () => { |
||||
|
currentNode.value={uuid:"root",name:"个人空间"} |
||||
|
//加载我的空间列表 |
||||
|
await getMySpaces(uid,{roles:Departs.value}).then((resp)=>{ |
||||
|
resp.data.forEach((item)=>{ |
||||
|
let ismanager=false |
||||
|
if(item.userUuid==rawUid || item.managers.includes(rawUid)) ismanager=true; |
||||
|
spaceTreeRef.value.append({name:item.name,uuid:item.uuid,dir:false,userUuid:item.userUuid,manager:ismanager,permits:item.permits}) |
||||
|
}) |
||||
|
}) |
||||
|
emit('update:modelValue', currentNode.value.uuid) |
||||
|
}); |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<p> <span style="font-size:20px;font-weight: bold;">请选择目标节点:</span> 当前节点 > {{ currentNode.name }}</p> |
||||
|
<div class="menus_tree"> |
||||
|
<div class="area_header"> |
||||
|
<el-icon :size="20"><House /></el-icon><span class="area_name" > 个人空间</span> |
||||
|
</div> |
||||
|
<el-tree |
||||
|
ref="treeRef" |
||||
|
style="max-width: 600px" |
||||
|
:data="treeData" |
||||
|
node-key="uuid" |
||||
|
highlight-current |
||||
|
lazy |
||||
|
:load="onNodeExpand" |
||||
|
:props="{label: 'name',children:'children',isLeaf:'dir'}" |
||||
|
:default-expanded-keys="['root']" |
||||
|
@node-click="onNodeClick" |
||||
|
> |
||||
|
<template #default="{ node, data }"> |
||||
|
<div class="tree-item"> |
||||
|
<span>{{ node.label }}</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-tree> |
||||
|
<div class="area_header"> |
||||
|
<el-icon :size="20"><Collection /></el-icon> <span class="area_name" > 共享空间</span> |
||||
|
</div> |
||||
|
<el-tree |
||||
|
ref="spaceTreeRef" |
||||
|
style="max-width: 600px" |
||||
|
node-key="uuid" |
||||
|
accordion |
||||
|
highlight-current |
||||
|
lazy |
||||
|
:props="{label: 'name',children:'children',isLeaf:'dir'}" |
||||
|
@node-click="onSpaceNodeClick" |
||||
|
> |
||||
|
<template #default="{ node, data }"> |
||||
|
<div class="tree-item"> |
||||
|
<span>{{ node.label}}</span> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-tree> |
||||
|
</div> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.menus_tree{ |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
height:550px; |
||||
|
overflow-y: scroll; |
||||
|
.el-tree{ |
||||
|
--el-color-primary-light-9:#6eb3f8; |
||||
|
--el-tree-node-hover-bg-color:#a1c7ee; |
||||
|
--el-tree-node-content-height:43px; |
||||
|
--el-tree-expand-icon-color:#4c4c4e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.area_header{ |
||||
|
display: flex; |
||||
|
margin-top: 9px; |
||||
|
padding: 5px 0; |
||||
|
background-color: white; |
||||
|
align-items: center; |
||||
|
.area_name{ |
||||
|
align-content: center; |
||||
|
margin-left: 8px; |
||||
|
color: #686854; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
</style> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.el-message-box__message{ |
||||
|
width: 100%; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue