|
|
|
@ -7,7 +7,7 @@ |
|
|
|
import { getExpirTime, getFileIcon, readableSize} from "./tools" |
|
|
|
import { useUserStore } from "@/store/modules/user"; |
|
|
|
import { getMatterList,postCreateDir,postDelMatter,postCreateShare,postMatterRename,postDelMatBatch} from "@/api/doc/index" |
|
|
|
import { matterPage,matterInfo,respCreateShare } from "@/api/doc/type" |
|
|
|
import { matterPage,matterInfo,respCreateShare,matterTree } from "@/api/doc/type" |
|
|
|
import { h } from 'vue' |
|
|
|
import { |
|
|
|
Delete, |
|
|
|
@ -18,7 +18,8 @@ import { |
|
|
|
Promotion, |
|
|
|
Folder, |
|
|
|
} from '@element-plus/icons-vue' |
|
|
|
import {ElSelect,ElOption, ElText,ElInput,TableInstance,ElMessage,UploadFile,UploadFiles,ElPagination} from "element-plus"; |
|
|
|
import {ElSelect,ElOption, ElText,ElInput,TableInstance,ElMessage,UploadFile,UploadFiles,ElPagination,ElTree,TreeInstance} from "element-plus"; |
|
|
|
import type { TreeNode } from 'element-plus/es/components/tree/src/tree.type' |
|
|
|
import { number } from "echarts"; |
|
|
|
|
|
|
|
//TODO: add file icons done! |
|
|
|
@ -41,12 +42,15 @@ const apiURL=import.meta.env.VITE_APP_BASE_API+"/hxpan/api" |
|
|
|
|
|
|
|
const matterList = ref<matterInfo[]>([]) |
|
|
|
const searchname=ref("") |
|
|
|
const currentUuid=ref("root") //打开的路径层次 |
|
|
|
const newdir=ref("") |
|
|
|
const currentHoverRow=ref("") |
|
|
|
const breadcrumbList=ref<matterInfo[]>([{name:"根目录",uuid:"root", dir:true}]) //面包屑导航 |
|
|
|
const selectedValue = ref("sixhour") |
|
|
|
const tabSelected=ref<matterInfo[]>([]) |
|
|
|
//to support tree mode refactor |
|
|
|
const treeData=ref<matterTree[]>([{name:'root',uuid:'root',children:[]}]) |
|
|
|
const treeRef = ref(); |
|
|
|
const currentNode=ref<matterTree>({}) //打开的路径层次 |
|
|
|
|
|
|
|
const multipleTableRef = ref<TableInstance>() |
|
|
|
const paginInfo = ref({ page: 0, total: 0 }) |
|
|
|
const formHeaders=ref({ |
|
|
|
@ -55,7 +59,7 @@ const formHeaders=ref({ |
|
|
|
const uploadFormData = computed(() => { |
|
|
|
return { |
|
|
|
userUuid: uid, // 用户的uuid |
|
|
|
puuid: currentUuid.value, // 父目录的uuid,基目录为root |
|
|
|
puuid: currentNode.value.uuid, // 父目录的uuid,基目录为root |
|
|
|
} |
|
|
|
}); |
|
|
|
const fileList=ref([])//upload files |
|
|
|
@ -63,7 +67,7 @@ const fileList=ref([])//upload files |
|
|
|
//--------------单文件分享------------- |
|
|
|
function onShareMatter(row?:matterInfo){ |
|
|
|
ElMessageBox({ |
|
|
|
title: '请选择分享有效时间', |
|
|
|
title: row?.name+' 请选择分享有效时间', |
|
|
|
message: () => h(ElSelect, { |
|
|
|
defaultFirstOption:true, |
|
|
|
modelValue: selectedValue.value, |
|
|
|
@ -131,14 +135,22 @@ function showShareMessage(row:respCreateShare){ |
|
|
|
//删除 |
|
|
|
function onDelMatter(row:matterInfo){ |
|
|
|
if (row.uuid){ |
|
|
|
ElMessageBox.confirm("确认删除此数据项?删除后不可恢复!", "警告", { |
|
|
|
ElMessageBox.confirm(`确认删除( ${row.name}) ?删除后不可恢复!取消则放弃删除操作。`, "警告", { |
|
|
|
confirmButtonText: "确定", |
|
|
|
cancelButtonText: "取消", |
|
|
|
type: "warning", |
|
|
|
}).then(()=>{ |
|
|
|
postDelMatter(uid,{ |
|
|
|
"uuid":row.uuid |
|
|
|
}).then(()=>onLoadMatterList()) |
|
|
|
}).then(()=>{ |
|
|
|
if (row.dir) { |
|
|
|
currentNode.value.uuid = row.puuid ?? "" |
|
|
|
currentNode.value.name = row.path ? row.path.replace(`/${row.name}`,'').match(/[^/]+$/g)?.pop() :"上级目录" |
|
|
|
|
|
|
|
treeRef.value.remove(row.uuid) |
|
|
|
} |
|
|
|
onLoadMatterList() |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
@ -189,27 +201,42 @@ function onMatterRename(row:matterInfo){ |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//加载文件列表 |
|
|
|
function onLoadMatterList(name?:string){ |
|
|
|
function onSearchFile(name?:string){ |
|
|
|
let _page: matterPage = { |
|
|
|
page: 0, |
|
|
|
pageSize: 50, |
|
|
|
orderCreateTime: "DESC", |
|
|
|
orderDir: "DESC", |
|
|
|
name:name |
|
|
|
}; |
|
|
|
|
|
|
|
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.filter((item)=>{ |
|
|
|
return !item.dir |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
//加载目录文件列表 |
|
|
|
function onLoadMatterList(){ |
|
|
|
let _page: matterPage = { |
|
|
|
page: paginInfo.value.page, |
|
|
|
pageSize: 50, |
|
|
|
orderCreateTime: "DESC", |
|
|
|
orderDir: "DESC" |
|
|
|
orderDir: "DESC", |
|
|
|
puuid:currentNode.value.uuid, |
|
|
|
deleted:false |
|
|
|
}; |
|
|
|
//如果有搜索条件,说明是按名称搜索,这里要把puuid清空;如果没有搜索条件,说明是普通目录查询 |
|
|
|
if(name){ |
|
|
|
_page.name=name |
|
|
|
}else{ |
|
|
|
_page.puuid=currentUuid.value |
|
|
|
_page.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 |
|
|
|
matterList.value=resp.data.data.filter((item)=>{ |
|
|
|
return !item.dir |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
//----------for dir----------- |
|
|
|
@ -228,10 +255,15 @@ function createDir(){ |
|
|
|
function onCreateDir(){ |
|
|
|
postCreateDir(uid,{ |
|
|
|
userUuid:uid, |
|
|
|
puuid:currentUuid.value, |
|
|
|
puuid:currentNode.value.uuid, |
|
|
|
name:newdir.value, |
|
|
|
}).then(()=> { |
|
|
|
}).then((resp)=> { |
|
|
|
newdir.value="" |
|
|
|
//调用tree的append方法 |
|
|
|
treeRef.value.append( |
|
|
|
{uuid:resp.data.uuid,dir:false,name:resp.data.name,puuid:resp.data.puuid}, |
|
|
|
currentNode.value.uuid |
|
|
|
) |
|
|
|
onLoadMatterList() |
|
|
|
}) |
|
|
|
.catch((e)=>{ |
|
|
|
@ -239,23 +271,73 @@ function onCreateDir(){ |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
function handleDoubleClick(row:matterInfo,ind?:number){ |
|
|
|
if(row.dir){ |
|
|
|
//table的双击事件也在此方法处理 |
|
|
|
if(typeof(ind)==="number"){ |
|
|
|
//返回某一级 |
|
|
|
if(breadcrumbList.value.length>1){ |
|
|
|
breadcrumbList.value=breadcrumbList.value.slice(0,ind+1) |
|
|
|
currentUuid.value=breadcrumbList.value[breadcrumbList.value.length-1].uuid |
|
|
|
onLoadMatterList() |
|
|
|
//树节点展开 |
|
|
|
function onNodeExpand(node: TreeNode, resolve: (data: matterTree[]) => void, reject: () => void) { |
|
|
|
if ((node.data as matterTree).uuid) { |
|
|
|
const cuuid = (node.data as matterTree).uuid |
|
|
|
currentNode.value = node.data |
|
|
|
|
|
|
|
let _page: matterPage = { |
|
|
|
page: 0, |
|
|
|
pageSize: 50, |
|
|
|
orderCreateTime: "DESC", |
|
|
|
orderDir: "DESC", |
|
|
|
puuid: cuuid, |
|
|
|
deleted: false |
|
|
|
}; |
|
|
|
|
|
|
|
getMatterList(uid, _page).then((resp) => { |
|
|
|
paginInfo.value = { total: resp.data.totalPages, page: resp.data.page } |
|
|
|
matterList.value = resp.data.data.filter((item)=>{ |
|
|
|
return !item.dir |
|
|
|
}) |
|
|
|
let node_data = resp.data.data.filter((item) => { |
|
|
|
return item.dir |
|
|
|
}).map((item) => { |
|
|
|
item.dir = !item.dir |
|
|
|
return item |
|
|
|
}) |
|
|
|
|
|
|
|
resolve(node_data) |
|
|
|
}).catch(() => reject()) |
|
|
|
} |
|
|
|
} |
|
|
|
//树节点单击 |
|
|
|
function onNodeClick(data:matterTree,node:TreeNode,self:any,env:any){ |
|
|
|
if (currentNode.value.uuid === data.uuid) return; |
|
|
|
const cuuid = data.uuid |
|
|
|
currentNode.value = data |
|
|
|
let _page: matterPage = { |
|
|
|
page: 0, |
|
|
|
pageSize: 50, |
|
|
|
orderCreateTime: "DESC", |
|
|
|
orderDir: "DESC", |
|
|
|
puuid: cuuid, |
|
|
|
deleted: false |
|
|
|
}; |
|
|
|
|
|
|
|
getMatterList(uid, _page).then((resp) => { |
|
|
|
paginInfo.value = { total: resp.data.totalPages, page: resp.data.page } |
|
|
|
matterList.value = resp.data.data.filter((item)=>{ |
|
|
|
return !item.dir |
|
|
|
}) |
|
|
|
|
|
|
|
//展开的时候暂时不做目录更新,看以后的使用情况 |
|
|
|
let node_data = resp.data.data.filter((item) => { |
|
|
|
return item.dir |
|
|
|
}).map((item) => { |
|
|
|
item.dir = !item.dir |
|
|
|
return item |
|
|
|
}) |
|
|
|
|
|
|
|
if (node) { |
|
|
|
if(data.children && data.children.length!==node_data.length){ |
|
|
|
treeRef.value.updateKeyChildren(data.uuid,node_data) |
|
|
|
} |
|
|
|
} else if(data.children.length!==node_data.length){ |
|
|
|
data.children = node_data |
|
|
|
} |
|
|
|
}else{ |
|
|
|
//进入下一级 |
|
|
|
currentUuid.value=row.uuid |
|
|
|
breadcrumbList.value.push(row) |
|
|
|
onLoadMatterList() |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
function handleMouseEnter(row:any){ |
|
|
|
@ -277,7 +359,7 @@ function handleSigLoadErr(error: Error, uploadFile: UploadFile, uploadFiles:Uplo |
|
|
|
//http://172.20.2.87:6010/api/alien/preview/5a10aaf6-396e-4d9a-7e87-3c5c8029d4db/123.png?ir=fill_100_100 |
|
|
|
//渲染完页面再执行 |
|
|
|
onMounted(() => { |
|
|
|
onLoadMatterList() |
|
|
|
onNodeClick(treeData.value[0], null as unknown as TreeNode, null, null) |
|
|
|
}); |
|
|
|
|
|
|
|
const handleSelectionChange = (val:matterInfo[]) => { |
|
|
|
@ -287,14 +369,26 @@ const handleSelectionChange = (val:matterInfo[]) => { |
|
|
|
</script> |
|
|
|
|
|
|
|
<template> |
|
|
|
<div style="display:grid;grid-template-columns:1fr 4fr; width: 100%;height: 100%;"> |
|
|
|
<div class="menus_tree"> |
|
|
|
<el-tree |
|
|
|
ref="treeRef" |
|
|
|
style="max-width: 600px" |
|
|
|
:data="treeData" |
|
|
|
node-key="uuid" |
|
|
|
lazy |
|
|
|
:props="{label: 'name',children:'children',isLeaf:'dir'}" |
|
|
|
:load="onNodeExpand" |
|
|
|
:default-expanded-keys="['root']" |
|
|
|
@node-click="onNodeClick" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
<div class="app_container"> |
|
|
|
<el-row :gutter="24" style="margin: 12px 0px;"> |
|
|
|
<el-breadcrumb separator="/"> |
|
|
|
<el-breadcrumb-item v-for="(item,index) in breadcrumbList" |
|
|
|
:key="index" @click="index===breadcrumbList.length-1?'': handleDoubleClick(item,index)"> |
|
|
|
<span style="font-weight: bold;">{{ item.name }}</span> |
|
|
|
</el-breadcrumb-item> |
|
|
|
</el-breadcrumb> |
|
|
|
<el-link v-if="currentNode.name!=='root'" @click="onNodeClick(treeData[0], null as unknown as TreeNode, null, null)"> |
|
|
|
<span style="font-weight: bold;margin-right: 5px;">根目录</span>/ |
|
|
|
</el-link> |
|
|
|
<span style="font-weight: bold;margin:0 5px;">{{ currentNode.name }}</span> |
|
|
|
</el-row> |
|
|
|
|
|
|
|
<el-row :gutter="24"> |
|
|
|
@ -315,11 +409,14 @@ const handleSelectionChange = (val:matterInfo[]) => { |
|
|
|
<el-button @click="onDelMatBatch">删除</el-button> |
|
|
|
</span> |
|
|
|
<el-button @click="onLoadMatterList()">刷新</el-button> |
|
|
|
<el-button type="danger" plain @click="onShareMatter({uuid:currentNode.uuid,name:currentNode.name})">分享目录</el-button> |
|
|
|
<el-button type="danger" plain @click="onDelMatter({uuid:currentNode.uuid,name:currentNode.name,dir:true, |
|
|
|
puuid:currentNode.puuid,path:currentNode.path})">删除目录</el-button> |
|
|
|
</el-col> |
|
|
|
|
|
|
|
<el-col :span="8" class="search"> |
|
|
|
<el-input placeholder="搜索文件" v-model="searchname" @blur="searchname===''?onLoadMatterList():''"/> |
|
|
|
<el-button :icon="Search" @click="onLoadMatterList(searchname)"></el-button> |
|
|
|
<el-button :icon="Search" @click="onSearchFile(searchname)"></el-button> |
|
|
|
</el-col> |
|
|
|
</el-row> |
|
|
|
|
|
|
|
@ -333,10 +430,9 @@ const handleSelectionChange = (val:matterInfo[]) => { |
|
|
|
row-key="uuid" |
|
|
|
:row-style ="() => ({ lineHeight: '36px' })" |
|
|
|
@selection-change="handleSelectionChange" |
|
|
|
@cell-dblclick="handleDoubleClick" |
|
|
|
@cell-mouse-enter="handleMouseEnter"> |
|
|
|
<el-table-column type="selection" width="50" /> |
|
|
|
<el-table-column width="650" property="name" label="文件名"> |
|
|
|
<el-table-column width="450" property="name" label="文件名"> |
|
|
|
<template #default="scope"> |
|
|
|
<input type="text" autofocus placeholder="文件夹名" style="border:groove;height:30px;" v-model="newdir" @change="onCreateDir" v-if="scope.row.name===''" /> |
|
|
|
<div v-if="scope.row.name" style="display: flex; align-items: center;"> |
|
|
|
@ -374,16 +470,26 @@ const handleSelectionChange = (val:matterInfo[]) => { |
|
|
|
</el-row> |
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<style lang="scss" scoped> |
|
|
|
.menus_tree{ |
|
|
|
padding: 20px 0px 0px 15px; |
|
|
|
height: 100%; |
|
|
|
overflow-y: auto; |
|
|
|
.el-tree{ |
|
|
|
--el-tree-node-hover-bg-color:#d9dadb; |
|
|
|
--el-tree-node-content-height:43px; |
|
|
|
--el-tree-expand-icon-color:#4c4c4e; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
.app_container { |
|
|
|
padding: 10px 30px 0px 30px; |
|
|
|
height: calc(100% - 10px); |
|
|
|
overflow: hidden; |
|
|
|
overflow-y: auto; |
|
|
|
width: 100%; |
|
|
|
|
|
|
|
} |
|
|
|
.search{ |
|
|
|
margin-right: 20px; |
|
|
|
@ -396,6 +502,8 @@ const handleSelectionChange = (val:matterInfo[]) => { |
|
|
|
align-self: flex-start; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.dynamic-width-message-box-byme .el-message-box__message{ |
|
|
|
width: 100%; |
|
|
|
} |
|
|
|
|